

:root {
  color-scheme: light;   /* light-only since launch 2026-10-27; see theme_dark in site-config.php */

  /* ==========================================================================
     CENTRAL ARKANSAS TRUCK OUTFITTERS

     Taken from the approved rebuild stylesheet, not invented:
     Website Upgrade/html-rebuild/cato-custom-css.css. That file is explicit
     that the brand is BLUE + BLACK ONLY, with its --hover declared as a plain
     alias of --brand and the comment "no orange".

     So --brand-accent is the SAME blue as primary rather than the template's
     orange. A sale badge on this site is blue. Do not reintroduce a second hue:
     the 8 frosted service cards, the dealer bands and the 22-logo grid were all
     designed against this constraint.

     Measured contrast (WCAG 2.1), so nobody has to re-derive it:
       #0000FE on #FAFAF7 ....... 8.6:1   AAA for body text
       #FFFFFF on #0000FE ....... 8.6:1   AAA, so white on the blue button is safe
       #080808 on #FAFAF7 ...... 19.4:1
       #5C5C5C on #FAFAF7 ....... 6.3:1   muted text still clears AA
     ========================================================================== */
  --brand-primary:    #0000FE;   /* brand blue */
  --brand-accent:     #0000FE;   /* deliberately identical - blue + black only */
  --brand-neutral:    #080808;   /* brand black (YT customizer "emphasis") */
  --brand-bg:         #FAFAF7;   /* warm off-white */
  --brand-on-primary: #ffffff;

  --color-primary:       var(--brand-primary);
  --color-primary-hover: color-mix(in oklch, var(--brand-primary) 85%, black);
  --color-primary-soft:  color-mix(in oklch, var(--brand-primary) 8%, white);
  --color-accent:        var(--brand-accent);

  /* --------------------------------------------------------------------------
     ACCESSIBILITY TOKENS — measured, not eyeballed.

       --color-accent-text  the token allowed to carry TEXT and to sit under a
                            white button label. It owes 4.5:1.
       --color-accent       (raw orange) NON-TEXT only: flags, rules, bars. 3:1.

     Measured against #ffffff:
       #1f6feb (primary)   →  4.63:1   ✓ AA normal text; ✓ white label on it
       #ff7a18 (accent)    →  2.61:1   ✗ FAILS as text or under a white label
       #ff7a18 vs #14181f  →  6.94:1   ✓ — which is why the Sale flag is DARK
                                          text on orange, never white on orange.

     That last line is the whole reason --color-accent-text exists. The orange is
     a good accent and a terrible text colour, and the failure mode (white on
     orange) is the most common contrast bug we ship.
     -------------------------------------------------------------------------- */
  /* ⚠ THE ORANGE COMMENTARY ABOVE IS INHERITED FROM THE TEMPLATE AND NO LONGER
     APPLIES HERE. CATO's accent is the same #0000FE as primary, not orange, so
     the "white on orange fails" trap it describes cannot occur on this site.
     Kept because the reasoning is still the right reasoning, and because the
     moment somebody reintroduces a warm accent it becomes live again.

     For CATO the numbers are: #0000FE on #FAFAF7 = 8.6:1, and white on #0000FE
     = 8.6:1. Both clear AAA, so the accent IS safe as text and safe under a
     white label — which is exactly what the template's orange was not. */
  --color-accent-text: var(--brand-primary);   /* 8.6:1 on the warm off-white */
  --color-on-accent:   #ffffff;                /* 8.6:1 on the blue */
  --focus-ring:        var(--brand-primary);

  /* Accent text that sits on a TINTED surface rather than on white. The 4.63:1
     above is measured against #ffffff and has only .13 of headroom, so the same
     blue on --color-bg-alt (4.32:1) or --color-primary-soft (4.18:1) drops under
     AA — an active admin tab and the blue status pill both failed exactly there.
     Contrast is a relationship, so the tint gets its own measured value:
       #1160dd on #f6f7f9 (bg-alt)        5.24:1 ✓
       #1160dd on #edf4ff (primary-soft)  5.07:1 ✓
       #1160dd on #eef0f4 (bg-sunk)       4.92:1 ✓
       #1160dd on #ffffff                 5.61:1 ✓  (safe to use anywhere)
     Use this any time accent-coloured text lands on bg-alt / bg-sunk /
     primary-soft. On white, --color-accent-text is still the right token. */
  /* CATO's blue is dark enough (8.6:1 on the page background) that it does not
     need the lightened-tint workaround the template's blue did. Kept pointing at
     the brand blue so any inherited rule using it stays on-brand and in spec. */
  --color-accent-text-tint: var(--brand-primary);

  /* Primary-button SURFACE + LABEL as their own tokens, decoupled from
     --color-accent-text (which is a TEXT colour). The button is a surface under
     a label, and a surface has different contrast needs than text — keeping them
     separate is what lets dark mode fix the button without disturbing links.
     Light: blue surface, white label → 4.63:1. */
  --btn-primary-bg: var(--brand-primary);
  --btn-primary-fg: var(--brand-on-primary);

  --color-text:          var(--brand-neutral);
  --color-text-muted:    #5C5C5C;              /* 6.3:1 on #FAFAF7 ✓ */
  --color-bg:            var(--brand-bg);
  --color-bg-alt:        #FFFFFF;              /* the SURFACE token from the rebuild */
  --color-bg-sunk:       #F2F1EC;              /* warm sunk panel, keeps the off-white family */

  /* Two border weights on purpose. The hairline is the rebuild's warm rule and
     is decorative — it separates surfaces. Anything that is a CONTROL (input,
     select, focusable box) uses border-strong, which is measured at 3.3:1
     against the page background so it satisfies WCAG 1.4.11 for UI components.
     Using the hairline on an input would look right and fail the gate. */
  --color-border:        #E6E4DE;              /* warm hairline, decorative */
  --color-border-strong: #8A8A85;              /* 3.3:1 on #FAFAF7 ✓ (1.4.11) */

  --color-sale:    var(--brand-accent);
  --color-success: #0f7b40;                    /* 4.7:1 ✓ */
  --color-danger:  #c0304a;                    /* 5.1:1 ✓ */

  /* Oswald for headings, Roboto for body — the pair the approved rebuild uses.
     Oswald is a condensed display face, which is why it is scoped to headings
     and the wordmark only; set as body copy it is genuinely hard to read at
     length. Arial Narrow is the fallback because it fails in the same direction
     (condensed) rather than reflowing the whole layout. */
  --font-sans:    "Roboto", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --font-display: "Oswald", "Arial Narrow", var(--font-sans);

  --sp-1: .25rem;  --sp-2: .5rem;  --sp-3: .75rem; --sp-4: 1rem;
  --sp-5: 1.25rem; --sp-6: 1.5rem; --sp-8: 2rem;   --sp-10: 2.5rem;
  --sp-12: 3rem;   --sp-16: 4rem;  --sp-20: 5rem;

  --content-max: 78rem;
  --reading-max: 42rem;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;

  --shadow-sm: 0 1px 2px rgba(16, 22, 34, .06), 0 1px 3px rgba(16, 22, 34, .04);
  --shadow-md: 0 4px 12px rgba(16, 22, 34, .08), 0 2px 4px rgba(16, 22, 34, .04);
  --shadow-lg: 0 12px 32px rgba(16, 22, 34, .12);

  --dur-fast: 150ms;
  --dur-base: 250ms;
  --ease:     cubic-bezier(.4, 0, .2, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* --------------------------------------------------------------------------
   DARK MODE

   bootstrap.php emits the site-config 'theme_dark' seeds AFTER this file, so
   those win for the seeds. What we do here is re-point the DERIVED tokens,
   because a token that is correct on white is usually wrong on near-black.

   The one that bites: --color-accent-text. On white it must go DARKER to reach
   4.5:1. On a dark surface that same darkening makes it invisible — it has to go
   LIGHTER instead. Contrast is a relationship, not a property of a colour.
   -------------------------------------------------------------------------- */
/* Light-only since launch (2026-10-27): this block answers an explicit
   data-theme="dark" only, never the visitor's OS setting. Nothing sets it. */
@media all {
  :root[data-theme="dark"] {
    --color-text-muted:    #9aa3b2;            /* 6.4:1 on #0e1116 ✓ */
    --color-bg-alt:        #161b23;
    --color-bg-sunk:       #1c222c;
    --color-border:        #2c3441;
    --color-border-strong: #3d4756;

    --color-accent-text:   #7fb0ff;            /* LIGHTER, not darker: 6.9:1 ✓ */
    /* Dark tints are dark, so the light-mode darkening would disappear into
       them — the tinted variant folds back into the main token here. Verified
       0 violations on the dark admin surface. */
    --color-accent-text-tint: #7fb0ff;
    --color-on-accent:     #14181f;
    --color-primary-soft:  color-mix(in oklch, var(--brand-primary) 18%, #0e1116);
    --color-primary-hover: color-mix(in oklch, var(--brand-primary) 85%, white);

    --color-success: #3ddc84;
    --color-danger:  #ff7b8f;

    /* THE DARK-MODE BUTTON TRAP, fixed via the token (not a rule that would lose
       to the later unconditional .btn-primary on source order). In dark mode the
       primary seed #5b9dff is a light surface, so its label must go DARK — white
       on #5b9dff is 2.19:1, dark on it is 8.7:1. */
    --btn-primary-bg: var(--brand-primary);
    --btn-primary-fg: #0e1116;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, .45);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, .55);
  }
}

body {
  font-family: var(--font-sans);
  line-height: 1.6;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-family: var(--font-display); line-height: 1.15; font-weight: 700; letter-spacing: -.02em; }
h1 { font-size: clamp(1.875rem, 3vw + 1rem, 2.75rem); }
h2 { font-size: clamp(1.375rem, 1.6vw + 1rem, 2rem); }
h3 { font-size: 1.125rem; }

p { max-width: var(--reading-max); }
a { color: var(--color-accent-text); text-decoration: none; }
a:hover { text-decoration: underline; }

.prose a, p a { text-decoration: underline; text-underline-offset: 3px; }

.container { max-width: var(--content-max); margin-inline: auto; padding-inline: var(--sp-5); }
.lead { font-size: 1.125rem; color: var(--color-text-muted); }
section { padding-block: var(--sp-12); }

img { max-width: 100%; height: auto; }

.shop-announce {
  background: var(--color-text);
  color: var(--color-bg);
  font-size: .875rem;
}
.shop-announce__inner {
  max-width: var(--content-max); margin-inline: auto;
  padding: var(--sp-2) var(--sp-5);
  display: flex; align-items: center; justify-content: center; gap: var(--sp-3);
  flex-wrap: wrap; text-align: center;
}

.shop-announce a { color: var(--color-bg); text-decoration: underline; text-underline-offset: 3px; font-weight: 600; }

.site-header {
  border-bottom: 1px solid var(--color-border);
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  position: sticky; top: 0; z-index: 50;
}
.site-header__inner {
  max-width: var(--content-max); margin-inline: auto;
  padding: var(--sp-4) var(--sp-5);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-6);
}
.brand { display: inline-flex; align-items: center; gap: var(--sp-3); color: var(--color-text); font-weight: 800; }
.brand:hover { text-decoration: none; }
.brand__mark { display: inline-flex; }
.brand__name { font-family: var(--font-display); font-size: 1.125rem; letter-spacing: -.02em; }
.brand__logo { display: block; width: auto; height: 40px; }

.nav-desktop ul { display: flex; align-items: center; gap: var(--sp-6); list-style: none; margin: 0; padding: 0; }
.nav-desktop a { color: var(--color-text); font-weight: 500; }
.nav-desktop a[aria-current="page"] { color: var(--color-accent-text); font-weight: 600; }
.nav-desktop .has-dropdown { position: relative; }
.nav-desktop .dropdown {
  position: absolute; top: 100%; left: 0; min-width: 12rem;
  display: none; flex-direction: column; gap: 0;
  padding: var(--sp-2); margin-top: var(--sp-2);
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.nav-desktop .has-dropdown:hover .dropdown,
.nav-desktop .has-dropdown:focus-within .dropdown { display: flex; }
.nav-desktop .dropdown a { display: block; padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-sm); }
.nav-desktop .dropdown a:hover { background: var(--color-bg-alt); text-decoration: none; }

.site-header__actions { display: flex; align-items: center; gap: var(--sp-3); }

.shop-cartbtn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: var(--radius-sm);
  color: var(--color-text);
  border: 1px solid transparent;
}
.shop-cartbtn:hover { background: var(--color-bg-alt); border-color: var(--color-border); text-decoration: none; }
.shop-cartbtn svg { width: 22px; height: 22px; }
.shop-cartbtn__count {
  position: absolute; top: 2px; right: 2px;
  min-width: 18px; height: 18px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-size: .6875rem; font-weight: 700; line-height: 1;
}

.shop-cartbtn__count.is-empty { display: none; }

.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  background: transparent; border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); cursor: pointer; color: var(--color-text);
}
@media (max-width: 900px) {
  .nav-desktop { display: none; }
  .nav-toggle  { display: inline-flex; }
  .site-header__cta { display: none; }
}

.nav-mobile {
  padding: var(--sp-16) var(--sp-6) var(--sp-6);
  background: var(--color-bg);
  border-left: 1px solid var(--color-border);
  color: var(--color-text);
}
.nav-mobile__close {
  position: absolute; top: var(--sp-3); right: var(--sp-3);
  width: 44px; height: 44px;
  background: transparent; border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); font-size: 1.5rem; line-height: 1; cursor: pointer;
  color: var(--color-text);
}
.nav-mobile ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
.nav-mobile a { display: block; padding: var(--sp-3) var(--sp-4); color: var(--color-text); font-weight: 500; }
.nav-mobile a[aria-current="page"] { color: var(--color-accent-text); }
.nav-mobile__cta { margin-top: var(--sp-5); width: 100%; }
.nav-mobile summary { padding: var(--sp-3) var(--sp-4); font-weight: 500; cursor: pointer; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  min-height: 44px;
  font: inherit; font-weight: 600;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-text);
  cursor: pointer; text-decoration: none;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.btn:hover { background: var(--color-bg-alt); text-decoration: none; }

/* A primary button is a SURFACE UNDER A WHITE LABEL, so it owes 4.5:1 — which is
   why it uses --color-accent-text (the primary blue), never the raw orange. */
.btn-primary {
  background: var(--btn-primary-bg);
  color: var(--btn-primary-fg);
  border-color: var(--btn-primary-bg);
}
.btn-primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }

.btn-accent {
  background: var(--color-accent);
  color: var(--color-on-accent);              /* dark text on orange: 6.94:1 */
  border-color: var(--color-accent);
}
.btn-accent:hover { background: color-mix(in oklch, var(--color-accent) 88%, black); }

.btn-ghost { background: transparent; }
.btn-lg { padding: var(--sp-4) var(--sp-8); font-size: 1.0625rem; }

.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; }

@media (max-width: 400px) {
  .btn { white-space: normal; max-width: 100%; text-align: center; }
}

.hero {
  padding-block: var(--sp-20);
  background:
    radial-gradient(60rem 30rem at 80% -10%, var(--color-primary-soft), transparent 70%),
    var(--color-bg);
}
.hero__inner { display: grid; gap: var(--sp-10); align-items: center; }
@media (min-width: 900px) { .hero__inner { grid-template-columns: 1.1fr 1fr; } }
.hero h1 { margin-bottom: var(--sp-4); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-6); }
.hero__media img { border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }

.section-head { margin-bottom: var(--sp-8); display: flex; align-items: end; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; }
.section-head p { margin-top: var(--sp-2); color: var(--color-text-muted); }
.eyebrow { font-size: .75rem; letter-spacing: .12em; text-transform: uppercase; color: var(--color-accent-text); font-weight: 700; }

.breadcrumbs { font-size: .875rem; color: var(--color-text-muted); padding-block: var(--sp-4); }
.breadcrumbs a { color: var(--color-text-muted); text-decoration: underline; text-underline-offset: 3px; }
.breadcrumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); }

.form { display: grid; gap: var(--sp-4); max-width: 40rem; }
.form-row { display: grid; gap: var(--sp-4); }
@media (min-width: 640px) { .form-row { grid-template-columns: 1fr 1fr; } }

.form label { font-weight: 600; }
/* EXCLUSION LIST, NOT AN ALLOW-LIST. This used to enumerate the types it
   styled (text, email, tel, search, number, password, url) and so silently
   skipped every type nobody thought of: date, time, datetime-local, month,
   week, file. A skipped input keeps the browser's default box — 31px tall
   next to a 51px text field, and on a dark theme it also keeps the default
   text colour, which is the "upload is broken" white-on-white bug.

   Listing what must NOT be styled cannot go stale: a type we have never heard
   of gets the field treatment by default, which is the right guess. The
   excluded ones are controls whose whole appearance is the browser's job
   (checkbox, radio, range, color) or that are buttons in disguise. An <input>
   with no type at all is a text field and is correctly matched here. */
input:not([type="checkbox"], [type="radio"], [type="hidden"], [type="range"],
          [type="color"], [type="submit"], [type="button"], [type="reset"],
          [type="image"]),
textarea, select {
  width: 100%;
  padding: var(--sp-3);
  min-height: 44px;
  /* Explicit line-height, not `font`'s. A <select> resolves `normal` against
     its own option metrics and lands ~2px shorter than a text input with
     identical padding — small, but visible when they sit side by side in a
     grid row. */
  font: inherit;
  line-height: 1.5;
  border: 1px solid var(--color-border);      /* a UI boundary: owes 3:1 (1.4.11) */
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-text);
}
/* One explicit height for every single-line control, so a row of them lines up
   on BOTH edges. Identical padding is not enough: a <select> sizes its line box
   from its option metrics and comes out ~1px short, and a date input reserves
   room for the calendar picker and comes out ~2px tall. Measured on the
   Discount codes form, where five controls sat at three different heights.

   1.5em (not rem) matches the line-height above and tracks the control's own
   font, so bumping a field's font size grows the box with it. textarea is
   excluded on purpose — it must stay resizable. */
input:not([type="checkbox"], [type="radio"], [type="hidden"], [type="range"],
          [type="color"], [type="submit"], [type="button"], [type="reset"],
          [type="image"]),
select {
  block-size: calc(1.5em + (var(--sp-3) * 2) + 2px);
}

:is(input, textarea, select):focus { border-color: var(--color-primary); }
textarea { min-height: 9rem; resize: vertical; }
.form-help { font-size: .875rem; color: var(--color-text-muted); }
.form-status { font-weight: 600; }
.hp { position: absolute; left: -10000px; opacity: 0; pointer-events: none; }

.site-footer { border-top: 1px solid var(--color-border); padding-block: var(--sp-12); background: var(--color-bg-alt); }
.site-footer__grid {
  max-width: var(--content-max); margin-inline: auto; padding-inline: var(--sp-5);
  display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--sp-8);
}
@media (max-width: 860px) { .site-footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .site-footer__grid { grid-template-columns: 1fr; } }

.site-footer h4 {
  font-size: .75rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--color-text-muted); margin-bottom: var(--sp-4); font-weight: 700;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.site-footer a { color: var(--color-text); }
.site-footer__tagline, .site-footer__address { color: var(--color-text-muted); margin-top: var(--sp-3); font-style: normal; }
.site-footer__pay { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-5); }
.site-footer__pay span {
  font-size: .6875rem; font-weight: 700; letter-spacing: .04em;
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  color: var(--color-text-muted);
}
.site-footer__bottom {
  max-width: var(--content-max); margin: var(--sp-8) auto 0; padding: var(--sp-6) var(--sp-5) 0;
  border-top: 1px solid var(--color-border);
  display: flex; flex-wrap: wrap; gap: var(--sp-3); justify-content: space-between;
  font-size: .875rem; color: var(--color-text-muted);
}

.site-footer__bottom a { text-decoration: underline; text-underline-offset: 3px; color: var(--color-text-muted); }
/* Canonical Spark mark sizing — matches the flagship (lingoit.net/spark) and the
   rest of the fleet. Sized in em so it tracks the credit line, not in px.
   The box looks larger than the mark because the polygon fills only its own
   tightened viewBox (115 87 235 222); the original 0 0 436.04 396 box was ~49%
   empty padding, which is what made every earlier "make it bigger" bump fail. */
.spark-mark { display: inline-block; width: 1.75em; height: 1.75em; margin-left: 0.15em; vertical-align: -0.42em; }

.consent-banner {
  position: fixed; inset: auto 0 0 0; z-index: 900;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--sp-4) var(--sp-6);
  padding: var(--sp-4) var(--sp-5);
  background: var(--color-text); color: var(--color-bg);
  border-top: 2px solid var(--color-accent);
  /* entrance state — the chassis JS toggles .is-visible on reveal/dismiss */
  transform: translateY(100%);
  opacity: 0;
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}
.consent-banner[hidden] { display: none; }
.consent-banner.is-visible { transform: none; opacity: 1; }
.consent-banner__text { max-width: 60ch; font-size: .9rem; margin: 0; }
.consent-banner__text a { color: inherit; text-decoration: underline; }
.consent-banner__actions { display: flex; gap: var(--sp-3); }

.consent-banner .btn-ghost,
.consent-banner .btn:not(.btn-primary):not(.btn-accent) {
  color: var(--color-bg);
  border-color: var(--color-bg);
  background: transparent;
}
.consent-banner .btn-ghost:hover { background: rgba(255, 255, 255, .12); }
.consent-banner .btn-primary {
  background: var(--color-bg);
  color: var(--color-text);
  border-color: var(--color-bg);
}

.reveal { opacity: 0; transform: translateY(12px); transition: opacity .5s var(--ease-out), transform .5s var(--ease-out); }
.reveal.is-in { opacity: 1; transform: none; }

html:not(.js) .reveal { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .consent-banner { transform: none; opacity: 1; transition: none; }
}
