/* ==========================================================================
   TOKENS — the single source of truth.
   Values extracted from the the reference theme. Nothing below this file
   should ever hardcode a colour, a spacing value, or a duration.
   ========================================================================== */

:root {
  /* ---------------------------------------------------------------------
     1. COLOUR — neutral ramp
     `ui-00` is white, `ui-950` is black. Alpha variants are suffixed with
     the opacity percentage (ui-950-60 = black at 60%).
     --------------------------------------------------------------------- */
  --ui-00:      rgb(255 255 255 / 100%);
  --ui-50:      rgb(247 247 247 / 100%);
  --ui-100:     rgb(235 235 235 / 100%);
  --ui-200:     rgb(217 217 217 / 100%);
  --ui-300:     rgb(188 188 188 / 100%);
  --ui-400:     rgb(146 146 146 / 100%);
  --ui-500:     rgb(124 124 124 / 100%);
  --ui-600:     rgb(99 99 99 / 100%);
  --ui-700:     rgb(66 66 66 / 100%);
  --ui-800:     rgb(30 30 30 / 100%);
  --ui-950:     rgb(0 0 0 / 100%);

  --ui-00-20:   rgb(255 255 255 / 20%);
  --ui-00-40:   rgb(255 255 255 / 40%);
  --ui-00-80:   rgb(255 255 255 / 80%);
  --ui-00-88:   rgb(255 255 255 / 88%);
  --ui-500-30:  rgb(124 124 124 / 30%);
  --ui-950-6:   rgb(0 0 0 / 6%);
  --ui-950-20:  rgb(0 0 0 / 20%);
  --ui-950-32:  rgb(0 0 0 / 32%);
  --ui-950-60:  rgb(0 0 0 / 60%);

  /* Warm accent ramp — used for editorial / highlight surfaces */
  --beige-100:    rgb(245 239 235 / 100%);
  --beige-100-50: rgb(245 239 235 / 50%);
  --beige-150:    rgb(241 230 218 / 100%);   /* footer dividers */
  --beige-200:    rgb(229 223 218 / 100%);
  --beige-250:    rgb(219 213 208 / 100%);
  --beige-500:    rgb(147 143 138 / 100%);
  --beige-600:    rgb(117 114 111 / 100%);

  /* Highlight tints — pastel surfaces for editorial blocks, promo strips and
     badges. Siblings of --beige-100 in role, not steps of one ramp: each is a
     separate hue and there is deliberately only one step of each, so a section
     picks a tint rather than a shade.

     All three are light: pair with --ui-950/800/700 (all AA). --ui-600 is AA on
     lime but only AA-large on lavender and peach, and white fails on all three
     — never set text-on-dark over these. */
  --lime-100:     rgb(242 252 210 / 100%);
  --lavender-100: rgb(223 218 241 / 100%);
  --peach-100:    rgb(238 188 166 / 100%);

  /* Feedback */
  --error:        rgb(246 67 67 / 100%);
  --error-light:  rgb(204 83 31 / 100%);
  --green-hover:  #648a0c;
  --green-active: #4f6e07;
  --success:      #648a0c;

  /* Feedback surfaces — low-alpha tints of the hues above, so a notice reads
     as a tinted panel like --lavender-100 rather than a warning label. Body
     text on all three stays --ui-800, which is why the tint can be this light
     and contrast is never in question. */
  --error-100:    rgb(246 67 67 / 10%);
  --success-100:  rgb(100 138 12 / 10%);

  /* Status TEXT, which is a different job from the surfaces above. --error and
     --success are the brand hues and neither passes AA as text: measured on
     white, --error is 3.62:1 and --success 4.05:1. These are the same hues
     taken to a lightness that does pass, one pair per ground.

     Light surfaces:  #c30909 6.24:1, #52710a 5.64:1 on white.
     Dark surfaces:   #f64343 4.61:1, #8fc511 8.07:1 on --ui-800.
     .on-dark swaps them; nothing else should reach for these directly. */
  --status-error:    #c30909;
  --status-success:  #52710a;
  --status-muted:    var(--ui-600);

  /* Form-control states — read by .checkbox / .sklad-select, which colour
     themselves from `currentcolor` so one property drives box and label. */
  --checkbox-color-default:  var(--ui-600);
  --checkbox-color-active:   var(--ui-950);
  --checkbox-color-disabled: var(--ui-300);

  /* Semantic aliases — prefer these in components over raw ramp steps */
  --surface:            var(--ui-00);
  --surface-muted:      var(--ui-50);
  --surface-highlight:  var(--beige-100);
  --surface-lime:       var(--lime-100);
  --surface-lavender:   var(--lavender-100);
  --surface-peach:      var(--peach-100);
  --surface-error:      var(--error-100);
  --surface-success:    var(--success-100);
  --text-primary:       var(--ui-950);
  --text-secondary:     var(--ui-600);
  --text-tertiary:      var(--ui-500);
  --text-on-dark:       var(--ui-00);
  --border-subtle:      var(--ui-100);
  --border-default:     var(--ui-200);
  --border-strong:      var(--ui-300);

  /* ---------------------------------------------------------------------
     2. TYPOGRAPHY
     Two families: DM Sans for UI and body, Sklad for editorial display.

     --condensed and --contrast are two display ROLES, not two files. Atacama
     filled them with two different cuts (high-contrast for display/h1/h2, a
     plain condensed one from h3 down, where the contrast cut's thin strokes
     break up). Sklad is a single master, so both roles resolve to it and
     that distinction currently has no effect — but the roles stay separate so
     a second cut can be dropped into one of them without touching call sites.

     To go back to Atacama, put data-display-font="atacama" on <html>; the
     scope near the bottom of this file re-points both roles.
     --------------------------------------------------------------------- */
  --font-sans-serif:      "DM Sans", Helvetica, sans-serif;
  --font-serif-condensed: Sklad, Helvetica, serif;
  --font-serif-contrast:  Sklad, Helvetica, serif;

  --font-weight-light:    300;
  --font-weight-regular:  400;
  --font-weight-medium:   500;
  --font-weight-semibold: 600;
  --font-weight-bold:     700;

  /* The weight the active display face actually ships. Sklad is a single
     Medium master, so display type asks for 500 and gets exactly that, rather
     than asking for 400 and being silently handed the only file there is.
     A face with a different master re-points this one token. */
  --font-display-weight:  var(--font-weight-regular);

  /* Display scale (serif) — mobile values; scaled up at `md` breakpoint */
  --title-display-size: 4.5rem;    --title-display-lh: 0.95;
  --title-h1-size:      3.5rem;    --title-h1-lh:      0.95;
  --title-h2-size:      2.875rem;  --title-h2-lh:      1.02;
  --title-h3-size:      2rem;      --title-h3-lh:      1.08;
  --title-h4-size:      2rem;      --title-h4-lh:      1.08;
  --title-h5-size:      1.75rem;   --title-h5-lh:      1.12;
  /* 1.5rem, not the 1.25 it was. The rung carries the blog card titles and
     twelve other things — article h3, blockquotes, the footer row, the panel
     title, the checkout section titles — and at 20px they all sat too quiet
     under Sklad. Stepping the consumers up to h5 was tried and overshot: 28px
     is a 40% jump and read as a different rank, not a louder one. */
  --title-h6-size:      1.5rem;    --title-h6-lh:      1.15;

  /* Text scale (sans) — constant across breakpoints */
  /* One rung above --text-large, sized for a title that has to sit in a
     column too narrow for --title-h6 (24px) without wrapping every line —
     the footer reassurance titles at two per row on a phone (see
     .footer-reassurance__item__title in components.css). Named "-plus" like
     the spacing scale's own half-steps (--space-small-plus and siblings)
     rather than a bare pixel value, because nothing about it is specific to
     that one component. */
  --text-large-plus-size: 1rem;      --text-large-plus-lh: 1.5rem;
  --text-large-size:     0.9375rem; --text-large-lh:     1.375rem;
  --text-medium-size:    0.875rem;  --text-medium-lh:    1.125rem;
  --text-paragraph-size: 0.875rem;  --text-paragraph-lh: 1.375rem;
  --text-small-size:     0.8125rem; --text-small-lh:     1.125rem;
  --text-xsmall-size:    0.75rem;   --text-xsmall-lh:    0.875rem;
  --text-ui-large-size:  0.9375rem; --text-ui-large-lh:  1.125rem;
  --text-ui-small-size:  0.625rem;  --text-ui-small-lh:  0.75rem;

  --tracking-wide: 0.06em;   /* small caps / eyebrow labels */

  /* Tracking belongs to the display face, not to the heading scale. Sklad is
     high-contrast with narrow sidebearings and sets loose untracked, and it is
     asked for in about twenty-five places of which only seven are .title-*.
     Every rule that opts into --font-serif-* opts into this alongside, so the
     two cannot drift apart — the first pass put the value on the scale
     classes alone and left article headings, blockquotes and the footer
     setting visibly wider than everything around them. */
  --tracking-display:       -0.045em;
  --tracking-display-large: -0.055em;  /* display and h1 */

  /* ---------------------------------------------------------------------
     3. SPACING — a named 2px-based scale, not a numeric one.
     --------------------------------------------------------------------- */
  --space-xxxsmall:     2px;
  --space-xxsmall:      4px;
  --space-xsmall:       6px;
  --space-small:        8px;
  --space-small-plus:   12px;
  --space-medium:       16px;
  --space-medium-plus:  20px;
  --space-large:        24px;
  --space-large-plus:   32px;
  --space-xlarge:       40px;
  --space-xlarge-plus:  48px;
  --space-xxlarge:      56px;
  --space-xxlarge-plus: 64px;
  --space-xxxlarge:     72px;

  /* ---------------------------------------------------------------------
     4. LAYOUT
     --------------------------------------------------------------------- */
  --max-width-container: 1940px;

  /* Sizes in this system are taken straight off a 1448px-wide design file and
     re-expressed as a proportion of the container, so a value measured in the
     mockup scales with the layout instead of being pinned to one width.
     A 984px measurement in the design becomes:

         max-width: calc(984 * var(--design-ratio));

     Use --design-ratio-fluid for things that should track the viewport
     rather than the capped container (drawers, overlays). */
  /* The mockup has two widths: a 392px phone board and a 1448px desktop one.
     Every design-ratio size resolves against whichever is current. */
  --base-design-viewport: 392;
  --design-ratio: calc(var(--max-width-container) / var(--base-design-viewport));
  --design-ratio-fluid: calc(var(--viewport-width) / var(--base-design-viewport));

  /* Measured by measureScrollBar() in main.js. On platforms with a classic,
     space-taking scrollbar, 100vw includes the gutter the scrollbar occupies,
     so anything sized against raw 100vw overflows by exactly that much.
     --viewport-width is the corrected value; use it instead of 100vw
     everywhere, so the correction cannot be applied in some places and
     forgotten in others. Overlay-scrollbar platforms measure 0 and the two
     are identical. */
  --scroll-bar:    0px;
  --viewport-width: calc(100vw - var(--scroll-bar));
  --grid-columns:  12;    /* 24 on desktop */
  --gutters:       12px;  /* gap between grid columns */
  --gutters-side:  16px;  /* page inline padding */
  /* 50px, measured off skladliving.com, which is the site this one replaces:
     its header is 50 at 375, at 768 and at 1440 alike. Only the phone board
     takes it here — the desktop override below is 56 and already close, and
     the brief was the phone. */
  --header-height: 50px;
  /* The bar's own height. Read by .announcement-bar and by anything that has
     to clear it — which is why the phone/desktop step lives HERE and not
     scoped to the bar: the pages that pull a hero up underneath the bar
     subtract this token, and a scoped override would leave them subtracting
     the wrong number. Was 2.75rem — two lines' worth, on the theory that the
     phone would always need room for a wrapping message. It measured taller
     than the site actually needed once .announcement-bar__text got its own
     smaller mobile font-size (see components.css) to keep ordinary messages
     on one line: 9px padding around a 12px line, the same rhythm as the
     desktop value below. */
  --announcement-bar-height: 30px;
  --grid-products-columns: 2;
  --grid-products-gap-x: var(--space-small-plus);
  --grid-products-gap-y: var(--space-xlarge-plus);
  --section-spacing: var(--space-xxlarge);

  /* ---------------------------------------------------------------------
     5. ELEVATION & EFFECTS
     --------------------------------------------------------------------- */
  --shadow-level-1: 0 2px 6px 0 rgb(0 0 0 / 6%);
  --shadow-level-2: 0 1px 2px 0 rgb(0 0 0 / 2%), 0 3px 6px 0 rgb(0 0 0 / 8%);
  --shadow-level-3: 0 4px 14px 0 rgb(0 0 0 / 6%);
  --blur-16: blur(16px);
  --blur-24: blur(24px);
  /* Not a backdrop like the two above: this one blurs an element of flat
     colour until it reads as light spilling off a photograph rather than a
     shape. It has to be this much larger than them because the rectangle
     underneath must disappear completely. */
  --blur-72: blur(72px);

  /* Surfaces and media are square; only controls are rounded, and they take
     their radius from the spacing scale rather than a radius scale of their
     own — buttons and inputs use --space-xsmall (6px). */
  --radius-none: 0;
  --radius-control: var(--space-xsmall);
  --radius-pill: 45px;

  /* ---------------------------------------------------------------------
     6. MOTION
     --------------------------------------------------------------------- */
  --duration-x-fast: 0.15s;
  --duration-fast:   0.2s;
  --duration-medium: 0.35s;
  --duration-slow:   0.5s;
  --duration-x-slow: 0.65s;

  --ease-out:           ease-out;
  --ease-out-circ:      cubic-bezier(0.075, 0.82, 0.165, 1);
  --ease-out-cubic:     cubic-bezier(0.33, 1, 0.68, 1);
  --ease-out-expo:      cubic-bezier(0.19, 1, 0.22, 1);
  --ease-out-quint:     cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out-cubic:  cubic-bezier(0.65, 0, 0.35, 1);
  --ease-in-out-quint:  cubic-bezier(0.86, 0, 0.07, 1);
  --ease-in-out-expo:   cubic-bezier(1, 0, 0, 1);

  /* ---------------------------------------------------------------------
     7. Z-INDEX — declared as a ladder so stacking is never guesswork.
     --------------------------------------------------------------------- */
  --z-base:      1;
  --z-sticky:    100;
  --z-header:    200;
  --z-overlay:   300;
  --z-panel:     400;
  --z-modal:     500;
}

/* --------------------------------------------------------------------------
   ALTERNATE DISPLAY FACES

   Sklad is the default (see TYPOGRAPHY above). Every other face the
   system has been tried with lives here as a scope: put data-display-font on
   <html> and all display type swaps, because it all resolves through three
   tokens — the two display roles and the weight. No rule anywhere names a
   font file directly, so a scope is three lines and nothing else changes.

   Atacama is the previous default, kept so the change is reversible and the
   two can still be compared side by side — home-atacama.html is that page.
   It is also the only two-cut face here: Sklad is a single master, so
   under it the display/h1/h2-vs-h3-down distinction has no visible effect.
   -------------------------------------------------------------------------- */

[data-display-font="atacama"] {
  --font-serif-condensed: AtacamaCondensed, Helvetica, serif;
  --font-serif-contrast:  AtacamaCondContrast, Helvetica, serif;
  --font-display-weight:  var(--font-weight-regular);
}

/* --------------------------------------------------------------------------
   8. BREAKPOINT OVERRIDES

   One breakpoint, 1024px, and a single third step at 1280 for the side
   gutters. Everything responsive in this system is a token re-pointed here,
   which is why components carry so few media queries of their own.
   -------------------------------------------------------------------------- */

@media (min-width: 1024px) {
  :root {
    --grid-columns:  24;
    --gutters:       24px;
    --gutters-side:  32px;
    --header-height: var(--space-xxlarge);
    --announcement-bar-height: 32px;

    --section-spacing: var(--space-xxxlarge);

    --grid-products-columns: 4;
    --grid-products-gap-x:   var(--space-large);
    --grid-products-gap-y:   var(--space-xxlarge-plus);

    /* The desktop design board. Every --design-ratio size resolves against it. */
    --base-design-viewport: 1448;

    /* Only the sizes step up. Leading is a ratio now, so it follows the size
       on its own and does not need restating per breakpoint. */
    --title-display-size: 8.375rem;
    --title-h1-size:      7.125rem;
    --title-h2-size:      4.25rem;
    --title-h3-size:      2.5rem;
  }
}

@media (min-width: 1280px) {
  :root { --gutters-side: 64px; }
}
