/* =========================================================================================
   Polk Vending Co. — site styles
   One stylesheet for every page; then a small page file (home.css, locations.css, machines.css,
   about.css, additional.css, contact.css); then phones.css (one pass for screens up to 600px), always last.

   Contents
     1  Fonts ............. Libre Caslon Text, Public Sans, the founder's hand (self-hosted)
     2  Brand tokens ...... THE block to edit: the palette and the roles, the font stacks, weights
     3  Derived tokens .... tints, metrics, motion (computed from §2, no need to edit)
     4  Tones ............. paper / alt / night / oxblood bands and the contextual colors they set
     5  Base .............. reset, body, focus, selection, skip link, paper grain, icons
     6  Layout ............ containers, sections, section heads, hairlines
     7  Type .............. display sizes (.d1–.d3), italic accents, lede, labels
     8  Buttons & links ... .btn, .link-arrow, .big-mail
     9  Header ............ bar, logo, slogan, frost on scroll, MENU button, full-screen menu sheet
    10  Heroes ............ pinned hero + the sheet that slides over it, the video hero, page hero
    11  Components
          11.1 Place cards           11.7  Filter chips                   11.13 Letter card
          11.2 Index (names, stage)  11.8  Feature list                   11.14 Split band
          11.3 Numbered list         11.9  Forms                          11.15 Steps + four words
          11.4 Titled columns, ticks 11.10 Map figure (paper and Night)   11.16 Machine figure             
          11.5 Value plates          11.11 Promise band (counters)        11.17 Story (portrait + text)
          11.6 Accordion             11.12 CTA band + split closing band  11.18 Printed-page backdrop
          11.19 Chain of stops       11.20 Tick list                      11.21 Product lineup
          11.22 Product rail
    12  Scene ............. the growing illustrated scene (scene.js writes --p)
    13  Footer ............ links, legal line, the engraved plate + grass breeze
    14  404
    15  Motion ............ line masks, reveals, stagger, curtain, draw, page veil
    16  Utilities
    17  Reduced motion
    18  Print
   Breakpoints (media queries can't read custom properties): the layout steps at 1100 · 900 · 760 · 640/641 · 600
   (phones.css); a few components keep their own: 1000 (letter borders), 980, 860 (backdrop type), 820 (header
   and menu sheet), 560, 520 and 380 (the smallest phones), landscape phones (max-height 500), and container
   queries on the map (560, 340). Upper bounds of a pair end in .98 (899.98 / 900).
   ========================================================================================= */


/* -----------------------------------------------------------------------------------------
   1  Fonts — self-hosted WOFF2 in assets/fonts/ (OFL licence files beside them). The two Caslon
   files are preloaded in every page <head>; Public Sans is one variable file; the handwriting face
   is used only by the founder's letter.
   ----------------------------------------------------------------------------------------- */
@font-face{font-family:"Libre Caslon Text";src:url("../fonts/libre-caslon-text-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Libre Caslon Text";src:url("../fonts/libre-caslon-text-400-italic.woff2") format("woff2");font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:"Public Sans";src:url("../fonts/public-sans-100-900.woff2") format("woff2");font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:"Cedarville Cursive";src:url("../fonts/cedarville-cursive-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}


/* -----------------------------------------------------------------------------------------
   2  Brand tokens — the palette (brand/palette.json) and the roles the components read
   ----------------------------------------------------------------------------------------- */
:root{
  /* palette */
  --limestone:#F0EBE3;          /* the page; text on dark */
  --limestone-deep:#E6DFD4;     /* alternate bands, cards, form fields, the footer */
  --iron-gall:#1F1A18;          /* text; the ink of every engraving on paper */
  --slate:#5E544E;              /* secondary text */
  --stone:#857A71;              /* hairlines and field borders (3:1) */
  --night:#2A1416;              /* deep bands: the hero still, statements, values, the 404 */
  --oxblood:#5F1E24;            /* the closing band of every page (and one plate on Our Approach), primary buttons, accent words on paper */
  --saddle-ink:#7E522C;         /* eyebrows, list numerals, notes, link hover on paper */
  --saddle:#CC9D72;             /* the accent on Night and Oxblood */
  --cabinet:#0E0F0E;            /* the machine: its drawings and its lit panel */

  /* roles (components use these; the palette above feeds them) */
  --paper:var(--limestone);
  --paper-2:var(--limestone-deep);
  --card:var(--limestone-deep);
  --ink:var(--iron-gall);
  --ink-soft:var(--slate);
  --ink-faint:var(--stone);
  --brand:var(--oxblood);       /* primary buttons, the closing band, the plate */
  --brand-deep:var(--night);    /* the deep bands */
  --accent:var(--oxblood);      /* italic accent words on paper */
  --accent-ink:var(--saddle-ink);   /* small accent text on paper: eyebrows, numerals, notes */
  --accent-soft:var(--saddle);  /* accents on Night and Oxblood */
  --hero-tint:var(--iron-gall); /* the tint over the hero reels (Night stained the footage maroon) */
  --line:color-mix(in srgb,var(--stone) 52%,transparent);   /* hairlines on paper */

  /* type: Caslon for every word you read, Public Sans for labels, buttons and fine print, a hand for the letter */
  --f-display:"Libre Caslon Text",Georgia,"Times New Roman",serif;
  --f-text:"Libre Caslon Text",Georgia,"Times New Roman",serif;
  --f-ui:"Public Sans","Helvetica Neue",Arial,sans-serif;
  --f-hand:"Cedarville Cursive","Segoe Print","Bradley Hand",cursive;

  /* weights and tracking (no bold anywhere: Caslon is set at 400 only) */
  --w-display:400;
  --w-hero:400;
  --w-text:400;
  --w-ui:500;                   /* form labels, inline UI links */
  --w-label:600;                /* eyebrows, MENU, buttons, column heads */
  --w-strong:400;               /* names and titles stay regular */
  --track-display:-.012em;
  --track-caps:.15em;           /* capitals in Public Sans: eyebrows +.16, buttons +.14 */
}


/* -----------------------------------------------------------------------------------------
   3  Derived tokens (computed from §2)
   ----------------------------------------------------------------------------------------- */
:root{
  --line-soft:color-mix(in srgb,var(--stone) 26%,transparent);
  --line-dark:color-mix(in srgb,var(--limestone) 17%,transparent);    /* hairlines on dark bands */
  --on-dark-soft:color-mix(in srgb,var(--limestone) 60%,var(--night)); /* secondary text on Night (≈ 6:1) */
  --frost:color-mix(in srgb,var(--paper) 92%,transparent);           /* the header once it frosts (no pink over the Oxblood band) */
  --shade:color-mix(in srgb,var(--night) 38%,transparent);           /* soft shadows */

  /* metrics */
  --gutter:clamp(1.25rem,4.4vw,4.5rem);
  --wide:1800px;
  --mid:1440px;
  --narrow:760px;
  --sect:clamp(3.75rem,7vw,7rem);
  --sect-half:clamp(2.2rem,3.8vw,3.8rem);
  --col-gap:clamp(1.8rem,3.6vw,4.6rem);
  --hdr:80px;                                                         /* header height, for offsets */
  --bar-x:clamp(1.1rem,1.8vw,2.1rem);                                 /* header side padding (the menu sheet uses it too) */
  --logo-h:40px;                                                      /* the header lockup's height (32px on phones) */

  /* motion */
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-io:cubic-bezier(.65,0,.35,1);
}


/* -----------------------------------------------------------------------------------------
   4  Tones
   A band sets its background and the contextual colors every component reads, so a component
   never needs a ".on-dark" override: it uses --fg, --fg-soft, --rule, --em, --focus …
     tone-paper (Limestone) · tone-alt (Limestone Deep) · tone-night (statements, values, heroes)
     · tone-oxblood (the closing band: one per page)
   ----------------------------------------------------------------------------------------- */
:root,.tone-paper,.tone-alt{
  --bg:var(--paper);
  --fg:var(--ink);
  --fg-soft:var(--ink-soft);
  --fg-faint:var(--ink-faint);
  --rule:var(--line);
  --rule-strong:var(--stone);
  --em:var(--accent);                 /* italic accent words: Oxblood on paper */
  --em-small:var(--accent-ink);       /* small accents: Saddle Ink */
  --focus:var(--oxblood);
  --surface:var(--paper-2);           /* cards and tiles sitting on the band */
  --field-bg:var(--paper-2);
  --field-line:var(--stone);
  --solid-bg:var(--oxblood);
  --solid-fg:var(--limestone);
  --solid-hover:var(--night);
}
.tone-alt{--bg:var(--paper-2);--surface:var(--paper);--field-bg:var(--paper)}
.tone-night,.tone-oxblood{
  --bg:var(--night);
  --fg:var(--limestone);
  --fg-soft:var(--on-dark-soft);
  --fg-faint:color-mix(in srgb,var(--limestone) 45%,transparent);
  --rule:var(--line-dark);
  --rule-strong:color-mix(in srgb,var(--limestone) 45%,transparent);
  --em:var(--saddle);
  --em-small:var(--saddle);
  --focus:var(--saddle);
  --surface:color-mix(in srgb,var(--limestone) 5%,transparent);
  --field-bg:color-mix(in srgb,var(--limestone) 6%,transparent);
  --field-line:color-mix(in srgb,var(--limestone) 42%,transparent);
  --solid-bg:var(--limestone);
  --solid-fg:var(--night);
  --solid-hover:var(--saddle);
}
.tone-oxblood{
  --bg:var(--oxblood);
  --fg-soft:color-mix(in srgb,var(--limestone) 72%,var(--oxblood));
  --rule:color-mix(in srgb,var(--limestone) 22%,transparent);
  --solid-fg:var(--oxblood);
}
.tone-paper,.tone-alt,.tone-night,.tone-oxblood{background-color:var(--bg);color:var(--fg)}


/* -----------------------------------------------------------------------------------------
   5  Base
   ----------------------------------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;font-synthesis:none}   /* no faked bold: Caslon is 400 only */
html:focus-within{scroll-behavior:smooth}
body{
  margin:0;
  background:var(--paper);color:var(--ink);
  font-family:var(--f-text);font-weight:var(--w-text);
  font-size:1.125rem;line-height:1.62;
  font-kerning:normal;font-variant-numeric:proportional-nums;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  overflow-x:clip;
}
body.is-locked{overflow:hidden}
img,svg,video,canvas{display:block;max-width:100%}
img{height:auto}
p,ul,ol,figure,blockquote,dl,dd{margin:0}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
::placeholder{color:var(--fg-soft);opacity:1}                 /* the hint carries real guidance: AA (5.5:1) */
::selection{background:var(--oxblood);color:var(--limestone)}
.tone-night ::selection,.tone-oxblood ::selection,.hero--video ::selection{background:var(--saddle);color:var(--night)}

/* keyboard focus: one ring, in the band's focus color */
:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
:focus:not(:focus-visible){outline:none}
main:focus,section[tabindex="-1"]:focus{outline:none}           /* jump targets, not controls */
html{scroll-padding-top:calc(var(--hdr) + 1.25rem)}      /* anchor jumps and keyboard focus land below the bar */

.skip-link{
  position:fixed;left:1rem;top:1rem;z-index:10000;padding:.85rem 1.25rem;
  background:var(--night);color:var(--limestone);font-family:var(--f-ui);font-weight:var(--w-ui);font-size:.95rem;line-height:1.2;
  transform:translateY(calc(-100% - 1.5rem));opacity:0;pointer-events:none;
  transition:transform .35s var(--ease-out),opacity .2s var(--ease);
}
.skip-link:focus{transform:none;opacity:1;pointer-events:auto;outline:2px solid var(--saddle);outline-offset:2px}

/* paper grain over everything: keeps flat color from looking generated */
body::after{
  content:'';position:fixed;inset:0;z-index:9998;pointer-events:none;opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* the UI icon sprite (inline in each page) and its uses: <svg class="icon"><use href="#i-arrow"/></svg> */
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.icon{width:1em;height:1em;flex:none;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}


/* -----------------------------------------------------------------------------------------
   6  Layout
   ----------------------------------------------------------------------------------------- */
.container{max-width:var(--mid);margin-inline:auto;padding-inline:var(--gutter)}
.container--wide{max-width:var(--wide);margin-inline:auto;padding-inline:var(--gutter)}
.container--narrow{max-width:calc(var(--narrow) + 2 * var(--gutter));margin-inline:auto;padding-inline:var(--gutter)}

.section{position:relative;padding-block:var(--sect)}
.section--tight{padding-block:var(--sect-half)}
.section--flush-top{padding-top:0}

/* a hairline across the top of each section (the footer's rule); none where a band runs on from the one above */
.section::before{content:'';position:absolute;top:0;left:0;width:100%;height:1px;background:var(--rule);pointer-events:none}
.section:is(.tone-night,.tone-oxblood)::before,.section--flush-top::before,
.slide-over>.section:first-child::before,.page-hero+.section::before,:is(.tone-night,.tone-oxblood)+.section::before,
.section.cta-band::before{display:none}

.section-head{display:grid;gap:clamp(1rem,1.5vw,1.4rem);max-width:900px;margin-bottom:clamp(2rem,3.4vw,3.4rem)}
.section-head--center{justify-items:center;text-align:center;margin-inline:auto}
.section-head--center .lede{text-align:center}
.section-head--wide{max-width:none}
.section-head--split{max-width:none;grid-template-columns:minmax(0,1fr) auto;align-items:end;column-gap:2rem}
@media (max-width:760px){.section-head--split{grid-template-columns:1fr}}


/* -----------------------------------------------------------------------------------------
   7  Type — Caslon for headlines and reading, Public Sans for labels (brand/type.md)
   ----------------------------------------------------------------------------------------- */
h1,h2,h3,h4{margin:0;font-weight:inherit}
.d1,.d2,.d3,.h4{font-family:var(--f-display);font-weight:var(--w-display);text-wrap:balance}
/* the leading of the display sizes is set by Caslon's long tails: at 1.2 a g, p or y on one line clears a d, an i's
   dot, an apostrophe or a capital on the line under it by a tenth of an em. At 1.14 they clear by half that, which
   reads as touching (the owner caught it twice); don't set display type tighter than this */
.d1{font-size:clamp(2.75rem,5.6vw,5.25rem);line-height:1.2;letter-spacing:var(--track-display)}
.d2{font-size:clamp(2.125rem,3.8vw,3.5rem);line-height:1.2;letter-spacing:-.008em}
.d3{font-size:clamp(1.6rem,2.4vw,2.3rem);line-height:1.2;letter-spacing:-.006em}
.h4{font-size:clamp(1.45rem,1.8vw,1.85rem);line-height:1.2}
/* the house move: one italic accent phrase per headline, its color set by the band (Oxblood on paper,
   Saddle on Night and Oxblood, Limestone over video) */
.d1 em,.d2 em,.d3 em,.h4 em,.statement em{font-style:italic;color:var(--em)}

.lede{
  font-size:clamp(1.19rem,1.04rem + .4vw,1.375rem);line-height:1.5;
  color:var(--fg-soft);max-width:56ch;text-wrap:pretty;
}
/* a statement: display type at reading size (mission words, hero statements) */
.statement{font-family:var(--f-display);font-weight:var(--w-display);font-size:clamp(1.6rem,3vw,2.9rem);line-height:1.2;letter-spacing:-.008em;text-wrap:balance}
/* eyebrows and small labels: Public Sans capitals, tracked */
.label{font-family:var(--f-ui);font-weight:var(--w-label);font-size:.75rem;line-height:1.3;letter-spacing:.16em;text-transform:uppercase;color:var(--em-small)}
.prose p+p{margin-top:1em}
/* no one-word last lines in running text; names and questions break evenly */
.prose p,.faq__body p,.step__d,.pcard__note{text-wrap:pretty}
.faq__q,.place-card__name{text-wrap:balance}
.prose a{text-decoration:underline;text-decoration-color:var(--rule-strong);text-underline-offset:.2em;transition:text-decoration-color .3s var(--ease),color .3s var(--ease)}
.prose a:hover{text-decoration-color:currentColor;color:var(--em-small)}
/* fine print: Public Sans, small */
.coords{font-family:var(--f-ui);font-size:.8125rem;line-height:1.5}


/* -----------------------------------------------------------------------------------------
   8  Buttons & links — buttons are Public Sans capitals; the primary is Oxblood (Limestone on dark bands)
   ----------------------------------------------------------------------------------------- */
.btn{
  --b-bg:transparent;--b-fg:var(--fg);--b-line:var(--rule-strong);
  display:inline-flex;align-items:center;justify-content:center;gap:.7rem;
  min-height:48px;padding:.95rem 1.55rem;border:1px solid var(--b-line);border-radius:0;
  background:var(--b-bg);color:var(--b-fg);
  font-family:var(--f-ui);font-weight:var(--w-label);font-size:.8125rem;line-height:1.2;letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;
  cursor:pointer;transition:background-color .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease);
}
.btn .icon{width:1.05rem;height:1.05rem;transition:transform .45s var(--ease-out)}
.btn:hover .icon{transform:translateX(3px)}
.btn:hover{--b-bg:var(--fg);--b-fg:var(--bg);--b-line:var(--fg)}
.btn--solid{--b-bg:var(--solid-bg);--b-fg:var(--solid-fg);--b-line:var(--solid-bg)}
.btn--solid:hover{--b-bg:var(--solid-hover);--b-fg:var(--solid-fg);--b-line:var(--solid-hover)}
.btn--block{width:100%}
@media (max-width:379.98px){.btn{max-width:100%;white-space:normal}}

.link-arrow{
  display:inline-flex;align-items:center;gap:.55rem;
  padding-bottom:.4rem;border-bottom:1px solid var(--rule-strong);
  font-family:var(--f-ui);font-weight:var(--w-ui);font-size:.9375rem;line-height:1.3;white-space:nowrap;color:var(--fg);
  transition:color .35s var(--ease),border-color .35s var(--ease);
}
.link-arrow .icon{width:1rem;height:1rem;transition:transform .45s var(--ease-out)}
.link-arrow:hover{color:var(--em-small);border-color:currentColor}
.link-arrow:hover .icon{transform:translateX(4px)}

/* the email set large: a quiet hairline at rest says "link"; hover draws the full line over it */
.big-mail{
  position:relative;justify-self:start;display:inline-block;padding-bottom:.3rem;
  font-family:var(--f-display);font-weight:var(--w-display);font-size:clamp(1.3rem,2.3vw,2rem);line-height:1.12;letter-spacing:-.01em;
  color:var(--em);overflow-wrap:anywhere;
  background:linear-gradient(color-mix(in srgb,currentColor 38%,transparent),color-mix(in srgb,currentColor 38%,transparent)) left bottom/100% 1px no-repeat;
}
.big-mail::after{content:'';position:absolute;left:0;bottom:0;width:100%;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .65s var(--ease-out)}
.big-mail:hover::after{transform:scaleX(1);transform-origin:left}


/* -----------------------------------------------------------------------------------------
   9  Header + menu sheet
   Without JS the bar is the logo and the five links. With JS (main.js) the links move into a
   full-screen sheet behind a MENU button, the bar frosts once you scroll, shows the slogan,
   slides away on the way down and comes back on the way up.
   ----------------------------------------------------------------------------------------- */
.site-header{
  position:fixed;inset:0 0 auto;z-index:900;color:var(--fg);
  border-bottom:1px solid transparent;
  transition:transform .55s var(--ease),background-color .45s var(--ease),border-color .45s var(--ease),color .45s var(--ease);
}
.site-header .bar{
  position:relative;display:flex;align-items:center;gap:1rem 1.5rem;flex-wrap:wrap;
  min-height:var(--hdr);padding:.75rem var(--bar-x);
  transition:padding .45s var(--ease);
}
/* without JS the bar never frosts, so it stays at the top of the page instead of riding over the bands */
html:not(.js) .site-header{position:absolute}
.site-header.is-stuck{background:var(--frost);-webkit-backdrop-filter:blur(16px) saturate(1.4);backdrop-filter:blur(16px) saturate(1.4);border-bottom-color:var(--line-soft)}
.site-header.is-hidden{transform:translateY(-105%)}

.brand{display:block;flex:none}
.brand img{height:var(--logo-h);width:auto}
.logo-light{display:none}

/* over a dark hero (body.has-dark-hero) and on the 404 the bar is light until it frosts, or until the menu opens:
   the menu is on the footer's paper, so the bar over it is ink on paper, like a frosted one */
.has-dark-hero .site-header:not(.is-stuck):not(.is-menu-open){--fg:var(--limestone);--focus:var(--saddle);border-bottom-color:var(--line-dark)}
.has-dark-hero .site-header:not(.is-stuck):not(.is-menu-open) .logo-dark{display:none}
.has-dark-hero .site-header:not(.is-stuck):not(.is-menu-open) .logo-light{display:block}

/* the slogan, beside the logo behind a hairline, once the bar frosts (wide screens) */
.bar-slogan{
  flex:none;margin-right:auto;padding-left:clamp(1rem,1.4vw,1.4rem);border-left:1px solid var(--rule);
  font-family:var(--f-display);font-style:italic;font-size:.97rem;line-height:1.5;white-space:nowrap;color:var(--oxblood);
  opacity:0;transform:translateX(-6px);pointer-events:none;
  transition:opacity .45s var(--ease),transform .6s var(--ease-out);
}
.site-header.is-stuck .bar-slogan{opacity:1;transform:none}
.site-header.is-menu-open .bar-slogan{opacity:0}
@media (max-width:899.98px){.bar-slogan{display:none}}
html:not(.js) .bar-slogan{display:none}

/* the section links: inline without JS (they become the sheet with it) */
.bar-cta{display:flex;align-items:center;margin-left:auto}
.bar-nav{display:flex;flex-wrap:wrap;align-items:center;gap:.2rem clamp(1rem,2vw,2.2rem)}
.bar-nav a{
  position:relative;padding-block:.5rem;color:inherit;
  font-family:var(--f-ui);font-weight:var(--w-ui);font-size:.9375rem;white-space:nowrap;
}
.bar-nav a::after{content:'';position:absolute;left:0;bottom:.25rem;width:100%;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .55s var(--ease-out)}
.bar-nav a:hover::after,.bar-nav a[aria-current="page"]::after{transform:scaleX(1);transform-origin:left}
.js .site-header .bar-cta{display:none}
.js .site-header .bar{flex-wrap:nowrap}

/* the MENU button: two drawn lines and the word, no box. Open, the lines cross and it reads Close. */
.menu-btn,.menu-sheet{display:none}
.js .menu-btn{
  display:inline-flex;align-items:center;gap:.85rem;min-height:44px;margin-left:auto;padding:.55rem 0 .55rem .6rem;
  border:0;background:none;color:var(--fg);cursor:pointer;-webkit-tap-highlight-color:transparent;
  font-family:var(--f-ui);font-weight:var(--w-label);font-size:.75rem;line-height:1;letter-spacing:.16em;text-transform:uppercase;
  transition:color .35s var(--ease);
}
.menu-btn__i{position:relative;flex:none;width:30px;height:10px}
.menu-btn__i::before,.menu-btn__i::after{
  content:'';position:absolute;right:0;height:1.5px;background:currentColor;
  transition:transform .45s var(--ease-out),top .45s var(--ease-out),width .45s var(--ease-out);
}
.menu-btn__i::before{top:0;width:100%}
.menu-btn__i::after{top:8px;width:66%}
.menu-btn[aria-expanded="true"] .menu-btn__i::before{top:4px;width:80%;transform:rotate(45deg)}
.menu-btn[aria-expanded="true"] .menu-btn__i::after{top:4px;width:80%;transform:rotate(-45deg)}
.site-header .menu-btn:focus-visible{outline:none}
.site-header .menu-btn:focus-visible .menu-btn__t{text-decoration:underline;text-underline-offset:.35em}
@media (hover:hover){.js .menu-btn:hover{color:var(--em-small)}.has-dark-hero .site-header:not(.is-stuck):not(.is-menu-open) .menu-btn:hover{color:var(--saddle)}}

/* the sheet: the footer's paper (Limestone Deep) with the footer's engraved scene along its foot (the owner's call,
   Oct 9: "a light colored background like this [the footer] and literally use the same background"; it was Night,
   with the night skyline at its foot, for two days). Full screen, under the bar; links large on the left, the
   details on the right */
.js .menu-sheet{
  --bg:var(--paper-2);--fg:var(--ink);--fg-soft:var(--ink-soft);--rule:var(--line);--em:var(--accent);
  display:flex;flex-direction:column;position:fixed;inset:0;z-index:899;
  padding:calc(var(--hdr) + clamp(1.4rem,6vh,3rem)) var(--bar-x) 0;   /* no foot padding: the scene's band is the foot */
  background:var(--bg);color:var(--fg);
  overflow-y:auto;overscroll-behavior:contain;
  visibility:hidden;opacity:0;transition:opacity .4s var(--ease),visibility 0s linear .4s;
}
.js .menu-sheet.is-open{visibility:visible;opacity:1;transition:opacity .4s var(--ease),visibility 0s}
.menu-sheet__in{
  width:100%;max-width:1080px;margin:auto;padding-bottom:clamp(1rem,6vh,4rem);
  display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);align-items:center;column-gap:clamp(2.5rem,7vw,7rem);
}
.menu-sheet ul{list-style:none;margin:0;padding:0}
.menu-sheet li a{
  display:inline-block;min-height:44px;padding:.3rem 0;color:var(--fg);
  font-family:var(--f-display);font-weight:var(--w-display);font-size:clamp(2.3rem,5.2vw,4.4rem);line-height:1.08;letter-spacing:var(--track-display);
  opacity:0;transform:translateY(14px);transition:opacity .45s var(--ease),transform .7s var(--ease-out),color .3s var(--ease);
}
.menu-sheet.is-open li a{opacity:1;transform:none}
.menu-sheet.is-open li:nth-child(2) a{transition-delay:.04s}
.menu-sheet.is-open li:nth-child(3) a{transition-delay:.08s}
.menu-sheet.is-open li:nth-child(4) a{transition-delay:.12s}
.menu-sheet.is-open li:nth-child(5) a{transition-delay:.16s}
.menu-sheet.is-open li:nth-child(6) a{transition-delay:.2s}
.menu-sheet li a[aria-current="page"]{font-style:italic;color:var(--em)}
@media (hover:hover){.menu-sheet li a:hover{color:var(--em)}}
.menu-sheet:focus,.menu-sheet :focus-visible{outline:none}
.menu-sheet li a:focus-visible{color:var(--em);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.14em}
.menu-sheet__info{
  align-self:stretch;display:flex;flex-direction:column;justify-content:center;gap:.2rem;
  padding-left:clamp(2.5rem,7vw,7rem);border-left:1px solid var(--rule);
  font-size:clamp(1rem,1.15vw,1.15rem);line-height:1.7;color:var(--fg-soft);
  opacity:0;transition:opacity .6s var(--ease) .25s;
}
.menu-sheet.is-open .menu-sheet__info{opacity:1}
.menu-sheet__h{margin-top:1.6rem;font-family:var(--f-display);font-style:italic;font-size:1.1em;color:var(--em)}
.menu-sheet__h:first-child{margin-top:0}
.menu-sheet__info a{border-bottom:1px solid transparent;transition:color .3s var(--ease),border-color .3s var(--ease)}
.menu-sheet__info a:hover,.menu-sheet__info a:focus-visible{color:var(--fg);border-color:currentColor}
/* the foot of the sheet: the footer's own scene (Fort Worth across the river, between two live oaks), in a band of
   its own under the links, so no word ever stands on the drawing. main.js §2 clones the footer's two pictures into
   the band's span, so the browser picks the same files and already has them if the footer has been seen; the
   footer's rules place them (.f-plate, .f-grass in §13: full width, bottom-anchored; 180% wide and centred at 640px
   and under) and here they hold still, as the footer's do at rest. The span is the plate's box: as wide as the sheet,
   as tall as the plate at that width (--plate-h), drawn up by 27% of its height, since the plate's top third is
   open sky: the band begins a little above the tallest mast. The band takes the room the links leave, up to the rest of the
   plate, and never less than a foot's padding (1rem, or the phone's safe area); a short window cuts the scene off
   at the foot, and under 5.5rem of room it stays out. The pictures are fetched when the menu is first reached for
   (the button's first hover, focus or touch, the opening, or a few idle seconds after the page has loaded on a
   desktop), never with the page, and the scene fades up only once both have arrived (.is-scene-ready). */
.js .menu-sheet .menu-sheet__in{flex-shrink:0;padding-bottom:0}
.menu-sheet__scene{
  --plate-h:54.17vw;                             /* the plate's height at full width (1300/2400), as in the footer */
  container-type:size;position:relative;overflow:hidden;flex:0 1 auto;
  min-height:max(1rem,env(safe-area-inset-bottom));height:calc(var(--plate-h) * .73);
  margin:0 calc(var(--bar-x) * -1);pointer-events:none;
}
.menu-sheet__scene span{
  position:absolute;left:0;top:0;width:100%;height:var(--plate-h);
  opacity:0;transform:translateY(calc(-27% + 12px));transition:opacity .9s var(--ease) .25s,transform 1.2s var(--ease-out) .25s;
}
.menu-sheet.is-open.is-scene-ready .menu-sheet__scene span{opacity:1;transform:translateY(-27%)}
@container (max-height:5.5rem){.menu-sheet__scene span{display:none}}
@media (max-width:640px){.menu-sheet__scene{--plate-h:97.5vw}}   /* the footer's phone crop: the plate 180% wide */
/* while the sheet is up the bar is part of it: the sheet's paper, ink, the dark logo, a hairline, no frost, never slid away */
.site-header.is-menu-open{background:var(--paper-2);-webkit-backdrop-filter:none;backdrop-filter:none;border-bottom-color:var(--line);transform:none}
html.menu-open body{padding-right:var(--lock-gap,0px)}
html.menu-open .site-header{right:var(--lock-gap,0px)}

@media (max-width:820px){
  :root{--logo-h:32px;--hdr:64px}
  .menu-sheet__in{grid-template-columns:minmax(0,1fr);row-gap:clamp(1.6rem,5vh,2.6rem);max-width:30rem;padding-bottom:0}
  .menu-sheet__info{padding:clamp(1.4rem,4vh,2rem) 0 0;border-left:0;border-top:1px solid var(--rule);font-size:1rem;line-height:1.65}
  .menu-sheet__h{margin-top:1rem}
  .menu-sheet li a{font-size:clamp(2.2rem,10.5vw,3.4rem);padding:.42rem 0}
  /* no-JS fallback: the links wrap under the logo */
  .bar-cta{width:100%;margin-left:0}
  .bar-nav{gap:0 1.1rem}
  .bar-nav a{font-size:.98rem;padding-block:.55rem}
  /* … which makes the bar taller than --hdr: on a paper page it joins the flow instead of covering the
     first words (a dark hero keeps its words low, clear of it) */
  html:not(.js) body:not(.has-dark-hero){--hdr:0px}
  html:not(.js) body:not(.has-dark-hero) .site-header{position:relative}
  /* a dark top that starts with its words (body.has-dark-top: Contact) does the same, the bar in Night */
  html:not(.js) body.has-dark-top{--hdr:0px}
  html:not(.js) body.has-dark-top .site-header{position:relative;background:var(--night)}
}
/* an upright phone with its browser's bars showing (760px tall and under): the same menu set closer, so it no longer
   scrolls there (it did, by a few pixels on an iPhone and by a lot on a small one) and the scene has its band */
@media (max-width:820px) and (max-height:760px) and (orientation:portrait){
  .js .menu-sheet{padding-top:calc(var(--hdr) + clamp(.6rem,16vh - 5.2rem,2rem))}   /* the first link a little under the bar where there is room for it */
  .menu-sheet__in{row-gap:1rem}
  .menu-sheet li a{padding:.2rem 0}
  .menu-sheet__info{padding-top:1rem;line-height:1.55}
  .menu-sheet__h{margin-top:.6rem}
}
/* a phone on its side: the links in two columns so the whole menu shows at once */
@media (orientation:landscape) and (max-height:500px){
  .js .menu-sheet{padding-top:calc(var(--hdr) + .4rem)}
  .menu-sheet__in{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);max-width:none;column-gap:1.6rem}
  .menu-sheet__info{padding:0 0 0 1.6rem;border-top:0;border-left:1px solid var(--rule);font-size:.9rem;line-height:1.5}
  .menu-sheet ul{display:grid;grid-template-columns:repeat(2,minmax(0,max-content));column-gap:clamp(1.6rem,4vw,3rem)}   /* each column as wide as its longest name: "Our Approach" on one line */
  .menu-sheet li a{padding:.25rem 0;font-size:clamp(1.6rem,4.4vw,2.1rem)}
}


/* -----------------------------------------------------------------------------------------
   10  Heroes
   .hero--pinned holds still (sticky) while .slide-over, the rest of the page, scrolls up over it.
   ----------------------------------------------------------------------------------------- */
.hero{
  position:relative;isolation:isolate;overflow:hidden;
  display:flex;flex-direction:column;min-height:100vh;min-height:100svh;
  padding-top:var(--hdr);
}
.hero--pinned{position:sticky;top:0;z-index:0}
.slide-over{position:relative;z-index:1;background:var(--paper)}

/* the video hero (GCE's): a dark base, a still first (the reel's first frame, or on the home page the engraved
   night skyline), the reel faded in by main.js once it plays, and a vertical tint of the darkest brand color.
   Reduced motion, Data Saver, slow connections and no JS keep the still. Over video the accent word is
   Limestone, not a color (no colored accent survives bright footage). */
.hero--video{--em:var(--limestone);--fg-soft:color-mix(in srgb,var(--limestone) 92%,transparent)}   /* the lede holds 4.5:1 over the brightest frames */
/* a soft Iron Gall shadow under the words for bright frames; on the title it is a filter, so the line masks
   (overflow: hidden) can't clip it */
.hero--video .hero__title{filter:drop-shadow(0 2px 14px color-mix(in srgb,var(--iron-gall) 50%,transparent))}
.hero--video .hero__lede{text-shadow:0 2px 28px color-mix(in srgb,var(--iron-gall) 50%,transparent)}
.hero-bg{position:absolute;inset:0;z-index:-1;overflow:hidden;background-color:var(--iron-gall);pointer-events:none;user-select:none;transition:background-color 1.2s var(--ease)}
.hero-bg>img,.hero-bg video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.hero-bg__poster{opacity:.7;filter:saturate(.6);transition:opacity 1.2s var(--ease)}
.hero-bg video{opacity:0;filter:saturate(.6);transition:opacity 1.2s var(--ease)}
.hero-bg.is-playing video{opacity:.74}
.hero-bg.is-playing .hero-bg__poster{opacity:0}
.hero-bg::after{
  content:'';position:absolute;inset:0;z-index:2;
  background:linear-gradient(180deg,color-mix(in srgb,var(--hero-tint) 48%,transparent) 0%,color-mix(in srgb,var(--hero-tint) 22%,transparent) 42%,color-mix(in srgb,var(--hero-tint) 72%,transparent) 100%);
}
/* the home still: the engraved skyline at night on Night, its window lights twinkling (the SVG's own animation) */
.hero-bg:has(.hero-night){background-color:var(--night)}
.hero-night{position:absolute;inset:0;opacity:.9;transition:opacity 1.2s var(--ease)}
.hero-night img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:64% 100%}
.hero-bg:has(.hero-night)::after{background:linear-gradient(180deg,color-mix(in srgb,var(--night) 70%,transparent) 0%,transparent 34%,transparent 70%,color-mix(in srgb,var(--night) 55%,transparent) 100%)}
.hero-bg.is-playing{background-color:var(--iron-gall)}
.hero-bg.is-playing .hero-night{opacity:0;visibility:hidden;transition:opacity 1.2s var(--ease),visibility 0s linear 1.2s}
/* nothing paints under the sheet once it covers the hero */
.hero.is-covered .hero-night{visibility:hidden}
.hero-bg.is-playing::after{background:linear-gradient(180deg,color-mix(in srgb,var(--hero-tint) 48%,transparent) 0%,color-mix(in srgb,var(--hero-tint) 22%,transparent) 42%,color-mix(in srgb,var(--hero-tint) 72%,transparent) 100%)}
/* a clear reel (.hero--clear: Home and Locations, the owner's call, Oct 3): the footage in its own colors on
   near-black, no tint and no desaturation; only neutral shade where the bar and the words sit (deepest under
   the words), sized so over every half second of each reel the titles keep 3:1 or more (large text) and the
   ledes 4.5:1 or more against the brightest 1% of the background behind their letters. The home still (the
   night skyline) keeps its own look until the reel plays. */
.hero--clear .hero-bg__poster,.hero--clear .hero-bg video{filter:none}
.hero--clear .hero-bg__poster,.hero--clear .hero-bg.is-playing video{opacity:1}
.hero--clear .hero-bg:not(:has(.hero-night)),.hero--clear .hero-bg.is-playing{background-color:var(--cabinet)}
.hero--clear .hero-bg:not(:has(.hero-night))::after,.hero--clear .hero-bg.is-playing::after{background:linear-gradient(180deg,color-mix(in srgb,var(--cabinet) 40%,transparent) 0%,transparent 24%,transparent 50%,color-mix(in srgb,var(--cabinet) 60%,transparent) 100%)}
.hero--clear .hero__title{filter:drop-shadow(0 2px 14px color-mix(in srgb,var(--cabinet) 55%,transparent))}
.hero--clear .hero__lede{text-shadow:0 2px 28px color-mix(in srgb,var(--cabinet) 55%,transparent)}

/* pause / play for the reel (it moves for more than five seconds: WCAG 2.2.2); main.js adds it with the video.
   The picture is kept clean (the owner's call): the button shows only to someone who reaches it with the
   keyboard, and stays in the accessibility tree with its name for screen readers */
.hero-video-btn{
  position:absolute;right:var(--gutter);bottom:clamp(1rem,3vh,2rem);z-index:3;
  display:grid;place-items:center;width:42px;height:42px;padding:0;border:1px solid color-mix(in srgb,var(--limestone) 45%,transparent);border-radius:50%;
  background:color-mix(in srgb,var(--night) 30%,transparent);color:var(--limestone);cursor:pointer;
  transition:background-color .3s var(--ease),border-color .3s var(--ease),opacity .6s var(--ease);
}
.hero-video-btn[hidden]{display:none}
.hero-video-btn:not(:focus-visible){opacity:0;pointer-events:none}
.hero-video-btn .icon{width:1.05rem;height:1.05rem}
.hero-video-btn:hover{background:color-mix(in srgb,var(--night) 70%,transparent);border-color:var(--limestone)}
.hero-video-btn:focus-visible{outline:2px solid var(--saddle);outline-offset:3px}
.hero__inner{position:relative;width:100%;margin-block:auto;padding-block:clamp(2rem,6vh,4.5rem)}
.hero__title{max-width:18ch}
.hero__lede{margin-top:clamp(1.2rem,2.4vw,2rem)}

/* statement at the foot, left (every video hero) */
.hero--foot{justify-content:flex-end}
.hero--foot .hero__inner{margin-block:auto 0;padding-bottom:clamp(2.6rem,8vh,5.5rem)}
/* a soft pool of the tint under the statement at the foot, so the words hold over bright frames */
.hero--foot .hero-bg::before{content:'';position:absolute;inset:0;z-index:3;background:linear-gradient(20deg,color-mix(in srgb,var(--hero-tint) 52%,transparent) 0%,transparent 55%)}
.hero--clear.hero--foot .hero-bg::before{background:linear-gradient(20deg,color-mix(in srgb,var(--cabinet) 84%,transparent) 0%,color-mix(in srgb,var(--cabinet) 60%,transparent) 36%,transparent 68%)}   /* reaches a little past the first line of a two-line statement at the display leading */

/* while the page slides over a pinned hero, its words recede a little (browsers with scroll timelines only) */
@supports (animation-timeline:scroll()){
  @media (prefers-reduced-motion:no-preference){
    .hero--pinned .hero__inner{animation:hero-recede linear both;animation-timeline:scroll(root);animation-range:0 100vh}
  }
}
@keyframes hero-recede{to{opacity:.25;transform:translateY(-7vh)}}

/* a plain page top (Contact) */
.page-hero{position:relative;padding-top:calc(var(--hdr) + clamp(3.2rem,9vh,7rem));padding-bottom:clamp(2.4rem,4.6vw,4.2rem)}
.page-hero .lede{margin-top:clamp(1.2rem,2.4vw,2rem)}


/* -----------------------------------------------------------------------------------------
   11  Components
   ----------------------------------------------------------------------------------------- */

/* 11.1 Place cards — the home grid of location types (spot illustration and name) */
.place-grid{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:clamp(1.8rem,2.6vw,2.6rem) clamp(.9rem,1.4vw,1.5rem)}
.place-card{display:grid;gap:.85rem;align-content:start}
.place-card__art{display:block;aspect-ratio:5/4;overflow:hidden;background:var(--surface);border:1px solid var(--rule)}
.place-card__art img{width:100%;height:100%;object-fit:cover;opacity:.88;transition:transform 1.1s var(--ease-out)}
.place-card:hover .place-card__art img{transform:scale(1.045)}
.place-card__name{font-family:var(--f-display);font-size:clamp(1.15rem,1.3vw,1.35rem);line-height:1.22}
@media (max-width:1100px){
  .place-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .place-grid>:last-child:nth-child(3n+1){grid-column:2}
}
@media (max-width:640px){
  .place-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .place-grid>:last-child:nth-child(3n+1){grid-column:auto}
}

/* 11.2 Index — a short list of names set large, each one a link; beside the list a stage shows the picture (and a
   line or two) that belongs to the name in turn. main.js §16 arms it and marks the item (.is-active): with a
   pointer, the name under it; otherwise the name crossing the middle of the screen, so the pictures change as the
   page scrolls. A new picture comes up over the last one from the ground line. The stage holds its place on
   screen while the list passes (sticky inside a box as tall as the list; every item's box lies over the others,
   and all stages are made as tall as the tallest: --stage-h, --stage-top come from the script). Below 900px the
   stage sits over the list and stays at the top of the screen while the names pass under it; there the turn goes
   to the first whole name under the stage. A name not in turn is set at half its ink (3.2:1 on Limestone; the
   names are large), at 62% where they are smaller. Without JS, with reduced motion and in
   print it is a plain list, two columns wide: every name with its own picture and lines under it. */
.index{list-style:none;margin:0;padding:0}
.index__row{display:grid;grid-template-columns:2.6rem minmax(0,1fr) auto;align-items:baseline;column-gap:clamp(.6rem,1.4vw,1.4rem);padding-block:clamp(.8rem,1.3vw,1.25rem);border-top:1px solid var(--rule);color:var(--fg);text-decoration:none}
.index__row:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.index__n{font-family:var(--f-display);font-style:italic;font-size:1.05rem;color:var(--em-small);font-variant-numeric:lining-nums}
.index__name{font-family:var(--f-display);font-weight:var(--w-display);font-size:clamp(1.5rem,2.9vw,2.9rem);line-height:1.2;letter-spacing:-.012em;text-wrap:balance}
.index__go{align-self:center;display:grid;place-items:center;width:2.4rem;height:2.4rem;border:1px solid var(--rule-strong);border-radius:50%;transition:background-color .3s var(--ease),border-color .3s var(--ease),color .3s var(--ease)}
.index__go .icon{width:.95rem;height:.95rem}
@media (hover:hover){.index__row:hover .index__go{background:var(--brand);border-color:var(--brand);color:var(--paper)}}
.index__stage{display:grid;grid-template-columns:minmax(0,12rem) minmax(0,1fr);gap:.5rem 1.4rem;padding:0 0 1.5rem calc(2.6rem + clamp(.6rem,1.4vw,1.4rem))}
.index__stage img{grid-row:1/3;align-self:center;width:100%;height:auto;opacity:.9}
.index__desc{align-self:end;font-family:var(--f-display);font-size:clamp(1.05rem,1.3vw,1.25rem);line-height:1.45;text-wrap:pretty}
.index__where{align-self:start;font-size:.9375rem;line-height:1.5;color:var(--fg-soft)}
.index__where>span{display:block;margin-bottom:.25rem;font-family:var(--f-ui);font-weight:var(--w-label);font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;color:var(--em-small)}
@media (min-width:900px){.index:not(.is-armed){display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--col-gap)}}
/* armed: the names, each in its turn */
.js .index__row.reveal{transition-delay:calc(var(--i,0) * .045s)}
.js .index.is-armed{position:relative}
.js .index.is-armed .index__name{transition:color .3s var(--ease),transform .5s var(--ease-out)}
.js .index.is-armed .index__item:not(.is-active) .index__name{color:color-mix(in srgb,var(--fg) 50%,transparent)}
.js .index.is-armed .index__item.is-active .index__name{color:var(--em);transform:translateX(.22em)}
.js .index.is-armed .index__item.is-active .index__n{color:var(--em)}
.js .index.is-armed .index__item.is-active .index__go{background:var(--brand);border-color:var(--brand);color:var(--paper)}
/* armed: the stage */
.js .index.is-armed .index__media{position:absolute;z-index:1;visibility:hidden;pointer-events:none;transition:visibility 0s .6s}
.js .index.is-armed .index__item.is-active .index__media{z-index:2;visibility:visible;transition:visibility 0s}
.js .index.is-armed .index__stage{position:sticky;display:block;min-height:var(--stage-h,0px);padding:0;background:var(--bg);pointer-events:auto;clip-path:inset(100% 0 0 0);transition:clip-path 0s .6s}
.js .index.is-armed .index__item.is-active .index__stage{clip-path:inset(0);transition:clip-path .6s cubic-bezier(.7,0,.2,1)}
.js .index.is-armed .index__stage img{display:block;opacity:.92}
.js .index.is-armed .index__desc{margin-top:clamp(.8rem,1.4vw,1.3rem)}
.js .index.is-armed .index__where{margin-top:.75rem}
@media (min-width:900px){
  .js .index.is-armed .index__row{margin-right:calc(42% + clamp(1.6rem,3.5vw,4rem))}
  .js .index.is-armed .index__item:last-child .index__row{border-bottom:1px solid var(--rule)}
  .js .index.is-armed .index__media{top:0;bottom:0;right:0;width:42%}
  .js .index.is-armed .index__stage{top:var(--stage-top,6rem)}
}
@media (max-width:899.98px){
  .js .index.is-armed{padding-top:var(--stage-h,0px)}
  .js .index.is-armed .index__media{inset:0 0 var(--row-h,3.7rem) 0}   /* the stage lets go one row early, so the last name stands whole under its picture */
  .js .index.is-armed .index__item:not(.is-active) .index__name{color:color-mix(in srgb,var(--fg) 62%,transparent)}   /* smaller names here: a name not in turn keeps 4.5:1 */
  .js .index.is-armed .index__stage{top:0;padding:.75rem 0 1rem;border-bottom:1px solid var(--rule-strong);transition:clip-path 0s .6s,top .4s var(--ease)}
  .js .index.is-armed .index__item.is-active .index__stage{transition:clip-path .6s cubic-bezier(.7,0,.2,1),top .4s var(--ease)}
  /* when the header slides back in (the page scrolled up), the stage steps down from under it */
  .site-header:not(.is-hidden)~main .index.is-armed .index__stage{top:calc(var(--hdr) + .3rem)}
  .js .index.is-armed .index__stage img{width:min(100%,42.5vh);margin-inline:auto}   /* never taller than about a third of the screen (the drawings are 5:4) */
  .js .index.is-armed .index__where{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
  .index__row{grid-template-columns:2rem minmax(0,1fr) auto}
  .index__go{width:2rem;height:2rem}
  .index__stage{grid-template-columns:minmax(0,34%) minmax(0,1fr);padding-left:0}
}
@supports (height:100svh){@media (max-width:899.98px){.js .index.is-armed .index__stage img{width:min(100%,42.5svh)}}}
@media (min-width:600px) and (max-width:899.98px){.index__name{font-size:clamp(1.5rem,4.4vw,2.4rem)}}   /* upright tablets: the names a size up */
/* the name in turn is underlined: a rule in the accent runs out under it */
.js .index.is-armed .index__row{position:relative}
.js .index.is-armed .index__row::after{content:'';position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--em);transform:scaleX(0);transform-origin:0 50%;transition:transform .5s var(--ease-out)}
.js .index.is-armed .index__item.is-active .index__row::after{transform:none}
/* turns coming faster than a picture can come up (a quick scroll, the pointer run down the list): each picture cuts in
   whole instead of wiping; main.js marks the list .is-quick. These stay last among the armed rules: they weigh the
   same as the rules they overrule, so order decides. */
.js .index.is-armed.is-quick .index__item .index__media{transition:none}
.js .index.is-armed.is-quick .index__item .index__stage{transition:none}
@media (max-width:899.98px){.js .index.is-armed.is-quick .index__item .index__stage{transition:top .4s var(--ease)}}

/* 11.3 Numbered list — italic accent numerals, title, a line; two columns on wide screens */
.numbered{list-style:none;margin:0;padding:0;display:grid;column-gap:var(--col-gap);border-top:1px solid var(--rule-strong)}
@media (min-width:900px){.numbered{grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:repeat(var(--rows,3),auto);grid-auto-flow:column}}
.numbered__item{position:relative;display:grid;align-content:start;grid-template-columns:clamp(2.4rem,3.2vw,3.2rem) minmax(0,1fr);align-items:baseline;padding-block:clamp(1.15rem,1.7vw,1.6rem) clamp(1.25rem,1.9vw,1.8rem)}
.numbered__item::after{content:'';position:absolute;left:0;right:0;bottom:0;border-bottom:1px solid var(--rule);transform-origin:0 50%}
.numbered__n{font-family:var(--f-display);font-style:italic;font-size:1.25rem;line-height:1;color:var(--em-small);font-variant-numeric:lining-nums}
.numbered__t{font-family:var(--f-display);font-size:clamp(1.35rem,1.75vw,1.75rem);line-height:1.2;text-wrap:balance}
.numbered__d{grid-column:2;margin-top:.45em;max-width:34em;color:var(--fg-soft);text-wrap:pretty}

/* 11.4 Titled columns — a head over a strong rule, items ruled in hairline (rows level across columns) */
.columns{--cols:3;display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));column-gap:var(--col-gap);row-gap:clamp(2.8rem,6vw,4rem)}
.columns--2{--cols:2}
.column__head{position:relative;align-self:end;padding-bottom:clamp(.9rem,1.35vw,1.3rem);font-family:var(--f-display);font-size:clamp(1.6rem,2.3vw,2.3rem);line-height:1.1;letter-spacing:-.008em;text-wrap:balance}
.column__head::after{content:'';position:absolute;left:0;right:0;bottom:0;border-bottom:1px solid var(--rule-strong);transform-origin:0 50%}
.column__list{list-style:none;margin:0;padding:0}
.column__item{position:relative;padding-block:clamp(1rem,1.5vw,1.45rem) clamp(1.1rem,1.6vw,1.6rem)}
.column__item::after{content:'';position:absolute;left:0;right:0;bottom:0;border-bottom:1px solid var(--rule);transform-origin:0 50%}
.column__t{font-family:var(--f-display);font-size:clamp(1.25rem,1.55vw,1.55rem);line-height:1.2;text-wrap:balance}
.column__d{margin-top:.42em;max-width:30em;color:var(--fg-soft);text-wrap:pretty}
.column__note{margin-top:1.2rem;font-family:var(--f-display);font-style:italic;font-size:clamp(1.2rem,1.5vw,1.45rem);color:var(--em-small)}
@media (min-width:900px){
  .column--wide{grid-column:span 2}
  .column--wide .column__list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:repeat(var(--rows,3),auto);grid-auto-flow:column;column-gap:var(--col-gap)}
}
@supports (grid-template-rows:subgrid){
  @media (min-width:900px){
    .columns--level{grid-template-rows:auto repeat(var(--rows,3),auto);row-gap:0}
    .columns--level>.column{grid-row:1/-1;display:grid;grid-template-rows:subgrid}
    .columns--level .column__list{grid-row:2/-1;display:grid;grid-template-rows:subgrid}
  }
}
@media (max-width:899.98px){.columns{--cols:1}}
/* ticked columns (.columns--ticked): every line carries a mark in a narrow column of its own, a tick or (in a
   column that says no, .column__tick--no) a cross; as the line arrives the mark draws itself, a cross one stroke
   after the other. Without JS, with reduced motion and in print the marks are simply there. */
.columns--ticked .column__item{display:grid;grid-template-columns:1.35rem minmax(0,1fr);column-gap:.8rem;align-items:start;align-content:start}
.columns--ticked .column__tick{grid-row:1/3;width:1.35rem;height:1.35rem;margin-top:.22em;color:var(--em-small);stroke-width:1.7}
.columns--ticked :is(.column__t,.column__d){grid-column:2}
.columns--ticked .column__d{margin-top:.3em}
.js .columns--ticked .column__tick path{stroke-dasharray:1;transition:stroke-dashoffset .8s var(--ease-io) .28s}
.js .columns--ticked .column__tick--no path{transition-duration:.45s}
.js .columns--ticked .column__tick--no path+path{transition-delay:.6s}
.js .columns--ticked .column__item.reveal:not(.is-in) .column__tick path{stroke-dashoffset:1;transition:none}

/* 11.5 Value plates — three engraved plates on a dark band: numeral, tree, name, one line */
.plates{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(1rem,2.2vw,2.4rem)}
.plate{position:relative;display:grid;gap:clamp(1rem,1.6vw,1.4rem);align-content:start}
.plate__art{position:relative;aspect-ratio:1/1;overflow:hidden;container-type:inline-size;border:1px solid var(--rule);background:radial-gradient(ellipse 70% 55% at 50% 60%,color-mix(in srgb,var(--paper) 5%,transparent),transparent 70%)}
.plate__idx{position:absolute;left:clamp(1rem,1.6vw,1.5rem);top:clamp(.8rem,1.4vw,1.3rem);z-index:1;font-family:var(--f-display);font-size:clamp(1.5rem,2.1vw,2.1rem);line-height:1;color:var(--em)}
.plate__name{font-family:var(--f-display);font-size:clamp(1.6rem,2.3vw,2.2rem);line-height:1.1;letter-spacing:-.008em;text-align:center}
.plate .piece__img{opacity:.9}
.plate__d{max-width:28em;margin-inline:auto;text-align:center;color:var(--fg-soft);text-wrap:pretty}
@media (max-width:900px){              /* tablets and phones: each picture beside its words */
  .plates{grid-template-columns:1fr;gap:1.2rem}
  .plate{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);align-items:center;column-gap:1.3rem}
  .plate__art{grid-row:1/3}
  .plate__name,.plate__d{text-align:left;margin:0}
  .plate__name{align-self:end}
  .plate__d{align-self:start}
}

/* 11.6 Accordion — native <details>, so it works without JS; main.js animates the height */
.faq{list-style:none;margin:0;padding:0;border-top:1px solid var(--rule-strong)}
.faq__item{border-bottom:1px solid var(--rule)}
.faq__q{
  list-style:none;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:1.5rem;
  padding-block:clamp(1.1rem,1.6vw,1.45rem);cursor:pointer;
  font-family:var(--f-display);font-size:clamp(1.2rem,1.65vw,1.55rem);line-height:1.25;letter-spacing:-.01em;
  transition:color .3s var(--ease);
}
.faq__q::-webkit-details-marker{display:none}
.faq__q:hover{color:var(--em-small)}
.faq__q:focus-visible{outline-offset:-2px}
.faq__icon{position:relative;width:1.05rem;height:1.05rem;flex:none}
.faq__icon::before,.faq__icon::after{content:'';position:absolute;left:0;right:0;top:50%;height:1.5px;margin-top:-.75px;background:currentColor;transition:transform .45s var(--ease-out)}
.faq__icon::after{transform:rotate(90deg)}
.faq__item[open] .faq__icon::after{transform:rotate(0deg)}
.faq__a{overflow:hidden}
.faq__body{padding:0 2.6rem clamp(1.3rem,2vw,1.8rem) 0;max-width:64ch;color:var(--fg-soft)}
.faq__body p+p{margin-top:.8em}

/* 11.7 Filter chips over a list of [data-cat] items (no page shows chips since Oct 6, 2026; the Machines rail, §11.22, still carries the types) */
.explorer__bar{display:flex;flex-wrap:wrap;align-items:center;gap:1rem 1.6rem;margin-bottom:clamp(1.4rem,2.4vw,2.2rem)}
.chips{display:flex;flex-wrap:wrap;gap:.5rem}
.chips[hidden]{display:none}
.chip{
  -webkit-appearance:none;appearance:none;min-height:44px;padding:.55rem 1.05rem;
  border:1px solid var(--rule-strong);border-radius:0;background:transparent;color:var(--fg);
  font-family:var(--f-ui);font-weight:var(--w-ui);font-size:.875rem;line-height:1.2;cursor:pointer;
  transition:background-color .3s var(--ease),border-color .3s var(--ease),color .3s var(--ease);
}
.chip:hover{border-color:var(--fg)}
.chip[aria-pressed="true"]{background:var(--oxblood);border-color:var(--oxblood);color:var(--limestone)}
.explorer__count{margin-left:auto;font-family:var(--f-ui);font-size:.8125rem;color:var(--fg-soft)}
[data-cat].is-arriving{animation:item-in .55s var(--ease-out) both}   /* an item a chip brings back */
@keyframes item-in{from{opacity:0;transform:translateY(8px)}}

/* a lead figure on a dark plate with a fine inner frame (the first item of a column: "75+") */
.fig-plate{position:relative;isolation:isolate;display:grid;justify-items:center;gap:.6rem;padding:clamp(2.4rem,4.6vw,4.6rem) clamp(1.2rem,3vw,3rem) clamp(2.6rem,5vw,5rem);text-align:center;background:var(--night);color:var(--limestone)}
.fig-plate::before{content:'';position:absolute;inset:clamp(8px,.8vw,13px);z-index:-1;border:1px solid var(--line-dark);pointer-events:none}
.fig-plate__n{font-family:var(--f-display);font-size:clamp(4.4rem,11vw,10rem);line-height:.9;letter-spacing:-.03em;font-variant-numeric:lining-nums}
.fig-plate__of{font-family:var(--f-display);font-style:italic;font-size:clamp(1.3rem,2.2vw,2.1rem);line-height:1.22;color:var(--saddle);text-wrap:balance}
.fig-plate__note{margin-top:.4rem;font-size:1rem;color:var(--on-dark-soft)}
@media (prefers-reduced-motion:no-preference){
  .js .fig-plate.reveal{opacity:1;transform:none;clip-path:inset(100% 0 0 0);transition:clip-path 1.15s cubic-bezier(.7,0,.2,1)}
  .js .fig-plate.reveal.is-in{clip-path:inset(0 0 0 0)}
  .js .fig-plate.reveal>*{opacity:0;transform:translateY(14px);transition:opacity .9s var(--ease) .55s,transform 1.1s var(--ease-out) .55s}
  .js .fig-plate.reveal.is-in>*{opacity:1;transform:none}
}

/* 11.8 Feature list — numbered features beside a figure */
.features{list-style:none;margin:0;padding:0;display:grid;gap:0;border-top:1px solid var(--rule-strong)}
.feature{position:relative;display:grid;grid-template-columns:clamp(2.8rem,4vw,4rem) minmax(0,1fr);padding-block:clamp(1.3rem,2vw,1.9rem)}
.feature::after{content:'';position:absolute;left:0;right:0;bottom:0;border-bottom:1px solid var(--rule);transform-origin:0 50%}
.feature__n{font-family:var(--f-display);font-style:italic;font-size:1.125rem;line-height:1.75;color:var(--em-small);font-variant-numeric:tabular-nums lining-nums}
.feature__t{font-family:var(--f-display);font-size:clamp(1.45rem,2vw,1.95rem);line-height:1.15;letter-spacing:-.008em}
.feature__d{grid-column:2;margin-top:.5em;max-width:36em;color:var(--fg-soft);text-wrap:pretty}

/* 11.9 Forms — labels above fields, square fields with a hairline, the band's focus color */
.form{display:grid;gap:clamp(1rem,1.5vw,1.35rem);align-content:start}
.form__row{display:grid;gap:inherit}
@media (min-width:640px){.form__row{grid-template-columns:repeat(2,minmax(0,1fr))}}
.field{display:grid;gap:.45rem}
.field__label{font-family:var(--f-ui);font-weight:var(--w-ui);font-size:.875rem;line-height:1.35;color:var(--fg)}
.field__opt{font-weight:400;color:var(--fg-soft)}
.field input,.field select,.field textarea{
  width:100%;min-width:0;padding:.9rem 1.1rem;border:1px solid var(--field-line);border-radius:0;
  background:var(--field-bg);color:var(--fg);font-family:var(--f-ui);font-size:1rem;line-height:1.4;
  transition:border-color .4s var(--ease),box-shadow .4s var(--ease);
}
.field textarea{min-height:8.5rem;resize:vertical}
.field select{
  -webkit-appearance:none;appearance:none;padding-right:2.9rem;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 6 8 10.5 12.5 6' stroke='%23857A71' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 1.1rem center;background-size:14px 14px;
}
.field select:invalid,.field select.is-empty{color:var(--fg-soft)}
.field select option{color:var(--ink);background:var(--card)}
.field :is(input,select,textarea):focus{outline:none;border-color:var(--focus);box-shadow:inset 0 0 0 1px var(--focus)}
.form__foot{display:flex;flex-wrap:wrap;align-items:center;gap:1rem 1.6rem;margin-top:.4rem}
.form__note{max-width:34em;font-family:var(--f-ui);font-size:.8125rem;line-height:1.5;color:var(--fg-soft)}
.form__status{font-size:1.02rem;line-height:1.5;color:var(--fg-soft)}
.form__status:empty{display:none}
.form__status:focus{outline:none}
.form__status a:not(.btn){color:var(--em-small);text-decoration:underline;text-underline-offset:.18em}
.form__status .form__fallback{margin-top:1rem}
.form__status>span{display:block}
.form.is-sending [type="submit"]{opacity:.55;pointer-events:none}
.form.is-sent>:not(.form__status){display:none}
.form.is-sent .form__status{padding-block:clamp(.8rem,2vw,1.4rem);font-family:var(--f-display);font-size:clamp(1.4rem,2vw,1.9rem);line-height:1.25;color:var(--fg);text-wrap:balance}

/* 11.10 Map figure — the Census-drawn plate (an <img>), the place names in HTML, the pin in an inline SVG.
   On arrival the streets ink outward from downtown, the pin drops in and pulses, the names follow. */
@property --map-r{syntax:'<percentage>';inherits:false;initial-value:150%}
.map{position:relative;margin:0;border:1px solid var(--rule);background:var(--paper-2);overflow:hidden;container-type:inline-size}
.map__plate{display:block;width:100%;height:auto}
.map__over{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.map__places{position:absolute;inset:0;pointer-events:none}
.map__places span{
  position:absolute;left:calc(var(--lx) * 1%);top:calc(var(--ly) * 1%);translate:-50% -100%;white-space:nowrap;
  font-family:var(--f-display);font-style:italic;font-size:clamp(.88rem,1.9cqi,1.05rem);line-height:1;color:var(--ink-soft);
  text-shadow:0 0 1px var(--paper-2),0 0 2px var(--paper-2),0 0 3px var(--paper-2),1px 1px 0 var(--paper-2),-1px 1px 0 var(--paper-2),1px -1px 0 var(--paper-2),-1px -1px 0 var(--paper-2),2px 0 1px var(--paper-2),-2px 0 1px var(--paper-2),0 2px 1px var(--paper-2),0 -2px 1px var(--paper-2);
}
.map__places .is-main{font-size:clamp(1rem,2.2cqi,1.25rem);color:var(--oxblood)}
/* a small map keeps the names that matter: the minor names drop out */
@container (max-width:560px){
  .map__places .is-minor{display:none}
}
/* the smallest (a 320px phone): a size down, and the one name that would sit on its neighbour goes too */
@container (max-width:340px){
  .map__places span{font-size:.8rem}
  .map__places .is-main{font-size:.9rem}
  .map__places .is-tight{display:none}
}
.map__places .is-water{font-size:clamp(.78rem,1.55cqi,.92rem);letter-spacing:.02em;color:var(--slate)}
.map-legend{display:flex;flex-wrap:wrap;gap:.5rem 1.6rem;margin-top:.9rem;font-family:var(--f-ui);font-size:.8125rem;color:var(--fg-soft)}
.map-legend>span::before{content:'';display:inline-block;margin-right:.55rem;vertical-align:-1px}
.map-legend .is-pin::before{width:9px;height:9px;margin-left:3px;border-radius:50%;background:var(--oxblood);box-shadow:0 0 0 2px var(--paper),0 0 0 3.2px var(--night)}
.map__pin .ring{fill:var(--paper);stroke:var(--night);stroke-width:2}
.map__pin .core{fill:var(--oxblood)}
.map__pin .pulse{fill:none;stroke:var(--oxblood);stroke-width:1.6;transform-box:fill-box;transform-origin:center;opacity:0}
/* the pin pulses twice as the map comes on screen (again each time it comes back, and when you point at the map),
   then rests: nothing here moves for more than five seconds on its own */
.map.is-live .map__pin .pulse,html:not(.js) .map__pin .pulse{animation:map-ring 3s var(--ease) .9s 1}
.map.is-live .map__pin .pulse--2,html:not(.js) .map__pin .pulse--2{animation-delay:1.9s}
.map.is-live .map__pin--2 .pulse,html:not(.js) .map__pin--2 .pulse{animation-delay:1.4s}          /* the second pin (Dallas) a beat behind the first; both are done inside five seconds */
.map.is-live .map__pin--2 .pulse--2,html:not(.js) .map__pin--2 .pulse--2{animation-delay:1.95s}
@media (hover:hover){.map.is-live:hover .map__pin .pulse{animation-name:map-ring-again;animation-delay:0s}.map.is-live:hover .map__pin .pulse--2{animation-delay:1s}}
@keyframes map-ring{0%{transform:scale(1);opacity:.85}100%{transform:scale(5.2);opacity:0}}
@keyframes map-ring-again{0%{transform:scale(1);opacity:.85}100%{transform:scale(5.2);opacity:0}}   /* the same ring under a second name, so pointing at the map starts it afresh */
.js .map .map__plate{
  --map-r:-24%;
  -webkit-mask-image:radial-gradient(circle at var(--pin-x,50%) var(--pin-y,55%),#000 var(--map-r),transparent calc(var(--map-r) + 22%));
          mask-image:radial-gradient(circle at var(--pin-x,50%) var(--pin-y,55%),#000 var(--map-r),transparent calc(var(--map-r) + 22%));
  transition:--map-r 2.6s cubic-bezier(.45,.05,.25,1) .1s;
}
.js .map.is-in .map__plate{--map-r:150%}
.js .map .map__pin{opacity:0;transform:translateY(-14px);transition:opacity .45s var(--ease) .2s,transform .8s var(--ease-out) .2s}
.js .map.is-in .map__pin{opacity:1;transform:none}
.js .map .map__pin--2{transition-delay:1.3s}   /* it drops in as the ink, spreading from the first pin, reaches it */
.js .map .map__places{opacity:0;transition:opacity .9s var(--ease) 1s}
.js .map.is-in .map__places{opacity:1}
/* On a Night band the map is the night plate (dfw-map-night-*.webp): the names in Limestone with a Night halo, the
   home city, the pin's core and its pulse in Saddle; the copy takes less of the row and the map more, and on
   narrow screens the map runs edge to edge. */
.tone-night .map{background:var(--night)}
.tone-night .map__places span{color:color-mix(in srgb,var(--limestone) 82%,transparent);
  text-shadow:0 0 2px var(--night),0 0 4px var(--night),1px 1px 0 var(--night),-1px 1px 0 var(--night),1px -1px 0 var(--night),-1px -1px 0 var(--night),0 2px 2px var(--night),0 -2px 2px var(--night)}
.tone-night .map__places .is-main{color:var(--saddle)}
.tone-night .map__places .is-water{color:color-mix(in srgb,var(--limestone) 55%,transparent)}
.tone-night .map__pin .ring{fill:var(--night);stroke:var(--limestone)}
.tone-night .map__pin .core{fill:var(--saddle)}
.tone-night .map__pin .pulse{stroke:var(--saddle)}
.tone-night .map-legend .is-pin::before{background:var(--saddle);box-shadow:0 0 0 2px var(--night),0 0 0 3.2px var(--limestone)}
/* the names light one after another, outward from the pin, a little behind the ink: each name's delay is its own
   distance from the pin (.map--radiate, with --px/--py on the figure: the pin again, as plain numbers; x is
   stretched by the map's 4:3). Where hypot() is not understood the names keep the plain fade above. */
@supports (transition-delay:calc(hypot(1,1) * 1ms)){
  .js .map--radiate .map__places{opacity:1;transition:none}
  .js .map--radiate .map__places span{opacity:0;transform:translateY(5px);transition:opacity .5s var(--ease),transform .7s var(--ease-out);
    transition-delay:calc(.25s + hypot((var(--lx) - var(--px)) * 1.333,var(--ly) - var(--py)) * 26ms)}
  .js .map--radiate.is-in .map__places span{opacity:1;transform:none}
}
.map-section__grid{display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);gap:clamp(2rem,5vw,6rem);align-items:center}
@media (min-width:901px){
  .tone-night .map-section__grid{grid-template-columns:minmax(0,.68fr) minmax(0,1.32fr);gap:clamp(2rem,4vw,5rem)}
  /* the heading beside the night map ends on a long name that must stay whole (Dallas–Fort Worth., 9.1em): it is sized to its column */
  .tone-night .map-section__copy{container-type:inline-size}
  .tone-night .map-section__copy .d2{font-size:min(clamp(2.125rem,3.8vw,3.5rem),10.7cqi)}
}
@media (max-width:900px){.tone-night.map-section .map{margin-inline:calc(var(--gutter) * -1);border-inline:0}}
.map-section__copy{display:grid;gap:clamp(1.4rem,2.6vw,2.4rem);align-content:center}
.map-section__note{display:grid;gap:.7rem;justify-items:start;padding-top:clamp(1.2rem,2vw,1.8rem);border-top:1px solid var(--rule)}
.map-section__place{font-family:var(--f-display);font-size:clamp(1.3rem,1.8vw,1.75rem);line-height:1.3}
.map-section__area{margin-top:-.35rem;font-style:italic;color:var(--fg-soft)}
.coords{font-size:.94rem;color:var(--fg-soft);font-variant-numeric:tabular-nums}
@media (max-width:900px){.map-section__grid{grid-template-columns:1fr}}

/* 11.11 Promise band — four figures, counted up as they arrive */
.promise__grid{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr))}
.promise__item{display:grid;gap:clamp(.8rem,1.3vw,1.2rem);align-content:start;padding:clamp(.4rem,1vw,1rem) clamp(1rem,2.2vw,2.4rem);border-left:1px solid var(--rule)}
.promise__item:first-child{border-left:0;padding-left:0}
.promise__fig{font-family:var(--f-display);font-weight:var(--w-display);font-size:clamp(3.4rem,6vw,6rem);line-height:.95;letter-spacing:-.01em;white-space:nowrap;font-variant-numeric:lining-nums}
:is(.promise__fig,.fig-plate__n) [data-count]{display:inline-block;min-width:var(--digits,1ch);text-align:right;font-variant-numeric:tabular-nums lining-nums}   /* while counting, the room for the last digit opens on the left, not between figure and unit */
.promise__unit{margin-left:.14em;font-style:italic;font-size:.42em;letter-spacing:-.01em;color:var(--em)}
.promise__label{max-width:22ch;color:var(--fg-soft);text-wrap:pretty}
@media (max-width:900px){
  .promise__grid{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:2.4rem}
  .promise__item:nth-child(odd){border-left:0;padding-left:0}
}

/* 11.12 CTA band — a centred serif line, an italic second line, the email; the split variant puts a form beside it */
.cta-band{position:relative;overflow:hidden;isolation:isolate}
.cta-band__inner{position:relative;display:grid;gap:clamp(1.2rem,2.2vw,1.8rem);justify-items:center;text-align:center;max-width:960px;margin-inline:auto}
.cta-band__actions{display:flex;flex-wrap:wrap;gap:.8rem 1.4rem;justify-content:center;align-items:center;margin-top:.4rem}
.cta-band--split .cta-band__inner{max-width:var(--wide);grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:0;align-items:start;justify-items:stretch;text-align:left}
.cta-band__copy{display:grid;gap:clamp(1.2rem,2.2vw,1.8rem);justify-items:start;padding-right:clamp(2rem,4.5vw,5rem)}
.cta-band__side{display:grid;gap:1.4rem;padding-left:clamp(2rem,4.5vw,5rem);border-left:1px solid var(--rule)}
.cta-band__side .h4{color:var(--fg)}
@media (max-width:1100px){
  .cta-band--split .cta-band__inner{grid-template-columns:1fr;gap:clamp(2rem,6vw,3rem)}
  .cta-band__copy{padding-right:0}
  .cta-band__side{padding:clamp(2rem,6vw,3rem) 0 0;border-left:0;border-top:1px solid var(--rule)}
}
/* the engraved rule under the line (art/spots/misc/rule.svg, inline so it takes the band's accent; main.js draws it on) */
.cta-rule{width:clamp(170px,18vw,230px);height:auto;color:var(--em);opacity:.9}
.cta-band--split .cta-rule{justify-self:start}

/* 11.13 Letter card — the founder's letter, set in a handwriting face on a sheet of good stock */
.letter-card{
  --stock:color-mix(in srgb,var(--limestone) 52%,#fff);
  position:relative;isolation:isolate;max-width:780px;margin-inline:auto;
  padding:clamp(2.4rem,5.4vw,4.4rem) clamp(1.5rem,7vw,5.4rem) clamp(2.6rem,5.6vw,4.6rem);
  background:linear-gradient(172deg,color-mix(in srgb,var(--stock) 60%,#fff) 0%,var(--stock) 46%,color-mix(in srgb,var(--stock) 92%,var(--ink)) 100%);
  color:var(--ink);
  box-shadow:0 0 0 1px var(--line-soft),0 2px 2px color-mix(in srgb,var(--ink) 4%,transparent),0 22px 40px -22px var(--shade),0 52px 80px -48px var(--shade);
}
.letter-card::before{
  content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;mix-blend-mode:multiply;opacity:.5;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='t'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.95' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .42 0 0 0 0 .36 0 0 0 0 .24 0 0 0 -1.1 .62'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23t)' opacity='.16'/%3E%3C/svg%3E");
}
.letter-card__head{display:grid;justify-items:center;gap:.5rem;text-align:center;margin-bottom:clamp(2.2rem,4.6vw,3.6rem)}
.letter-card__head::after{content:'';display:block;width:64px;height:1px;margin-top:clamp(.9rem,1.8vw,1.3rem);background:var(--line)}
.letter-card__mark{width:auto;height:clamp(40px,3.8vw,48px);margin-bottom:.4rem}
.letter-card__firm{font-family:var(--f-display);font-size:clamp(1.15rem,1rem + .35vw,1.3rem);line-height:1.1;color:var(--ink)}
.letter-card__place{font-family:var(--f-ui);font-weight:var(--w-label);font-size:.6875rem;line-height:1.45;letter-spacing:.16em;text-transform:uppercase;color:var(--slate)}
.letter-card__body{font-family:var(--f-hand);font-size:clamp(1.28rem,1.12rem + .5vw,1.48rem);line-height:1.7;letter-spacing:0;color:var(--iron-gall)}
.letter-card__body p{margin:0 0 .62em;text-wrap:pretty}
.letter-card__body strong{font-weight:inherit;background:linear-gradient(currentColor,currentColor) 0 100%/100% 1px no-repeat;padding-bottom:.08em}
.letter-card__close{margin-top:1.2em}
.letter-card__sign{margin-top:.4rem}
.letter-card__sig{display:block;width:clamp(190px,20vw,250px);height:auto;margin:.3rem 0 .9rem -.2rem}
.letter-card__name{font-family:var(--f-display);font-size:1.0625rem;line-height:1.4}
.letter-card__role{font-family:var(--f-ui);font-weight:var(--w-label);font-size:.6875rem;line-height:1.6;letter-spacing:.16em;text-transform:uppercase;color:var(--slate)}
/* the signature inks in left to right once it is on screen */
.js .letter-card__sig.reveal,.js .signature.reveal img{
  opacity:1;transform:none;
  -webkit-mask-image:linear-gradient(90deg,#000 40%,transparent 60%);mask-image:linear-gradient(90deg,#000 40%,transparent 60%);
  -webkit-mask-size:250% 100%;mask-size:250% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:100% 0;mask-position:100% 0;
  transition:-webkit-mask-position 1.9s cubic-bezier(.5,.1,.3,1) .35s,mask-position 1.9s cubic-bezier(.5,.1,.3,1) .35s;
}
.js .letter-card__sig.reveal.is-in,.js .signature.reveal.is-in img{-webkit-mask-position:0 0;mask-position:0 0}

/* a signature image with its small caption (the mission band, on Our Approach) */
.signature{display:grid;justify-items:center;gap:.5rem;margin:0}
.signature img{width:clamp(170px,15vw,230px);height:auto}
.signature figcaption{font-family:var(--f-ui);font-weight:var(--w-label);font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;color:var(--fg)}   /* full ink: it sits over the scene's art */

/* 11.14 Split band — a statement on one side, a figure on the other */
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(2rem,5vw,6rem);align-items:center}
.split__copy{display:grid;gap:clamp(1.2rem,2.2vw,1.9rem);justify-items:start}
.split__media{display:grid;justify-items:center}
@media (max-width:900px){.split{grid-template-columns:1fr}}

/* 11.15 Steps (cards: icon, number, title, line) and the four words (tap, grab, close, go) */
.steps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(.9rem,1.6vw,1.5rem);counter-reset:step}
.step{display:grid;gap:.75rem;align-content:start;padding:clamp(1.5rem,2.4vw,2.3rem);background:var(--surface);border:1px solid var(--rule);transition:background-color .55s var(--ease),color .55s var(--ease),border-color .55s var(--ease)}
.step__icon{width:2.4rem;height:2.4rem;color:var(--em-small);stroke-width:1.3;transition:color .55s var(--ease)}
.step__n{margin-top:.6rem;font-family:var(--f-display);font-style:italic;font-size:1.125rem;color:var(--em-small);font-variant-numeric:tabular-nums lining-nums}
.step__t{font-family:var(--f-display);font-size:clamp(1.4rem,1.8vw,1.75rem);line-height:1.2;text-wrap:balance}
.step__d{font-size:1rem;line-height:1.6;color:var(--fg-soft);transition:color .55s var(--ease)}
@media (hover:hover){
  .steps:not(.steps--open) .step:hover{background:var(--night);border-color:var(--night);color:var(--limestone)}
  .steps:not(.steps--open) .step:hover :is(.step__icon,.step__n){color:var(--saddle)}
  .steps:not(.steps--open) .step:hover .step__d{color:var(--on-dark-soft)}
}
@media (max-width:1100px){.steps{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.steps:not(.steps--open){grid-template-columns:1fr}}
/* open steps (.steps--open): no cards. Each step stands on the band under a hairline that runs on from step to step
   as they arrive, and its icon does its one small thing on its turn. The icons are drawn inline with the parts
   Home's four words use (tgg__wave, tgg__lift, tgg__lock + tgg__shackle, tgg__check) and move as they do there.
   A step's turn (--turn) is its place in its row: --i across four, 0 or 1 where they stand two by two (1100px and
   under, phones included). Without JS, with reduced motion and in print the row stands, every icon at rest. */
.steps--open{--step-gap:clamp(1.4rem,3vw,3.6rem);gap:clamp(2rem,4vw,3rem) var(--step-gap)}
.steps--open .step{--turn:var(--i,0);position:relative;gap:.6rem;padding:clamp(1.4rem,2.2vw,2.1rem) 0 0;background:none;border:0;transition:none}
.steps--open .step::before{content:'';position:absolute;left:0;right:calc(var(--step-gap) * -1);top:0;border-top:1px solid var(--rule-strong);transform-origin:0 50%}
.steps--open .step:last-child::before{right:0}
.steps--open .step__icon{width:3.2rem;height:3.2rem;color:var(--em);stroke-width:1.05;overflow:visible}
.steps--open .step__n{margin-top:.5rem}
@media (max-width:1100px){
  .steps--open .step:nth-child(odd){--turn:0}
  .steps--open .step:nth-child(even){--turn:1}
  .steps--open .step:nth-child(even)::before{right:0}
}
.js .steps--open .step.reveal::before{transform:scaleX(0);transition:transform .5s cubic-bezier(.4,0,.2,1) calc(var(--turn) * .42s)}
.js .steps--open .step.reveal.is-in::before{transform:none}
.js .steps--open .step.reveal .tgg__check{stroke-dasharray:1;stroke-dashoffset:1}
.js .steps--open .step.reveal.is-in .tgg__check{stroke-dashoffset:0;transition:stroke-dashoffset .6s var(--ease-out) calc(var(--turn) * .42s + .4s)}
.js .steps--open .step.reveal.is-in .tgg__wave{animation:tgg-wave .55s var(--ease) calc(var(--turn) * .42s + .45s) 2 both}
.js .steps--open .step.reveal.is-in .tgg__wave+.tgg__wave{animation-delay:calc(var(--turn) * .42s + .59s)}
.js .steps--open .step.reveal.is-in .tgg__lift{animation:tgg-lift .9s var(--ease-out) calc(var(--turn) * .42s + .4s) both}
.js .steps--open .step.reveal .tgg__shackle{stroke-dasharray:1;stroke-dashoffset:.26;transform:translateY(-2.25px)}
.js .steps--open .step.reveal.is-in .tgg__shackle{stroke-dashoffset:0;transform:none;transition:transform .3s cubic-bezier(.55,0,.9,.45) calc(var(--turn) * .42s + .65s),stroke-dashoffset .3s cubic-bezier(.55,0,.9,.45) calc(var(--turn) * .42s + .65s)}
.js .steps--open .step.reveal.is-in .tgg__lock{animation:tgg-click .34s var(--ease-out) calc(var(--turn) * .42s + .93s) both}

/* the four words (Home): Tap. Grab. Close. Go., each over its drawn icon, as large as the screen allows, on one
   line (one under another on phones, where the size follows the screen's height too). With JS and motion the
   band is taller than the screen by --hold and its stage sticks while the page scrolls through it; main.js §13
   marks each word as it arrives: it pops up (.is-in, with a little overshoot), the one before it steps back
   (.is-past), and at the end all four stand together (.is-done on the band). Scrolling back takes them away
   again, quickly and without the bounce. Without JS or with reduced motion it is an ordinary band, the four
   words standing. */
.tgg{--hold:125vh;--past:.3;position:relative}
.tgg:is(.tone-paper,.tone-alt){--past:.5}   /* on a light band a word that has stepped back keeps more of its ink (3:1 on Limestone) */
.tgg__stage{display:grid;place-items:center;min-height:clamp(20rem,72vh,46rem);padding:clamp(3rem,8vh,6rem) var(--gutter);overflow:hidden;overflow:clip}
.tgg__words{display:flex;flex-wrap:wrap;justify-content:center;align-items:baseline;gap:.1em .3em;margin:0;font-family:var(--f-display);font-weight:var(--w-display);font-size:clamp(3rem,8.6vw,13rem);line-height:1;letter-spacing:-.022em}
.tgg__w{display:inline-flex;flex-direction:column;align-items:center;gap:.16em;transform-origin:50% 70%}
.tgg__w em{font-style:italic;color:var(--em)}
.tgg__i{width:.5em;height:.5em;color:var(--em);stroke-width:.9;overflow:visible}
.js .tgg.is-armed{height:calc(100vh + var(--hold))}
.js .tgg.is-armed .tgg__stage{position:sticky;top:0;height:100vh;min-height:0}
@supports (height:100svh){
  .tgg{--hold:125svh}
  .js .tgg.is-armed{height:calc(100svh + var(--hold))}
  .js .tgg.is-armed .tgg__stage{height:100svh}
}
.js .tgg.is-armed .tgg__w{opacity:0;transform:translateY(.46em) scale(.62);transition:opacity .22s var(--ease),transform .32s var(--ease)}
.js .tgg.is-armed .tgg__w.is-in{opacity:1;transform:none;transition:opacity .3s var(--ease),transform .74s cubic-bezier(.3,1.55,.5,1)}
.js .tgg.is-armed:not(.is-done) .tgg__w.is-past{opacity:var(--past);transition:opacity .55s var(--ease),transform .74s cubic-bezier(.3,1.55,.5,1)}
.js .tgg.is-armed.is-done .tgg__w{transition:opacity .6s var(--ease),transform .74s cubic-bezier(.3,1.55,.5,1)}
/* each icon follows its word by a beat and does its one small thing: the card's waves blink, the hand lifts
   the can, the padlock is pushed shut, the check draws itself */
.js .tgg.is-armed .tgg__i{opacity:0;transform:translateY(-.12em) scale(.4);transition:opacity .2s var(--ease),transform .25s var(--ease)}
.js .tgg.is-armed .tgg__w.is-in .tgg__i{opacity:1;transform:none;transition:opacity .3s var(--ease) .22s,transform .66s cubic-bezier(.3,1.7,.5,1) .22s}
.js .tgg.is-armed .tgg__check{stroke-dasharray:1;stroke-dashoffset:1}
.js .tgg.is-armed .tgg__w.is-in .tgg__check{stroke-dashoffset:0;transition:stroke-dashoffset .6s var(--ease-out) .42s}
.js .tgg.is-armed .tgg__w.is-in .tgg__wave{animation:tgg-wave .55s var(--ease) .6s 2 both}
.js .tgg.is-armed .tgg__w.is-in .tgg__wave+.tgg__wave{animation-delay:.74s}
.js .tgg.is-armed .tgg__w.is-in .tgg__lift{animation:tgg-lift .9s var(--ease-out) .55s both}
/* the padlock arrives open: its shackle raised, and drawn only as far as the icon set's open padlock goes (.74
   of its length, the free end short of the body). Then the shackle drops, its free leg runs down into the body,
   and the lock gives under the push. It opens again, unseen, once its word has left. */
.js .tgg.is-armed .tgg__shackle{stroke-dasharray:1;stroke-dashoffset:.26;transform:translateY(-2.25px);transition:transform 0s .3s,stroke-dashoffset 0s .3s}
.js .tgg.is-armed .tgg__w.is-in .tgg__shackle{stroke-dashoffset:0;transform:none;transition:transform .3s cubic-bezier(.55,0,.9,.45) .8s,stroke-dashoffset .3s cubic-bezier(.55,0,.9,.45) .8s}
.js .tgg.is-armed .tgg__w.is-in .tgg__lock{animation:tgg-click .34s var(--ease-out) 1.08s both}
@keyframes tgg-wave{0%,100%{opacity:1}50%{opacity:.1}}
@keyframes tgg-lift{40%{transform:translateY(-3px)}}
@keyframes tgg-click{35%{transform:translateY(1.1px)}}
@media (max-width:600px){
  .tgg__stage{padding-block:2.2rem}
  .tgg__words{flex-direction:column;align-items:center;gap:.2em;font-size:min(clamp(3.4rem,20vw,6rem),11.6vh)}
  .tgg__w{gap:.12em}
  .tgg__i{width:.44em;height:.44em;stroke-width:1.1}
}
@supports (height:100svh){@media (max-width:600px){.tgg__words{font-size:min(clamp(3.4rem,20vw,6rem),11.6svh)}}}
@media (prefers-reduced-motion:reduce){
  .js .tgg.is-armed{height:auto}
  .js .tgg.is-armed .tgg__stage{position:static;height:auto;min-height:clamp(20rem,72vh,46rem)}
  .js .tgg.is-armed :is(.tgg__w,.tgg__i,.tgg__shackle){opacity:1!important;transform:none!important}
  .js .tgg.is-armed :is(.tgg__check,.tgg__shackle){stroke-dashoffset:0!important}
}

/* 11.16 Machine figure — the line drawing of the cooler at a set width (a lit panel for a location's logo, and a
   note pointing at it, stood over the drawing in a band on Machines; both went on Oct 9, 2026, when the owner
   stopped offering that) */
.machine{position:relative;margin:0;width:min(100%,var(--machine-w,300px))}
.machine>img{width:100%;height:auto}

/* 11.17 Story — a portrait beside the text */
.story{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:clamp(2rem,5vw,6rem);align-items:center}
.story__portrait{margin:0;display:grid;gap:.9rem}
.story__photo{overflow:hidden;background:var(--surface);aspect-ratio:4/5}
.story__photo img{width:100%;height:100%;object-fit:cover;object-position:50% 22%;filter:grayscale(1) contrast(1.03);transition:filter .8s var(--ease),transform 1.6s var(--ease-out)}
.story__portrait:hover .story__photo img{filter:none}
.story__caption{font-size:.9375rem;font-style:italic;color:var(--fg-soft)}
.story__copy{display:grid;gap:clamp(1.2rem,2.2vw,1.8rem);max-width:40em}
.story__copy .prose{font-size:clamp(1.08rem,1rem + .25vw,1.2rem);color:var(--fg-soft)}
@media (max-width:900px){.story{grid-template-columns:1fr}.story__portrait{max-width:420px}}


/* 11.18 Printed-page backdrop — the slogan set as a finely printed page behind a band: one repeating
   SVG tile of outlined italic (tools/pagetext.mjs), sized in em so it keeps the type size of a page of
   text; the page holds no repeated words. --pt-w / --pt-h (the tile's size in em) are written by the builder. */
.page-band{position:relative;overflow:hidden;isolation:isolate}
.page-band>.container--wide,.page-band>.container{position:relative;z-index:1}
.pagetext{
  --pt-w:17.7880;--pt-h:31.60;
  position:absolute;inset:0;z-index:0;pointer-events:none;
  font-size:clamp(1.3rem,1.7vw,1.85rem);opacity:.06;
  background:url("../img/pagetext.svg?v=1") repeat;background-size:calc(var(--pt-w) * 1em) calc(var(--pt-h) * 1em);
  background-position:-4.5em -.7em;
  -webkit-mask-image:linear-gradient(to bottom,#000 0,#000 56px,rgba(0,0,0,.4) 120px,rgba(0,0,0,.4) 100%);
          mask-image:linear-gradient(to bottom,#000 0,#000 56px,rgba(0,0,0,.4) 120px,rgba(0,0,0,.4) 100%);
}
@media (max-width:860px){.pagetext{font-size:1.12rem}}


/* 11.19 Chain of stops — the hands a request passes through, drawn as stations on a line: a ring on a hairline,
   its name under it; the two ends are solid. Every chain sits on the same seven-stop grid, so a short chain
   visibly ends early. Below 900px each chain runs down the page instead. */
.chains{display:grid;gap:clamp(2.4rem,4.4vw,4rem)}
.chain{display:grid;gap:clamp(1rem,1.5vw,1.4rem)}
.chain__stops{--n:7;list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(var(--n),minmax(0,1fr))}
.chain__stop{position:relative;padding:2rem .9rem 0 0;font-family:var(--f-display);font-size:clamp(1.05rem,1.4vw,1.45rem);line-height:1.2;color:var(--fg-soft);text-wrap:balance}
.chain__stop::before{content:'';position:absolute;left:0;top:.15rem;z-index:1;box-sizing:border-box;width:13px;height:13px;border:1px solid var(--fg);border-radius:50%;background:var(--bg)}
.chain__stop::after{content:'';position:absolute;left:13px;right:0;top:calc(.15rem + 6px);border-top:1px solid var(--rule-strong)}
.chain__stop:last-child::after{display:none}
.chain__stop:is(:first-child,:last-child){color:var(--fg)}
.chain__stop:is(:first-child,:last-child)::before{background:var(--fg)}
.chain__stop em{font-style:italic;color:var(--em)}
@media (max-width:900px){
  .chain__stops{grid-template-columns:minmax(0,1fr)}
  .chain__stop{padding:0 0 1.05rem 1.9rem}
  .chain__stop:last-child{padding-bottom:0}
  .chain__stop::before{top:.24em}
  .chain__stop::after{left:6px;right:auto;top:calc(.24em + 13px);bottom:calc(-.24em);border-top:0;border-left:1px solid var(--rule-strong)}
}


/* 11.20 Tick list — a few short lines, each ticked. As a line arrives (a reveal, or its turn in a stagger) its
   tick draws itself; a list that never gets its reveal (no JS, reduced motion, print) stands there ticked. */
.ticks{list-style:none;margin:0;padding:0;display:grid;gap:.75rem}
.ticks li{display:grid;grid-template-columns:1.35rem minmax(0,1fr);column-gap:.75rem;align-items:start;font-family:var(--f-display);font-size:clamp(1.15rem,1.5vw,1.45rem);line-height:1.3;text-align:left}
.ticks .icon{width:1.35rem;height:1.35rem;margin-top:.1em;color:var(--em-small);stroke-width:1.7}
.js .ticks li.reveal .icon path{stroke-dasharray:1;transition:stroke-dashoffset .8s var(--ease-io) .3s}
.js .ticks li.reveal:not(.is-in) .icon path{stroke-dashoffset:1;transition:none}


/* 11.21 Product lineup — a photograph of the coolers, cut out of its studio ground (tools/cutout.mjs), standing on
   the band; never taller than the screen, so the whole row is seen at once. A second copy of the picture, dimmed
   (the lights off), lies over it. As scene.js runs --p from 0 to 1 that copy is clipped away from the left in
   four steps, one cooler at a time, each step a quick sweep across its cooler: the lights come on along the row,
   and go off again on the way back up. On the figure: --b1 --b2 --b3, where each cooler's right edge falls
   (percent of the width); the first edge steps (--b1t above --by, percent of the height) round the second
   cooler's sign, which stands out behind the first cooler's top. Without JS, with reduced motion and in print
   --p is 1: the dim copy is clipped to nothing. */
.lineup{padding-bottom:var(--sect-half)}
.lineup .section-head{margin-bottom:clamp(1.6rem,3vw,3rem)}
.lineup__figure{--p:1;position:relative;margin:0 auto;width:min(100%,max(17rem,calc((100vh - 8.5rem) * 1.385)));width:min(100%,max(17rem,calc((100svh - 8.5rem) * 1.385)))}   /* 1.385: the picture's own proportion */
.lineup__figure img{display:block;width:100%;height:auto}
.lineup__off{
  --k1:clamp(0,(var(--p) - .1) * 1000,1);--k2:clamp(0,(var(--p) - .32) * 1000,1);--k3:clamp(0,(var(--p) - .54) * 1000,1);--k4:clamp(0,(var(--p) - .76) * 1000,1);   /* each cooler's turn on --p: the last is lit just before the band's heading reaches the top of a short laptop screen */
  --rest:calc((var(--b3) - var(--b2)) * var(--k3) + (100 - var(--b3)) * var(--k4));
  --xb:calc(var(--b1) * var(--k1) + (var(--b2) - var(--b1)) * var(--k2) + var(--rest));                                   /* the dim copy's left edge, below the step */
  --xt:calc(var(--b1t,var(--b1)) * var(--k1) + (var(--b2) - var(--b1t,var(--b1))) * var(--k2) + var(--rest));             /* … and above it */
  position:absolute;inset:0;filter:brightness(.2) saturate(.3);
  clip-path:polygon(calc(var(--xt) * 1%) 0,100% 0,100% 100%,calc(var(--xb) * 1%) 100%,calc(var(--xb) * 1%) calc(var(--by,0) * 1%),calc(var(--xt) * 1%) calc(var(--by,0) * 1%));
  transition:clip-path .5s cubic-bezier(.4,0,.2,1);
}
.lineup__more{display:flex;justify-content:center;margin-top:clamp(1.4rem,2.6vw,2.4rem)}
@media (max-width:600px){.lineup__figure{width:auto;margin-inline:calc(var(--gutter) * -1)}}
/* a phone on its side: the picture takes nearly the whole height */
@media (min-width:601px) and (max-height:500px){.lineup__figure{width:min(100%,calc((100vh - 3rem) * 1.385));width:min(100%,calc((100svh - 3rem) * 1.385))}}


/* 11.22 Product rail — a row of poster cards that runs off the right edge of the screen, to be scrolled sideways: a
   swipe, a trackpad, the arrow keys (the rail takes focus) or the two round buttons, which main.js §15 brings in
   and keeps in step with it. Each card: its number, a line drawing, its name. The cards take four colors in turn
   (Limestone, Oxblood, Saddle, a lifted Night), the drawing in its ink or turned to white with them; the first
   card lines up with the page's text column. A fine bar under the rail shows how far along it is. As a card comes
   into view it slides in from the right. Without JS it is the same row with the browser's own scrollbar; in print
   the cards wrap. Made for a dark band (the open last card and the buttons take the band's colors). */
.rail-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:1.2rem 2rem;margin-bottom:clamp(1.6rem,3vw,3rem)}
.rail-nav{display:flex;gap:.6rem;margin:0 0 .5rem}
.rail-nav[hidden]{display:none}
.rail-btn{-webkit-appearance:none;appearance:none;display:grid;place-items:center;width:3.25rem;height:3.25rem;padding:0;border:1px solid var(--rule-strong);border-radius:50%;background:none;color:var(--fg);cursor:pointer;transition:background-color .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease),opacity .3s var(--ease)}
.rail-btn .icon{width:1.15rem;height:1.15rem}
.rail-btn--prev .icon{transform:scaleX(-1)}
.rail-btn[aria-disabled="true"]{opacity:.32;cursor:default}
@media (hover:hover){.rail-btn:not([aria-disabled="true"]):hover{background:var(--fg);border-color:var(--fg);color:var(--bg)}}
@media (hover:none){.rail-nav{display:none}}
.rail{--pad:max(var(--gutter),calc((100% - var(--wide)) / 2 + var(--gutter)));--gap:clamp(.7rem,1.3vw,1.3rem);--card:clamp(13rem,20.5vw,20.5rem);overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;scroll-padding-inline:var(--pad)}
.js .rail{scrollbar-width:none}
.js .rail::-webkit-scrollbar{display:none}
.rail:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
@media (max-width:600px){.rail{--card:min(62vw,16rem)}}   /* phones: a card and most of the next */
.rail__track{list-style:none;display:flex;gap:var(--gap);margin:0;padding:.5rem 0 1rem var(--pad)}   /* as wide as the rail; the cards simply run out of it (WebKit sizes a max-content row by the cards' words, not their widths) */
/* the space after the last card is a piece of the row, not padding, so that it scrolls into view in every engine */
.rail__track::after{content:'';flex:0 0 auto;width:max(var(--gutter),calc((100vw - var(--wide)) / 2 + var(--gutter)));margin-left:calc(var(--gap) * -1)}
.pcard{--c-bg:var(--limestone);--c-fg:var(--iron-gall);--c-n:var(--saddle-ink);
  flex:0 0 var(--card);aspect-ratio:3/4;display:grid;grid-template-rows:auto minmax(0,1fr) auto;gap:.4rem;padding:clamp(1rem,1.5vw,1.5rem);
  background:var(--c-bg);color:var(--c-fg);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--c-fg) 12%,transparent);scroll-snap-align:start}
.pcard[hidden]{display:none}
.pcard:nth-child(4n+2){--c-bg:var(--oxblood);--c-fg:var(--limestone);--c-n:var(--saddle)}
.pcard:nth-child(4n+3){--c-bg:var(--saddle);--c-fg:var(--night);--c-n:var(--night)}
.pcard:nth-child(4n){--c-bg:color-mix(in srgb,var(--limestone) 9%,var(--night));--c-fg:var(--limestone);--c-n:var(--saddle)}
.pcard__n{font-family:var(--f-display);font-style:italic;font-size:1rem;line-height:1;color:var(--c-n);font-variant-numeric:lining-nums}
.pcard img{place-self:center;width:88%;height:auto;transition:transform .8s var(--ease-out)}   /* the drawings fill about half their own frame, so the frame is set wide */
.pcard:not(.pcard--request) img{transform:scale(1.24);transform-origin:50% 89%}                  /* … and grown from their ground line (89% down the frame), which keeps them clear of the name */
.pcard:is(:nth-child(4n+2),:nth-child(4n)) img{filter:invert(1) hue-rotate(180deg)}   /* the ink turned to (warm) white */
.pcard__name{position:relative;align-self:end;font-family:var(--f-display);font-weight:var(--w-display);font-size:clamp(1.45rem,2.1vw,2.2rem);line-height:1.2;text-wrap:balance}
@media (hover:hover){.pcard:not(.pcard--request):hover img{transform:translateY(-4%) rotate(-4deg) scale(1.32)}}
/* the last card asks for requests: open, in a dashed frame, in the band's own colors */
.pcard.pcard--request{--c-bg:transparent;--c-fg:var(--fg);grid-template-rows:auto auto minmax(0,1fr) auto;gap:.7rem;box-shadow:none;border:1px dashed color-mix(in srgb,var(--em-small) 62%,transparent)}
.pcard--request img{place-self:start;width:3.4rem}
.tone-night .pcard--request img{filter:invert(1) hue-rotate(180deg)}
.pcard--request .pcard__name{align-self:start;font-style:italic;color:var(--em-small)}
.pcard__note{font-size:.9rem;line-height:1.5;color:var(--fg-soft)}
.pcard--request .link-arrow{align-self:end;justify-self:start;font-size:.92rem}
.js .pcard.reveal{transform:translateX(min(3rem,var(--gutter)));transition:opacity .5s var(--ease),transform .9s var(--ease-out)}   /* never further than the space after the last card, so the row's length holds still as cards arrive */
.rail-bar{position:relative;height:1px;margin-top:clamp(1rem,2vw,1.8rem);background:var(--rule)}
html:not(.js) .rail-bar{display:none}
.rail-bar span{position:absolute;left:0;top:-1px;height:3px;width:calc(var(--rv,.3) * 100%);background:var(--em-small);transform:translateX(calc(var(--rp,0) * (1 - var(--rv,.3)) / var(--rv,.3) * 100%))}


/* -----------------------------------------------------------------------------------------
   12  Scene — the growing illustrated scene
   scene.js writes ONE custom property, --p (0 → 1), on each [data-scene]; every piece maps it
   through its own window [--s, --e] and grows from its base. Without JS (or under reduced motion)
   --p stays 1: fully grown and still.
     .piece            style="--x (left, % of width) --h (height, scene units) --b (bottom, units)
                              --s/--e (growth window) --lean (deg) · phones: --xs --hs --bs"
     .piece--tree      a slender sapling that thickens as it climbs
     .piece--rise      pushes up out of the ground (grass tufts)
     .piece--build     a building surfacing out of the mist (the skyline)
     .piece--far       a far tree surfacing out of the mist
     .perch            a bird on a branch: --x of its tree, --dx offset (units), --b, --w · phones --xs --dxs --bs --ws
   Layers sit back to front in .scene__art; the wind (sway + gusts) runs on the images only while
   the scene is on screen (.is-live) and stops after a quiet minute (.is-idle).
   Modes (data-scene): pin = a full-screen stage that holds while it grows (home) · intro = grows on
   load (Our Approach hero) · follow = follows its position on screen (letter borders, value plates).
   ----------------------------------------------------------------------------------------- */
.scene{
  --p:1;
  --stage:100vh;                        /* the visible stage */
  --pin:50vh;                           /* extra scroll the stage holds for (pin mode) */
  --u:min(1vh,1.05vw,13.5px);           /* the art unit: ≈1% of the stage height, capped */
  --gc:14s;                             /* one gust every … */
  --gx:.024s;                           /* … crossing the scene left to right */
}
@supports (height:100svh){.scene{--stage:100svh;--u:min(1svh,1.05vw,13.5px)}}

/* pin mode: the band is taller than its stage; the stage sticks while the art finishes */
.scene--pin{position:relative;height:var(--stage)}
.scene--pin.is-armed{height:calc(var(--stage) + var(--pin))}
.scene__stage{position:sticky;top:0;height:var(--stage);overflow:hidden;overflow:clip;isolation:isolate;background:var(--paper)}
/* intro mode starts unborn once JS is known to run (a failsafe shows it grown after 3s if scene.js never does) */
@media (prefers-reduced-motion:no-preference){
  .js .scene--intro:not(.is-armed){--p:0;animation:scene-failsafe 0s 3s forwards}
}
@keyframes scene-failsafe{to{--p:1}}

/* the rig: [back art] [veil] [front art] stacked in one cell at the foot of the stage. In pin mode
   the rig is two stages tall and each art is sticky to the bottom of the viewport, so while the
   band is still rising the scene stands on the bottom of the screen and grows up from it. */
.scene__rig{position:absolute;left:0;right:0;bottom:0;z-index:1;height:var(--stage);display:grid;grid-template:minmax(0,1fr)/minmax(0,1fr);pointer-events:none;user-select:none}
.scene__art,.scene__veil{grid-area:1/1;align-self:end;position:relative;height:var(--stage)}
.scene--pin.is-armed .scene__rig{height:calc(var(--stage) * 2)}
.scene--pin.is-armed .scene__art{position:sticky;bottom:0}
.scene__layer{position:absolute;inset:0}

.piece{
  --t:clamp(0,(var(--p) - var(--s,0)) / (var(--e,1) - var(--s,0)),1);    /* this piece's own progress */
  --g:calc(var(--t) * var(--t) * (3 - 2 * var(--t)));                    /* eased (smoothstep) */
  position:absolute;left:calc(var(--x) * 1%);bottom:calc(var(--b,0) * var(--u));height:calc(var(--h) * var(--u));
  translate:-50% 0;rotate:var(--lean,0deg);transform-origin:50% 100%;
  transform:scale(calc(.3 + .7 * var(--g)),calc(.12 + .88 * var(--g)));  /* a flower: the stem leads, then it fills out */
  opacity:clamp(0,var(--t) * 4,1);
}
.piece--tree{transform:scale(calc(.18 + .82 * var(--g) * var(--g)),calc(.12 + .88 * var(--g)))}
.piece--rise{transform:translateY(calc((1 - var(--g)) * 72%)) scaleY(calc(.55 + .45 * var(--g)))}
.piece--build{transform:translateY(calc((1 - var(--g)) * 46%));opacity:clamp(0,var(--t) * 2.2,1)}
.piece--far{transform:translateY(calc((1 - var(--g)) * 40%)) scale(calc(.88 + .12 * var(--g)));opacity:clamp(0,var(--t) * 2,1)}
.piece__img{
  display:block;height:100%;width:auto;max-width:none;transform-origin:50% 100%;
  animation:sway var(--sd,6s) ease-in-out calc(var(--x) * -.13s) infinite alternate,
            gust var(--gc) cubic-bezier(.45,.05,.3,1) calc(var(--x) * var(--gx) - var(--gc)) infinite;
  animation-play-state:paused;
}
.scene.is-live .piece__img{animation-play-state:running}
.scene.is-idle .piece__img{animation-play-state:paused}
.piece.is-flip .piece__img{scale:-1 1;--dir:-1}
.piece--build .piece__img,.piece--far .piece__img{animation:none}       /* buildings don't sway; far trees are too far to show it */
@keyframes sway{from{rotate:calc(var(--amp,1) * -1deg)}to{rotate:calc(var(--amp,1) * 1deg)}}
/* a gust: calm most of the cycle, then a push downwind, a rebound, a settle */
@keyframes gust{
  0%,56%,100%{transform:skewX(0deg)}
  63%{transform:skewX(calc(var(--gust,2) * var(--dir,1) * -1deg))}
  70%{transform:skewX(calc(var(--gust,2) * var(--dir,1) * .4deg))}
  77%{transform:skewX(calc(var(--gust,2) * var(--dir,1) * -.16deg))}
  85%{transform:skewX(0deg)}
}

/* layers, back to front: opacity sets the depth; tempo and reach per layer */
.scene__layer--skyline{opacity:.3}
.scene__layer--far{opacity:.28}
.scene__mist{position:absolute;left:0;right:0;bottom:0;height:calc(var(--u) * 30);background:linear-gradient(to top,var(--paper) calc(var(--u) * 12),transparent)}
.scene__layer--mid{opacity:.55}
.scene__layer--mid .piece__img{--sd:9s;--amp:.4;--gust:.7}
.scene__layer--near{opacity:.9}
.scene__layer--near .piece__img{--sd:12s;--amp:.3;--gust:.75}
.scene__layer--back .piece__img{--gust:3;animation-name:none,gust}
.scene__layer--back .piece.is-ink .piece__img{opacity:.5}
.scene__layer--bed .piece__img{--sd:5.8s;--amp:1.2;--gust:2.8}
.scene__layer--bed .piece:nth-child(3n+1) .piece__img{--sd:6.6s;--amp:1}
.scene__layer--bed .piece:nth-child(3n+2) .piece__img{--sd:4.9s;--amp:1.5}
.scene__layer--bed,.scene__layer--front{opacity:.9}
.scene__layer--front .piece__img{--sd:3.1s;--amp:2.6;--gust:6}
.scene__layer--front .piece:nth-child(odd) .piece__img{animation-name:none,gust}
/* open sky: the canopy tops dissolve into paper, and a clearing opens behind the words (pages tune the ellipse) */
.scene__veil{
  --clear-w:35%;--clear-h:31%;--clear-y:30%;
  background:
    linear-gradient(180deg,var(--paper) 0,color-mix(in srgb,var(--paper) 88%,transparent) 5%,transparent 21%),
    radial-gradient(ellipse var(--clear-w) var(--clear-h) at 50% var(--clear-y),color-mix(in srgb,var(--paper) 95%,transparent) 0,color-mix(in srgb,var(--paper) 78%,transparent) 48%,transparent 100%);
}
/* the ground: a short band of soil that ends in the next band's color (--ground), so no seam shows */
.scene__ground{
  position:absolute;left:0;right:0;bottom:0;height:calc(var(--u) * 4.5);
  background:linear-gradient(180deg,transparent 0,color-mix(in srgb,var(--ground,var(--night)) 40%,transparent) 30%,color-mix(in srgb,var(--ground,var(--night)) 82%,transparent) 62%,var(--ground,var(--night)) 88%);
  opacity:clamp(0,(var(--p) - .08) * 4,1);
}

/* the air: birds, seed fluff and leaves, only once the scene is grown and live */
.scene__layer--air{opacity:clamp(0,(var(--p) - .92) * 12,1);visibility:hidden;transition:opacity .9s}
.scene.is-live .scene__layer--air,html:not(.js) .scene__layer--air{visibility:visible}
html:not(.js) .scene__layer--air :is(.drift,.fall){display:none}     /* without JS only the perched bird shows */
.scene.is-idle .scene__layer--air{opacity:0}
/* a perched bird sits on its tree: --x is the tree's own --x, --dx the offset to the branch in art units */
.perch{position:absolute;left:calc(var(--x) * 1% + var(--dx,0) * var(--u));bottom:calc(var(--b) * var(--u));width:calc(var(--w) * var(--u));translate:-50% 0;opacity:.9}
.perch img{display:block;width:100%;height:auto}
.drift{position:absolute;left:-6%;top:calc(var(--y) * 1%);width:calc(var(--w) * var(--u));opacity:0;animation:drift var(--d,30s) linear var(--dl,0s) infinite paused}
.drift img{display:block;width:100%;height:auto;animation:tumble var(--td,6s) ease-in-out infinite alternate paused}
.drift--bird img{animation:glide var(--td,3s) ease-in-out infinite alternate paused}
.fall{position:absolute;left:calc(var(--x) * 1%);top:calc(var(--y) * 1%);width:calc(var(--w) * var(--u));opacity:0;animation:fall var(--gc) linear calc(var(--x) * var(--gx) - var(--gc) + var(--ld,0s)) infinite paused}
.fall img{display:block;width:100%;height:auto;animation:flutter var(--lf,1.6s) ease-in-out infinite alternate paused}
.scene.is-live :is(.drift,.drift img,.fall,.fall img){animation-play-state:running}
.scene.is-idle :is(.drift,.drift img,.fall,.fall img){animation-play-state:paused}
@keyframes drift{0%{transform:translate(0,0);opacity:0}8%{opacity:.8}35%{transform:translate(40vw,calc(var(--u) * -5))}70%{transform:translate(78vw,calc(var(--u) * 4))}92%{opacity:.7}100%{transform:translate(112vw,calc(var(--u) * -2));opacity:0}}
@keyframes tumble{from{rotate:-35deg;translate:0 calc(var(--u) * -1.2)}to{rotate:55deg;translate:0 calc(var(--u) * 1.4)}}
@keyframes glide{from{translate:0 calc(var(--u) * -.8)}to{translate:0 calc(var(--u) * .8)}}
@keyframes fall{
  0%,59%{opacity:0;transform:translate(0,0) rotate(var(--r0,0deg))}
  62%{opacity:.9}
  79%{transform:translate(calc(var(--dx) * var(--u) * .45),calc(var(--dy) * var(--u) * .3)) rotate(calc(var(--r0,0deg) + 160deg))}
  88%{opacity:.8}
  100%{opacity:0;transform:translate(calc(var(--dx) * var(--u)),calc(var(--dy) * var(--u))) rotate(calc(var(--r0,0deg) + 340deg))}
}
@keyframes flutter{from{transform:scaleY(1) skewX(0deg)}to{transform:scaleY(.55) skewX(14deg)}}

/* phones: fewer and larger pieces, each with its own place (--xs, --hs, --bs) */
@media (max-width:640px){
  .scene{--pin:28vh;--u:min(1vh,2.1vw)}
  @supports (height:100svh){.scene{--pin:28svh;--u:min(1svh,2.1vw)}}
  .scene .hide-sm{display:none}
  .piece{left:calc(var(--xs,var(--x)) * 1%);height:calc(var(--hs,var(--h)) * var(--u));bottom:calc(var(--bs,var(--b,0)) * var(--u))}
  .fall{left:calc(var(--xs,var(--x)) * 1%);top:calc(var(--ys,var(--y)) * 1%)}
  .perch{left:calc(var(--xs,var(--x)) * 1% + var(--dxs,var(--dx,0)) * var(--u));bottom:calc(var(--bs,var(--b)) * var(--u));width:calc(var(--ws,var(--w)) * var(--u))}
}


/* -----------------------------------------------------------------------------------------
   13  Footer — the brand and links on open sky; below them an engraved plate rises in as the
   footer arrives, its grass layer moving in a slow breeze.
   The plate (footer-plate.webp, 2400×1300) and the grass (footer-grass.webp, 2400×240) are both
   full width and bottom-anchored, so they always scale together and stay registered.
   ----------------------------------------------------------------------------------------- */
.site-footer{
  --plate-h:54.2vw;                             /* the plate's height at full width (1300/2400) */
  position:relative;isolation:isolate;overflow:hidden;
  min-height:max(560px,var(--plate-h));padding-bottom:max(15rem,41vw);   /* the words end above the plate's spires (its top third is open sky) */
  background:var(--paper-2);color:var(--ink);border-top:1px solid var(--line);
}
.site-footer>.container--wide{position:relative;z-index:1}
.f-scene{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.f-plate,.f-grass{position:absolute;left:0;bottom:0;width:100%;height:auto;transform-origin:50% 100%;opacity:.88}
/* the plate's sky fades into the paper so there is no edge anywhere */
.f-plate{
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.35) 12%,#000 28%);
          mask-image:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.35) 12%,#000 28%);
  animation:footer-wind 13s ease-in-out infinite alternate paused;
}
.f-grass{animation:footer-breeze 5.5s ease-in-out -2s infinite alternate paused}
.site-footer.is-live .f-plate,.site-footer.is-live .f-grass,html:not(.js) .f-plate,html:not(.js) .f-grass{animation-play-state:running}
@keyframes footer-wind{from{transform:scale(1.035) skewX(-.3deg)}to{transform:scale(1.035) skewX(.3deg)}}
@keyframes footer-breeze{from{transform:skewX(-1.1deg) scaleX(1.012)}to{transform:skewX(1.1deg) scaleX(1.012)}}
/* arrival: the plate rises and fades up as the footer comes into view */
.js .f-scene{opacity:0;transform:translateY(4%);transition:opacity 1.6s var(--ease),transform 2.2s var(--ease-out)}
.js .site-footer.is-in .f-scene{opacity:1;transform:none}

.site-footer .top{
  display:grid;grid-template-columns:1.4fr repeat(3,1fr);gap:clamp(1.8rem,3vw,3rem);
  padding-block:clamp(3.4rem,6vw,6rem) clamp(2.4rem,4.2vw,3.8rem);border-bottom:1px solid var(--line);
}
.fbrand a{display:inline-block}                          /* so its focus ring wraps the logo */
.fbrand img{height:44px;width:auto}
.fbrand__tag{margin-top:1.1rem;font-family:var(--f-display);font-style:italic;font-size:clamp(1.12rem,1.35vw,1.3rem);line-height:1.3;color:var(--oxblood)}
.site-footer h2{margin:0 0 1.15rem;font-family:var(--f-ui);font-weight:var(--w-label);font-size:.75rem;line-height:1.3;letter-spacing:.16em;text-transform:uppercase;color:var(--saddle-ink)}
.site-footer ul{list-style:none;margin:0;padding:0;display:grid;gap:.75rem}
.site-footer li{line-height:1.4}
.site-footer li a,.site-footer li span{font-size:.9375rem;color:var(--ink-soft);transition:color .35s var(--ease)}
.site-footer li a:hover,.site-footer li a:focus-visible{color:var(--ink)}
@media (pointer:coarse){.site-footer li a{padding-block:.35rem}}
.site-footer .legal{display:flex;flex-wrap:wrap;justify-content:space-between;gap:.4rem 1.5rem;padding-top:1.6rem;font-family:var(--f-ui);font-size:.8125rem;color:var(--ink-soft)}
@media (max-width:900px){
  .site-footer .top{grid-template-columns:repeat(3,minmax(0,1fr))}
  .fbrand{grid-column:1/-1}
}
@media (max-width:640px){
  .site-footer{padding-bottom:74vw;min-height:0}
  .f-plate,.f-grass{width:180%;max-width:none;left:-40%}      /* the middle of the plate: the city, the river, both oak crowns */
}
@media (max-width:520px){
  .site-footer .top{grid-template-columns:repeat(2,minmax(0,1fr));column-gap:1.25rem;row-gap:2.1rem}
  .site-footer .top>.col--contact{grid-column:1/-1}
  .site-footer .legal{flex-direction:column}
}


/* -----------------------------------------------------------------------------------------
   14  404 — one dark band: the drawing behind, the message centred, the sections underneath
   ----------------------------------------------------------------------------------------- */
.nf{
  position:relative;isolation:isolate;overflow:hidden;min-height:100vh;min-height:100svh;display:grid;place-items:center;
  padding:calc(var(--hdr) + clamp(2rem,6vh,4.5rem)) var(--gutter) clamp(3rem,8vh,5rem);
  background:radial-gradient(120% 80% at 50% 110%,color-mix(in srgb,var(--limestone) 7%,transparent),transparent 62%),var(--night);
}
.nf__inner{display:grid;gap:clamp(1.1rem,2vw,1.5rem);justify-items:center;text-align:center;max-width:720px}
.nf__art{width:clamp(220px,30vw,400px);height:auto;margin-bottom:.4rem;opacity:.9}
.nf__code{font-family:var(--f-ui);font-weight:var(--w-label);font-size:.75rem;letter-spacing:.16em;text-transform:uppercase;color:var(--em-small)}
.nf .d1{font-size:clamp(2.5rem,5.4vw,4.9rem)}
.nf .lede{text-align:center;max-width:46ch;text-wrap:balance}
.nf__links{display:flex;flex-wrap:wrap;justify-content:center;gap:0 clamp(1.1rem,2.4vw,2rem);margin-top:clamp(1.4rem,4vh,2.6rem);padding-top:clamp(.65rem,2vh,1.05rem);border-top:1px solid var(--rule);font-family:var(--f-ui);font-weight:var(--w-ui);font-size:.9375rem}
.nf__links a{display:inline-flex;align-items:center;min-height:44px;color:var(--fg-soft);transition:color .3s var(--ease)}
.nf__links a:hover{color:var(--fg)}


/* -----------------------------------------------------------------------------------------
   15  Motion — armed only once JS runs (html.js), so without JS nothing is ever hidden
   ----------------------------------------------------------------------------------------- */
/* masked lines: main.js sets display headings line by line once the fonts are in.
   The mask has a little room below (descenders) and to the right (italic overhang). */
.line-mask{display:block;overflow:hidden;padding:0 .12em .16em 0;margin:0 -.12em -.16em 0}
.line-mask>span{display:block}
.js .line-mask>span{transform:translateY(105%);opacity:0;transition:transform 1.05s var(--ease-out),opacity .8s var(--ease)}
.is-in .line-mask>span,.line-mask.is-in>span{transform:none;opacity:1}
.no-motion .line-mask>span{transition:none!important}
/* hold display headings until they're split, so they don't flash in full and then drop away;
   the animation is a failsafe if the script never runs */
@media (prefers-reduced-motion:no-preference){
  .js :is(.d1,.d2,.d3):not([data-split]){visibility:hidden;animation:unhide 0s 2.4s forwards}
}
@keyframes unhide{to{visibility:visible}}

/* fade-and-rise */
.js .reveal{opacity:0;transform:translateY(24px);transition:opacity .85s var(--ease),transform 1s var(--ease-out)}
.js .reveal.is-in{opacity:1;transform:none}

/* curtain: a band-colored panel lifts off the media; the box keeps its size so the observer still sees it */
.js .reveal-scale{position:relative;overflow:hidden;isolation:isolate}
.js .reveal-scale::after{content:'';position:absolute;inset:-1px;z-index:3;background:var(--bg);transform:translateY(0);transition:transform 1.15s var(--ease-out)}
.js .reveal-scale.is-in::after{transform:translateY(-101.5%)}
.js .reveal-scale img{transform:scale(1.08);transition:transform 1.6s var(--ease-out)}
.js .reveal-scale.is-in img{transform:none}

/* rules that draw left to right as their item arrives (columns, lists) */
@media (prefers-reduced-motion:no-preference){
  .js :is(.column__head,.column__item,.numbered__item,.feature).reveal::after{transform:scaleX(0);transition:transform 1.25s var(--ease-out) .12s;transition-delay:inherit}
  .js :is(.column__head,.column__item,.numbered__item,.feature).reveal.is-in::after{transform:none}
}

/* page veil: the deep brand color wipes up between pages (main.js). At rest it waits below the screen,
   hidden, so no toolbar resize or overscroll can show it; it is only visible while it moves or covers. */
.veil{position:fixed;inset:0;z-index:9990;background:var(--brand-deep);pointer-events:none;transform:translateY(100%);visibility:hidden}
.veil.is-out{visibility:visible;transform:translateY(0);transition:transform .4s var(--ease-out)}
.veil.is-in{visibility:hidden;transform:translateY(-100%);transition:transform .78s var(--ease-out),visibility 0s .78s}


/* -----------------------------------------------------------------------------------------
   16  Utilities
   ----------------------------------------------------------------------------------------- */
.visually-hidden{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.nowrap{white-space:nowrap}
.center{text-align:center}
.stack{display:grid;gap:clamp(1rem,1.8vw,1.6rem);justify-items:start}
.mt-section{margin-top:var(--sect-half)}


/* -----------------------------------------------------------------------------------------
   17  Reduced motion — no hold, no pin, art fully drawn, nothing sways or pulses
   ----------------------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  html:focus-within{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;transition-delay:0s!important}
  .reveal,.reveal-scale,.line-mask>span,.reveal-scale img{opacity:1!important;transform:none!important}
  .js .reveal-scale::after{display:none}
  .hero--pinned{position:relative}
  .scene{--p:1!important}
  .scene--pin,.scene--pin.is-armed{height:var(--stage)!important}
  .scene--pin .scene__rig{height:var(--stage)!important}
  .scene--pin .scene__art{position:relative!important}
  .piece__img,.drift,.drift img,.fall,.fall img,.f-plate,.f-grass{animation:none!important}
  .scene__layer--air{visibility:visible;opacity:1}
  .scene__layer--air :is(.drift,.fall){display:none}
  .js .f-scene{opacity:1;transform:none}
  .js .map .map__plate{-webkit-mask-image:none;mask-image:none}
  .js .map .map__pin,.js .map .map__places,.js .map .map__places span{opacity:1;transform:none}
  .map__pin .pulse{display:none}
  .js .letter-card__sig.reveal,.js .signature.reveal img{-webkit-mask-image:none;mask-image:none}
  .veil{display:none}
}


/* -----------------------------------------------------------------------------------------
   18  Print — every word shows (nothing waits for a reveal; main.js opens the FAQ answers for the
   printout), the art and the moving parts stay off the paper, dark bands print as ink on white
   ----------------------------------------------------------------------------------------- */
@media print{
  .site-header,.menu-sheet,.veil,.skip-link,.hero-video-btn,.hero-bg,.scene__rig,.f-scene,.pagetext,.letter-beds,.plates .piece,body::after{display:none!important}
  html,body{background:none}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .reveal,.reveal-scale,.line-mask>span,.reveal-scale img,.d1,.d2,.d3{opacity:1!important;transform:none!important;visibility:visible!important;clip-path:none!important}
  .reveal-scale::after{display:none!important}
  .hero,.hero--pinned{position:relative!important;min-height:0!important;padding-block:2rem!important}
  .scene,.scene--pin,.scene--pin.is-armed,.about-hero{height:auto!important;min-height:0!important}
  .scene__stage{position:relative!important;height:auto!important;overflow:visible!important}
  .scene__stage::after{display:none!important}
  .about-hero__inner{position:static!important;padding-top:1rem!important}
  .tone-night,.tone-oxblood,.hero,.nf,.fig-plate,.plate__art{--bg:transparent;--fg:var(--ink);--fg-soft:var(--ink-soft);--em:var(--accent);--em-small:var(--accent-ink);--rule:var(--line);background:none!important;color:var(--ink)!important}
  .js .map .map__plate{-webkit-mask-image:none!important;mask-image:none!important}
  .js .map .map__pin,.js .map .map__places,.js .map .map__places span{opacity:1!important;transform:none!important}
  .js .letter-card__sig.reveal,.js .signature.reveal img{-webkit-mask-image:none!important;mask-image:none!important}
  .js .signature.reveal figcaption{opacity:1!important}
  .js .fig-plate.reveal,.js .fig-plate.reveal>*{opacity:1!important;transform:none!important;clip-path:none!important}
  .ticks .icon path,.column__tick path{stroke-dashoffset:0!important}
  .index{padding-top:0!important}
  .index__row{margin-right:0!important}
  .index__name,.index__n{color:var(--ink)!important;transform:none!important}
  .index__row::after{display:none!important}
  .index__go{background:none!important;border-color:var(--line)!important;color:var(--ink)!important}
  .index__media{position:static!important;width:auto!important;visibility:visible!important}
  .index__stage{position:static!important;display:grid!important;min-height:0!important;padding:0 0 1rem!important;border:0!important;background:none!important;clip-path:none!important}
  .index__stage img{width:100%!important;max-height:none!important}
  .index__where{position:static!important;width:auto!important;height:auto!important;margin:0!important;overflow:visible!important;clip:auto!important;clip-path:none!important;white-space:normal!important}
  .rail{overflow:visible!important}
  .rail__track{flex-wrap:wrap!important;padding-inline:0!important}
  .pcard{flex-basis:8.5rem!important;aspect-ratio:auto!important;background:none!important;color:var(--ink)!important;box-shadow:none!important;border:1px solid var(--line)!important}
  .pcard img{filter:none!important;transform:none!important}
  .rail__track::after{display:none!important}
  .pcard__n,.pcard--request .pcard__name{color:var(--accent-ink)!important}
  .rail-nav,.rail-bar{display:none!important}
  .steps--open .step::before{transform:none!important}
  .steps--open :is(.tgg__check,.tgg__shackle){stroke-dashoffset:0!important;transform:none!important}
  .lineup__off{display:none!important}
  .reveal img,.reveal .icon{clip-path:none!important}
  .tgg,.tgg.is-armed{height:auto!important}
  .tgg .tgg__stage{position:static!important;height:auto!important;min-height:0!important;padding-block:2rem!important}
  .tgg :is(.tgg__w,.tgg__i,.tgg__shackle){opacity:1!important;transform:none!important}
  .tgg :is(.tgg__check,.tgg__shackle){stroke-dashoffset:0!important}
  .tgg__words{font-size:3rem!important}
  .fig-plate__of{color:var(--accent)!important}
  .fig-plate__note{color:var(--ink-soft)!important}
  .hero--video .hero__title,.hero--video .hero__lede{filter:none!important;text-shadow:none!important}
  .plate__art{aspect-ratio:auto!important;height:3rem!important;border:0!important;background:none!important}
  :is(.promise__fig,.fig-plate__n)>.visually-hidden{position:static!important;width:auto!important;height:auto!important;margin:0!important;clip:auto!important;clip-path:none!important;white-space:nowrap!important}
  :is(.promise__fig,.fig-plate__n)>[aria-hidden="true"]{display:none!important}
  .faq__item,.index__item,.plate,.place-card,.pcard,.step,.letter-card,figure{break-inside:avoid}
  a[href^="mailto:"]{text-decoration:none}
}

