/* Gravin Wood — design tokens (brand identity 2026, decisions D9–D11)
   Source of truth for the storefront theme. theme.json mirrors the palette and
   type scale so the block editor offers the same set. Use logical properties
   downstream so dir="rtl" mirrors without a second stylesheet.

   ---- contrast, WCAG 2.x, computed (not eyeballed) ----------------------------
   AA = 4.5:1 for text, 3:1 for large text (>=24px, or >=18.66px bold) and for
   non-text UI (focus rings, input borders that carry state).

   light scope (:root) — on off-white #F3F1ED / raise #FAF9F7 / sunk #ECE8E3 / alt #E4E0DA
     charcoal  #4B4642 text ............ 8.26 / 8.85 / 7.64 / 7.09   AA
     strong    #312E2B emphasis ....... 11.96 / 12.82 / 11.06 / 10.26 AA
     muted     #69615B secondary text .. 5.38 / 5.77 / 4.97 / 4.61   AA
     taupe     #8D837A ................. 3.29 / 3.53 / 3.04 / 2.82   FAILS for text.
               Brand colour 02 is decoration only (stars, rules, image mats).
               Secondary text uses --gravin-muted, taupe pulled 55% to charcoal.
     copper    #B07D4F ................. 3.16 / 3.39 / 2.92 / 2.71   FAILS for text,
               and off-white ON copper is 3.16 — fails as a button ground too.
               Copper stays the brand accent for rules, underlines, the star.
     copper-deep #7F5A39 accent text ... 5.44 / 5.83 / 5.03 / 4.67   AA
               off-white on copper-deep 5.44 — the primary-action ground.
               Also the focus ring: 5.44 on off-white, 3.94 on stone (>=3:1).
     error     #9B3426 ................. 6.39 / 6.85 / 5.91 / 5.48   AA
     success   #45633A ................. 6.01 / 6.44 / 5.56 / 5.15   AA
     warning   #7E5A12 ................. 5.54 / 5.94 / 5.13 / 4.76   AA
     sale      #9B4A2C ground, off-white text on it 5.46            AA
     charcoal on stone #D6CEC6 5.99 AA; taupe on stone 2.39 and copper on
     stone 2.29 both fail.

   dark scope (footer, photo captions, dark heroes) — on charcoal #4B4642
     off-white #F3F1ED text ............ 8.26  AA
     stone     #D6CEC6 muted text ...... 5.99  AA
     copper-light #D4B89E accent ....... 4.95  AA (copper itself 2.61 fails)
     taupe on charcoal 2.51 — fails; never text on the dark ground.
   ----------------------------------------------------------------------------- */

:root {
  /* ---- brand palette, ranked as in the brand book (01–05) ---- */
  --gravin-charcoal: #4B4642;  /* 01 text, primary */
  --gravin-taupe:    #8D837A;  /* 02 secondary — decoration only, never text on off-white */
  --gravin-stone:    #D6CEC6;  /* 03 */
  --gravin-offwhite: #F3F1ED;  /* 04 background */
  --gravin-copper:   #B07D4F;  /* 05 primary action, as accent; see copper-deep for grounds */

  /* The same colours as channel lists, for translucent use: rgba(var(--x-rgb), a).
     Computed values then stay rgba(), which the focus-contrast spec can read. */
  --gravin-charcoal-rgb:      75, 70, 66;
  --gravin-charcoal-deep-rgb: 49, 46, 43;
  --gravin-offwhite-rgb:      243, 241, 237;
  --gravin-copper-rgb:        176, 125, 79;

  /* ---- derived (each pair is in the table above) ---- */
  --gravin-charcoal-deep: #312E2B;  /* charcoal 35% to black */
  --gravin-taupe-text:    #69615B;  /* taupe 55% to charcoal */
  --gravin-copper-deep:   #7F5A39;  /* copper 28% to black */
  --gravin-copper-light:  #D4B89E;  /* copper 45% to white, for the dark scope */

  /* ---- semantic ---- */
  --gravin-error:   #9B3426;
  --gravin-success: #45633A;
  --gravin-warning: #7E5A12;
  --gravin-sale:    #9B4A2C;  /* a ground: badges carry --gravin-on-action on it */

  /* ---- roles: everything downstream uses these, never the palette directly ----
     The dark scope below re-declares the same names, so a component written
     once reads correctly on either ground. */
  --gravin-bg:      var(--gravin-offwhite);  /* the page */
  --gravin-raise:   #FAF9F7;                 /* cards, panels, summary boxes */
  --gravin-sunk:    #ECE8E3;                 /* input wells, sunk surfaces (stone 25%) */
  --gravin-alt:     #E4E0DA;                 /* the alternate band (stone 50%) */
  --gravin-text:    var(--gravin-charcoal);       /* all primary text; also the selected-state ground */
  --gravin-muted:   var(--gravin-taupe-text);     /* secondary text */
  --gravin-strong:  var(--gravin-charcoal-deep);  /* emphasis, hover, active nav */
  --gravin-inverse: var(--gravin-offwhite);       /* text ON --gravin-text / --gravin-strong grounds */
  --gravin-accent:  var(--gravin-copper-deep);    /* prices, figures, accent text */
  --gravin-rule:    var(--gravin-copper);         /* rules and active underlines — never text */
  --gravin-focus:   var(--gravin-copper-deep);    /* focus rings */
  --gravin-action:  var(--gravin-copper-deep);    /* primary-action ground */
  --gravin-on-action: var(--gravin-offwhite);     /* text on --gravin-action and --gravin-sale */

  /* ---- lines ---- */
  --gravin-hair:   rgba(75, 70, 66, .16);  /* every divider and inactive border (charcoal 16%) */
  --gravin-edge:   var(--gravin-text);     /* selected/active border */
  --gravin-radius: 0;                      /* nothing is rounded, anywhere */

  /* ---- texture ----
     Two layers on the page element, in this order, with
     background-blend-mode: overlay, normal, normal */
  --gravin-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='.25'/%3E%3C/svg%3E");
  --gravin-plaster:
    radial-gradient(120% 80% at 20% 0%, rgba(214, 206, 198, .25), transparent 60%),
    radial-gradient(100% 70% at 90% 100%, rgba(176, 125, 79, .05), transparent 55%);

  /* Photograph scrims. Dark ones put their text in the dark scope. The home hero
     is light (charcoal wordmark on off-white), so its wash is off-white. */
  --gravin-scrim-hero: linear-gradient(180deg, rgba(243, 241, 237, .72) 0%, rgba(243, 241, 237, .1) 40%, rgba(243, 241, 237, .82) 100%);
  --gravin-scrim-flat: rgba(49, 46, 43, .55);   /* charcoal-deep 55% */
  --gravin-caption-bg: rgba(49, 46, 43, .9);    /* captions get their own ground, never bare */
  --gravin-veil:       rgba(243, 241, 237, .78); /* off-white over a photograph, light text scope */

  /* Timber swatches stand in for grain photographs (workshop page). They depict
     the wood, not the brand, so they are not palette colours. */
  --gravin-timber-walnut: linear-gradient(160deg, #4C3A28, #2E2419);
  --gravin-timber-ash:    linear-gradient(160deg, #B9A886, #8C7D60);
  --gravin-timber-beech:  linear-gradient(160deg, #B08A5F, #7E6240);
  --gravin-timber-oak:    linear-gradient(160deg, #9A7B4E, #6B5335);

  /* ---- type: Latin Gravin Sans (Mona Sans), Arabic KO Sans (D22) ----
     From the brand book mockups (pp. 8–11): headings are light and sentence
     case, body is regular, labels are small tracked capitals.

       role      size                      weight  line   tracking
       h1        40 → 64                   300     1.05   -.02em
       h2        32 → 48                   300     1.1    -.015em
       h3        24 → 32                   400     1.15   -.01em
       h4        22                        400     1.2    0
       lead      19                        400     1.6    0
       body      17                        400     1.62   0
       label     12, uppercase             500     1.35   .12em
       price     18 / 15 / 13, tabular     500     —      .01em
     Weights stay within the variable axis (200–900); width stays at 100%. */
  --gravin-display: "Gravin Sans", system-ui, sans-serif;  /* headings, product names */
  --gravin-sans:    "Gravin Sans", system-ui, sans-serif;  /* prose, nav, chips */
  --gravin-label:   "Gravin Sans", system-ui, sans-serif;  /* uppercase labels, buttons, figures */

  /* Arabic: KO Sans leads; Plex stays as fallback per D22. */
  --gravin-display-ar: "KO Sans", "IBM Plex Sans Arabic", "Gravin Sans", sans-serif;
  --gravin-sans-ar:    "KO Sans", "IBM Plex Sans Arabic", "Gravin Sans", sans-serif;

  --gravin-fw-heading: 300;
  --gravin-fw-subhead: 400;
  --gravin-fw-body:    400;
  --gravin-fw-label:   500;

  --gravin-fs-h1:      clamp(2.5rem, 1.75rem + 3.2vw, 4rem);      /* 40 → 64 */
  --gravin-fs-h2:      clamp(2rem, 1.5rem + 2.1vw, 3rem);         /* 32 → 48 */
  --gravin-fs-h3:      clamp(1.5rem, 1.25rem + 1.05vw, 2rem);     /* 24 → 32 */
  --gravin-fs-h4:      1.375rem;   /* 22 · card and panel titles */
  --gravin-fs-caption: 1.25rem;    /* 20 · image captions */

  --gravin-fs-lead:    1.1875rem;  /* 19 · lh 1.6  */
  --gravin-fs-body:    1.0625rem;  /* 17 · lh 1.62 */
  --gravin-fs-body-sm: 1rem;       /* 16 · lh 1.6  */
  --gravin-fs-label:   0.75rem;    /* 12 · uppercase labels */
  --gravin-fs-note:    0.875rem;   /* 14 · helper text, required note */
  --gravin-ls-label:   .12em;

  --gravin-fs-price:    1.125rem;   /* 18 · product page, totals */
  --gravin-fs-price-sm: 0.9375rem;  /* 15 · cards, summary rows */
  --gravin-fs-price-xs: 0.8125rem;  /* 13 · mobile cards */
  --gravin-fw-price:    500;
  --gravin-ls-price:    .01em;

  --gravin-fs-fig:     0.8125rem;  /* 13 · dimensions, references */
  --gravin-fs-fig-sm:  0.75rem;    /* 12 · table figures */
  --gravin-fs-badge:   0.625rem;   /* 10 · uppercase badges */
  --gravin-ls-fig:     .06em;
  --gravin-ls-badge:   .16em;

  /* ---- spacing: 4px base, no in-between values ---- */
  --gravin-s-1: .25rem;  --gravin-s-2: .5rem;   --gravin-s-3: .75rem;
  --gravin-s-4: 1rem;    --gravin-s-5: 1.5rem;  --gravin-s-6: 2rem;
  --gravin-s-7: 3rem;    --gravin-s-8: 3.5rem;  --gravin-s-9: 4.5rem;
  --gravin-s-10: 5.5rem; --gravin-s-11: 8rem;

  --gravin-gutter-desktop: 3.5rem;   /* 56 — every 1440 screen */
  --gravin-gutter-mobile:  1.25rem;  /* 20 — every 390 screen  */

  /* The reference is drawn at 1440 with two 56 gutters, so the column it actually
     composes is 1328. Past that width the extra space belongs to the gutters. */
  --gravin-max:    1328px;
  --gravin-gutter: max(var(--gravin-gutter-desktop), (100% - var(--gravin-max)) / 2);
  --gravin-band:  5.5rem;            /* 88 — band-to-band, desktop */
  --gravin-band-mobile: 2.25rem;     /* 36 */
  --gravin-measure: 62ch;
  --gravin-hit: 44px;                /* minimum touch target */

  /* Logo clear space: the brand book asks for at least the height of "wood"
     around the whole logo. "wood" is 413px of the 5812px-wide asset, so 7.1% of
     the wordmark's rendered width. The brand links carry it as padding
     (base.css); the header's own 24px block padding covers the block axis there. */
  --gravin-logo-clear: .071;

  /* ---- motion ---- */
  --gravin-dur-fast: 140ms;   /* state change */
  --gravin-dur:      260ms;   /* entrance     */
  --gravin-ease:     cubic-bezier(.22,.61,.36,1);
  --gravin-rise:     18px;    /* the only travel distance */
}

/* ---- dark scope -------------------------------------------------------------
   The footer (stone wordmark on charcoal, D10) and every surface that sits on a
   photograph or a dark ground. Re-declares the roles, then re-declares colour,
   because colour inherits as an already-computed value. */
.gravin-site-footer,
.gravin-scope-dark,
.gravin-wood-hero,
.gravin-consultation__hero,
.gravin-wood-timber,
.gravin-home-category-card,
.gravin-home-tile figcaption,
.gravin-shop-joinery figcaption,
.gravin-product-card__badge,
.gravin-product-gallery__zoom,
.gravin-states-card__image > i {
  --gravin-bg:      var(--gravin-charcoal);
  --gravin-raise:   #55504B;
  --gravin-sunk:    #433E3A;
  --gravin-alt:     #55504B;
  --gravin-text:    var(--gravin-offwhite);
  --gravin-muted:   var(--gravin-stone);
  --gravin-strong:  #FFFFFF;
  --gravin-inverse: var(--gravin-charcoal);
  --gravin-accent:  var(--gravin-copper-light);
  --gravin-rule:    var(--gravin-copper-light);
  --gravin-focus:   var(--gravin-copper-light);
  --gravin-hair:    rgba(214, 206, 198, .22);
  color: var(--gravin-text);
}

/* Below the mobile breakpoint the gutter is 20, not 56. */
@media (max-width: 700px) {
  :root { --gravin-gutter-desktop: var(--gravin-gutter-mobile); }
}

@media (prefers-reduced-motion: reduce) {
  :root { --gravin-dur-fast: 0ms; --gravin-dur: 0ms; --gravin-rise: 0px; }
}

/* ---- Arabic locale: swap the roles, kill Latin tracking ---- */
[dir="rtl"], :lang(ar) {
  --gravin-display: var(--gravin-display-ar);
  --gravin-sans:    var(--gravin-sans-ar);
  --gravin-label:   var(--gravin-sans-ar);
  --gravin-fw-heading: 700;
  --gravin-fw-subhead: 700;
  /* The re-declaration is REQUIRED. Redefining the variable alone does nothing:
     font-family inherits as an already-computed value from outside the subtree, so it
     must be declared again here for the new variable to resolve. */
  font-family: var(--gravin-sans-ar);
  letter-spacing: 0 !important;
}
[dir="rtl"] *, :lang(ar) { letter-spacing: 0 !important; }

/* Arabic headings need more leading than Latin. The root locale outranks the
   later component rules (such as .gravin-product-summary h1 at weight 300). */
:root:is([dir="rtl"], :lang(ar)) :is(h1, h2, h3, h4, h5, h6) { font-weight: 700; line-height: 1.3; }

/* Display text outside semantic headings keeps the brand's light weight. */
:is([dir="rtl"], :lang(ar)) .gravin-display:not(:is(h1, h2, h3, h4, h5, h6)) { font-weight: 300; }

/* Numerals stay Eastern Arabic (٠١٢٣٤٥٦٧٨٩) — client decision. Request tabular
   figures where the selected font supports them. */
[dir="rtl"] { font-variant-numeric: tabular-nums; }
