/* ============================================================
   Elevated Carpentry — design tokens
   BRAND BOOK BUILD, 2026-08-19.
   Supersedes the Samara/Oakame linen-and-walnut system.

   Source of truth: `.planning/reviews/elevated-brand-book-2026-08-19.html`
   in the teloscreative repo. That document is a build spec, not a mood
   board: the palette is measured out of the hero photograph and the
   contrast ratios below are computed, not assumed.

   WHAT CHANGED FROM THE PREVIOUS BUILD, AND WHY
   - Ground. Linen #f6f1eb -> Paper #F6F3F0, and DARK is now the default
     behind photography. The brand book's rule: dark for imagery, Paper
     for long-form reading, never a mid-grey site.
   - Accent. There was deliberately no chromatic accent. There is one
     now, and it is two colours doing two jobs, because one could not do
     both accessibly: Sunset #D9662E is graphic-only on dark grounds,
     Sunset Button #C25520 carries every button fill.
   - Type. Plus Jakarta Sans at weight 400 everywhere -> Archivo, with
     real weight contrast (H1 700, H2 800) and Archivo Black for the one
     display wordmark. The previous "a headline is never bolded" rule is
     reversed: this is a builder, and the type is meant to have heft.
   - Shape. 12/18/24px radius everywhere -> squared surfaces and buttons,
     full radius on interactive pills only. One rule, no per-component
     exceptions, because mixed radii without a rule is how a page starts
     looking assembled rather than designed.
   - Motion. UNCHANGED. Every token in the motion block below survives
     from the previous build, along with the prefers-reduced-motion
     handling in base.css. The expo-out curve was chosen deliberately
     and it stays.

   CONTRAST, COMPUTED NOT ASSUMED (sRGB, WCAG 2.1 relative luminance)
     ink on paper        17.03:1     night on paper      17.91:1
     cedar on paper       8.17:1     sunset-hi on paper   5.11:1
     white on night      19.80:1     paper on night      17.91:1
     white on bark       17.65:1     paper on bark       15.96:1
     gold on night       11.09:1     sky on night        13.24:1
     ridge on night       5.85:1     sunset on night      5.55:1
     white on sunset-btn  4.55:1     white on sunset-hi   5.65:1
     ink on sky          12.59:1     cedar on sky         6.04:1
     paper at 78% on night          10.91:1

   ⛔ FAILS, RECORDED SO NOBODY REACHES FOR THEM
     white on sunset #D9662E    3.57:1  large text only, never a button
     sunset-btn on paper        4.12:1  fill only, never text on Paper
     ridge on paper             3.06:1  borders and graphics, never text
     board on paper             3.21:1  borders and graphics, never text
   ============================================================ */

:root {
  /* ---------- colour: core ---------- */
  --night: #0b0a07;        /* primary dark. Header, footer, cards, bands */
  --bark: #1c1814;         /* second dark, for layering on Night */
  --paper: #f6f3f0;        /* light page ground. Long-form reading */
  --ink: #14110c;          /* body text on Paper. Never pure black */

  /* ---------- colour: accent, two colours doing two jobs ---------- */
  --sunset: #d9662e;       /* GRAPHIC ONLY, dark grounds. Rules, ticks */
  --sunset-btn: #c25520;   /* every button fill. White text passes AA */
  --sunset-hi: #ae4718;    /* button hover, and links on Paper */
  --gold: #e8b98f;         /* small emphasis on dark. The rating line */

  /* ---------- colour: measured from the photograph ---------- */
  --sky: #f7cab2;          /* warm section wash */
  --ridge: #94898a;        /* cool grey. Dividers */
  --board: #938581;        /* composite grey. Borders */
  --cedar: #594533;        /* timber. Secondary text on Paper */
  --white: #ffffff;        /* text on dark or filled surfaces only */

  /* hairlines and washes, derived so nothing goes flat grey */
  --line: rgba(20, 17, 12, 0.14);
  --line-strong: rgba(20, 17, 12, 0.30);
  --line-on-dark: rgba(246, 243, 240, 0.16);
  --wash: rgba(20, 17, 12, 0.05);
  --wash-input: rgba(20, 17, 12, 0.03);
  --wash-border: rgba(20, 17, 12, 0.12);
  --on-dark-soft: rgba(246, 243, 240, 0.78);   /* 10.91:1 on Night */

  /* ---------- legacy aliases ----------
     The other nine page modules and both stylesheets still speak the
     previous build's vocabulary in ~150 places. Rather than a rename
     sweep across pages this run does not touch, the old names are
     mapped onto the brand palette so the whole site moves together and
     nothing is left half-themed. New work uses the names above. */
  --linen: var(--paper);
  --warm-sand: #efe9e4;    /* card surface on Paper. Warm, not grey */
  --driftwood: #e6dfd9;    /* secondary control surface */
  --walnut: var(--ink);
  --charcoal: var(--ink);
  --slate: var(--cedar);
  --timber: var(--sunset-hi);
  --evergreen: var(--cedar);

  /* ---------- type ----------
     Archivo for everything, Archivo Black for the display wordmark.
     Both self-hosted, latin subset, no CDN: this site ships to shared
     hosting as plain static files and must not depend on fonts.gstatic.
     Archivo Black rather than bare Arial Black so the heavy grotesque
     is the same shape on Android and Linux as it is on Daniel's screen;
     Arial Black stays in the stack as the metric-compatible fallback. */
  --sans: Archivo, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --display: "Archivo Black", "Arial Black", "Helvetica Neue", Impact, var(--sans);

  --fs-12: 0.75rem;
  --fs-13: 0.8125rem;
  --fs-14: 0.875rem;
  --fs-15: 0.9375rem;
  --fs-16: 1rem;
  --fs-18: 1.125rem;
  --fs-21: 1.3125rem;
  --fs-23: 1.4375rem;
  --fs-29: 1.8125rem;
  --fs-30: 1.875rem;
  --fs-36: 2.25rem;
  --fs-43: 2.6875rem;
  --fs-48: 3rem;
  --fs-60: 3.75rem;
  --fs-96: 6rem;

  --fs-display: clamp(2.25rem, 1.1rem + 4.6vw, 5rem);       /* 36 -> 80 */
  --fs-h-lg: clamp(2rem, 1.55rem + 1.8vw, 3.25rem);         /* 32 -> 52 */
  --fs-h: clamp(1.75rem, 1.5rem + 1.0vw, 2.5rem);           /* 28 -> 40 */
  --fs-h-sm: clamp(1.3125rem, 1.24rem + 0.32vw, 1.5rem);    /* 21 -> 24 */
  --fs-lead: clamp(1.0625rem, 1.02rem + 0.2vw, 1.25rem);    /* 17 -> 20 */
  --fs-body: var(--fs-16);   /* brand book: never below 16px on the site */
  --fs-body-sm: var(--fs-15);
  --fs-caption: var(--fs-14);
  --fs-label: var(--fs-12);

  /* Archivo is a grotesque with generous sidebearings, so the negative
     tracking is lighter than the previous build's geometric sans wanted.
     Brand book: H1 -1.4%, H2 -2%. */
  --track-display: -0.014em;
  --track-h-lg: -0.022em;
  --track-h: -0.02em;
  --track-h-sm: -0.014em;

  /* PROSE MEASURE. Measured on the built page: Archivo's average advance is
     0.4336em and one CSS `ch` is 0.573em, so 1ch carries about 1.32 real
     characters and 54ch lands on ~72 of them at ANY size it is applied to.
     That is what makes it one measure and not three: the lede at 24px, the
     lead at 18-20px and the body at 16px all read the same length line. */
  /* ⛔ UNITLESS ON PURPOSE, and multiplied by 1ch at the point of use:
     `--measure: 54ch` declared HERE resolves its `ch` against the ROOT font
     and then inherits as a fixed length, so it silently became 544px on
     everything and stopped adapting to the size it was applied to, which is
     the entire reason for using `ch`. Measured that happening. Use
     `max-width: calc(var(--measure-ch) * 1ch)` so the `ch` resolves against
     the element's own font. */
  --measure-ch: 54;
  --track-body: 0;
  --track-label: 0.2em;      /* eyebrow */
  --track-strip: 0.48em;     /* the hero micro strip, and only that */

  --lh-display: 0.9;
  --lh-h-lg: 1.05;
  --lh-h: 1.12;
  --lh-h-sm: 1.22;
  --lh-lead: 1.5;
  --lh-body: 1.55;

  /* weights: real contrast, unlike the previous build's flat 400 */
  --w-body: 400;
  --w-med: 500;
  --w-h1: 700;
  --w-h2: 800;
  --w-label: 700;

  /* ---------- space ---------- */
  --s-5: 5px;   --s-6: 6px;   --s-8: 8px;   --s-10: 10px;
  --s-12: 12px; --s-14: 14px; --s-16: 16px; --s-18: 18px;
  --s-24: 24px; --s-30: 30px; --s-32: 32px; --s-36: 36px;
  --s-42: 42px; --s-54: 54px; --s-72: 72px; --s-96: 96px; --s-120: 120px;

  --section-y: clamp(4rem, 7vw, 7.5rem);
  --section-y-lg: clamp(5rem, 9vw, 9rem);

  --masthead-h: 72px;
  --container: 1280px;
  --measure: 34rem;          /* brand book: 34ch body measure */
  --gutter: clamp(1.25rem, 4vw, 3rem);

  /* ---------- shape ----------
     THE RULE: interactive pills get full radius. Surfaces and buttons
     are square. It is the whole system and it is not negotiable
     per-component. */
  --r-card: 0px;
  --r-input: 0px;
  --r-btn: 0px;
  --r-specialty: 0px;
  --r-media: 0px;
  --r-pill: 999px;

  /* ---------- elevation: short and soft only ---------- */
  --shadow-subtle: rgba(0, 0, 0, 0.12) 0px 0.5px 2px 0px;
  --shadow-sm: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px;
  --shadow-md: rgba(0, 0, 0, 0.08) 0px 2px 10px 0px;

  /* ---------- motion ----------
     CARRIED OVER UNCHANGED from the motion-architecture build. --ease is
     an expo-out, chosen partly because it is audibly not
     cubic-bezier(.22,1,.36,1), the curve both previous builds on this
     book of clients used. transform and opacity only, so every effect
     stays on the compositor. */
  --ease: cubic-bezier(0.19, 1, 0.22, 1);       /* entrances, reveals */
  --ease-soft: cubic-bezier(0.33, 0, 0.15, 1);  /* large ambient movement */
  --ease-ui: cubic-bezier(0.4, 0, 0.2, 1);      /* buttons, inputs, state */

  --dur-fast: 240ms;
  --dur: 620ms;
  --dur-slow: 1100ms;

  --rise: 12px;
  --parallax: 8%;
}

/* Archivo, SIL Open Font License, self-hosted latin subset. No CDN. */
@font-face {
  font-family: Archivo;
  src: url("../assets/fonts/archivo-var.woff2") format("woff2-variations");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
/* Declared across the full heavy range so `font-weight: 900` resolves to
   this file rather than triggering a synthetic bold on top of a face that
   is already black. */
@font-face {
  font-family: "Archivo Black";
  src: url("../assets/fonts/archivo-black.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}
