/* ============================================================
   isaiah — design system
   One token set, shared by every page.

   Rules for whoever edits this next:
   1. Every space value comes from --s. Every size from --t.
      If you need a value that isn't on a scale, take the nearest one.
   2. Anything sitting over video or photography uses the --on-film /
      --scrim / --glass tokens. Never a raw white or a raw rgba().
   3. The page does not explain itself. Don't add a line that tells
      the visitor what something means.
   ============================================================ */

/* ============================================================
   TeX Gyre Heros — self-hosted, so non-Apple visitors get Helvetica
   LETTERFORMS rather than a different typeface entirely.

   Why this exists: Helvetica Neue is licensed by Monotype and cannot legally be
   served as a webfont. It IS installed on every Mac, iPhone and iPad, so calling
   it by name is free and legal — but Windows and Android have no copy. Without
   this, those visitors saw a completely different face.

   TeX Gyre Heros descends from Nimbus Sans, which was drawn from Helvetica, so
   the skeleton matches: horizontal terminals, the same R leg, the same
   proportions. Licensed under the GUST Font License, legally identical to the
   LaTeX Project Public License v1.3c — a free licence that permits
   redistribution. The licence text ships in fonts/ alongside it.

   Converted otf -> woff2 only. Not subset, not renamed, outlines untouched,
   which keeps us unambiguously inside what that licence allows.
   ~51 KB per weight, and only downloaded by browsers that actually need it.
   ============================================================ */
@font-face{
  font-family:"TeX Gyre Heros";
  src:url("fonts/texgyreheros-regular.woff2") format("woff2");
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"TeX Gyre Heros";
  src:url("fonts/texgyreheros-bold.woff2") format("woff2");
  font-weight:700; font-style:normal; font-display:swap;
}

:root{
  /* ---- paper & ink ---- */
  --paper:#f3f1ec;        --paper-rgb:243,241,236;
  --surface:#faf9f6;
  --ink:#33312e;          --ink-rgb:51,49,46;
  --ink-strong:#1a1815;
  /* was #8a857d — measured 3.25:1 on paper, 3.48:1 on surface. AA wants 4.5
     for anything under 18.66px, and --muted carries .label (12px),
     .cap (13px), .note (14px) and .spec dt (15.5px). #6f6a61 is the lightest
     value that clears it on BOTH backgrounds: 4.76 on paper, 5.10 on surface. */
  --muted:#6f6a61;
  --rule:rgba(var(--ink-rgb),.14);
  --rule-soft:rgba(var(--ink-rgb),.07);

  /* ---- over media ----
     everything that sits on top of film or photography lives here.
     before these existed there were 15 hardcoded colours in the sheet. */
  --film-bg:#14161a;
  --on-film:#ffffff;
  --on-film-rule:rgba(255,255,255,.4);   /* underline on the film */
  --on-film-shade:0 1px 10px rgba(0,0,0,.4); /* keeps white legible on any frame */
  --veil:rgba(8,10,13,.22);              /* over the shoot, before it plays */
  --scrim-core:rgba(8,10,13,.42);   /* behind the mark */
  --scrim-edge:rgba(8,10,13,.04);
  --scrim-top:rgba(8,10,13,.34);
  --scrim-foot:rgba(8,10,13,.32);
  --glass:rgba(18,20,24,.34);
  --glass-edge:rgba(255,255,255,.72);
  --glass-solid:rgba(8,10,13,.7);        /* reduced-transparency fallback */

  /* ---- space, 8pt ---- */
  --s1:4px;  --s2:8px;   --s3:12px;  --s4:16px; --s5:24px; --s6:32px;
  --s7:48px; --s8:64px;  --s9:96px;  --s10:128px; --s11:160px;

  /* ---- type ----
     Anything a buyer has to READ — the fit, the shipping terms, the spec rows,
     the disclosure titles — is set at body size (--t-b). --t-m is for the size
     buttons and the note under the buy button; --t-s for navigation words and
     captions. Nothing that carries meaning sits under 13px. The small register
     came up from 12.5 for the same reason the easier-reading switch below
     exists: at 12.5 the nav, the footer and the note were the first things a
     dyslexic reader would have struggled with. */
  --t-xs:12px; --t-s:13px; --t-m:14px; --t-b:15.5px;
  --t-l:19px;  --t-xl:26px;  --t-2xl:36px; --t-3xl:54px;

  /* ---- fluid display steps ----
     These replace bare clamp(--t-xl, Nvw, --t-3xl) constructions. The problem
     with those: at 390px, 4vw is 15.6px — BELOW the 26px floor — so every
     display size sat on its minimum and the whole page collapsed to one size.
     On a phone the landing title, the product name and the onward links were
     all exactly 26px: three levels of hierarchy, rendered identically.
     Each step below is solved to hit its phone size at 390px and its desktop
     size at 1440px, and to interpolate for real in between. */
  --f-display:clamp(32px, 23.829px + 2.0952vw, 54px);  /* page titles      */
  --f-title:  clamp(27px, 23.657px + 0.8571vw, 36px);  /* the product name */
  --f-onward: clamp(22px, 16.800px + 1.3333vw, 36px);  /* onward links     */

  /* tracking is size-specific — one letter-spacing for everything is
     wrong somewhere by definition. Negative tracking read as clenched;
     Literata is a wide face, and tight tracking on a serif is half of what
     reads as formal, so display sits almost at zero. */
  --tr-display:-.004em; --tr-xl:-.003em; --tr-l:0em;
  --tr-body:0em; --tr-small:.008em; --tr-label:.14em;
  --tr-digits:.06em;   /* the size buttons — digits in a box want a little air */

  /* Literata. Chosen over EB Garamond, Newsreader, Spectral, Crimson and Source
     Serif because it is the only one of the six not designed for books — it was
     drawn for screen reading, so it has low stroke contrast and sturdy, upright
     forms. It reads solid rather than literary. Variable optical size axis, so
     it thickens slightly at small sizes and refines at display sizes on its own.
     Only the 400 weight is loaded: nothing on the site sets the serif heavier. */
  --serif:"Literata",Georgia,"Times New Roman",serif;
  /* Helvetica Neue is licensed — it cannot legally be SERVED as a webfont, but
     it is installed on every Mac, iPhone and iPad, so calling it by name costs
     nothing and breaks no licence. Everyone else falls through to TeX Gyre
     Heros above — same Helvetica skeleton, so the site looks like itself on
     Windows and Android instead of looking like a different brand.
     ORDER MATTERS: Heros must come BEFORE plain "Helvetica". Windows ships a
     font-substitution table that quietly answers "Helvetica" with Arial, and
     browsers honour it — with Helvetica second, the webfont was never reached
     on Windows and every Windows visitor got Arial. */
  --sans:"Helvetica Neue","TeX Gyre Heros",Helvetica,Arial,sans-serif;

  /* ---- motion ---- */
  --ease:cubic-bezier(.22,.72,.26,1);
  --fast:.28s; --mid:.45s; --slow:.9s;

  --gutter:clamp(var(--s4),5vw,var(--s8));
  --bar:clamp(64px,7vw,84px);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;
  scroll-padding-top:calc(env(safe-area-inset-top,0px) + var(--bar) + var(--s5))}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;color:var(--ink);
  background:var(--paper);
  font-family:var(--sans);font-weight:400;
  font-size:var(--t-b);line-height:1.62;letter-spacing:var(--tr-body);
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
p{margin:0}
button{font:inherit;color:inherit}
:focus-visible{outline:1.5px solid var(--ink-strong);outline-offset:3px}
/* the header repeats on all four pages, so there has to be a way past it
   (WCAG 2.4.1). Off-screen until it is focused, then it arrives on paper —
   it must not be white-on-film, because on the landing page it sits on video. */
.skip{position:absolute;left:var(--gutter);top:var(--s2);z-index:60;
  display:inline-flex;align-items:center;min-height:44px;
  padding:var(--s2) var(--s4);background:var(--paper);color:var(--ink-strong);
  font-family:var(--sans);font-size:var(--t-s);letter-spacing:var(--tr-small);
  text-decoration:none;border:1px solid var(--rule);
  transform:translateY(-300%);transition:transform var(--fast) var(--ease)}
.skip:focus{transform:none}
main:focus{outline:none}   /* tabindex="-1" target, not a real focus stop */
/* the mark sits over film at the top of the landing, so an ink ring there is
   both invisible and ugly. Keyboard users still get a ring; it just matches
   whatever it is sitting on. */
.brand:focus-visible{outline-color:var(--on-film);outline-offset:6px}
.bar.solid .brand:focus-visible{outline-color:var(--ink-strong)}
/* same problem, same fix: these three all sit on video at some point */
.bar a.nv:focus-visible,.film-route a:focus-visible,.play:focus-visible{
  outline-color:var(--on-film)}
.bar.solid a.nv:focus-visible{outline-color:var(--ink-strong)}

/* ---- 44px hit areas ----
   WCAG 2.5.5 and Apple's HIG both want 44px. These are 11-12.5px words with a
   1px underline, so the box cannot grow without dragging the underline away
   from the text. An invisible centred ::after carries the target instead:
   nothing moves on screen, the tappable area is 44px tall. */
.bar a.nv,.film-route a,footer .flinks a,footer .flinks .easy,.crumb{position:relative}
.bar a.nv::after,.film-route a::after,footer .flinks a::after,footer .flinks .easy::after,.crumb::after{
  content:"";position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);height:44px;width:max(100%,44px)}
/* centred, not left-anchored: a word narrower than 44px ("Film") used to grow
   its target to the right only, past the gutter, and that invisible 19px was
   enough to register as horizontal overflow on a 360px phone. */

/* Headings are the only serif on the site apart from the eight lines. One
   weight, 400 — the optical-size axis does the refining, not a heavier cut. */
h1,h2,h3{margin:0;font-family:var(--serif);font-weight:400;line-height:1.24;
  letter-spacing:var(--tr-xl);text-wrap:balance;font-optical-sizing:auto}
/* ---- the two registers ----
   Tracked capitals are for LABELS only: the collection line above the product
   name, and "Numbered" beside the price. Things you can click — the routes on
   the film, the buy button, the dock — are sentence case, like the nav and the
   footer. Tracked-caps buttons are the old luxury-minimal reflex and were a
   good part of what kept reading as formal. */
.label{font-family:var(--sans);font-size:var(--t-xs);letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--muted);font-weight:500}

/* ============================================================
   header
   background and blur are driven continuously by --p (0…1) from
   site.js, so it materialises with the scroll instead of snapping
   at a threshold. Colour flips once, on a long ease, because text
   legibility is a discrete problem, not a gradual one.
   ============================================================ */
.bar{position:sticky;top:0;z-index:50;height:var(--bar);
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--s4);padding:0 var(--gutter);--p:1}
.bar::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:rgba(var(--paper-rgb),.88);
  backdrop-filter:saturate(1.4) blur(14px);
  -webkit-backdrop-filter:saturate(1.4) blur(14px);
  border-bottom:1px solid var(--rule-soft);
  opacity:var(--p)}
.bar > *{position:relative;z-index:1}

.brand{display:flex;align-items:center;gap:clamp(var(--s2),1.2vw,var(--s4));
  text-decoration:none;color:inherit}
.sw{position:relative;display:block}
.sw img{display:block;transition:opacity var(--mid) var(--ease)}
.sw img.ink{position:absolute;inset:0;opacity:var(--p)}
.sw img.lit{opacity:calc(1 - var(--p))}
.brand img.h{height:clamp(42px,4.4vw,56px);width:auto}
.brand img.w{height:clamp(18px,1.9vw,24px);width:auto;margin-top:4px}

.bar nav{display:flex;gap:var(--s5);align-items:center}
.bar a.nv{color:var(--on-film);text-decoration:none;font-family:var(--sans);
  font-size:var(--t-s);letter-spacing:var(--tr-small);
  padding-bottom:2px;border-bottom:1px solid transparent;
  text-shadow:var(--on-film-shade);
  transition:color .6s var(--ease),border-color var(--fast),text-shadow .6s var(--ease)}
.bar.solid a.nv{color:var(--ink);text-shadow:none}
.bar a.nv:hover{border-bottom-color:currentColor}
.bar a.nv[aria-current="page"]{border-bottom-color:currentColor}
/* the route to buy is never just another word in a row */
.bar a.nv.primary{font-weight:500;border-bottom-color:currentColor}

/* ============================================================
   film
   ============================================================ */
.film{position:relative;width:100%;height:min(88svh,940px);min-height:400px;
  margin-top:calc(var(--bar) * -1);overflow:hidden;background:var(--film-bg)}
.film video,.film .still{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
.film-scrim{position:absolute;inset:0;pointer-events:none;background:
  radial-gradient(ellipse 74% 64% at 50% 48%,var(--scrim-core),var(--scrim-edge) 74%),
  linear-gradient(to bottom,var(--scrim-top),transparent 20%,transparent 68%,var(--scrim-foot))}
.film-mark{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:clamp(150px,17vw,260px)}
.film-mark img{width:100%;height:auto;display:block;opacity:0;
  animation:markIn 1.9s .45s var(--ease) forwards}
@keyframes markIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
/* Centring lives on the container, the animation lives on the child.
   markIn ends on `transform:none`, so animating the same element that carries
   translateX(-50%) silently wipes the centring out. Never put both on one node. */
/* Two routes, not one. The only above-the-fold link used to be Collection,
   which sends people away from buying — on a site whose whole job is
   pre-orders. Pre-order leads and carries the rule under it; Collection sits
   beside it for anyone not ready. Centring stays on the container, the
   animation stays on the children. */
.film-route{position:absolute;left:50%;bottom:clamp(var(--s7),9vh,var(--s9));
  transform:translateX(-50%);display:flex;gap:clamp(var(--s5),4vw,var(--s7));
  align-items:baseline;white-space:nowrap}
.film-route a{display:inline-block;color:var(--on-film);text-decoration:none;
  opacity:0;animation:markIn 1.9s 1.1s var(--ease) forwards;
  font-family:var(--sans);font-size:var(--t-b);letter-spacing:var(--tr-body);
  padding-bottom:var(--s2);
  border-bottom:1px solid var(--on-film-rule);
  text-shadow:var(--on-film-shade);transition:border-color var(--fast)}
.film-route a:hover{border-bottom-color:var(--on-film)}
/* the route to buy is never just another word in a row — same rule as the nav */
.film-route a.lead{font-weight:500;border-bottom-color:var(--on-film)}
.film-route a:nth-child(2){animation-delay:1.28s}

/* ============================================================
   page furniture
   ============================================================ */
.wrap{max-width:1240px;margin:0 auto}
.band{padding:var(--s10) var(--gutter);border-top:1px solid var(--rule-soft)}
.band:first-of-type{border-top:0}
/* centred, because the mark and the route above it are centred — the page
   should not change axis halfway down the first screen */
.lede{padding:var(--s8) var(--gutter) var(--s9);text-align:center}
.lede-line{font-family:var(--serif);font-weight:400;
  font-size:var(--f-display);
  line-height:1.2;max-width:22ch;margin:0 auto;
  color:var(--ink-strong);letter-spacing:var(--tr-display)}
.lede .sub{margin:var(--s4) auto 0}
/* one route onward, at the foot of every page */
.onward{display:flex;flex-wrap:wrap;gap:var(--s5) var(--s8);
  align-items:baseline;justify-content:space-between}
.onward a{font-family:var(--serif);font-weight:400;
  font-size:var(--f-onward);
  letter-spacing:var(--tr-display);color:var(--ink-strong);text-decoration:none;
  border-bottom:1px solid var(--rule);padding-bottom:var(--s2);
  transition:border-color var(--fast)}
.onward a:hover{border-bottom-color:var(--ink-strong)}

/* ============================================================
   product
   ============================================================ */
.product{display:grid;grid-template-columns:1fr;gap:var(--s7);
  padding:var(--s7) var(--gutter) var(--s10);align-items:start}
@media(min-width:900px){
  .product{grid-template-columns:minmax(0,1.15fr) minmax(330px,.85fr);
    gap:clamp(var(--s7),6vw,var(--s9))}
  .col-detail{position:sticky;top:calc(var(--bar) + var(--s6))}
}
.stage{position:relative;width:100%;aspect-ratio:4/5;background:var(--surface);
  overflow:hidden;touch-action:pan-y;cursor:grab;user-select:none;-webkit-user-select:none}
.stage.dragging{cursor:grabbing}
.track{display:flex;height:100%;will-change:transform}
.slide{flex:0 0 100%;height:100%}
.slide img{width:100%;height:100%;object-fit:cover;pointer-events:none;-webkit-user-drag:none}
.rail{display:flex;gap:var(--s2);margin-top:var(--s2)}
.rail button{flex:1;padding:0;border:1px solid var(--rule-soft);background:var(--surface);
  cursor:pointer;overflow:hidden;aspect-ratio:1;transition:border-color var(--fast);
  will-change:transform}
.rail button img{width:100%;height:100%;object-fit:cover}
.rail button[aria-current="true"]{border-color:var(--ink)}
/* :hover and [aria-current] had identical specificity, and :hover came
   second — so pointing at the selected thumb faded its border out. */
.rail button:hover:not([aria-current="true"]){border-color:var(--muted)}

.name{font-size:var(--f-title);letter-spacing:var(--tr-display);
  margin-bottom:var(--s5)}
/* the collection line above the product name. Was four inline style attributes. */
.crumb{color:inherit;text-decoration:none;border-bottom:1px solid var(--rule);
  transition:border-color var(--fast)}
.crumb:hover{border-bottom-color:var(--ink)}
.label-crumb{margin-bottom:var(--s3)}
/* One line of the poem sits under the name, as an epigraph. It is set exactly
   as the poem is set on the collection page (see .wants below) — the same
   words used to appear here in a different face at a different size, which
   is the kind of seam that makes a site feel assembled rather than designed.
   Kept short so the price is in the first screen on a phone. */
.frag{list-style:none;margin:0 0 var(--s6);padding:0;max-width:36ch}

.price-row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s4);
  padding-bottom:var(--s4);border-bottom:1px solid var(--rule-soft)}
.price{font-family:var(--serif);font-size:var(--t-xl);letter-spacing:var(--tr-xl)}

.sizes{display:grid;grid-template-columns:repeat(auto-fit,minmax(58px,1fr));
  gap:var(--s2);margin:var(--s5) 0 0}
.size{padding:var(--s3) var(--s2);background:transparent;color:var(--ink);
  border:1px solid var(--rule);font-family:var(--sans);font-size:var(--t-m);
  letter-spacing:var(--tr-digits);cursor:pointer;will-change:transform;
  transition:border-color var(--fast) ease,background var(--fast) ease,color var(--fast) ease}
.size:hover:not(:disabled){border-color:var(--ink)}
.size[aria-pressed="true"]{background:var(--ink-strong);color:var(--paper);
  border-color:var(--ink-strong)}
/* a sold-out size can still be chosen — the button then offers the waiting
   list — so it is struck through and quiet, not disabled */
.size.out{color:var(--muted);border-color:var(--rule-soft);
  text-decoration:line-through;text-decoration-thickness:1px}
.size.out:hover{border-color:var(--muted)}
.size.out[aria-pressed="true"]{background:var(--muted);border-color:var(--muted);color:var(--paper)}
/* what the chosen size means, the moment it is chosen — one line, in ink */
.fits{margin:var(--s3) 0 0;font-family:var(--sans);font-size:var(--t-m);letter-spacing:var(--tr-small);
  color:var(--ink)}
.fits[hidden]{display:none}
/* the question beside the sizes, for anyone who would rather ask than guess */
.ask{margin:var(--s3) 0 0;font-family:var(--sans);font-size:var(--t-m);letter-spacing:var(--tr-small)}
.fits:not([hidden]) + .ask{margin-top:var(--s1)}
.ask a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--rule);
  padding-bottom:1px;transition:border-color var(--fast)}
.ask a:hover{border-bottom-color:var(--ink)}

.buy{width:100%;margin-top:var(--s5);padding:var(--s4) var(--s5);
  background:var(--ink-strong);color:var(--paper);border:1px solid var(--ink-strong);
  font-family:var(--sans);font-size:var(--t-b);letter-spacing:var(--tr-small);
  font-weight:500;cursor:pointer;will-change:transform;
  transition:background var(--fast) ease,border-color var(--fast) ease}
.buy:hover:not(:disabled){background:var(--ink);border-color:var(--ink)}
.buy:disabled{background:transparent;color:var(--muted);border-color:var(--rule);
  cursor:not-allowed}
.note{font-family:var(--sans);font-size:var(--t-m);color:var(--muted);
  margin-top:var(--s3);line-height:1.5;letter-spacing:var(--tr-small)}
/* "Ships from 31 October. Returns within 14 days." — the two questions
   everyone has, answered before they tap. In ink: it is an answer, not a footnote. */
.note.when{color:var(--ink)}
.note + .note{margin-top:var(--s1)}

.discs{margin-top:var(--s7)}
.disc{border-top:1px solid var(--rule-soft)}
.disc:last-of-type{border-bottom:1px solid var(--rule-soft)}
.disc-t{width:100%;display:flex;align-items:center;justify-content:space-between;
  gap:var(--s4);padding:var(--s4) 0;background:none;border:0;cursor:pointer;
  text-align:left;font-family:var(--sans);font-size:var(--t-b);letter-spacing:var(--tr-small)}
.disc-t .pm{position:relative;width:11px;height:11px;flex:none}
.disc-t .pm::before,.disc-t .pm::after{content:"";position:absolute;background:var(--ink);
  left:50%;top:50%;transform:translate(-50%,-50%)}
.disc-t .pm::before{width:11px;height:1px}
.disc-t .pm::after{width:1px;height:11px;transition:opacity var(--fast) ease}
.disc-t[aria-expanded="true"] .pm::after{opacity:0}
/* JS springs this open. Without JS there is nothing to open it, so the
   fabric, the fit and the shipping terms were simply unreachable. */
.disc-p{overflow:hidden;height:0}
html.no-js .disc-p{height:auto;overflow:visible}
html.no-js .disc-t .pm{display:none}
.disc-in{padding:0 0 var(--s5)}
.disc-in dl{margin:0}
.disc-in p{font-family:var(--sans);font-size:var(--t-b);color:var(--ink);
  max-width:40ch;margin-bottom:var(--s3)}
.disc-in p:last-child{margin-bottom:0}
.spec{display:flex;justify-content:space-between;gap:var(--s4);
  padding:var(--s2) 0;border-bottom:1px solid var(--rule-soft);
  font-family:var(--sans);font-size:var(--t-b)}
.spec:last-child{border-bottom:0}
.spec dt{color:var(--muted);margin:0;letter-spacing:var(--tr-small)}
.spec dd{margin:0;text-align:right}
/* a row with nothing to say is removed by site.js, not shown with a dash.
   display:flex above would otherwise beat the hidden attribute. */
.spec[hidden]{display:none}
.rates{margin:var(--s4) 0 var(--s4)}
.rates[hidden]{display:none}
/* measurements: a small table of numbers, set like the spec rows — one rule
   under each line, figures ranged right, tabular so the columns hold. */
.measure{width:auto;border-collapse:collapse;margin:var(--s4) 0 0;
  font-family:var(--sans);font-size:var(--t-m);letter-spacing:var(--tr-small);
  font-variant-numeric:tabular-nums}   /* width:auto — the figures sit beside the size, not at the far edge */
.measure[hidden]{display:none}
.measure caption{text-align:left;color:var(--muted);padding:0 0 var(--s2);caption-side:top;white-space:nowrap}
.measure th,.measure td{padding:var(--s2) 0;border-bottom:1px solid var(--rule-soft);
  font-weight:400;text-align:left;vertical-align:baseline}
.measure th.n,.measure td.n{text-align:right;padding-left:var(--s6)}
.measure thead th{color:var(--muted)}
.measure tbody th{white-space:nowrap}
.measure tr:last-child th,.measure tr:last-child td{border-bottom:0}
.model{margin-top:var(--s3);font-family:var(--sans);font-size:var(--t-m);color:var(--muted);
  letter-spacing:var(--tr-small)}
.model[hidden]{display:none}

/* the dock — on a phone the buy control leaves the screen as soon as you
   read the detail, so it comes back as a bar instead of making you scroll up */
.dock{position:fixed;left:0;right:0;bottom:0;z-index:40;
  display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  padding:var(--s3) var(--gutter);
  padding-bottom:calc(var(--s3) + env(safe-area-inset-bottom,0px));
  background:rgba(var(--paper-rgb),.93);
  backdrop-filter:saturate(1.4) blur(14px);-webkit-backdrop-filter:saturate(1.4) blur(14px);
  border-top:1px solid var(--rule-soft);
  transform:translateY(110%);visibility:hidden;
  transition:transform .5s var(--ease),visibility .5s}
/* translateY alone left it focusable and readable by screen readers while it
   sat off the bottom of the screen. visibility takes it out of the tree too. */
.dock.up{transform:none;visibility:visible}
.dock .p{font-family:var(--serif);font-size:var(--t-l);letter-spacing:var(--tr-l)}
.dock button{padding:var(--s3) var(--s6);background:var(--ink-strong);color:var(--paper);
  border:0;font-family:var(--sans);font-size:var(--t-b);letter-spacing:var(--tr-small);
  font-weight:500;cursor:pointer;will-change:transform}
@media(min-width:900px){.dock{display:none}}
@media (prefers-reduced-transparency:reduce){
  .dock{background:var(--paper);backdrop-filter:none;-webkit-backdrop-filter:none}
}

/* ============================================================
   the collection note
   ============================================================ */
/* one column, one measure, one rhythm — it reads as a piece of writing
   rather than lines dropped into a layout */
.story{max-width:38rem;margin:0 auto}
/* every inner page opens the same way: one serif title at display size.
   The collection and the film both use this; the product uses .name because
   it sits in a column beside the photographs. */
.page-head{font-size:var(--f-display);
  letter-spacing:var(--tr-display);margin-bottom:var(--s6)}
.story-open p{font-family:var(--sans);font-weight:400;font-size:var(--t-l);
  line-height:1.58;letter-spacing:var(--tr-body);color:var(--ink);margin-bottom:var(--s5)}
.story-open p:last-child{margin-bottom:0}

/* ---- the eight lines, set like a poem in a collected edition ----
   They used to be the largest text on the page after the heading, which made
   them shout. A poem in a book is set at text size, in a narrow measure, in
   the book's serif, with stanzas separated by a modest space and a lot of
   quiet around the whole thing. That is what this is now: smaller than the
   prose above it, not bigger; Literata rather than the sans; ~36 characters
   wide; verse leading rather than prose leading. */
.wants{list-style:none;margin:var(--s9) 0 0;padding:0;max-width:36ch}
/* .frag li is the one line quoted on the product page — same setting, always */
.wants li,.frag li{font-family:var(--serif);font-weight:400;
  font-size:var(--t-b);line-height:1.5;
  letter-spacing:0;color:var(--ink);margin-bottom:var(--s4)}
.frag li:last-child{margin-bottom:0}
/* the last line is the ending; one stanza break before it, no more */
.wants li:last-child{margin-bottom:0;margin-top:var(--s5)}
/* This used to be a list of abstract nouns, and 14px muted was right for
   that — it was metadata. It is now the sign-off of a letter to three people,
   the most personal line on the site. It gets the same weight as the letter. */
.dedication{margin-top:var(--s9);padding-top:var(--s6);
  border-top:1px solid var(--rule-soft);
  font-family:var(--sans);font-size:var(--t-l);line-height:1.58;
  color:var(--ink-strong);max-width:34ch}

/* ============================================================
   player
   ============================================================ */
.player{position:relative;width:100%;aspect-ratio:16/9;background:var(--film-bg);
  overflow:hidden;cursor:pointer}
.player video,.player img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.player .veil{position:absolute;inset:0;background:var(--veil);
  transition:opacity .6s var(--ease);pointer-events:none}
.player.playing .veil{opacity:0}
/* Centred with inset+margin:auto, NOT transform. pressable() in site.js writes
   transform:scale() on pointer-down, which would overwrite a centring translate
   and fling the button into the corner — the same trap as .film-route.
   Anything pressable() touches must leave `transform` free. */
.play{position:absolute;inset:0;margin:auto;
  width:66px;height:66px;border-radius:50%;border:1px solid var(--glass-edge);
  background:var(--glass);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  display:grid;place-items:center;cursor:pointer;padding:0;
  will-change:transform;transition:opacity var(--mid) ease}
.play svg{width:15px;height:17px;margin-left:3px;fill:var(--on-film);display:block}
.player.playing .play{opacity:0;pointer-events:none}
/* once native controls are up, the wrapper is no longer the thing you click */
.player.playing{cursor:default}
.cap{display:flex;justify-content:space-between;gap:var(--s4);flex-wrap:wrap;
  margin-top:var(--s3)}
.cap p{font-family:var(--sans);font-size:var(--t-s);color:var(--muted);
  letter-spacing:var(--tr-small)}

/* ============================================================
   footer
   ============================================================ */

footer{padding:var(--s7) var(--gutter) var(--s8);border-top:1px solid var(--rule-soft);
  display:flex;flex-wrap:wrap;gap:var(--s5);align-items:flex-end;justify-content:space-between}
/* the same lockup as the header, at the same size — the page opens and closes
   on the mark. It used to be a 36px stacked logo at 85% opacity, which made the
   wordmark under the horse unreadable and the whole thing look like a favicon. */
footer .brand:focus-visible{outline-color:var(--ink-strong)}
footer .flinks a,footer .flinks .easy{color:var(--ink);text-decoration:none;font-family:var(--sans);font-size:var(--t-s);
  letter-spacing:var(--tr-small);   /* same setting as the nav links */
  border-bottom:1px solid var(--rule);padding-bottom:1px;transition:border-color var(--fast)}
footer .flinks a:hover,footer .flinks .easy:hover{border-bottom-color:var(--ink)}
.flinks{display:flex;gap:var(--s5);flex-wrap:wrap;align-items:baseline}
/* who is selling: trading name, place, email — on its own line under both */
footer .fine{flex-basis:100%;margin:0;font-family:var(--sans);font-size:var(--t-s);
  color:var(--muted);letter-spacing:var(--tr-small)}
footer .fine a{color:inherit;text-decoration:none;border-bottom:1px solid var(--rule);
  padding-bottom:1px;transition:border-color var(--fast)}
footer .fine a:hover{border-bottom-color:var(--ink)}
/* The easier-reading switch. site.js puts it in the footer of every page (it
   needs JS to work, so it only exists when JS is running). A toggle button
   with aria-pressed, dressed as the footer links are, with a small box in
   front that fills when it is on — the label never changes, only the state. */
footer .flinks .easy{display:inline-flex;align-items:center;gap:var(--s2);
  background:none;border-top:0;border-left:0;border-right:0;padding:0 0 1px;
  cursor:pointer;line-height:inherit}
footer .flinks .easy::before{content:"";width:9px;height:9px;flex:none;
  border:1px solid var(--ink);transition:background var(--fast) ease}
footer .flinks .easy[aria-pressed="true"]::before{background:var(--ink)}

/* ============================================================
   motion & the four accessibility signals
   ============================================================ */
.rv{opacity:0;transform:translateY(10px)}
html.no-js .rv,.rv.in{opacity:1;transform:none}
.rv.in{transition:opacity var(--slow) var(--ease),transform var(--slow) var(--ease)}

@media (prefers-reduced-motion:reduce){
  .rv{opacity:1;transform:none}
  /* BOTH of these start at opacity:0 and are revealed by markIn. Suppress the
     animation without restoring the opacity and the element — here, the only
     route off the landing page — never appears at all. */
  .film-mark img,.film-route a{opacity:1;animation:none}
  *{transition-duration:.01ms!important;animation-duration:.01ms!important;
    animation-iteration-count:1!important}
}
@media (prefers-reduced-transparency:reduce){
  .bar::before{background:var(--paper);backdrop-filter:none;-webkit-backdrop-filter:none}
  .play{background:var(--glass-solid);backdrop-filter:none;-webkit-backdrop-filter:none}
}
@media (prefers-contrast:more){
  :root{--rule:rgba(var(--ink-rgb),.45);--rule-soft:rgba(var(--ink-rgb),.24);--muted:#57534c}
  .bar::before{background:var(--paper);backdrop-filter:none}
  .film-scrim{--scrim-core:rgba(8,10,13,.6);--scrim-top:rgba(8,10,13,.5)}
}

/* ============================================================
   easier reading — html.easy
   The switch in the footer adds this class; a two-line script in every
   <head> restores it from localStorage before the first paint, so it never
   flickers between pages. It is NOT a "dyslexia font": OpenDyslexic and
   Dyslexie have been tested against Helvetica/Arial several times (Rello &
   Baeza-Yates 2013; Wery & Diliberto 2017; Kuster et al. 2018) and read no
   faster or more accurately. What measurably helps is size, letter and word
   spacing, line spacing, a short measure, no capitals, no grey text — the
   British Dyslexia Association's style guide, in short. So that is all this
   does. The page is the same page, set more generously.
   ============================================================ */
html.easy{
  --t-xs:13.5px; --t-s:15px; --t-m:16.5px; --t-b:18px; --t-l:21px;
  --tr-body:.025em; --tr-small:.03em; --tr-label:.03em;
}
html.easy body{line-height:1.75;word-spacing:.08em}
/* capitals lose the word shape a dyslexic reader navigates by */
html.easy .label,html.easy .crumb{text-transform:none}
/* the eight lines and the epigraph move to the sans, at prose leading, and
   open out a little. Headings stay in Literata: at 32px and up the serif is
   not what makes text hard, and it is the site's voice. */
html.easy .wants li,html.easy .frag li{font-family:var(--sans);line-height:1.7;
  letter-spacing:var(--tr-body);max-width:44ch}
html.easy .frag{max-width:44ch}
html.easy .disc-in p{max-width:46ch}
html.easy .story-open p,html.easy .dedication{line-height:1.7}
/* nothing a reader needs is grey. Disabled controls keep --muted, because
   grey is how they say they are disabled. */
html.easy .note,html.easy .cap p,html.easy .spec dt,html.easy .label,
html.easy .model,html.easy .measure caption,html.easy .measure thead th,
html.easy footer .fine{color:var(--ink)}
html.easy .disc-in p{margin-bottom:var(--s4)}
html.easy .wants li{margin-bottom:var(--s5)}
