/* ============================================================
   Messy Buns Organized Spaces — design tokens
   ------------------------------------------------------------
   Sampled directly from the live homepage render, not from the
   skillui extraction. The extracted SKILL.md reported Arial and
   a purple accent (#8c85ff / #673de6) with tokens named
   --cc-toggle-* and --grid-button-*; those came from the cookie
   consent widget and the Zyro page-builder chrome, not from the
   brand. Real palette below.

   Core aesthetic: warm taupe and cream, black nav, navy for
   anything interactive and one terracotta for anything that asks
   for the sale, SHARP corners (the live site is rectangular),
   light-weight uppercase Montserrat display over Manrope body.
   ============================================================ */

:root {
  /* ---------- surfaces ---------- */
  --c-taupe: #bfafa4; /* page background — the signature warm mid-tone */
  --c-taupe-light: #cfc4bb;
  --c-taupe-deep: #9e8a7e; /* dividers, image mats, rules — never text */
  /* Interactive boundaries — form inputs, choice tiles, anything whose EDGE is
     what tells you it is a control. WCAG 1.4.11 requires 3:1 for those, and
     --c-taupe-deep only reaches 2.70:1 on cream, so it is fine for decorative
     hairlines and not for these. Same hue and saturation, lower lightness.
     Passes on all three light surfaces: 3.34 on cream-light, 3.06 on cream,
     3.73 on white. Found by scripts/verify-contrast.mjs. */
  --c-border-ui: #968074;
  --c-taupe-deeper: #4e423b; /* eyebrow text on taupe — 4.56:1 */
  /* Secondary button ground. #9e8a7e with cream text scored 2.70:1, so the
     button gets its own deeper tone (5.13:1) while dividers keep the lighter
     one. Same warm family, still reads as the taupe counterpart to the navy. */
  --c-taupe-btn: #6f5d52;
  --c-taupe-btn-hover: #5c4d43;

  --c-cream: #ede8e4; /* content cards, offset panels */
  --c-cream-light: #f5f2f0; /* airier sections, form fields */
  --c-cream-deep: #e0d9d3; /* cream-on-cream separation */

  --c-black: #000000; /* nav bar, footer */
  --c-black-soft: #14110f;
  /* Warm dark ground for the service-area panel. Black there read heavy against
     the rest of the page, and this keeps the section in the taupe family while
     still clearing AA comfortably: cream 10.32:1, taupe labels 5.91:1. */
  --c-brown-deep: #3a322c;

  /* ---------- ink ----------
     These defaults are tuned for the TAUPE page background, which is the
     darkest surface body text ever sits on. Warm mid-tone text on a warm
     mid-tone ground is the one real accessibility trap in this palette:
     the original #7d736d muted tone scored 2.17:1 on taupe against a 4.5
     requirement. Cream surfaces re-declare softer values in global.css,
     scoped by CSS variable, so the airier look survives where it can. */
  --c-ink: #1d1e20; /* headings — rgb(29,30,32) on every light surface */

  /* READING COPY, AND IT IS SURFACE-DEPENDENT.
     Doug's spec, 2026-08-15: body is rgb(111,102,97) on cream, rgb(72,68,65)
     on the taupe ground, rgb(185,176,170) on navy and black.

     One literal value could not do that job. Reading copy sits on two light
     grounds in roughly equal measure — cream #ede8e4 (101 elements) and taupe
     #bfafa4 (94) — and #6f6661 measures 4.60:1 on cream but 2.64:1 on taupe.
     Shipping it flat would have put half the body copy under AA and made it
     genuinely hard to read.

     So this token carries the TAUPE value here and global.css re-declares it on
     cream, exactly as it already did for --c-ink-muted. Nothing that uses
     var(--c-ink-soft) needed to change: 44 declarations across six files pick
     the right value up from the surface they land on.

     Before this, reading copy rendered in four different grays depending on
     which component it was in — #484441, #1d1e20, #4a4440, #6f6661. None of
     that was a decision; it was accumulation. */
  --c-ink-soft: #484441; /* rgb(72,68,65) — 4.54:1 on taupe, 7.92:1 on cream */

  /* Secondary text, NOT reading copy: fine print, figcaptions, attributions,
     counts, table cells. Relaxes on cream in global.css.

     Aligned to --c-ink-soft on 2026-08-15. It was #4a4440, which differs from
     #484441 by two values in one channel — invisible, but enough to make the
     palette check report a mismatch on every FAQ answer and outro that happened
     to use it. On cream the two tokens already resolved to the same #6f6661, so
     this only finishes what was true on the other half of the site.

     They are the same color now, and the token is kept because the ROLE is
     still different: what separates secondary text here is size, not ink. If a
     future change wants a real color distinction back, this is the one to
     move, not --c-ink-soft. */
  --c-ink-muted: #484441; /* 4.54:1 on taupe */

  --c-on-dark: #ede8e4; /* headings on black or navy */
  --c-on-dark-muted: #b9b0aa; /* rgb(185,176,170) — reading copy on dark */

  /* ---------- the one accent ----------
     Sampled from her hero button as #495269, darkened one step to #3a4254.
     The original scored 3.67:1 against the taupe page background, so links and
     text set in it failed AA. #3a4254 clears every surface it touches: 4.74:1
     on taupe, 8.27:1 on cream, and 8.27:1 for cream text on it as a button
     ground. Visually near-identical, still unmistakably her navy. */
  --c-navy: #3a4254;
  --c-navy-hover: #2e3540;
  --c-navy-deep: #292f3a;

  /* ---------- the action color ----------
     Navy is a calm color. It was doing two incompatible jobs: marking what is
     interactive (links, selected tiles, focus rings, progress) AND being the
     thing that asks for the sale. A CTA the same tone as a body link does not
     read as a CTA, and on the taupe page the navy buttons sat back rather than
     came forward.

     So the two jobs are split. Terracotta is the ask; navy keeps everything
     else. Warm clay, one hue family away from her signature taupe, so it reads
     as native to the palette and not as a bolted-on "buy now" color — the
     brand survives a color this loud only because it is the warm one.

     NOT the #a3453f already in the palette: that is --c-error, and a CTA sharing
     a color with validation errors is a genuine readability problem.

     This value is pinned by a squeeze, not chosen by eye, and it is narrow:
     the fill has to clear 3:1 against BOTH the light taupe page and the black
     nav, which bounds its luminance from both ends. #9c4a2f sat back on taupe
     (2.88:1) and #8f3f24 disappeared into the nav (2.90:1). #954429 threads it —
     3.15:1 on taupe, 3.14:1 on black, 5.50:1 for cream text on it, 5.50:1 on
     cream sections. Darkening or lightening it fails one end or the other, so
     re-run scripts/verify-contrast.mjs before touching it.

     Strictly WCAG 1.4.11 exempts these fills, since a filled button is
     identified by its label rather than its edge. The 3:1 is held anyway: a CTA
     that barely separates from its background is the exact problem this color
     was introduced to fix. */
  --c-action: #954429;
  --c-action-hover: #7c3720;

  /* ---------- status ---------- */
  --c-success: #4f7256;
  --c-error: #a3453f;
  --c-focus: #3a4254;

  /* ---------- type families ---------- */
  --font-display: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Manrope", "Helvetica Neue", Arial, sans-serif;

  /* ---------- fluid type scale ----------
     Display sizes stay light-weight and letterspaced; that thin
     geometric treatment is the most recognizable thing about her
     brand and it breaks if weight creeps up. */
  /* Headings are set uppercase with 0.06em tracking, which makes them read a
     good deal larger than the raw px value suggests. The scale was pulled down
     roughly 18% at the top end for that reason: 3.75rem hero became 3rem, and
     the h2 dropped from 2.5rem to 2rem. Lower bounds are still governed by the
     longest unbreakable word ("TRANSFORMATIONS") fitting a 320px screen. */
  --t-hero: clamp(1.75rem, 1.1rem + 2.6vw, 3rem);
  --t-h1: clamp(1.75rem, 1.25rem + 2.2vw, 2.75rem);
  --t-h2: clamp(1.375rem, 1.1rem + 1.3vw, 2rem);
  --t-h3: clamp(1.125rem, 1.05rem + 0.5vw, 1.375rem);
  --t-h4: 1.125rem; /* 18px */
  --t-body: 1.0625rem; /* 17px */
  /* Deliberately EQUAL to --t-body, not a step above it. It was
     clamp(1.0625rem, 1rem + 0.3vw, 1.25rem), so a lead ran 20px against 17px
     body at desktop widths and every page carried two reading sizes: the hero
     standfirst against the paragraph under it, the Meet Ashley lede against the
     section below. Ashley read that as inconsistent and she was right.

     The token is kept rather than replaced by --t-body at the 15 call sites,
     because "lead" is still a real role — it just no longer differs by SIZE.
     It differs by COLOR and MEASURE: leads are --c-ink-soft/--c-ink-muted at
     40-52ch against body ink at full width. That is enough hierarchy, and it is
     the hierarchy that survives a phone, where the clamp collapsed to 17px
     anyway and the distinction silently vanished.

     If it ever needs to step back up, use a FIXED 1.125rem rather than
     reinstating the clamp: the clamp is what made the gap appear only on
     desktop, which is why it read as a bug rather than a decision. */
  --t-lead: var(--t-body);
  --t-small: 1rem; /* 16px. Was 15px, which is too small for the 84 elements
                       that use it, including service card descriptions. */
  --t-micro: 0.875rem; /* 14px. Reserved for labels, buttons and badges only.
                          At 13px it was being used for descriptive copy too. */

  --lh-display: 1.15;
  --lh-heading: 1.25;
  --lh-body: 1.65;

  /* Wide tracking on uppercase display type is core to the look. */
  --ls-display: 0.06em;
  --ls-label: 0.18em;
  --ls-button: 0.1em;
  --ls-body: 0;

  /* Weight has one job per role. Applying these inconsistently was the source of
     the "something feels off" problem: .h3 rendered at 300 while .bento__q
     rendered at 400 in the same 22px size, on the same page.

       300  every display heading, at every size. Size carries hierarchy.
       400  body copy.
       500  labels, buttons, eyebrows, table headers. Never prose.
       600  emphasis inside prose (strong, inline links).

     Nothing else. If a fifth weight seems necessary, the hierarchy is being
     solved with weight where it should be solved with size or space. */
  --fw-light: 300;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;

  /* ---------- spacing: 4px grid ---------- */
  --s-1: 0.25rem; /*  4px */
  --s-2: 0.5rem; /*  8px */
  --s-3: 0.75rem; /* 12px */
  --s-4: 1rem; /* 16px */
  --s-5: 1.5rem; /* 24px */
  --s-6: 2rem; /* 32px */
  --s-7: 3rem; /* 48px */
  --s-8: 4rem; /* 64px */
  --s-9: 6rem; /* 96px */
  --s-10: 8rem; /* 128px */

  /* Vertical rhythm between major page sections, tightened on mobile. */
  --section-y: clamp(3rem, 2rem + 5vw, 7rem);

  /* Height of the mobile sticky CTA bar, and the width it stops applying at.
     Three things depend on the height — the bar itself, the bottom padding that
     keeps it off the end of the footer, and the offset that lifts the
     back-to-top button clear of it — so it is a token rather than a number
     repeated in three files that would drift apart. The 3.5rem is the tab
     content; the safe-area inset is added on top where it exists.

     The bar shows below 48rem / 767px. That number is repeated in the media
     queries rather than tokenised because custom properties are not allowed in
     a @media condition — the token would silently never match. The nav's own
     breakpoint is 1140px and deliberately not reused: a two-tab bar stretched
     across a 1000px tablet looks like a mistake. */
  --mobile-bar-h: 3.5rem;

  /* ---------- layout ---------- */
  --container: 75rem; /* 1200px */
  --container-narrow: 46rem; /* 736px — prose measure */
  --container-wide: 88rem; /* 1408px — full-bleed galleries */
  --gutter: clamp(1.25rem, 0.75rem + 2vw, 2.5rem);

  /* ---------- THE SPLIT GUTTER. DO NOT CHANGE IT PER SECTION. ----------

     The gap between the two halves of any copy-and-media split, at desktop.

     This is a BRANDING CONSTANT, not a tuning knob. The homepage established it
     — .whencall__grid and .procshot__grid both step from --s-7 to --s-9 at
     60rem — and the separation it creates is a large part of what the site
     looks like. When the area-page bands shipped at --s-7 with no step-up, the
     photographs read as crowding the copy, and the fix was not a better ratio
     or a smaller image: it was this number.

     Anything that puts copy beside a photograph, a form or a second column uses
     this. If a section appears to need a different value, the section is wrong,
     not the token. Doug's instruction, 16 Aug: hardcode it and treat it as a
     core principle.

     THE STACKED VALUES ARE NOT SMALLER VERSIONS OF IT. Below 60rem the two
     halves sit one above the other, so the gap is vertical and doing a different
     job: separating a paragraph from a photograph rather than two columns from
     each other. And the phone value is LARGER than the tablet one, which looks
     like a mistake and is not — the homepage has always done this, because a
     stacked image needs more clearing from the copy under it on a narrow screen
     than on a wide one. Preserved rather than tidied. */
  --split-gap: var(--s-9); /* 6rem  — desktop, side by side */
  --split-gap-sm: var(--s-7); /* 3rem  — stacked */
  --split-gap-xs: var(--s-8); /* 4rem  — stacked on a phone, deliberately more */

  /* ---------- shape ----------
     The live site is square-cornered. Only the nav CTA is a pill.
     Rounding these would read as a different brand. */
  --radius: 0;
  --radius-pill: 999px;

  --border-hairline: 1px solid var(--c-taupe-deep);
  --border-ink: 1px solid var(--c-ink);
  --border-cream: 1px solid var(--c-cream-deep);

  /* ---------- elevation ----------
     Restrained. Depth here comes from offset panels overlapping
     photography, not from drop shadows. */
  --shadow-sm: 0 1px 2px rgba(29, 30, 32, 0.06);
  --shadow-md: 0 4px 16px rgba(29, 30, 32, 0.1);
  --shadow-lg: 0 12px 40px rgba(29, 30, 32, 0.16);

  /* ---------- motion ---------- */
  --dur-fast: 150ms;
  --dur-base: 250ms;
  --dur-slow: 500ms;
  --dur-reveal: 700ms;
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);

  /* ---------- z-index ---------- */
  --z-base: 1;
  --z-raised: 10;
  --z-sticky: 100;
  --z-nav: 200;
  --z-overlay: 300;
  --z-modal: 400;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 1ms;
    --dur-base: 1ms;
    --dur-slow: 1ms;
    --dur-reveal: 1ms;
  }
}
