/* =========================================================================
   Found Surface — public site
   -------------------------------------------------------------------------
   BUILT ON BINGO!, the Found Surface design system
   (claude.ai/design project c80bfd71 — "Live: Alpha Bingo! Found Surface").
   Bingo! says of itself that it "powers everything Found Surface ships: the
   MAKE+ application, the website, and the wider brand aesthetic. One set of
   tokens, one type system, one motion language, one component library."

   So the values below are NOT invented here. Colors, the type scale, spacing,
   radii, elevation, focus and motion are transcribed from the system's own
   tokens/*.css. Where this file adds anything it is a website-only layer, and
   it is marked as such.

   Two deliberate divergences, both flagged for Aidan (who owns the system):

     1. THE YARN PALETTE. Bingo!'s tokens/colors.css carries --yarn-undyed
        #E6D9A8, --yarn-navy #1C2A4A, --yarn-red #A33529 and so on. Those are
        NOT the hexes the shop runs: Samples-Api CORE_COLORS — the values on
        every direction card and in Order Creation, the Sample Queue, the
        Product Directory and the portal's Knitting Studio — are Ecru #F0DDC8,
        Navy Blue #272C3B, Red #C51F2C. This site PAINTS CLOTH with these
        numbers, so a garment knitted in #E6D9A8 would misrepresent the product
        it is selling. CORE_COLORS wins here until the system is reconciled.

     2. THE DISPLAY STEP. The scale tops out at --fs-display 46px, which is
        right for an operations tool. A hero headline is the one place a
        storefront needs more, so --fs-hero exists as a website-only step. It
        uses the system's family, weight and tight line-height.

   The system's app register is "precise, data-dense, industrial-but-clean" and
   carries no photography. The website register is the other job it names for
   itself — same tokens, same components, but photography-led and airier. That
   distinction is the system's own: "Where imagery goes: the website, decks, and
   brand surfaces. Not the MAKE+ app ... Two different jobs from one system."
   ========================================================================= */
/* ===== Bingo! tokens ===================================================== */
:root{
  /* Brand & actions — blue is the action color in this system; red means
     destructive / OUT / consumption and is not a call to action. */
  --blue-primary:#2563EB; --blue-primary-hover:#1D4ED8; --blue-tint:#EAF1FE;
  --green:#2E8B4F; --green-tint:#E7F4EC;
  --red:#C0392B; --red-tint:#FBEAE8;
  --amber:#D97706; --amber-tint:#FCEFD9;

  /* Neutrals */
  --ink:#1A1A1A; --text-secondary:#6B7280; --border:#E5E7EB;
  --surface:#FFFFFF; --canvas:#F5F6F7; --muted:#F3F4F6;

  /* Semantic aliases, as the system defines them */
  --text-primary:var(--ink); --text-link:var(--blue-primary);
  --bg-page:var(--canvas); --bg-card:var(--surface); --bg-input:var(--surface);
  --bg-table-header:var(--muted);
  --border-default:var(--border); --border-focus:var(--blue-primary);
  --action-primary:var(--blue-primary); --action-primary-hover:var(--blue-primary-hover);
  --action-success:var(--green); --action-danger:var(--red); --flag:var(--amber);

  /* Material / yarn palette — see divergence 1 above: these are Samples-Api
     CORE_COLORS, the cones the machines are actually loaded with. */
  --yarn-ecru:#F0DDC8; --yarn-black:#2C2B2E; --yarn-navy:#272C3B;
  --yarn-dark-brown:#3F322A; --yarn-green:#006339; --yarn-red:#C51F2C;
  --yarn-burgundy:#483237;

  /* Type */
  --font-sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700; --fw-extrabold:800;
  --fs-display:46px; --fs-h1:30px; --fs-h2:20px; --fs-h3:16px;
  --fs-body:15px; --fs-body-sm:14px; --fs-overline:11px; --fs-caption:12px; --fs-kpi:36px;
  --lh-tight:1.1; --lh-snug:1.25; --lh-body:1.5;
  --ls-overline:0.08em; --ls-tight:-0.01em;
  --fnum:'tnum' 1,'lnum' 1;

  /* Shape */
  --radius-card:12px; --radius-input:12px; --radius-chip:8px; --radius-pill:9999px;
  --radius-tile:10px; --radius-track:10px;
  --border-width:1px; --border-hairline:1px solid var(--border);
  --divider-dotted:radial-gradient(circle at 1px 1px,var(--border) 1px,transparent 1.2px)
    left center / 5px 2px repeat-x;

  /* Elevation — soft and layered; the system forbids heavy drop shadows */
  --shadow-card:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.06);
  --shadow-tile:0 1px 2px rgba(16,24,40,.06);
  --shadow-pill:0 1px 2px rgba(16,24,40,.06),0 2px 6px rgba(16,24,40,.05);
  --shadow-raised:0 2px 4px rgba(16,24,40,.04),0 8px 20px rgba(16,24,40,.08);
  --shadow-menu:0 4px 8px rgba(16,24,40,.06),0 12px 32px rgba(16,24,40,.14);
  --shadow-modal:0 8px 16px rgba(16,24,40,.08),0 24px 56px rgba(16,24,40,.18);
  --ring-focus:0 0 0 3px rgba(37,99,235,.20);

  /* Spacing — 4px base */
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
  --space-6:24px; --space-8:32px; --space-12:48px;
  --pad-card:22px; --content-max:1280px; --gutter:32px;

  /* Motion — the house curve and four durations */
  --dur-instant:90ms; --dur-fast:140ms; --dur-base:200ms; --dur-slow:320ms;
  --dur-reveal:560ms;   /* scroll reveals and the header's pop-down: slower than UI feedback */
  --ease-out:cubic-bezier(.22,1,.36,1); --ease-in-out:cubic-bezier(.4,0,.2,1);
  --ease-settle:cubic-bezier(.34,1.32,.64,1);
  --press-scale:.975;
  --t-feedback:color var(--dur-instant) var(--ease-out),
               background-color var(--dur-fast) var(--ease-out),
               border-color var(--dur-fast) var(--ease-out);

  /* ===== Website-only layer ============================================= */
  /* One extra display step (divergence 2), and the warm daylight grounds the
     studio is lit in. The system's canvas is #F5F6F7; these sit beside it. */
  --fs-hero:clamp(34px,5vw,68px);
  --stage-1:#FFFFFF; --stage-2:#F7F8F9; --stage-3:#EDEFF1;
  --font:var(--font-sans);
  --display:var(--font-sans);
  --paper:var(--canvas); --paper-2:var(--surface); --paper-3:var(--muted);
  --paper-in:#EAECEF;
  --line:var(--border); --line-2:#D7DAE0;
  --mid:var(--text-secondary); --dim:var(--text-secondary); --faint:#9CA3AF;
  --coal:#1A1A1A; --coal-2:#232323; --coal-3:#2E2E2E;
  --on-coal:#FFFFFF; --on-coal-mid:#C9CBD1; --on-coal-dim:#9CA3AF;
  --coal-line:rgba(255,255,255,.16);
  --red-hi:#D3483A; --red-lo:#A32F22;
  --pill:var(--radius-pill); --r:var(--radius-card); --r-sm:var(--radius-chip);
  --r-lg:var(--radius-card);
  --sh-1:var(--shadow-card); --sh-2:var(--shadow-raised); --sh-3:var(--shadow-modal);
  --sh-in:none;
  --wrap:var(--content-max);
}
@media (prefers-reduced-motion:reduce){
  :root{ --dur-instant:0ms; --dur-fast:0ms; --dur-base:0ms; --dur-slow:0ms; --dur-reveal:0ms }
  html{scroll-behavior:auto}
  .factory-bg img,.factory-bg video{animation:none}
  html{ scroll-behavior:auto !important }
}
*{box-sizing:border-box}
[hidden]{display:none !important}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;background:var(--coal)}
body{margin:0;background:var(--canvas);color:var(--ink);font-family:var(--font-sans);
  font-size:var(--fs-body);line-height:var(--lh-body);-webkit-font-smoothing:antialiased}
img,canvas{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
::selection{background:var(--blue-primary);color:#fff}
p{margin:0}
button,input,textarea,select{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:0;padding:0;
  transition:color var(--dur-instant) var(--ease-out),background-color var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out),
             transform var(--dur-instant) var(--ease-out),opacity var(--dur-fast) var(--ease-out)}
/* The system presses by scaling to 0.975, not by moving down. */
button:active:not(:disabled){transform:scale(var(--press-scale))}
:focus-visible{outline:none;border-color:var(--blue-primary);box-shadow:var(--ring-focus)}

/* ── Type ─────────────────────────────────────────────────────────────────
   Display is set tight and big and used sparingly; everything else is Inter,
   larger and in fewer, longer lines than the portal would ever allow. */
/* Bingo!'s scale, exactly: display 46/700 tight, H1 30/700, H2 20/600,
   H3 16/600. h1 on this site is the hero, so it takes the website-only
   --fs-hero step; everything else is the system's own. */
h1,h2,h3,h4{margin:0;font-family:var(--font-sans);letter-spacing:var(--ls-tight)}
h1{font-size:var(--fs-hero);font-weight:var(--fw-bold);line-height:var(--lh-tight);
  letter-spacing:-.022em}
h2{font-size:var(--fs-h1);font-weight:var(--fw-bold);line-height:var(--lh-tight)}
h3{font-size:var(--fs-h3);font-weight:var(--fw-semibold);line-height:var(--lh-snug)}
h4{font-size:var(--fs-h3);font-weight:var(--fw-semibold);line-height:var(--lh-snug)}
.fs-display{font-size:var(--fs-display);font-weight:var(--fw-bold);line-height:var(--lh-tight)}
/* The system's own utilities, verbatim. */
.fs-overline{font-family:var(--font-sans);font-size:var(--fs-overline);
  font-weight:var(--fw-medium);text-transform:uppercase;letter-spacing:var(--ls-overline);
  color:var(--text-secondary)}
.fs-tabular{font-variant-numeric:tabular-nums lining-nums;font-feature-settings:var(--fnum)}
.eyebrow{display:inline-block;font-family:var(--font-sans);font-size:var(--fs-overline);
  font-weight:var(--fw-medium);text-transform:uppercase;letter-spacing:var(--ls-overline);
  color:var(--text-secondary)}
.lede{font-size:1.15rem;color:var(--text-secondary);max-width:34em;line-height:1.55}
.sep{color:var(--faint);margin:0 .45rem}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 clamp(1.2rem,4vw,2.6rem)}
.note{font-size:.85rem;color:var(--dim);line-height:1.6}
.note a{color:var(--text-link);text-decoration:underline;text-underline-offset:2px}

/* ── Buttons ─────────────────────────────────────────────────────────────
   Squared, physical: a hairline, a lit top edge, a shadow underneath, and a
   press that moves down rather than shrinking. */
/* Button — Bingo!/components/core/Button.jsx: pill, weight 600, sizes
   sm 6/12@13 · md 9/18@14 · lg 11/22@15. `secondary` is the outline variant
   and hovers to --muted; `primary` is BLUE. Red is the danger variant only. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);
  padding:9px 18px;border-radius:var(--radius-pill);border:1px solid var(--border);
  background:var(--surface);color:var(--ink);font-size:var(--fs-body-sm);
  font-weight:var(--fw-semibold);line-height:1;white-space:nowrap}
.btn:hover{background:var(--muted)}
.btn-primary{background:var(--blue-primary);border-color:transparent;color:#fff}
.btn-primary:hover{background:var(--blue-primary-hover)}
.btn-danger{background:var(--red);border-color:transparent;color:#fff}
.btn-danger:hover{background:#a32f22}
.btn-ink{background:var(--ink);border-color:transparent;color:#fff}
.btn-ink:hover{background:#000}
.btn-ghost{background:transparent;border-color:var(--line-2);color:var(--mid);box-shadow:none}
.btn-plain{background:none;border:0;box-shadow:none;color:var(--text-link);padding:0;
  font-weight:var(--fw-semibold)}
.btn-plain:hover{text-decoration:underline;text-underline-offset:3px}
.btn-ghost:hover{color:var(--ink);border-color:var(--ink)}
.btn-lg{padding:11px 22px;font-size:var(--fs-body)}
.btn-sm{padding:6px 12px;font-size:13px}
.btn-block{width:100%}
.btn[disabled]{opacity:.45;cursor:not-allowed}
.lnk{font-size:13px;font-weight:var(--fw-semibold);color:var(--text-link);
  text-decoration:underline;text-underline-offset:2px;background:none;border:0}

/* ── Tagline strip + header ─────────────────────────────────────────────── */
.tagline{background:var(--ink);color:var(--on-coal-mid)}
.tagline .wrap{display:flex;align-items:center;gap:1rem;min-height:2.4rem;font-size:.74rem;
  letter-spacing:.02em}
.tagline b{font-weight:var(--fw-semibold);color:#fff;letter-spacing:.01em;
  font-size:var(--fs-caption)}
.tagline .t-end{margin-left:auto;display:flex;gap:.9rem;align-items:center}
.tagline a{color:var(--on-coal);text-decoration:underline;text-underline-offset:3px}
/* The header is dark, so the tagline strip, the header and the studio read as
   one block of black at the top of the page and the paper starts where the
   talking starts. It stays dark over the paper sections while you scroll,
   which is what keeps it looking deliberate rather than stuck. */
/* Frosted daylight, the way a shop's glass front behaves. */
/* The header is NOT on the first screen. The Studio takes the whole viewport
   and the header pops down once you scroll (El: "make the knitting studio
   panel take up the entire screen at first - the header can pop down when you
   scroll"). Fixed, so it takes no room in the flow; hidden above the top edge
   until site.js adds .show. */
header.bar{position:fixed;left:0;right:0;top:0;z-index:60;background:rgba(251,250,247,.86);
  backdrop-filter:saturate(1.6) blur(20px);-webkit-backdrop-filter:saturate(1.6) blur(20px);
  transform:translateY(-100%);
  transition:transform var(--dur-reveal) var(--ease-out),box-shadow var(--dur-base) var(--ease-out)}
header.bar.show{transform:none}
/* anchors land under the popped-down header, not behind it */
main section{scroll-margin-top:4.8rem}
main section:first-child{scroll-margin-top:0}
header.bar.stuck{box-shadow:0 1px 0 rgba(29,27,22,.06),0 10px 26px -20px rgba(29,27,22,.35)}
header.bar .wrap{display:flex;align-items:center;gap:1.5rem;min-height:4.6rem}
.lockup{display:flex;align-items:center;gap:.85rem;flex:none}
.lockup img{height:1.9rem;width:auto;display:block}
.lockup i{font-style:normal;font-weight:700;color:var(--faint);letter-spacing:.16em;font-size:.58rem;
  text-transform:uppercase;padding-left:.85rem;border-left:1px solid var(--line-2);
  align-self:stretch;display:flex;align-items:center}
/* The system: "Pick the file by background; never recolour with a CSS
   filter." So the footer places logo-wordmark-white.png rather than inverting
   the black one, which is what this used to do. */
footer .lockup img{height:2.2rem}
nav.main{display:flex;gap:.1rem;margin-left:.4rem}
nav.main a{white-space:nowrap;padding:.55rem .75rem;font-size:.9rem;font-weight:600;color:var(--mid);
  position:relative;transition:color var(--dur-instant) var(--ease-out)}
nav.main a::after{content:'';position:absolute;left:.75rem;right:.75rem;bottom:.3rem;height:2px;
  background:var(--blue-primary);transform:scaleX(0);transform-origin:left;
  transition:transform var(--dur-base) var(--ease-out)}
nav.main a:hover{color:var(--ink)}
nav.main a:hover::after{transform:scaleX(1)}
.bar-end{margin-left:auto;display:flex;align-items:center;gap:.6rem}
.burger{display:none;width:2.8rem;height:2.8rem;border:1px solid var(--line-2);border-radius:var(--r);
  align-items:center;justify-content:center;background:var(--paper-2)}
.burger span{display:block;width:1.1rem;height:1.5px;background:var(--ink);position:relative}
.burger span::before,.burger span::after{content:'';position:absolute;left:0;width:100%;height:1.5px;
  background:var(--ink)}
.burger span::before{top:-5px}.burger span::after{top:5px}
.on-narrow{display:none}

/* ── Sections ────────────────────────────────────────────────────────────
   Ground changes carry the rhythm: paper, paper, coal. No card frames. */
section{padding:clamp(3.2rem,6vw,5.4rem) 0}
section[id],main[id]{scroll-margin-top:5.4rem}
.sec-head{display:grid;gap:1rem;margin-bottom:clamp(2rem,4vw,3.2rem);max-width:46em}
.sec-head h2{margin:.3rem 0 .2rem}
.sec-head p{color:var(--mid);font-size:1.05rem;max-width:34em}
.sec-head .btn{justify-self:start}
.band{background:var(--paper-2)}
.band-ink{background:var(--coal);color:var(--on-coal)}
.band-ink h2,.band-ink h3{color:var(--on-coal)}
.band-ink p,.band-ink .lede{color:var(--on-coal-mid)}
.band-ink .eyebrow{color:var(--on-coal-dim)}
.grid{display:grid;gap:clamp(1rem,2.4vw,1.8rem)}
.g-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g-4{grid-template-columns:repeat(4,minmax(0,1fr))}

/* A "card" is a block of type with a rule over it, not a box. That single
   change takes about ninety borders off the page. */
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-card);
  padding:var(--pad-card);box-shadow:var(--shadow-card);text-align:left;
  transition:box-shadow var(--dur-base) var(--ease-out),transform var(--dur-base) var(--ease-out)}
.card p{color:var(--mid);font-size:.97rem;margin-top:.5rem;max-width:34em}
.card h3{display:flex;align-items:baseline;gap:.6rem}
a.card:hover,button.card:hover{transform:translateY(-2px);box-shadow:var(--shadow-raised)}
.band-ink .card{background:rgba(247,244,238,.06);border-color:var(--coal-line)}
.band-ink .card p{color:var(--on-coal-mid)}
.card-k{margin-left:auto;font-family:var(--font-sans);font-size:var(--fs-overline);
  font-weight:var(--fw-medium);letter-spacing:var(--ls-overline);text-transform:uppercase;
  color:var(--text-secondary)}
/* KPI — 36/700, tabular, as the system specifies. */
.num{font-family:var(--font-sans);font-weight:var(--fw-bold);font-size:var(--fs-kpi);
  letter-spacing:var(--ls-tight);line-height:var(--lh-tight);
  font-variant-numeric:tabular-nums lining-nums;font-feature-settings:var(--fnum)}
.stat{padding:1rem 0 0}
.stat .num{display:block;margin:var(--space-2) 0 var(--space-1);color:var(--ink);
  font-size:var(--fs-kpi);line-height:var(--lh-tight)}
.stat span{font-size:var(--fs-caption);color:var(--text-secondary)}
.band-ink .stat span{color:var(--on-coal-dim)}
.steps{counter-reset:s}
.step{padding-left:0}
/* An IconTile-shaped step number: 10px radius, blue on blue tint. */
.step h3::before{counter-increment:s;content:counter(s);font-weight:var(--fw-bold);
  font-size:13px;color:var(--blue-primary);background:var(--blue-tint);width:26px;height:26px;
  border-radius:var(--radius-tile);display:inline-grid;place-items:center;flex:none;
  font-variant-numeric:tabular-nums lining-nums}

/* ── Tables ──────────────────────────────────────────────────────────────
   The one place hairlines earn their keep. */
.tbl{width:100%;border-collapse:collapse;font-size:.94rem;background:none}
/* DataTable — gray sticky header, hairline under it, right-aligned numerics. */
.tbl th{text-align:left;font-size:var(--fs-overline);font-weight:var(--fw-medium);
  text-transform:uppercase;letter-spacing:var(--ls-overline);color:var(--text-secondary);
  background:var(--bg-table-header);padding:10px 14px;border-bottom:1px solid var(--border)}
.tbl td{padding:12px 14px;border-bottom:1px solid var(--border);color:var(--text-secondary);
  font-variant-numeric:tabular-nums lining-nums}
.tbl tr:last-child td{border-bottom:0}
.tbl td b{color:var(--ink);font-weight:700}
.tbl-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.yarnrow{display:flex;flex-wrap:wrap;gap:1.1rem 1.6rem;margin-top:1.6rem}
.yarn{display:flex;align-items:center;gap:.6rem;font-size:.86rem;font-weight:700;color:var(--ink)}
.yarn em{font-style:normal;font-weight:500;color:var(--faint)}
/* ColorSwatch — a yarn chip, not an action. */
.yarn i{width:24px;height:24px;border-radius:var(--radius-chip);
  border:1px solid rgba(16,24,40,.14);display:block;box-shadow:var(--shadow-tile)}

/* ── The case band (was the hero) ────────────────────────────────────────── */
.hero{padding:clamp(3.4rem,6vw,5.6rem) 0 clamp(2rem,3vw,3rem)}
.hero-grid{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:start}
/* The scale tops out at --fs-display; nothing on the page may exceed it except
   the hero, which has its own website-only step. */
.hero h2.h1ish{font-size:var(--fs-display);margin:var(--space-3) 0 var(--space-4)}
.hero em{font-style:normal;color:var(--blue-primary)}
.hero-cta{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:2rem}
/* A spec plate, screwed to the page: flat head, hairline rows. */
.plate{background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh-2);overflow:hidden}
.plate-hd{background:var(--muted);color:var(--text-secondary);font-size:var(--fs-overline);
  font-weight:var(--fw-medium);text-transform:uppercase;letter-spacing:var(--ls-overline);
  padding:12px var(--pad-card);border-bottom:1px solid var(--border)}
.plate dl{margin:0;padding:.2rem 1.1rem}
.plate dl>div{display:grid;grid-template-columns:7.4rem minmax(0,1fr);gap:var(--space-3);
  padding:12px 0;background:var(--divider-dotted);background-position:left bottom}
.plate dl>div:last-child{background:none}
.plate dt{font-size:var(--fs-overline);font-weight:var(--fw-medium);
  letter-spacing:var(--ls-overline);text-transform:uppercase;color:var(--text-secondary);
  padding-top:2px}
.plate dd{margin:0;font-weight:var(--fw-semibold);font-size:var(--fs-h3);
  letter-spacing:var(--ls-tight);line-height:var(--lh-snug);
  font-variant-numeric:tabular-nums lining-nums}
.plate dd span{display:block;font-family:var(--font);font-size:.8rem;font-weight:500;color:var(--dim);
  letter-spacing:0;margin-top:.35rem;line-height:1.45}
.plate-ft{background:var(--paper-3);border-top:1px solid var(--line);padding:.7rem 1.1rem;
  font-size:.74rem;color:var(--dim);font-weight:600}

/* A small spec list on paper: the blank cards, and anywhere else a few
   figures need to sit under a paragraph. */
.mspec{display:grid;margin-top:1.1rem}
/* Rows INSIDE a card get the dotted rule — the system calls this "one of the
   highest-leverage details": it keeps a long list from reading like a
   spreadsheet. Solid hairlines are for card edges and table headers only. */
.mspec div{display:flex;justify-content:space-between;gap:var(--space-4);padding:7px 0;
  font-size:var(--fs-body-sm);background:var(--divider-dotted);background-position:left bottom}
.mspec div:last-child{background:none}
.mspec span{color:var(--dim);white-space:nowrap}
.mspec b{text-align:right;color:var(--ink);font-weight:700;font-variant-numeric:tabular-nums}

/* ── Reveal ──────────────────────────────────────────────────────────────── */
html{scroll-behavior:smooth}
.rv{opacity:0;transform:translateY(22px);
  transition:opacity var(--dur-reveal) var(--ease-out),transform var(--dur-reveal) var(--ease-out)}
.rv.in{opacity:1;transform:none}
/* glass cards over the factory footage rise a little further */
.factory-cards .card.rv{transform:translateY(34px)}
.factory-cards .card.rv.in{transform:none}

/* ── Drawer ──────────────────────────────────────────────────────────────── */
.scrim{position:fixed;inset:0;background:rgba(15,15,13,.55);opacity:0;pointer-events:none;
  transition:opacity var(--dur-slow) var(--ease-out);z-index:70;backdrop-filter:blur(3px)}
.scrim.on{opacity:1;pointer-events:auto}
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(32rem,100%);background:var(--paper-2);
  z-index:80;transform:translateX(100%);transition:transform var(--dur-slow) var(--ease-out);
  display:flex;flex-direction:column;box-shadow:var(--sh-3)}
.drawer.on{transform:none}
.drawer-hd{display:flex;align-items:center;gap:.8rem;padding:1.4rem 1.6rem;
  background:var(--paper-3);border-bottom:1px solid var(--line)}
.drawer-hd b{font-weight:var(--fw-semibold);font-size:var(--fs-h2);letter-spacing:var(--ls-tight)}
.x{margin-left:auto;width:2.4rem;height:2.4rem;border-radius:var(--pill);
  border:1px solid var(--line-2);display:grid;place-items:center;font-size:1rem;
  color:var(--dim);background:var(--paper-2)}
.x:hover{color:var(--ink);border-color:var(--dim)}
.drawer-bd{padding:1.5rem;overflow:auto;flex:1}
.tabs{display:flex;gap:0;border-bottom:1px solid var(--line);margin-bottom:1.6rem}
.tabs button{flex:1;padding:.75rem .5rem;font-size:.88rem;font-weight:700;color:var(--dim);
  border-bottom:3px solid transparent;margin-bottom:-2px}
.tabs button.on{color:var(--blue-primary);border-bottom-color:var(--blue-primary)}
label.f{display:block;margin-bottom:1.1rem}
/* FieldLabel is an overline. */
label.f>span{display:block;font-size:var(--fs-overline);font-weight:var(--fw-medium);
  letter-spacing:var(--ls-overline);text-transform:uppercase;color:var(--text-secondary);
  margin-bottom:var(--space-2)}
/* Input — Bingo!/components/forms/Input.jsx: 10/12 padding, 14px, 12px radius,
   focus = blue border + the 3px translucent ring. */
input[type=text],input[type=email],input[type=tel],textarea,select{width:100%;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-input);
  padding:10px 12px;font-size:var(--fs-body-sm);
  transition:border-color var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out)}
textarea{min-height:7rem;resize:vertical;line-height:1.55}
input:focus,textarea:focus,select:focus{outline:none;border-color:var(--blue-primary);
  box-shadow:var(--ring-focus)}
.seg{display:flex;gap:.5rem}
.seg button{flex:1;border:1.5px solid var(--border);border-radius:var(--radius-card);
  padding:12px 16px;background:var(--surface);text-align:left;font-size:var(--fs-body-sm);
  font-weight:var(--fw-bold);line-height:1.3}
.seg button small{display:block;font-weight:500;color:var(--dim);font-size:.75rem;margin-top:.2rem}
/* SegmentedToggle — selection is a tint fill plus a coloured border. */
.seg button.on{border-color:var(--blue-primary);background:var(--blue-tint);
  color:var(--blue-primary)}
.seg button.on small{color:var(--blue-primary)}
.msg{border-radius:var(--r);padding:.8rem .9rem;font-size:.86rem;font-weight:600;margin-bottom:1.1rem}
.msg-ok{background:var(--green-tint);color:var(--green)}
.msg-bad{background:var(--red-tint);color:var(--red)}
.recap{background:var(--paper);border:1px solid var(--line);border-radius:var(--r);padding:1rem;
  margin-bottom:1.2rem;font-size:.85rem}
.recap>b{display:block;font-weight:var(--fw-semibold);margin-bottom:.5rem;font-size:var(--fs-h3)}
.recap .r{display:flex;justify-content:space-between;gap:1rem;padding:.25rem 0}
.recap .r span{color:var(--dim)}
.recap .r b{text-align:right}
.recap .r-wide{display:block;color:var(--text-secondary);line-height:1.5;padding:7px 0;
  background:var(--divider-dotted);background-position:left top;margin-top:.4rem}

/* ── Footer ──────────────────────────────────────────────────────────────── */
footer{background:var(--coal);color:var(--on-coal-mid);padding:4rem 0 2.4rem;font-size:.92rem}
footer .cols{display:grid;grid-template-columns:1.7fr repeat(3,1fr);gap:2.4rem}
footer h4{color:var(--on-coal);font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;
  margin-bottom:1rem}
footer a:hover{color:var(--on-coal)}
footer ul{list-style:none;margin:0;padding:0;display:grid;gap:.55rem}
footer .lockup{margin-bottom:1rem}
footer .fine{margin-top:3rem;padding-top:1.4rem;border-top:1px solid var(--coal-line);
  display:flex;gap:1rem;flex-wrap:wrap;font-size:.8rem;color:var(--on-coal-dim)}
footer .fine span{margin-left:auto}
footer .fine span:first-child{margin-left:0}

/* ── Narrow ──────────────────────────────────────────────────────────────── */
/* The Account link that only exists inside the burger menu — see index.html. */
.on-menu{display:none}
@media (max-width:1060px){
  nav.main{display:none}
  .burger{display:flex}
  /* margin-left:.4rem above is what left the open panel 6px short of the left
     edge, with the page showing through beside it (El, 2026-09-03 — mobile
     spacing, menu area). The panel is a sheet under the bar: full bleed, its
     own hairline, and nothing peeking out at either side. */
  nav.main.open{display:flex;position:absolute;top:100%;left:0;right:0;margin:0;
    background:var(--paper-2);border-top:1px solid var(--line);border-bottom:1px solid var(--line);
    flex-direction:column;padding:.35rem 0 .5rem;gap:0;box-shadow:var(--sh-2)}
  /* 48px tap targets, the wrap's own gutter, and a rule between them so the
     list reads as a menu rather than three floating words */
  nav.main.open a{padding:.8rem clamp(1.2rem,4vw,2.6rem);font-size:1rem;min-height:2.6rem;
    display:flex;align-items:center;border-bottom:1px solid var(--line-2)}
  nav.main.open a:last-child{border-bottom:none}
  nav.main.open a::after{display:none}
  nav.main.open a:active{background:var(--paper-3,rgba(29,27,22,.04))}
  .on-menu{display:none}
}
@media (max-width:760px){
  /* below here .bar-end's Account button is gone, so the menu carries it */
  nav.main.open .on-menu{display:flex}
}
@media (max-width:960px){
  .hero-grid{grid-template-columns:minmax(0,1fr)}
  .g-4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .g-3{grid-template-columns:repeat(2,minmax(0,1fr))}
  footer .cols{grid-template-columns:1fr 1fr}
}
@media (max-width:760px){
  body{font-size:16px}
  .bar-end .btn-hide{display:none}
  .on-wide{display:none}
  .on-narrow{display:inline}
  .lockup img{height:1.65rem}
  /* El, 4 Sep: "make usa show on mobile too". It was hidden here only for
     room — the header carries the wordmark, a Design button and the burger on
     a 375px screen. So it comes back TIGHTENED rather than at desktop size:
     narrower tracking, less padding, one step down. Below 360px it goes away
     again, because at that width something has to and the wordmark cannot. */
  .lockup i{display:flex;font-size:.5rem;letter-spacing:.09em;padding-left:.5rem}
  header.bar .wrap{gap:.6rem;min-height:4.1rem}
  .tagline .wrap{min-height:2.2rem;font-size:.71rem}
  .tagline .t-mid,.tagline .t-end{display:none}
  .g-2,.g-3,.g-4{grid-template-columns:minmax(0,1fr)}
  footer .cols{grid-template-columns:1fr}
}

/* The line under the studio: still on the dark, so the studio reads as one
   block of making before the page turns to paper and starts talking. */
.studio-strip{background:var(--paper);border-top:1px solid var(--line);color:var(--dim);
  font-size:.88rem}
.studio-strip .wrap{display:flex;gap:1.5rem;align-items:baseline;padding-top:1.1rem;
  padding-bottom:1.1rem;flex-wrap:wrap}
.studio-strip b{color:var(--ink);font-weight:700}
.studio-strip .t-end{margin-left:auto;font-size:.82rem;color:var(--faint)}
@media (max-width:760px){ .studio-strip .t-end{display:none} }

/* ── The cloth, photographed ──────────────────────────────────────────────
   A render sells a configurator; a photograph sells knitwear. These shots are
   the real garments off our own machines, and they happen to be lit on a ground
   the same warmth as the page — so the picture sits IN the paper rather than on
   a card on top of it. No frame, no shadow, no rounded corner. */
/* El, 4 Sep: "make the graphic is the cotton pannel the same size as the other
   pannels and make the image block larger than the text block". So: the same
   min-height the factory and industries bands use — literally the same value,
   so the three cannot drift — and the picture takes 1.55 of the row against
   the copy's 1. The columns STRETCH now rather than centring, so the photo
   fills the panel's full height and the copy centres itself inside it. */
/* NO min-height. It carried min(92vh,58rem) from El's 4 Sep "same size as the
   other pannels", which forced 828px onto a panel whose tallest column is
   643px — 101px of dead white above the blanket and 101px below its caption.
   El, 8 Sep: "still too thick of a band here". The band cannot be both the
   factory's height and free of that white: the picture is width-constrained
   (747 wide is 598 tall at its own ratio) and filling the extra height means
   cropping off the lettering down its edges, which is the part worth showing.
   So the panel is its content now, and the later instruction wins. */
.cloth{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  gap:clamp(1.6rem,4vw,4rem);align-items:stretch;padding:0;background:var(--paper-2)}
/* CONTAIN, not cover. The piece is photographed whole on a near-white ground
   and its own edges carry the lettering — "A Stag at Sharkey's" up one side,
   "THE CLEVELAND MUSEUM OF ART" down the other. Covering a near-square column
   with a landscape photo crops exactly those two edges off, which is the part
   worth showing. The ground it is lit on matches --paper-2, so the letterbox
   reads as the page rather than as a gap. */
.cloth-fig{margin:0;display:flex;flex-direction:column;justify-content:center;
  background:var(--paper-2)}
/* El, 8 Sep: the caption sat miles under the blanket. The img was `flex:1`, so
   its BOX absorbed all the column's spare height — 747x798 for a picture that
   only draws 747x598 — and `contain` centred the picture inside it, leaving
   100px of letterbox between the bottom of the blanket and a caption that is
   positioned under the BOX, not under the picture. `flex:0 1 auto` with
   height:auto makes the box the picture's own ratio, so the caption sits right
   beneath it and the figure's justify-content centres the pair. max-height +
   contain stay as the fallback for a viewport too short for the full ratio. */
.cloth-fig img{flex:0 1 auto;min-height:0;width:100%;height:auto;max-height:100%;
  object-fit:contain;object-position:center;display:block}
/* Ink on paper, and IN THE FLOW. It used to be white type on a dark gradient
   absolutely positioned over the picture, which worked while the photo was a
   dark garment shot that filled its box. Against a contained photo on a light
   ground it became grey type sitting on the middle of a black blanket —
   exactly what it did on a phone, where there is no letterbox for it to sit
   in. Below the picture it cannot land on top of it at any size. */
.cloth-fig figcaption{flex:none;
  padding:.7rem clamp(1rem,2vw,1.4rem) 0;font-size:.7rem;letter-spacing:.06em;
  font-weight:600;color:var(--text-secondary);text-align:center}
.cloth-say{padding:clamp(2.4rem,5vw,4.5rem) clamp(1.2rem,4vw,3.4rem) clamp(2.4rem,5vw,4.5rem) 0;
  max-width:38em;align-self:center}
.cloth-say h2{margin:.5rem 0 1.1rem}
.cloth-say em{font-style:normal;color:var(--blue-primary)}
/* Two by two. With four of these (El, 4 Sep) a wrapping flex row broke 3 + 1
   in this column and left "100%" stranded on a line of its own, which reads as
   an accident rather than a layout. A fixed pair of columns is predictable at
   every width the copy column takes, mobile included. */
.cloth-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:1.05rem 2rem;margin:2rem 0}
.cloth-facts div{display:grid;gap:.1rem}
.cloth-facts b{font-weight:var(--fw-bold);font-size:var(--fs-kpi);
  letter-spacing:var(--ls-tight);line-height:var(--lh-tight);
  font-variant-numeric:tabular-nums lining-nums}
/* El, 8 Sep: "spacing of the subtext here needs help - it should be tighter".
   The label was capped at 11em — 137px inside a 199px cell — so "cotton,
   graphic included" wrapped to two lines with 62px of the cell going unused,
   and the wrap is what made the block look airy. The cap is the cell now, so
   it sets on one line where there is room, and the leading is tighter for the
   narrower cells on a phone where it still has to wrap. */
.cloth-facts span{font-size:.78rem;color:var(--dim);max-width:none;line-height:1.25}

/* Product photography on the blank cards. */
.card-shot{display:block;aspect-ratio:4/5;object-fit:cover;
  margin:calc(var(--pad-card)*-1) calc(var(--pad-card)*-1) var(--space-4);
  width:calc(100% + var(--pad-card)*2);
  border-radius:var(--radius-card) var(--radius-card) 0 0;background:var(--muted)}
a.card:hover .card-shot,button.card:hover .card-shot{filter:saturate(1.06)}

/* The floor, moving if the connection and the device can take it. */
/* ── The factory, immersive ─────────────────────────────────────────────────
   El: "i want the video showing wide screen in the back." The floor footage is
   the whole section — full-bleed, edge to edge, most of a screen tall — and
   the copy and the three cards sit on a gradient over it, glass over coal so
   the room stays visible through them. */
.factory{position:relative;isolation:isolate;overflow:hidden;background:var(--coal);color:var(--on-coal);
  min-height:min(92vh,58rem);display:flex;align-items:flex-end}
.factory-bg{position:absolute;inset:0;z-index:-2}
.factory-bg img,.factory-bg video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  /* a slow push-in, back and forth, so the room never sits still */
  transform-origin:50% 42%;animation:kb 26s var(--ease-in-out) infinite alternate}
@keyframes kb{from{transform:scale(1)}to{transform:scale(1.09)}}
/* THE STILL SITS ON TOP; THE VIDEO IS NEVER HIDDEN.
   It used to be the other way round — video at opacity 0 until it started
   playing — and on iOS that is a deadlock waiting to happen: WebKit can refuse
   or suspend playback for a media element it does not consider visibly
   rendered, and this one was transparent inside a z-index:-2 layer until
   playback began. It could not begin, so it never became visible, so it could
   not begin. Now the video is fully rendered from the moment it is inserted
   and the photograph covers it until there is moving footage to show, which
   also means a stalled or refused video is never what is on screen. */
.factory-bg img{z-index:1;transition:opacity 900ms var(--ease-out)}
.factory-bg img.gone{opacity:0}
.factory-bg video{z-index:0;opacity:1}
.factory-scrim{position:absolute;inset:0;z-index:-1;
  background:linear-gradient(to top,rgba(15,15,13,.94) 0%,rgba(15,15,13,.66) 40%,rgba(15,15,13,.34) 72%,rgba(15,15,13,.16) 100%)}
.factory-in{width:100%;padding-top:clamp(7rem,16vh,11rem);padding-bottom:clamp(2rem,5vw,4rem)}
.factory-copy{max-width:40em;margin-bottom:clamp(2rem,4vw,3rem)}
.factory-copy{text-shadow:0 1px 2px rgba(0,0,0,.35),0 8px 28px rgba(0,0,0,.35)}
.factory-copy .eyebrow{color:#fff;opacity:.85}
.factory-copy h2{color:#fff;margin:.4rem 0 .9rem;font-size:clamp(2rem,4.4vw,3.6rem)}
.factory-copy .lede{color:#fff;opacity:.86}
.factory-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem}
.factory-cards .card{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.14);color:#fff;
  backdrop-filter:blur(16px) saturate(1.2);-webkit-backdrop-filter:blur(16px) saturate(1.2)}
.factory-cards .card h3{color:#fff}
.factory-cards .card p{color:var(--on-coal-mid)}
@media (max-width:900px){
  .factory{min-height:0}
  .factory-cards{grid-template-columns:minmax(0,1fr)}
  .factory-in{padding-top:clamp(5rem,30vw,8rem)}
}

@media (max-width:900px){
  .cloth{grid-template-columns:minmax(0,1fr)}
  .cloth-fig img{max-height:32rem}
  .cloth-fig figcaption{text-align:left;padding-left:clamp(1.2rem,4vw,2.6rem);
    padding-right:clamp(1.2rem,4vw,2.6rem)}
  .cloth-say{padding:2rem clamp(1.2rem,4vw,2.6rem) 3rem}
}

/* Below 360px the strapline goes; the wordmark and the way into the studio do
   not. (See the note beside .lockup i in the ≤760 block.) */
@media (max-width:359px){ .lockup i{display:none} }

/* The industries band ran a reduced push-in (kb-soft) while its photo was a
   1331-wide PORTRAIT shot: cropped into a wide band that was already a ~2x
   upscale, and the shared 9% zoom on top of it was what read as blur. El
   replaced it on 4 Sep with a 2000-wide LANDSCAPE frame, which DOWNSCALES at
   1280 and is a mild 1.28x on a retina screen — so the reason for the
   exception is gone and the band is back on the factory's own animation.
   One rule for both again. */

/* The tap that plays the floor when autoplay was refused. It is inserted by
   site.js ONLY after the video has failed to start on its own — Low Power Mode
   on iOS turns every autoplay down and no site can talk it round, so a real
   gesture is the only remaining route. Glass over the footage, like the cards. */
.reel-play{position:absolute;z-index:3;
  top:clamp(1rem,3vw,1.6rem);right:clamp(1.2rem,4vw,2.6rem);
  display:inline-flex;align-items:center;gap:.45rem;
  font-family:inherit;font-size:.8rem;font-weight:var(--fw-semibold);letter-spacing:.01em;
  color:#fff;background:rgba(15,15,13,.55);border:1px solid rgba(255,255,255,.28);
  border-radius:var(--radius-pill);padding:.52rem .95rem;cursor:pointer;
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  transition:var(--t-feedback)}
.reel-play:hover{background:rgba(15,15,13,.74)}
.reel-play:active{transform:scale(var(--press-scale))}
.reel-play span{font-size:.7em;line-height:1}
