/* ==========================================================================
   TOKENS — the single source of truth for the whole theme.
   Change values here; never hard-code a colour or size in a component.

   THREE LAYERS, AND THE ORDER MATTERS.

   1. BRAND INPUT (`--brand-*`). What a deployment owns. `/v1/site-config`
      returns the deployment's tokens and the UI emits them into `:root`
      after this file, so a plain `:root` block is all it takes to override
      one. Nothing below re-declares a `--brand-*` value in a scheme block.

   2. SEMANTIC COLOUR (`--color-*`). What components read. Every brand-derived
      value is computed FROM layer 1 with `color-mix`, once per scheme, so a
      deployment that sets one purple gets a purple hover, a purple wash and a
      purple focus ring without setting any of them.

   3. SCHEME (light default, dark below). Redefines layer 2 ONLY.

   This layering is the fix for a real bug: the dark block is written
   `:root:not([data-theme="light"])`, which outranks the deployment's plain
   `:root`, so when dark mode redefined `--color-primary` directly it silently
   threw the deployment's brand away and served the theme's own green to every
   visitor whose OS is dark. Deriving instead of redefining keeps the brand and
   still adapts it to the ground it is painted on. See D-65.
   ========================================================================== */

:root {
  /* ---------------------------------------------------------------
     1. BRAND INPUT — the only values a deployment is expected to set.
     Defaults are the theme's own: Zilly deep green-teal + Zilly yellow.
     --------------------------------------------------------------- */
  --brand-primary:   #22524d;   /* Zilly deep green / teal */
  --brand-accent:    #ffd400;   /* Zilly yellow */

  /* Derived from primary unless the deployment says otherwise, so a brand that
     sets one colour never ends up with the theme's green as its second. */
  --brand-secondary: color-mix(in oklab, var(--brand-primary) 78%, #000);

  /* ---------------------------------------------------------------
     BRAND RAMP — kept because the theme's own defaults are quoted from
     the source design and a few neutrals still reference them.
     --------------------------------------------------------------- */
  --green-50:  #f2f7f6;
  --green-100: #dbeae8;
  --green-200: #b6d4d0;
  --green-300: #86b5af;
  --green-400: #4f918a;
  --green-500: #33706a;
  --green-600: #22524d;   /* the default --brand-primary */
  --green-700: #1b423e;
  --green-800: #143331;
  --green-900: #0e2422;

  --yellow-100: #fff8d1;
  --yellow-400: #ffd400;  /* the default --brand-accent */
  --yellow-600: #d9b400;

  /* ---------------------------------------------------------------
     2. SEMANTIC COLOUR — light scheme
     --------------------------------------------------------------- */
  --color-primary:        var(--brand-primary);
  --color-primary-hover:  color-mix(in oklab, var(--brand-primary) 84%, #000);
  --color-primary-soft:   color-mix(in oklab, var(--brand-primary) 8%, #fff);
  --color-secondary:      var(--brand-secondary);

  --color-accent:         var(--brand-accent);
  --color-accent-hover:   color-mix(in oklab, var(--brand-accent) 86%, #000);
  --color-accent-soft:    color-mix(in oklab, var(--brand-accent) 18%, #fff);

  --color-heading:        #161925;
  --color-body:           #626571;
  /* Measured, not eyeballed: --color-meta carries the "valid until" line on every
     card and the offer count in the hero, and both sit on a tinted band as often
     as on white. 5.3:1 on white and 4.8:1 on the tint. The theme shipped #b0b2b8
     here, which was 2.1:1. */
  --color-muted:          #63666f;
  --color-meta:           #646873;
  --color-meta-strong:    #55585f;

  /* The page GROUND and the card SURFACE are no longer the same colour. They
     were both #ffffff, and a white card on a white page is a flat card however
     much shadow you put under it — the lift had nothing to lift off. The ground
     is barely tinted on purpose: enough for a card edge to exist, not enough to
     read as grey. Put it back to #ffffff to get the flat look back. */
  --color-bg:             #f4f5f7;
  --color-surface:        #ffffff;
  --color-surface-alt:    #eff1f3;  /* image plates, soft buttons */
  --color-surface-tint:   color-mix(in oklab, var(--brand-primary) 6%, #fff);
  --color-border:         #d7d7d7;
  --color-border-soft:    #ececec;

  --color-white:          #ffffff;
  --color-black:          #161925;

  /* Status */
  /* The price red. It is a TEXT colour first — the "now" price on a deal tile is
     the largest thing on the card, and large text needs 3:1, which this clears
     comfortably at 4.4:1 on white. It does NOT clear 4.5:1, so anything setting
     small white text on a red FILL uses --color-sale-strong instead. One vibrant
     red for the number, one darker red for the chips: that is why there are two. */
  --color-sale:        #e52e06;
  --color-sale-strong: color-mix(in oklab, var(--color-sale) 86%, #000);
  --color-danger:  #d90429;
  --color-error:   #d64545;
  --color-success: #1b8057;
  --color-warning: #b45309;
  --color-info:    #1d6fd0;
  --color-rating:  var(--color-accent);

  /* A SERVICE'S OWN COLOUR, and the only one in this file that is not the
     deployment's to change. WhatsApp green is a third-party mark in exactly the
     sense the `whatsapp://` scheme this product composes is — a convention that
     belongs to the service, not a fact about the country, the language or the
     brand. It is here rather than inline in a component so there is one of it,
     and it is the same value in both schemes because a service mark that drifts
     with the page's colour scheme stops being recognisable. See D-74. */
  --color-whatsapp: #25d366;

  /* ---------------------------------------------------------------
     INVERSE SURFACE — a band that is deliberately the opposite of the
     page: the promo strip, `.section--dark`, the dark footer.

     It is its OWN pair, not `--color-heading` with white written over it.
     That pairing is what made the promo strip white-on-white the moment
     `--color-heading` inverted for dark mode (1.10:1, measured). A surface
     token and a content token change together or not at all.
     --------------------------------------------------------------- */
  --color-inverse-surface: #161925;
  --color-inverse-content: rgb(255 255 255 / 82%);
  --color-inverse-heading: #ffffff;
  --color-inverse-border:  rgb(255 255 255 / 14%);

  /* The scrim behind a drawer or modal. Always dark, in both schemes — it is
     shade, not a surface, and it inverted along with --color-heading before. */
  --color-scrim: rgb(6 8 12 / 58%);

  /* ---------------------------------------------------------------
     ON-COLOUR TEXT — what to write ON a filled brand surface.

     Static defaults first, so a browser without relative colour syntax still
     gets a deliberate answer. The @supports block below then computes the
     real one from the colour's own lightness, which is what lets a deployment
     pick any brand — a near-black navy or a lemon yellow — and still get
     legible button labels without anyone hand-picking a foreground.
     --------------------------------------------------------------- */
  --color-primary-fg: #ffffff;
  --color-accent-fg:  #161925;
  --color-sale-fg:    #ffffff;
  /* Black, not white. WhatsApp's own button is white-on-green and measures
     2.0:1, which is not a button label — it is a decoration. The same green
     under black is 10.6:1 and is still unmistakably the WhatsApp button. */
  --color-whatsapp-fg: #161925;

  /* RGB channels, kept for consumers outside this file (WaslAdminUi reads
     --rgb-primary). Static: a hex custom property cannot be decomposed in CSS.
     Nothing in this theme uses them any more — brand-derived alphas are
     `color-mix(… , transparent)` so they follow the deployment's colour. */
  --rgb-primary:  34 82 77;
  --rgb-heading:  22 25 37;
  --rgb-accent:   255 212 0;
  --rgb-sale:     229 46 6;

  /* ---------------------------------------------------------------
     TYPOGRAPHY

     Two faces, and which one leads is decided by the page's language rather
     than by the build. Arabic pages lead with Cairo, English pages with Inter
     — the same binaries, one stylesheet, `:root:lang(en)` doing the switch.

     A deployment may put its own face in front through `--brand-font-body`.
     It is a LEAD, not a replacement: the script stack and the system
     fallbacks are always appended after it, which is the fix for a brand
     token of `'Cairo', sans-serif` collapsing the whole stack to one face and
     rendering the English site in an Arabic-first type.

     Self-hosted — see wwwroot/fonts/README.md.
     --------------------------------------------------------------- */
  --font-arabic: "Cairo";
  --font-latin:  "Inter";
  --font-fallback: "Segoe UI", Tahoma, "Geeza Pro", "Noto Sans Arabic",
                   -apple-system, BlinkMacSystemFont, Arial, sans-serif;

  /* Arabic first by default: this is an Arabic-first product, and `ar` is the
     language a deployment that sets no `lang` will be serving. */
  --font-lead:  var(--font-arabic);
  --font-stack: var(--font-arabic), var(--font-latin), var(--font-fallback);

  --font-body:    var(--brand-font-body, var(--font-lead)), var(--font-stack);
  --font-heading: var(--brand-font-heading, var(--brand-font-body, var(--font-lead))), var(--font-stack);
  --font-sans:    var(--font-body);
  --font-mono: "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;

  --fw-light:    300;
  --fw-normal:   400;
  --fw-medium:   500;
  --fw-semibold: 600;
  --fw-bold:     700;

  /* Type scale — matches the source design 1:1 */
  --fs-h1: 44px;  --lh-h1: 54px;
  --fs-h2: 36px;  --lh-h2: 42px;
  --fs-h3: 28px;  --lh-h3: 36px;
  --fs-h4: 22px;  --lh-h4: 28px;
  --fs-h5: 18px;  --lh-h5: 24px;
  --fs-h6: 14px;  --lh-h6: 18px;

  --fs-xs:   12px;
  --fs-sm:   13px;
  --fs-base: 14px;   /* dominant UI size: cards, buttons, nav */
  --fs-md:   15px;
  --fs-lg:   16px;   /* body copy */
  --fs-xl:   20px;

  --lh-body:  28px;  /* 1.75 on 16px — the theme's generous default */
  --lh-tight: 1.2;
  --lh-snug:  1.5;

  --ls-tight:  -0.2px;
  --ls-normal: 0;
  --ls-wide:   0.5px;  /* used on primary CTA labels */

  /* ---------------------------------------------------------------
     SPACING — 4px base
     --------------------------------------------------------------- */
  --space-0:  0;
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-7:  30px;
  --space-8:  36px;
  --space-9:  44px;
  --space-10: 56px;
  --space-11: 70px;
  --space-12: 90px;

  --section-py:    90px;  /* vertical rhythm of a page section */
  --section-py-sm: 56px;

  /* ---------------------------------------------------------------
     RADII
     --------------------------------------------------------------- */
  --radius-xs:   4px;
  --radius-sm:   5px;
  --radius:      12px;  /* THE CARD CORNER — cards, plates, inputs, panels */
  --radius-md:   8px;   /* inner chrome INSIDE a card: media plates, wells */
  --radius-lg:   12px;  /* == --radius; kept so existing card rules land on 12 */
  --radius-xl:   16px;
  --radius-2xl:  20px;
  --radius-3xl:  30px;
  --radius-pill: 50px;  /* EVERY button, every chip, the search bar */
  --radius-full: 50%;

  /* Semantic pair — what a new component should reach for, so the two shapes
     this design system actually has stay two and do not drift into five.
     `--radius-md` is deliberately SMALLER than the card: a plate nested inside
     a 12px corner with a 12px corner of its own reads as a misprint. */
  --radius-card:    var(--radius);
  --radius-control: var(--radius-pill);

  /* ---------------------------------------------------------------
     ELEVATION
     --------------------------------------------------------------- */
  /* The card lift. Every offer sits on one of these — wide, soft and low
     contrast, so a grid of forty reads as forty objects on a surface rather
     than forty drop shadows. Hover deepens it instead of adding a second. */
  --shadow-card:       0 4px 20px rgb(0 0 0 / 8%);
  --shadow-card-hover: 0 10px 30px rgb(0 0 0 / 12%);

  --shadow-xs:      0 2px 10px rgb(0 0 0 / 8%);
  --shadow-sm:      0 5px 15px rgb(0 0 0 / 5%);
  --shadow:         0 5px 20px rgb(0 0 0 / 5%);
  --shadow-md:      0 8px 24px rgb(149 157 165 / 20%);
  --shadow-lg:      0 30px 30px rgb(0 0 0 / 10%);
  --shadow-popover: 0 0 30px rgb(0 0 0 / 12%);
  --shadow-brand:   0 8px 8px color-mix(in srgb, var(--color-primary) 22%, transparent);
  --shadow-focus:   0 0 0 3px color-mix(in srgb, var(--color-primary) 24%, transparent);

  /* ---------------------------------------------------------------
     MOTION — 0.21s ease-in-out is the theme's signature timing
     --------------------------------------------------------------- */
  --dur-fast: 0.1s;
  --dur:      0.21s;
  --dur-slow: 0.4s;
  --ease:        ease-in-out;
  --ease-out:    cubic-bezier(0.25, 0.8, 0.25, 1);
  --ease-spring: cubic-bezier(0.3, 0.02, 0, 0.6);
  --transition:  all var(--dur) var(--ease);

  /* ---------------------------------------------------------------
     LAYOUT
     --------------------------------------------------------------- */
  --container-sm:  540px;
  --container-md:  720px;
  --container-lg:  960px;
  --container-xl:  1140px;
  --container-2xl: 1320px;
  --container-max: var(--container-2xl);
  --gutter: 24px;          /* full gap between grid columns */
  --gutter-half: 12px;     /* container side padding */

  --header-height: 80px;

  /* The front page's search pill. A hero control is sized by what it has to say
     about the page, not by what fits — this is the "savings search engine"
     claim, and 60px is what reads as that claim at hero scale. 50px was the
     brief's floor and is what it drops to below 768px. */
  --searchbar-hero-height: 60px;

  /* The phone's bottom bar, as a token because three files need to agree on it:
     layout.css draws it, the body pads for it, and the offer page's fixed action
     cluster sits where it would have been. */
  --mobile-bar-height: 64px;
  --z-dropdown: 100;
  --z-sticky:   200;
  --z-drawer:   900;
  --z-modal:    1000;
  --z-toast:    1100;

  /* Component-level knobs */
  --icon-size: 1em;
  --drawer-width: 360px;
  --focus-ring: 2px solid var(--color-primary);

  /* Masked, never filled: the glyph carries the shape and the CSS carries the
     colour, so nothing in this file paints a brand colour into a data-URI. */
  --tick-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.5 12.5 5 5 10-11'/%3E%3C/svg%3E");

  /* ---------------------------------------------------------------
     DIRECTION
     One multiplier, consumed as translateX(calc(Npx * var(--flip))),
     for the few transforms that have to follow the reading direction.
     Logical properties cover everything else; reach for this only when
     the thing being flipped is a transform.
     --------------------------------------------------------------- */
  --flip: 1;
}

[dir="rtl"] { --flip: -1; }

/* Latin leads on an English page. One rule, both directions, no second build —
   `lang` on <html> already comes from the request culture. */
:root:lang(en) {
  --font-lead:  var(--font-latin);
  --font-stack: var(--font-latin), var(--font-arabic), var(--font-fallback);
}

/* ==========================================================================
   ON-COLOUR TEXT, COMPUTED

   `oklch(from <colour> …)` reads the colour's own lightness. The clamp is a
   switch, not a gradient: below 0.62 lightness the expression goes positive
   and saturates to 1 (white text); above it, negative, clamping to 0 (black).
   Chroma is forced to 0 so the result is a true neutral either way.

   Guarded, because a browser without relative colour syntax would drop the
   declaration and inherit — and the static defaults above are the answer for
   the theme's own brand anyway.
   ========================================================================== */
@supports (color: oklch(from #000 l c h)) {
  :root {
    --color-primary-fg: oklch(from var(--color-primary) clamp(0, (0.62 - l) * 100, 1) 0 h);
    --color-accent-fg:  oklch(from var(--color-accent)  clamp(0, (0.62 - l) * 100, 1) 0 h);
    --color-sale-fg:    oklch(from var(--color-sale)    clamp(0, (0.62 - l) * 100, 1) 0 h);
    --color-whatsapp-fg: oklch(from var(--color-whatsapp) clamp(0, (0.62 - l) * 100, 1) 0 h);
  }
}

/* ==========================================================================
   DARK SCHEME
   Opt in with <html data-theme="dark">, or let the media query pick it up
   from the OS. Only LAYER 2 is redefined — never a `--brand-*`.
   ========================================================================== */
:root[data-theme="dark"] {
  /* The deployment's own colour, lifted until it carries on a dark ground.
     oklab keeps the hue, so a purple brand stays purple. */
  --color-primary:       color-mix(in oklab, var(--brand-primary) 55%, #fff);
  --color-primary-hover: color-mix(in oklab, var(--brand-primary) 38%, #fff);
  --color-primary-soft:  color-mix(in oklab, var(--brand-primary) 22%, #121826);
  --color-secondary:     color-mix(in oklab, var(--brand-secondary) 50%, #fff);

  /* THE ACCENT IS NOT LIFTED. Every other brand-derived colour here is mixed
     toward white to carry on a dark ground; the accent is the one that must not
     be, because mixing a saturated yellow toward white does not brighten it, it
     BLEACHES it — #ffd400 went to a pale cream and the search button stopped
     being the one loud thing on the page. A yellow is already at the light end
     of its own hue; it needs no help against #121826. Hover goes lighter, which
     is the only direction left. See D-71. */
  --color-accent:        var(--brand-accent);
  --color-accent-hover:  color-mix(in oklab, var(--brand-accent) 82%, #fff);
  --color-accent-soft:   color-mix(in oklab, var(--brand-accent) 20%, #121826);

  --color-heading:     #f3f4f6;
  --color-body:        #c3c9d4;
  /* The floor for anything secondary is #9ca3af — 7.0:1 on the page and 5.8:1 on
     a card. What was here read #8d939f and #9aa0ac, which are the "valid until"
     line and the offer count: the two things a visitor scans a grid for. */
  --color-muted:       #9ca3af;
  --color-meta:        #9ca3af;
  --color-meta-strong: #b7bdc9;

  /* Deep NAVY, not black and not neutral charcoal. A pure #000 ground makes every
     shadow disappear and every card edge with it; a blue-leaning ground keeps the
     surface ladder visible and stops a warm brand from looking muddy on it. */
  --color-bg:           #121826;
  --color-surface:      #1f2937;   /* the card: a clear step above the page */
  --color-surface-alt:  #2b3646;   /* plates INSIDE a card, a step above it again */
  --color-surface-tint: color-mix(in oklab, var(--brand-primary) 14%, #121826);
  --color-border:       #374151;
  --color-border-soft:  #2b3646;

  --color-black: #f3f4f6;

  /* Inverse stays dark here, one step up from the page rather than flipped. */
  --color-inverse-surface: #232f42;
  --color-inverse-content: #c3c9d4;
  --color-inverse-heading: #f3f4f6;
  --color-inverse-border:  rgb(255 255 255 / 10%);

  /* Lifted just far enough to clear its ground and no further. #e52e06 on #1f2937
     is 3.3:1, which the 22px price would scrape through on and nothing else
     would; this is 4.4:1 and is still unmistakably the same vibrant red-orange
     rather than the washed salmon a heavier white mix produces. Its computed
     foreground flips to black at this lightness, so the urgency chip reads
     black-on-red at 6.3:1 instead of white-on-red at 3.3:1. */
  --color-sale:        #ff4d1a;
  --color-sale-strong: var(--color-sale);
  --color-danger:  #ff6b6b;
  --color-error:   #ff8787;
  --color-success: color-mix(in oklab, #1b8057 55%, #fff);
  --color-warning: #fbbf24;
  --color-info:    #60a5fa;

  --rgb-primary: 79 145 138;
  --rgb-heading: 243 244 246;

  /* Same geometry, more of it: on a dark ground the lightness step above
     does most of the separating and the shadow only anchors the card. */
  --shadow-card:       0 4px 20px rgb(0 0 0 / 45%);
  --shadow-card-hover: 0 10px 30px rgb(0 0 0 / 55%);

  --shadow-xs:      0 2px 10px rgb(0 0 0 / 45%);
  --shadow-sm:      0 5px 15px rgb(0 0 0 / 40%);
  --shadow:         0 5px 20px rgb(0 0 0 / 45%);
  --shadow-md:      0 8px 24px rgb(0 0 0 / 55%);
  --shadow-lg:      0 30px 30px rgb(0 0 0 / 50%);
  --shadow-popover: 0 0 30px rgb(0 0 0 / 60%);
  --shadow-brand:   0 8px 8px rgb(0 0 0 / 45%);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* The deployment's own colour, lifted until it carries on a dark ground.
       oklab keeps the hue, so a purple brand stays purple. */
    --color-primary:       color-mix(in oklab, var(--brand-primary) 55%, #fff);
    --color-primary-hover: color-mix(in oklab, var(--brand-primary) 38%, #fff);
    --color-primary-soft:  color-mix(in oklab, var(--brand-primary) 22%, #121826);
    --color-secondary:     color-mix(in oklab, var(--brand-secondary) 50%, #fff);

    /* THE ACCENT IS NOT LIFTED. Every other brand-derived colour here is mixed
       toward white to carry on a dark ground; the accent is the one that must not
       be, because mixing a saturated yellow toward white does not brighten it, it
       BLEACHES it — #ffd400 went to a pale cream and the search button stopped
       being the one loud thing on the page. A yellow is already at the light end
       of its own hue; it needs no help against #121826. Hover goes lighter, which
       is the only direction left. See D-71. */
    --color-accent:        var(--brand-accent);
    --color-accent-hover:  color-mix(in oklab, var(--brand-accent) 82%, #fff);
    --color-accent-soft:   color-mix(in oklab, var(--brand-accent) 20%, #121826);

    --color-heading:     #f3f4f6;
    --color-body:        #c3c9d4;
    /* The floor for anything secondary is #9ca3af — 7.0:1 on the page and 5.8:1 on
       a card. What was here read #8d939f and #9aa0ac, which are the "valid until"
       line and the offer count: the two things a visitor scans a grid for. */
    --color-muted:       #9ca3af;
    --color-meta:        #9ca3af;
    --color-meta-strong: #b7bdc9;

    /* Deep NAVY, not black and not neutral charcoal. A pure #000 ground makes every
       shadow disappear and every card edge with it; a blue-leaning ground keeps the
       surface ladder visible and stops a warm brand from looking muddy on it. */
    --color-bg:           #121826;
    --color-surface:      #1f2937;   /* the card: a clear step above the page */
    --color-surface-alt:  #2b3646;   /* plates INSIDE a card, a step above it again */
    --color-surface-tint: color-mix(in oklab, var(--brand-primary) 14%, #121826);
    --color-border:       #374151;
    --color-border-soft:  #2b3646;

    --color-black: #f3f4f6;

    /* Inverse stays dark here, one step up from the page rather than flipped. */
    --color-inverse-surface: #232f42;
    --color-inverse-content: #c3c9d4;
    --color-inverse-heading: #f3f4f6;
    --color-inverse-border:  rgb(255 255 255 / 10%);

    /* Lifted just far enough to clear its ground and no further. #e52e06 on #1f2937
       is 3.3:1, which the 22px price would scrape through on and nothing else
       would; this is 4.4:1 and is still unmistakably the same vibrant red-orange
       rather than the washed salmon a heavier white mix produces. Its computed
       foreground flips to black at this lightness, so the urgency chip reads
       black-on-red at 6.3:1 instead of white-on-red at 3.3:1. */
    --color-sale:        #ff4d1a;
    --color-sale-strong: var(--color-sale);
    --color-danger:  #ff6b6b;
    --color-error:   #ff8787;
    --color-success: color-mix(in oklab, #1b8057 55%, #fff);
    --color-warning: #fbbf24;
    --color-info:    #60a5fa;

    --rgb-primary: 79 145 138;
    --rgb-heading: 243 244 246;

    /* Same geometry, more of it: on a dark ground the lightness step above
       does most of the separating and the shadow only anchors the card. */
    --shadow-card:       0 4px 20px rgb(0 0 0 / 45%);
    --shadow-card-hover: 0 10px 30px rgb(0 0 0 / 55%);

    --shadow-xs:      0 2px 10px rgb(0 0 0 / 45%);
    --shadow-sm:      0 5px 15px rgb(0 0 0 / 40%);
    --shadow:         0 5px 20px rgb(0 0 0 / 45%);
    --shadow-md:      0 8px 24px rgb(0 0 0 / 55%);
    --shadow-lg:      0 30px 30px rgb(0 0 0 / 50%);
    --shadow-popover: 0 0 30px rgb(0 0 0 / 60%);
    --shadow-brand:   0 8px 8px rgb(0 0 0 / 45%);
  }
}

/* Denser type on small screens */
@media (max-width: 767px) {
  :root {
    --fs-h1: 30px;  --lh-h1: 38px;
    --fs-h2: 24px;  --lh-h2: 31px;
    --fs-h3: 20px;  --lh-h3: 27px;
    --fs-h4: 18px;  --lh-h4: 25px;
    --fs-h5: 16px;  --lh-h5: 22px;
    --lh-body: 26px;
    --section-py: 44px;
    --section-py-sm: 24px;
    --gutter: 16px;
  }
}
