/* =========================================================================
   ATX WRITING CLUB — DESIGN SYSTEM
   "Paper & Rust" · v1.0
   -------------------------------------------------------------------------
   Two inks on warm paper, borrowed from the West Texas screen-print set,
   set on an editorial grid with slow, confident motion.

   Contents
     01  Fonts
     02  Tokens
     03  Reset & base
     04  Typography
     05  Layout & grid
     06  Rules, marks & ornament
     07  Buttons & links
     08  Forms
     09  Media
     10  Motion primitives
     11  Header & navigation
     12  Footer
     13  Utilities
   ========================================================================= */

/* -- 01  FONTS ----------------------------------------------------------- */
/* @font-face lives in fonts.css, generated at build time with the woff2 files
   embedded as data URIs. That is one fewer round trip, no FOUT, and — the
   reason it matters here — it means the site renders correctly when opened
   straight off disk with file://, where cross-origin font requests are blocked. */

/* -- 02  TOKENS ---------------------------------------------------------- */

:root {
  /* ---- ink ---- */
  --paper:        #F2E4C8;   /* primary ground — the pack's suggested paper, warmed */
  --paper-hi:     #FBF3E2;   /* raised card / lifted surface */
  --paper-lo:     #E7D6B2;   /* recessed band */
  --paper-edge:   #DCC79E;   /* the darkest paper step, for chips & wells */

  --ink:          #1C1610;   /* display + body            14.3:1 on paper */
  --ink-2:        #4A3E31;   /* secondary                  8.3:1 */
  --ink-3:        #6B5B45;   /* meta, captions             5.2:1 */
  --ink-4:        #7A6A54;   /* placeholder & hairline     4.2:1 — never body copy */

  --rust:         #C8431F;   /* the burnt-rust ink, display use */
  --rust-ink:     #B03A19;   /* rust that is safe as body-size text  4.8:1 */
  --rust-bright:  #D64B24;   /* exact pack ink — for art-matched moments only */
  --olive:        #7C6417;   /* second ink */
  --olive-ink:    #6E5813;   /* olive safe as text  5.4:1 */

  --night:        #14100B;   /* inverted ground */
  --night-2:      #211A12;
  --night-3:      #2E251A;
  --on-night:     #F2E4C8;
  --on-night-2:   #B8A588;   /* 7.9:1 on night */
  --on-night-3:   #9C8A6B;
  --rust-night:   #E2683F;   /* rust that reads on night  5.7:1 */

  --rule:         color-mix(in srgb, var(--ink) 16%, transparent);
  --rule-strong:  color-mix(in srgb, var(--ink) 30%, transparent);
  --rule-night:   color-mix(in srgb, var(--on-night) 18%, transparent);

  /* ---- type ---- */
  --f-display: 'Instrument Serif', 'Times New Roman', serif;
  --f-body:    'Newsreader', Georgia, 'Times New Roman', serif;
  --f-label:   'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --f-poster:  'Bebas Neue', 'Archivo', Impact, sans-serif;

  --t-hero:  clamp(3.75rem, 12.2vw, 12.5rem);
  --t-d1:    clamp(2.9rem,  7.4vw,  7rem);
  --t-d2:    clamp(2.1rem,  4.4vw,  4rem);
  --t-d3:    clamp(1.65rem, 2.9vw,  2.6rem);
  --t-d4:    clamp(1.3rem,  1.9vw,  1.6rem);
  --t-lead:  clamp(1.1875rem, 1.55vw, 1.5rem);
  --t-body:  clamp(1.0625rem, 1.06vw, 1.1875rem);
  --t-small: 0.9375rem;
  --t-meta:  0.8125rem;
  --t-label: 0.6875rem;
  --t-micro: 0.625rem;

  /* ---- space ---- */
  --gut:      clamp(1.25rem, 4.2vw, 3.75rem);   /* page gutter */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 3rem;     --s-8: 4rem;
  --s-9: 6rem;     --s-10: 8rem;    --s-11: 12rem;
  --band:     clamp(4.5rem, 11vh, 10rem);        /* vertical section rhythm */
  --band-lg:  clamp(7rem, 17vh, 15rem);
  --measure:  40rem;                             /* 640px reading measure */
  --max:      92rem;

  /* ---- motion ---- */
  --e-expo:  cubic-bezier(.16, 1, .30, 1);
  --e-quint: cubic-bezier(.22, 1, .36, 1);
  --e-quart: cubic-bezier(.76, 0, .24, 1);
  --e-soft:  cubic-bezier(.33, .01, 0, 1);
  --d-fast:  340ms;
  --d-base:  800ms;
  --d-slow:  1200ms;
  --d-image: 1600ms;

  --header-h: 74px;
  --grain: .034;
}

@media (max-width: 800px) {
  :root {
    --header-h: 64px;
    --t-label: 0.75rem;    /* 12px — 11px reads thin at arm's length */
    --t-micro: 0.75rem;    /* 12px */
    --t-meta:  0.875rem;   /* 14px */
    --t-small: 1rem;       /* 16px — no body-adjacent text below 16 on a phone */
  }
}

/* -- 03  RESET & BASE ---------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: var(--t-body);
  font-weight: 380;
  line-height: 1.62;
  font-variant-numeric: oldstyle-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  text-rendering: optimizeLegibility;
}

/* The paper grain. One fixed layer over the whole document — it is what stops
   the flat colour reading as "web" and starts it reading as "printed". */
body::after {
  content: '';
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 9000;
  opacity: var(--grain);
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

::selection { background: var(--rust); color: var(--paper-hi); }

:focus-visible {
  outline: 2px solid var(--rust-ink);
  outline-offset: 3px;
  border-radius: 1px;
}

.skip {
  position: absolute; left: var(--gut); top: -100px;
  z-index: 10000; background: var(--ink); color: var(--paper);
  padding: .75rem 1.25rem; font-family: var(--f-label);
  font-size: var(--t-label); letter-spacing: .16em; text-transform: uppercase;
  text-decoration: none; transition: top 200ms var(--e-expo);
}
.skip:focus { top: 12px; }

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

/* Tracking law: the larger the type, the tighter it is set.
   ≥72px −.028em · 48–72 −.022 · 32–48 −.016 · 15–20 0 · caps 10–13 +.14 */

.display, h1, h2, h3 {
  font-family: var(--f-display);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -.022em;
  text-wrap: balance;
}

.t-hero { font-family: var(--f-display); font-size: var(--t-hero); line-height: .92; letter-spacing: -.032em; }
.t-d1   { font-family: var(--f-display); font-size: var(--t-d1);   line-height: .97; letter-spacing: -.026em; }
.t-d2   { font-family: var(--f-display); font-size: var(--t-d2);   line-height: 1.03; letter-spacing: -.020em; }
.t-d3   { font-family: var(--f-display); font-size: var(--t-d3);   line-height: 1.12; letter-spacing: -.014em; }
.t-d4   { font-family: var(--f-display); font-size: var(--t-d4);   line-height: 1.2;  letter-spacing: -.008em; }

/* Signature device, borrowed and made ours: italic on the function words. */
.t-hero em, .t-d1 em, .t-d2 em, .t-d3 em, .t-d4 em {
  font-style: italic;
  letter-spacing: -.01em;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.48;
  font-weight: 330;
  color: var(--ink-2);
  max-width: 36ch;
  text-wrap: pretty;
}

.prose { max-width: var(--measure); }
.prose p + p { margin-top: 1.15em; }
.prose p { text-wrap: pretty; hyphens: auto; }
.prose > * + h3, .prose > * + h4 { margin-top: 2.2em; }
.prose h4 {
  font-family: var(--f-label); font-size: var(--t-label);
  letter-spacing: .16em; text-transform: uppercase; font-weight: 620;
  color: var(--rust-ink); margin-bottom: .9em;
}
.prose em { font-style: italic; }
.prose strong { font-weight: 600; }

/* Drop-cap on the first paragraph of long-form pieces. */
.prose--feature > p:first-of-type::first-letter {
  font-family: var(--f-display);
  float: left;
  font-size: 4.1em;
  line-height: .78;
  padding: .06em .1em 0 0;
  color: var(--rust);
}

.pull {
  font-family: var(--f-display);
  font-size: var(--t-d3);
  line-height: 1.14;
  letter-spacing: -.016em;
  color: var(--ink);
  margin: clamp(2.5rem, 6vh, 4.5rem) 0;
  padding-left: clamp(1rem, 3vw, 2.25rem);
  border-left: 1px solid var(--rust);
  text-wrap: balance;
}

.label {
  font-family: var(--f-label);
  font-size: var(--t-label);
  font-weight: 620;
  font-stretch: 105%;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1.25;
}
.label--rust { color: var(--rust-ink); }
.label--night { color: var(--on-night-2); }

.poster {
  font-family: var(--f-poster);
  text-transform: uppercase;
  letter-spacing: .012em;
  line-height: .88;
}

.meta {
  font-family: var(--f-label);
  font-size: var(--t-meta);
  font-weight: 420;
  color: var(--ink-3);
  letter-spacing: .01em;
}

.num {
  font-family: var(--f-label);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: .18em;
  color: var(--ink-3);
  font-variant-numeric: lining-nums tabular-nums;
}

/* -- 05  LAYOUT & GRID --------------------------------------------------- */

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gut); }
.wrap--wide { max-width: 116rem; }
.wrap--tight { max-width: 62rem; }

.band   { padding-block: var(--band); }
.band-lg{ padding-block: var(--band-lg); }
.band-t { padding-top: var(--band); }
.band-b { padding-bottom: var(--band); }

.grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--s-6) clamp(1rem, 2.4vw, 2rem); }
@media (max-width: 900px) { .grid { grid-template-columns: repeat(6, 1fr); } }

/* end-only, so an inline grid-column-start still spans correctly */
.c1{grid-column-end:span 1}.c2{grid-column-end:span 2}.c3{grid-column-end:span 3}
.c4{grid-column-end:span 4}.c5{grid-column-end:span 5}.c6{grid-column-end:span 6}
.c7{grid-column-end:span 7}.c8{grid-column-end:span 8}.c9{grid-column-end:span 9}
.c10{grid-column-end:span 10}.c11{grid-column-end:span 11}.c12{grid-column-end:span 12}
@media (max-width: 900px) {
  .c3,.c4,.c5 { grid-column: span 3 !important; }
  .c6,.c7,.c8,.c9,.c10,.c11,.c12 { grid-column: span 6 !important; }
  .m-full { grid-column: span 6 !important; }
}
@media (max-width: 620px) { .grid { grid-template-columns: 1fr; } [class*="c"] { grid-column: 1 / -1 !important; } }

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-5); padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--rule);
  margin-bottom: clamp(2rem, 5vh, 4rem);
}
.section-head__n { white-space: nowrap; }
/* The kicker is nowrap so a short count never breaks mid-phrase. Longer ones
   ("Season 01 — The West Texas capsule") then push the document sideways on a
   phone, so below 700px the head stacks and the kicker is allowed to wrap. */
@media (max-width: 700px) {
  .section-head { flex-wrap: wrap; }
  .section-head__n { white-space: normal; }
}

/* Inverted ground */
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) { background: var(--night); color: var(--on-night); }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .label { color: var(--on-night-2); }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .lead, :is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .meta { color: var(--on-night-2); }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .section-head { border-color: var(--rule-night); }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .num { color: var(--on-night-2); }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) ::selection { background: var(--rust-night); color: var(--night); }

.paper-lo { background: var(--paper-lo); }

/* -- 06  RULES, MARKS & ORNAMENT ---------------------------------------- */

.rule { height: 1px; background: var(--rule); border: 0; }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .rule { background: var(--rule-night); }

/* Decorative screen-print elements from the asset pack. They sit behind and
   beside content, never inside the reading measure. */
.mark {
  position: absolute;
  pointer-events: none;
  user-select: none;
  z-index: 0;
  opacity: .92;
}
.mark img { width: 100%; height: auto; }
.mark--behind { z-index: 0; opacity: .16; }


.rosette {
  width: clamp(78px, 9vw, 128px);
  aspect-ratio: 1;
}

/* An inline ornament used to break long stretches of reading. */
.ornament {
  display: grid; place-items: center;
  padding-block: clamp(2.5rem, 6vh, 5rem);
}
.ornament img { width: clamp(56px, 7vw, 96px); height: auto; opacity: .85; }

/* -- 07  BUTTONS & LINKS ------------------------------------------------- */

a { color: inherit; }

/* Body links: a 1px rule that draws in from the left. */
.link {
  position: relative;
  text-decoration: none;
  color: var(--rust-ink);
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  padding-bottom: 1px;
  transition: background-size var(--d-fast) var(--e-expo), color 220ms linear;
}
.link:hover { background-size: 0% 1px; background-position: 100% 100%; }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .link { color: var(--rust-night); }

.link-quiet {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 100% 100%;
  background-size: 0% 1px;
  padding-bottom: 2px;
  transition: background-size var(--d-fast) var(--e-expo);
}
.link-quiet:hover { background-size: 100% 1px; background-position: 0 100%; }

/* The button. A rule box that fills from the bottom on hover; the label
   swaps colour 60ms into the fill so it never reads as a flicker. */
.btn {
  --btn-ink: var(--ink);
  --btn-fill: var(--ink);
  --btn-on-fill: var(--paper);
  position: relative;
  display: inline-flex; align-items: center; gap: .85em;
  padding: 1.05em 1.9em;
  font-family: var(--f-label);
  font-size: var(--t-label);
  font-weight: 620; letter-spacing: .16em; text-transform: uppercase;
  color: var(--btn-ink);
  text-decoration: none;
  border: 1px solid currentColor;
  overflow: hidden;
  isolation: isolate;
  transition: color 240ms linear 60ms, border-color 240ms linear;
  white-space: nowrap;
}
.btn::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--btn-fill);
  transform: scaleY(0); transform-origin: 50% 100%;
  transition: transform 420ms var(--e-expo);
}
.btn:hover { color: var(--btn-on-fill); border-color: var(--btn-fill); }
.btn:hover::before { transform: scaleY(1); }
.btn__arrow { transition: transform 420ms var(--e-expo); }
.btn:hover .btn__arrow { transform: translateX(4px); }

.btn--rust { --btn-ink: var(--rust-ink); --btn-fill: var(--rust); --btn-on-fill: var(--paper-hi); }
.btn--solid { color: var(--paper); border-color: var(--ink); }
.btn--solid::before { transform: scaleY(1); }
.btn--solid:hover { color: var(--ink); }
.btn--solid:hover::before { transform: scaleY(0); }
.btn--night { --btn-ink: var(--on-night); --btn-fill: var(--on-night); --btn-on-fill: var(--night); }

/* The primary action on a night ground, pre-filled. .btn--rust is a paper
   button: its ink is --rust-ink, which is mixed to sit on cream and reads as a
   smudge on black. This is the same button carrying --rust-night, the one rust
   in the system built for the dark (5.5:1 against night), filled rather than
   outlined so the one thing on the section worth clicking looks like it.
   Hovering wipes it to cream the same way every other button in the set does. */
.btn--rust-night {
  --btn-ink: var(--night);
  --btn-fill: var(--on-night);
  --btn-on-fill: var(--night);
  color: var(--night);
  background: var(--rust-night);
  border-color: var(--rust-night);
}
.btn--rust-night:hover { color: var(--night); border-color: var(--on-night); }

/* A slow highlight crossing the face of the button. Reserved for the single
   action on a page we most want taken — on a site this quiet, one moving thing
   is an arrow, and two would be a fairground. It rides on ::after so the fill
   wipe on ::before is untouched, sits under the label, and is clipped by the
   overflow the button already has. */
.btn--shimmer::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg,
              transparent 38%,
              color-mix(in srgb, var(--on-night) 42%, transparent) 50%,
              transparent 62%);
  transform: translateX(-130%);
  animation: btn-shimmer 4.2s var(--e-expo) infinite;
  pointer-events: none;
}
@keyframes btn-shimmer {
  0%        { transform: translateX(-130%); }
  58%, 100% { transform: translateX(130%); }
}
/* On hover the cream fill is already sweeping across; a second sweep on top of
   it just reads as noise. */
.btn--shimmer:hover::after { animation: none; opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .btn--shimmer::after { animation: none; opacity: 0; }
}
.btn--sm { padding: .8em 1.4em; font-size: var(--t-micro); }

/* -- 08  FORMS ----------------------------------------------------------- */

.field { position: relative; display: block; }
.field input, .field textarea, .field select {
  width: 100%;
  background: transparent;
  border: 0; border-bottom: 1px solid var(--rule-strong);
  padding: .95rem 0 .7rem;
  font-family: var(--f-body); font-size: var(--t-body); color: var(--ink);
  transition: border-color 300ms var(--e-expo);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-4); }
.field input:focus, .field textarea:focus { outline: none; border-color: var(--rust); }
.field textarea { resize: vertical; min-height: 8rem; }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .field input, :is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .field textarea {
  border-color: var(--rule-night); color: var(--on-night);
}
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .field input::placeholder { color: var(--on-night-3); }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .field input:focus { border-color: var(--rust-night); }

.signup { display: flex; gap: var(--s-4); align-items: flex-end; flex-wrap: wrap; }
.signup .field { flex: 1 1 18rem; }

/* -- 09  MEDIA ----------------------------------------------------------- */

.fig { position: relative; overflow: hidden; background: var(--paper-lo); }
.fig img { width: 100%; height: 100%; object-fit: cover; }
.fig--32 { aspect-ratio: 3 / 2; }
.fig--45 { aspect-ratio: 4 / 5; }
.fig--11 { aspect-ratio: 1; }
.fig--169{ aspect-ratio: 16 / 9; }
.fig--21 { aspect-ratio: 2.2 / 1; }
/* 2.2:1 is a banner on a desktop and a 160px letterbox on a phone, where it
   slices the top off everyone's head. Below 900px it opens up to 3:2 so the
   frame survives the width instead of being cropped to a strip. */
@media (max-width: 900px) { .fig--21 { aspect-ratio: 3 / 2; } }
.fig--circle { border-radius: 50%; }

.caption {
  margin-top: .85rem;
  font-family: var(--f-label);
  font-size: var(--t-meta);
  color: var(--ink-3);
  max-width: 34ch;
}
.credit {
  font-family: var(--f-label);
  font-size: var(--t-micro);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3);
}

/* A photo hover that is slow enough to read as considered. */
.fig--hover img { transition: transform 900ms var(--e-expo), filter 900ms var(--e-expo); }
a:hover .fig--hover img, .fig--hover:hover img { transform: scale(1.035); }

/* -- 10  MOTION PRIMITIVES ---------------------------------------------- */

/* Everything below fires once, on entry, and then unobserves.
   Distance is small; duration is long. That is the whole trick. */

[data-anim] { will-change: transform, opacity; }

[data-anim="up"]      { opacity: 0; transform: translateY(24px); }
[data-anim="up-lg"]   { opacity: 0; transform: translateY(40px); }
[data-anim="up-sm"]   { opacity: 0; transform: translateY(14px); }
[data-anim="fade"]    { opacity: 0; }
[data-anim="scale"]   { opacity: 0; transform: scale(.985) translateY(20px); }

[data-anim] {
  transition:
    opacity var(--d-base) var(--e-expo) var(--delay, 0ms),
    transform var(--d-base) var(--e-expo) var(--delay, 0ms);
}
[data-anim].is-in { opacity: 1; transform: none; }

/* Masked image reveal — a curtain wipes off over 1200ms while the picture
   inside settles from 1.12 over 1600ms, so the image outlasts its own mask.
   Deliberately a curtain and not clip-path on the element itself: a target
   clipped to zero area never reports as intersecting, so a clip-path reveal
   silently never fires inside horizontally-scrolled or pinned sections. */
.reveal { position: relative; overflow: hidden; isolation: isolate; }
.reveal > * { transform: scale(1.12); transform-origin: 50% 55%;
  transition: transform var(--d-image) var(--e-expo) var(--delay, 0ms); }
.reveal::after {
  content: ''; position: absolute; inset: -1px; z-index: 2;
  background: var(--curtain, var(--paper-lo));
  transform: scaleY(1); transform-origin: 50% 100%;
  transition: transform var(--d-slow) var(--e-quint) var(--delay, 0ms);
}
.reveal.is-in::after { transform: scaleY(0); }
.reveal.is-in > * { transform: scale(1); }

.reveal--right::after { transform: scaleX(1); transform-origin: 100% 50%; }
.reveal--right.is-in::after { transform: scaleX(0); }

:is(.night,.ftr,.menu,.tier--feature,.mcard--dark), .ftr { --curtain: var(--night-2); }
.paper-lo { --curtain: var(--paper-edge); }

/* Line-by-line display reveal. 105% not 100% — descenders. */
.lines { display: block; }
.lines .line { display: block; overflow: hidden; padding-bottom: .06em; margin-bottom: -.06em; }
.lines .line > span {
  display: block;
  transform: translateY(105%);
  transition: transform 1000ms var(--e-expo) var(--line-delay, 0ms);
}
.lines.is-in .line > span { transform: translateY(0); }

/* Word reveal, for short statements. */
.words .word { display: inline-block; overflow: hidden; vertical-align: bottom; }
.words .word > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 720ms var(--e-expo) var(--word-delay, 0ms);
}
.words.is-in .word > span { transform: translateY(0); }

/* Parallax. Ceiling of 0.30 — beyond that it stops reading as depth and
   starts reading as a bug. */
[data-parallax] { will-change: transform; }

/* Marquee / ticker */
.ticker { overflow: hidden; position: relative; }
.ticker__track {
  display: flex; width: max-content;
  animation: ticker var(--ticker-dur, 46s) linear infinite;
}
.ticker:hover .ticker__track { animation-play-state: paused; }
.ticker__set { display: flex; align-items: center; flex: none; }
@keyframes ticker { to { transform: translateX(-50%); } }

/* Counter */
.counter { font-variant-numeric: lining-nums tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  [data-anim] { opacity: 1 !important; transform: none !important; }
  .reveal::after { display: none !important; }
  .reveal > * { transform: none !important; }
  .lines .line > span, .words .word > span { transform: none !important; }
  .ticker__track { animation: none !important; }
}

/* -- 11  HEADER & NAVIGATION -------------------------------------------- */

.hdr {
  position: fixed; inset: 0 0 auto 0; z-index: 900;
  height: var(--header-h);
  display: flex; align-items: center;
  transition: transform 420ms var(--e-quart), background-color 420ms var(--e-expo),
              border-color 300ms linear, color 300ms linear;
  border-bottom: 1px solid transparent;
  color: var(--ink);
}
.hdr__in { width: 100%; display: flex; align-items: center; gap: var(--s-5); min-width: 0; }
.hdr.is-stuck { background: color-mix(in srgb, var(--paper) 88%, transparent); backdrop-filter: blur(14px) saturate(1.1); border-bottom-color: var(--rule); }
.hdr.is-hidden { transform: translateY(-102%); }
.hdr.on-dark { color: var(--on-night); }
/* The header CTA inherited the paper-ground button tokens everywhere, so on a
   page that opens with a dark hero it was ink-on-ink and effectively gone.
   Over a dark header it takes the night tokens, same as .btn--night. */
.hdr.on-dark .btn { --btn-ink: var(--on-night); --btn-fill: var(--on-night); --btn-on-fill: var(--night); }
.hdr.on-dark.is-stuck { background: color-mix(in srgb, var(--night) 82%, transparent); border-bottom-color: var(--rule-night); }

.brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; flex: none;
  min-height: 44px; }
.brand__mark { width: 34px; height: 34px; flex: none; transition: transform 800ms var(--e-expo), filter 400ms linear; }
.brand:hover .brand__mark { transform: rotate(-9deg); }

.brand__type {
  font-family: var(--f-label); font-weight: 700; font-stretch: 84%;
  font-size: .76rem; letter-spacing: .19em; text-transform: uppercase;
  line-height: 1.12;
}
@media (max-width: 480px) { .brand__type { font-size: .62rem; letter-spacing: .13em; max-width: 8ch; } }

/* The illustrated horizontal lockup is a seal, not a UI mark — it is used
   large, on paper or night, where its two inks can actually be read. */
.lockup { width: clamp(220px, 26vw, 420px); height: auto; }


.nav { margin-left: auto; display: flex; align-items: center; gap: clamp(1rem, 2.2vw, 2.1rem); }
.nav a {
  font-family: var(--f-label); font-size: var(--t-label); font-weight: 560;
  letter-spacing: .15em; text-transform: uppercase; text-decoration: none;
  transition: opacity 240ms linear;
  position: relative; padding-block: .35rem;
}
.nav a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: 100% 50%;
  transition: transform 380ms var(--e-expo);
}
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); transform-origin: 0 50%; }
/* sibling dimming — the hovered item stays, its neighbours step back */
.nav:hover a { opacity: .45; }
.nav:hover a:hover { opacity: 1; }
.nav a[aria-current="page"] { opacity: 1; }

@media (max-width: 1020px) { .nav--desktop { display: none; } }

.burger { display: none; margin-left: auto; width: 48px; height: 48px; position: relative;
  margin-right: -10px; }
@media (max-width: 1020px) { .burger { display: block; } }
.burger span {
  position: absolute; left: 4px; right: 4px; height: 1.5px; background: currentColor;
  transition: transform 460ms var(--e-expo), opacity 200ms linear;
}
.burger span { left: 12px; right: 12px; }
.burger span:nth-child(1) { top: 21px; }
.burger span:nth-child(2) { top: 27px; }
body.menu-open .burger span:nth-child(1) { transform: translateY(3px) rotate(45deg); }
body.menu-open .burger span:nth-child(2) { transform: translateY(-3px) rotate(-45deg); }

.menu__seal {
  position: absolute; right: -8%; bottom: -14%;
  width: min(62vw, 620px); opacity: .16; pointer-events: none;
}
.menu {
  position: fixed; inset: 0; z-index: 890;
  background: var(--night); color: var(--on-night);
  display: grid; align-content: center;
  padding: calc(var(--header-h) + 2rem) var(--gut) var(--gut);
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  transition: clip-path 760ms var(--e-quint), visibility 0s linear 760ms;
  overflow-y: auto;
}
body.menu-open .menu {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path 760ms var(--e-quint), visibility 0s;
}
.menu a {
  font-family: var(--f-display); font-size: clamp(2rem, 7vw, 4rem);
  line-height: 1.16; letter-spacing: -.02em; text-decoration: none;
  display: block; opacity: 0; transform: translateY(24px);
  transition: opacity 620ms var(--e-expo), transform 620ms var(--e-expo);
}
body.menu-open .menu a { opacity: 1; transform: none; }
.menu a:hover { color: var(--rust-night); font-style: italic; }
.menu__foot { margin-top: var(--s-8); display: flex; gap: var(--s-5); flex-wrap: wrap; }
.menu__foot a { font-family: var(--f-label); font-size: var(--t-label); letter-spacing: .16em; text-transform: uppercase; }

/* -- 12  FOOTER ---------------------------------------------------------- */

.ftr { background: var(--night); color: var(--on-night); position: relative; overflow: hidden; }
.ftr__seal {
  position: absolute; right: -6%; top: 50%; translate: 0 -50%;
  width: min(46vw, 520px); opacity: .16; pointer-events: none;
}
@media (max-width: 900px) { .ftr__seal { right: -22%; opacity: .07; } }
.ftr__statement {
  font-family: var(--f-display);
  font-size: clamp(1.85rem, 4.4vw, 4rem);
  line-height: 1.08; letter-spacing: -.02em;
  max-width: 20ch;
}
.ftr a { text-decoration: none; }
.ftr__links { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-6); }
.ftr__links a {
  font-family: var(--f-label); font-size: var(--t-label); font-weight: 560;
  letter-spacing: .16em; text-transform: uppercase; color: var(--on-night-2);
  transition: color 240ms linear;
}
.ftr__links a:hover { color: var(--rust-night); }
.ftr__legal { display: flex; justify-content: space-between; gap: var(--s-5); flex-wrap: wrap;
  padding-top: var(--s-5); border-top: 1px solid var(--rule-night); }

/* -- 13  UTILITIES ------------------------------------------------------- */

.u-center { text-align: center; }
.u-right  { text-align: right; }
.u-rel    { position: relative; }
.u-clip   { overflow: clip; }
.u-flex   { display: flex; }
.u-between{ display: flex; justify-content: space-between; align-items: center; gap: var(--s-5); flex-wrap: wrap; }
/* Without the wrap above, a long lead beside a button pushes the button past
   the right edge on a phone — and because the section clips, the CTA simply
   vanishes rather than causing a visible scrollbar. Stack them instead. */
@media (max-width: 640px) { .u-between { align-items: flex-start; } }
.u-stack > * + * { margin-top: var(--stack, 1rem); }
.u-mt1{margin-top:var(--s-4)} .u-mt2{margin-top:var(--s-5)} .u-mt3{margin-top:var(--s-6)}
.u-mt4{margin-top:var(--s-7)} .u-mt5{margin-top:var(--s-8)} .u-mt6{margin-top:var(--s-9)}
.u-mb2{margin-bottom:var(--s-5)} .u-mb3{margin-bottom:var(--s-6)} .u-mb4{margin-bottom:var(--s-7)}
.u-measure { max-width: var(--measure); }
.u-narrow  { max-width: 34rem; }
.u-rust { color: var(--rust-ink); }
.u-olive { color: var(--olive-ink); }
:is(.night,.ftr,.menu,.tier--feature,.mcard--dark) .u-rust { color: var(--rust-night); }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* The honeypot on every form. Off-screen rather than display:none — a bot
   that parses CSS skips hidden inputs but fills this one happily. It is
   taken out of the flow entirely, including the input itself, so it cannot
   push a grid around or register as a real tap target. */
.u-hide-visually {
  position: absolute !important;
  left: -10000px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}
.u-hide-visually input { width: 1px; height: 1px; padding: 0; border: 0; }
@media (max-width: 900px) { .hide-m { display: none; } }
@media (min-width: 901px) { .hide-d { display: none; } }


/* -- 14  TOUCH ----------------------------------------------------------- */
/* On a coarse pointer every standalone control clears the 44px Apple/WCAG
   target. Inline links inside running prose are exempt by spec and are left
   alone — padding them out would wreck the leading. */

@media (pointer: coarse) {
  .nav a,
  .ftr__links a,
  .menu__foot a,
  .article__nav a,
  .drawer__head button,
  .cart-btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .nav a { padding-block: .9rem; }
  /* standalone links in lists are navigation, not prose — they get a target */
  /* Standalone links — list items, bylines, breadcrumbs — get a real target.
     Links inside running prose are exempt under WCAG 2.5.8 and are left alone;
     padding them out would wreck the leading. */
  li > .link, li > .link-quiet, .u-stack > .link,
  .label > .link-quiet, .label--rust > .link-quiet,
  .article__byline .link, .writer dd > .link,
  /* commerce: keep shopping, fit & sizing, checkout back / edit */
  .link-quiet.meta, button.link-quiet {
    min-height: 44px; display: inline-flex; align-items: center;
  }
  .article__nav a, .j-row, .ev, .prod, .tax { min-height: 44px; }
  .mono, code { font-size: 0.9em; }
  .ftr__links { gap: 0 var(--s-6); }
  .ftr__links a { padding-block: .55rem; }
  .menu__foot { gap: .25rem var(--s-5); }
  .btn { padding-block: 1.15em; }
  .btn--sm { padding-block: 1em; }
  .faq__q { min-height: 56px; }
  .field input, .field textarea, .field select { padding-block: 1rem .85rem; }
  .tax { min-height: 112px; }
  .pol:hover, .fig--hover:hover img, .tier:hover, .mcard:hover { transform: none; }
}
