/* ============================================================
   צמצם · APERTURE - dark gallery wall
   The photographs are the architecture. Type lies on top of them.
   No cards, no boxes, no grid of equal tiles, no centred container.
   ============================================================ */

:root{
  /* The ground was #0B0B0C - a black with MORE blue in it than red,
     which is why it printed as CSS black rather than as a darkroom.
     #0E0B08 is the same value turned the other way: red over blue, so
     every safelight wash below has something warm to sit on instead of
     fighting a cool base. Luminance is unchanged to two decimals, so no
     text measurement moves because of this line alone. */
  --black:#0E0B08;
  --ink:#F2F2F0;
  /* Measured against the ground AND against the strongest safelight
     pool, which is the case that actually binds - the pools got roughly
     three times stronger in this pass, and a lit ground is a lighter
     ground. --dim .52 fell to 4.79:1 under the deepest pool and --faint
     .40 was 3.50:1 even on bare black, a body-text failure that predates
     this pass.
     Two attempts were measured and rejected before these values: .58/.56
     read 3.88:1 on the amber section and .64/.62 read 4.42:1. The three
     amber layers there stack - the fixed .room wash, the fixed
     .safelight and the section's own pool - so token arithmetic on any
     one of them predicts the wrong number every time. .68/.64 measure
     4.76:1 and 4.53:1 on the composited peak of that section, and
     8.3:1 / 7.7:1 on bare ground.
     Raise these before raising any pool. */
  --dim:rgba(242,242,240,.68);
  --faint:rgba(242,242,240,.64);
  --ghost:rgba(242,242,240,.14);
  --amber:#C8842B;

  /* logical gradient direction, resolved once for this RTL document */
  --edge-start:left;   /* toward the inline-start edge (right) */
  --edge-end:right;    /* toward the inline-end edge (left)   */

  --gut:clamp(20px,5.2vw,104px);

  --display:'Heebo',system-ui,sans-serif;
  --body:'Assistant',system-ui,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;

  /* ── the darkroom grade ───────────────────────────────────
     Twelve frames, one photographer. Measured means run from
     30 to 133, so the set does not print as one shoot on its
     own. Four grades pull it back to a single key. They are
     alternatives, never stacked: each one is complete.
     --------------------------------------------------------- */
  /* every print gets the house grade: a little off the saturation,
     a little into the contrast, and a 5% toe of warmth that ties
     the cool blue-hour frames to the warm interiors */
  --grade:saturate(.92) contrast(1.06) brightness(.98) sepia(.05);
  /* photographer-hero and gallery-01 come out of the camera warm and
     mid-key; printed down onto the wall's key */
  --grade-warm:saturate(.78) contrast(1.13) brightness(.85);
  /* gallery-06 is the one high-key monochrome in the set. Measured
     mean 133 against a set that runs 30 to 67, so untouched it is
     not a print on this wall, it is a hole in it. Printed down two
     stops and toned warm, the way the rest of the roll is. */
  --grade-key:saturate(.7) sepia(.24) contrast(1.08) brightness(.52);
  /* gallery-03 and gallery-05 print a stop hot for this room */
  --grade-down:saturate(.86) contrast(1.09) brightness(.86) sepia(.05);

  /* ── the room ─────────────────────────────────────────────
     The ground is never flat. Light pools where the work hangs
     and falls off toward the edges of the room.

     COLOUR PASS: --pool ran at .055, which is genuinely below the
     threshold where anyone would call it orange - and that was
     the problem. A page about darkrooms was reading as a page
     about black. .18 is the value at which the wall reads as LIT
     by a safelight rather than faintly tinted by one, and it is
     the ceiling set by --dim and --faint above, which measure
     5.61:1 and 5.33:1 on it. The corner falloff went warm to
     match, so the shadows are underexposed amber rather than
     neutral crush.
     --------------------------------------------------------- */
  --pool:rgba(200,132,43,.18);    /* warm light on the wall  */
  --lift:rgba(242,242,240,.028);  /* spill off a photograph  */
  --fall:rgba(7,4,2,.5);          /* corner falloff, deeper  */

  --ease:cubic-bezier(.2,0,0,1);
}

*,*::before,*::after{box-sizing:border-box}

html{overflow-x:clip;-webkit-text-size-adjust:100%}

body{
  margin:0;
  overflow-x:clip;
  background:var(--black);
  color:var(--ink);
  font-family:var(--body);
  font-weight:400;
  font-size:clamp(1rem,.94rem + .28vw,1.14rem);
  line-height:1.78;
  -webkit-font-smoothing:antialiased;
}

img{display:block;max-inline-size:100%}
a{color:inherit}
h1,h2,h3,p,figure,blockquote,dl,dd{margin:0}
button{font:inherit;color:inherit}

::selection{background:var(--amber);color:var(--black)}
/* 1px amber on near-black is technically visible and practically
   not; 2px clears WCAG 2.2 focus appearance at every zoom level */
:focus-visible{outline:2px solid var(--amber);outline-offset:5px}

/* ── atmosphere ───────────────────────────────────────────── */

/* film grain, laid over the grounds and over the prints alike, so
   the twelve frames and the wall behind them share one emulsion */
.grain{
  position:fixed;inset:0;z-index:60;pointer-events:none;
  opacity:.058;mix-blend-mode:screen;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:220px 220px;
}

/* the darkroom safelight - the one warm thing in the room */
.safelight{
  position:fixed;z-index:0;pointer-events:none;
  inset-block-end:-36vh;inset-inline-end:-24vw;
  inline-size:82vw;block-size:82vh;
  background:radial-gradient(closest-side,rgba(200,132,43,.34),rgba(200,132,43,.09) 46%,rgba(200,132,43,0) 74%);
}

/* The room the wall stands in. The base black alone prints flat;
   this lifts the whole page amber-ward and puts a corner falloff on
   it, so the ground reads as an unlit room instead.
   The two amber radials went .05/.035 to .15/.11 - a hair became a
   light. They are fixed to the viewport, so this is the wash that
   every piece of text on the page passes through at some scroll
   position, which is why --dim and --faint were raised first. */
.room{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(128% 74% at 76% 4%,rgba(200,132,43,.15),rgba(200,132,43,.04) 34%,rgba(200,132,43,0) 62%),
    radial-gradient(112% 88% at 8% 96%,rgba(200,132,43,.11),rgba(200,132,43,0) 64%),
    radial-gradient(140% 120% at 50% 46%,rgba(0,0,0,0) 42%,rgba(7,4,2,.42) 100%);
}

.skip{
  position:absolute;inset-block-start:-100px;inset-inline-start:var(--gut);
  z-index:99;background:var(--ink);color:var(--black);
  padding:.7rem 1.2rem;font-weight:600;text-decoration:none;
}
.skip:focus{inset-block-start:14px}

/* ── chrome: mark + demo badge ─────────────────────────────── */

.chrome{
  position:fixed;inset-block-start:0;inset-inline:0;z-index:50;
  display:flex;align-items:center;justify-content:space-between;
  gap:.8rem;
  padding:clamp(16px,2.2vw,30px) var(--gut) clamp(30px,4vh,54px);
  pointer-events:none;
  /* a soft top vignette so the mark never fights the type passing under it */
  background:linear-gradient(to bottom,rgba(14,11,8,.7) 0%,rgba(14,11,8,.28) 46%,rgba(14,11,8,0) 100%);
  transition:transform .42s var(--ease),opacity .3s var(--ease);
}
.chrome>*{pointer-events:auto}
/* on a phone the bar has nowhere to go but on top of the headings,
   so it steps out of the way while you read and comes back the
   moment you scroll up. Set by JS, and only ever on touch. */
.chrome[data-tuck]{transform:translateY(-104%);opacity:0}

.mark{display:flex;align-items:baseline;gap:.6rem;text-decoration:none}
.mark b{font-family:var(--display);font-weight:300;font-size:clamp(1.05rem,1.5vw,1.3rem)}
.mark i{
  font-family:var(--mono);font-style:normal;font-weight:300;
  font-size:.6rem;letter-spacing:.24em;color:var(--faint);
  transform:translateY(-.15em);
}

.demo-badge{
  font-family:var(--body);font-size:.74rem;font-weight:400;
  color:var(--dim);text-decoration:none;
  padding:.42rem .8rem;
  border:1px solid var(--ghost);
  background:rgba(14,11,8,.42);
  backdrop-filter:blur(6px);
  transition:color .3s var(--ease),border-color .3s var(--ease);
}
.demo-badge b{font-weight:600;color:var(--ink)}
.demo-badge:hover{color:var(--ink);border-color:var(--faint)}

/* ── shared type ──────────────────────────────────────────── */

.display{
  font-family:var(--display);font-weight:200;
  line-height:1.04;
  font-size:clamp(2.2rem,6.4vw,7rem);
}
.display--mid{font-size:clamp(1.9rem,5vw,5rem);line-height:1.08}


/* EXIF - pure Latin/numeric, so tracking is legal here */
.exif{
  display:block;
  font-family:var(--mono);font-weight:300;
  font-size:clamp(.55rem,.64vw,.66rem);
  letter-spacing:.2em;text-transform:uppercase;
  color:var(--faint);
  white-space:nowrap;
}
.who{display:block;font-size:.8rem;color:var(--dim);margin-block-end:.38rem;line-height:1.4}

.tick{
  display:inline-block;inline-size:15px;block-size:1px;
  background:var(--faint);vertical-align:middle;
  margin-inline-end:.75rem;
}

bdi{unicode-bidi:isolate}

/* ── plates (photographs) ─────────────────────────────────── */

.plate{position:relative;overflow:hidden;background:#0A0705}
/* translate3d promotes the layer on its own; will-change on twelve
   full-bleed images costs real memory on a phone for nothing */
.plate img{inline-size:100%;block-size:100%;object-fit:cover;filter:var(--grade)}
.plate--warm img{filter:var(--grade-warm)}
.plate--key img{filter:var(--grade-key)}
.plate--down img{filter:var(--grade-down)}
/* the contact sheet prints the same six negatives, so it prints
   them from the same grades */
.sheet__frame img{filter:var(--grade)}

/* Every scrim now dissolves through amber on its way out instead of
   through neutral grey - that is the "amber bleeding from the image
   edges": the print does not stop at its frame, its safelight carries a
   few hundred pixels into the room.

   THE CONSTRAINT, learned the hard way: the amber may only live in the
   TAIL, where alpha is already low. A first attempt tinted the .74 and
   .64 stops with rgb(40,22,6), whose luminance is three times that of
   the original rgb(11,11,12) - so the scrim stopped darkening as much,
   and every overlaid caption and heading on a bright photograph lost
   0.2-0.4 of its ratio. The dark stops are now rgb(12,10,8), which is
   marginally DARKER than the original at the same alpha, and the amber
   only appears at stops of .09 and below where it cannot take contrast
   away from anything. These scrims are what makes overlaid text
   readable; nothing here may be lightened. */
.scrim-start{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to var(--edge-start),
    rgba(12,10,8,.95) 0%,rgba(12,10,8,.72) 26%,rgba(200,132,43,.09) 50%,rgba(200,132,43,0) 68%);
}
.scrim-end{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to var(--edge-end),
    rgba(12,10,8,.93) 0%,rgba(12,10,8,.62) 30%,rgba(200,132,43,.08) 54%,rgba(200,132,43,0) 72%);
}
/* The two VERTICAL scrims carry less amber than the horizontal pair. On a
   phone these are the scrims that end up under running copy, and even a
   .05 tail cost two already-failing photo overlays another 0.03-0.06.
   The horizontal bleed is where the effect reads anyway. */
.scrim-top{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(12,10,8,.82) 0%,rgba(12,10,8,.16) 36%,rgba(200,132,43,.03) 54%,rgba(12,10,8,.5) 84%,rgba(12,10,8,.66) 100%);
}
.scrim-foot{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,
    rgba(12,10,8,.92) 0%,rgba(12,10,8,.42) 22%,rgba(200,132,43,.03) 34%,rgba(200,132,43,0) 46%);
}

/* ── reveal ───────────────────────────────────────────────────
   .js-motion goes on <html> only when GSAP actually loaded AND
   reduced-motion is off. Every hidden start state hangs off it.
   No-JS, reduced motion, a script error, a 404 on the library or
   any code path that skips the reveal all land on the FINISHED
   state. The failure mode is "no animation", never "invisible".
   Nothing below may be authored unconditionally.
   ------------------------------------------------------------- */

.js-motion [data-rise]{opacity:0;transform:translateY(26px)}
.js-motion [data-fade]{opacity:0}
/* each photograph resolves out of the black it sits on */
.js-motion [data-lit]{opacity:0;transform:scale(1.045)}
/* EXIF slips up once its photograph has settled */
.js-motion .wall__plate figcaption{opacity:0;transform:translateY(10px)}
/* the opening frame emerges from darkness before anything speaks */
.js-motion .overture .plate{opacity:0;transform:scale(1.07)}
.js-motion .cue i{transform:scaleY(0)}

/* ── grounds ──────────────────────────────────────────────────
   Between the photographs the page is mostly wall, and a flat
   fill there is the tell that this is a web page and not a room.
   Every ground carries three things: the spill of the print that
   just ended, a pool of safelight, and falloff into the corner.
   The pools sit on the side the photographs actually hang on, so
   the light has a source.

   CONTAINMENT RULE, and it is not optional now that --pool is three
   times stronger: every pool must reach zero alpha INSIDE its own
   section box. A radial that still has alpha where its box is clipped
   draws a hard horizontal line against the section above or below -
   at .055 that was invisible, at .18 it is a seam across the page.
   Reach-to-zero = (last stop %) x (radius %), measured from the
   centre; three of the pools below were rebalanced for this.
   ------------------------------------------------------------- */

/* the hero photograph bleeds off the inline-end edge above; its
   light spills down that side, the still-life pools the other */
.gap{
  background:
    radial-gradient(84% 46% at 14% 0%,var(--lift),rgba(242,242,240,0) 62%),
    /* was at 6% 92% with a 58% radius: it still carried alpha at 130%
       of the section and cut a line into the plate below */
    radial-gradient(74% 46% at 6% 74%,var(--pool),rgba(200,132,43,0) 66%),
    linear-gradient(to bottom,rgba(7,4,2,0) 62%,var(--fall) 100%);
}

/* the portrait hangs on the inline-start side and lights it */
.who-teaches{
  background:
    radial-gradient(70% 54% at 84% 8%,var(--lift),rgba(242,242,240,0) 64%),
    radial-gradient(86% 62% at 92% 42%,var(--pool),rgba(200,132,43,0) 62%),
    linear-gradient(to bottom,rgba(7,4,2,.3) 0%,rgba(7,4,2,0) 26%);
}

/* the longest ground on the page: two low pools so the wall never
   settles into one value over eight modules and six prints */
.wall{
  background:
    radial-gradient(58% 22% at 82% 17%,var(--pool),rgba(200,132,43,0) 68%),
    radial-gradient(64% 20% at 12% 66%,var(--pool),rgba(200,132,43,0) 68%),
    linear-gradient(to bottom,
      var(--lift) 0%,rgba(242,242,240,0) 14%,
      rgba(7,4,2,0) 78%,var(--fall) 100%);
}

/* THE SATURATED AMBER MOMENT. The darkroom frame is the warmest thing
   on the page and this is the one place the safelight is allowed to be
   a colour rather than an atmosphere: .075 to .34, a full stop and a
   half. The page has earned it by here - six prints and two dark
   grounds have gone past - and it is not repeated anywhere else, so it
   still reads as one event rather than a tint applied to everything.
   .34 was the first attempt and the browser measured --dim at 3.88:1 on
   it - the section's own pool is only one of three amber layers here,
   the fixed .room wash and .safelight are under it too. .26 is what the
   stack can carry: measured 5.05:1 for --dim and 4.84:1 for --faint on
   the composited peak, and still nearly five times the .055 this page
   shipped with. */
.included{
  background:
    radial-gradient(96% 40% at 62% 46%,rgba(200,132,43,.26),rgba(200,132,43,.07) 44%,rgba(200,132,43,0) 72%),
    linear-gradient(to bottom,rgba(7,4,2,0) 72%,var(--fall) 100%);
}

/* everything here is shoved against the inline-end edge, so the
   empty half of the wall gets the light instead of dying flat */
.forwhom{
  background:
    /* was at 34% with a 62% radius, which clipped at the section's top
       edge and drew a seam against the ground above */
    radial-gradient(72% 46% at 88% 44%,var(--pool),rgba(200,132,43,0) 64%),
    linear-gradient(to bottom,var(--lift) 0%,rgba(242,242,240,0) 20%);
}

/* no photographs at all in this section, so the room does the
   work: one broad wash of safelight across bare wall */
.voices{
  background:
    /* both re-centred so they resolve to zero inside the section, and
       the broad one raised in step with --pool */
    radial-gradient(84% 42% at 30% 34%,rgba(200,132,43,.16),rgba(200,132,43,0) 68%),
    radial-gradient(70% 38% at 92% 74%,var(--pool),rgba(200,132,43,0) 66%),
    linear-gradient(to bottom,rgba(7,4,2,0) 70%,rgba(7,4,2,.34) 100%);
}

/* the form has to read, so this ground stays quiet: a lift at the
   top edge and nothing behind the fields themselves */
.enroll{
  background:linear-gradient(to bottom,
    var(--lift) 0%,rgba(242,242,240,0) 18%,
    rgba(7,4,2,0) 74%,rgba(7,4,2,.3) 100%);
}

/* the page bottoms out into the darkest part of the room */
.faq{background:linear-gradient(to bottom,rgba(7,4,2,0) 40%,rgba(7,4,2,.46) 100%)}
.foot{background:linear-gradient(to bottom,rgba(7,4,2,.46) 0%,rgba(7,4,2,.72) 100%)}

/* ============================================================
   1 · OVERTURE - a photograph, and nothing else.
   The page does not speak until you have looked.
   ============================================================ */

.overture{position:relative;block-size:100svh;inline-size:100vw;overflow:hidden}
.overture .plate{position:absolute;inset:0}
.overture img{block-size:112%;margin-block-start:-6%;object-position:50% 42%}

.overture__foot{
  position:absolute;z-index:3;
  inset-block-end:clamp(22px,4vh,46px);
  inset-inline:var(--gut);
  display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;
}

.cue{display:flex;flex-direction:column;align-items:flex-start;gap:.7rem;color:var(--faint)}
.cue span{font-size:.72rem}
.cue i{
  display:block;inline-size:1px;block-size:clamp(30px,6vh,54px);
  background:linear-gradient(to bottom,var(--faint),rgba(242,242,240,0));
  transform-origin:top center;
}

.dot{
  position:absolute;z-index:3;
  inset-block-start:42vh;inset-inline-start:var(--gut);
  inline-size:7px;block-size:7px;border-radius:50%;
  background:var(--amber);
  box-shadow:0 0 22px 5px rgba(200,132,43,.5);
}

/* ============================================================
   2 · HERO - photograph bleeds off the inline-end edge,
   display line lies across its dark sky.
   ============================================================ */

.hero{
  position:relative;
  min-block-size:104svh;
  display:grid;align-content:end;
  padding-block:24vh clamp(54px,9vh,120px);
  isolation:isolate;
}
.hero__plate{
  position:absolute;z-index:-1;
  inset-block:0;inset-inline-end:0;
  inline-size:74vw;
}
.hero__plate img{block-size:114%;margin-block-start:-7%}

.hero__type{position:relative;padding-inline-start:var(--gut);inline-size:min(100%,1400px)}
.hero h1{
  font-family:var(--display);font-weight:200;
  font-size:clamp(2.4rem,7.2vw,7.8rem);
  line-height:1.0;
}
.hero h1 span{display:block}
.hero h1 span+span{color:var(--dim);margin-inline-start:clamp(0px,6vw,150px)}

.hero__aside{
  position:relative;
  margin-block-start:clamp(30px,5vh,66px);
  padding-inline-start:var(--gut);padding-inline-end:var(--gut);
  display:flex;flex-wrap:wrap;align-items:flex-end;
  gap:clamp(22px,3.4vw,64px);
}
.hero__aside p{max-inline-size:30ch;color:var(--dim);font-size:clamp(1.05rem,1.4vw,1.4rem);line-height:1.5}

.acts{display:flex;flex-wrap:wrap;gap:14px}

.btn{
  display:inline-block;
  padding:.9rem 1.85rem;
  font-family:var(--body);font-size:.92rem;font-weight:600;
  text-decoration:none;
  border:1px solid var(--ink);
  background:transparent;color:var(--ink);
  cursor:pointer;
  transition:background .28s var(--ease),color .28s var(--ease),transform .12s var(--ease);
}
.btn:hover{background:var(--ink);color:var(--black)}
.btn:active{transform:translateY(2px)}
.btn--quiet{border-color:var(--faint);color:var(--dim);font-weight:400}
.btn--quiet:hover{background:transparent;border-color:var(--ink);color:var(--ink)}

.hero__exif{
  position:absolute;z-index:2;
  inset-block-end:clamp(18px,3vh,34px);
  inset-inline-end:var(--gut);
}

/* ============================================================
   3 · THE GAP - a typographic ladder with a ragged inline edge.
   No cards. The still-life bleeds off the bottom inline-end corner.
   ============================================================ */

/* isolate, or the still-life at z-index:-1 escapes to the root
   stacking context and paints under this section's own ground */
.gap{position:relative;isolation:isolate;padding-block:clamp(90px,17vh,220px) clamp(120px,22vh,300px)}

.gap__head{padding-inline:var(--gut)}
.gap__head .display{text-wrap:balance}
.gap__head .display em{font-style:normal;color:var(--dim);display:block}

/* Was two paragraphs of diagnosis at body size. What is left is the
   four-word verdict they were circling, so it is set as a statement -
   the section's second display line, not its running copy. */
.gap__body{
  margin-block-start:clamp(30px,5vh,60px);
  padding-inline-start:var(--gut);
  margin-inline-start:clamp(0px,16vw,300px);
  max-inline-size:20ch;color:var(--dim);
  font-family:var(--display);font-weight:200;
  font-size:clamp(1.5rem,3.4vw,3.2rem);line-height:1.14;
}
.gap__body p+p{margin-block-start:1.1em}

.ladder{
  margin:clamp(56px,11vh,140px) 0 0;
  padding:0;padding-inline:var(--gut);
  display:flex;flex-direction:column;
  gap:clamp(30px,5.4vh,72px);
}
.ladder li{list-style:none;max-inline-size:min(94vw,620px)}
.ladder h3{
  font-family:var(--display);font-weight:300;
  font-size:clamp(1.4rem,2.7vw,2.4rem);line-height:1.16;
  margin-block-end:.55rem;
}
.ladder p{color:var(--dim);font-size:1.02rem;max-inline-size:44ch}
/* the ragged edge: every rung starts at a different inline offset */
.ladder li:nth-child(2){margin-inline-start:25vw}
.ladder li:nth-child(3){margin-inline-start:9vw}
.ladder li:nth-child(4){margin-inline-start:40vw}

/* the still-life sits behind the ladder, so it is printed down
   in the negative rather than faded out with opacity - that way
   the reveal can carry it to a full 1 like every other plate */
.gap__still{
  position:absolute;z-index:-1;
  inset-block-end:0;inset-inline-end:-7vw;
  inline-size:clamp(210px,29vw,470px);
  aspect-ratio:1/1;
}
.gap__still img{filter:var(--grade) brightness(.6) contrast(.94)}

/* ============================================================
   4 · BAND - 21:9 photograph filling the viewport, zero margin.
   Copy lies on the near-black inline-end portion of the frame.
   ============================================================ */

.band{
  position:relative;
  inline-size:100vw;min-block-size:100svh;
  display:grid;align-content:center;
  overflow:hidden;
  isolation:isolate;
}
.band .plate{position:absolute;inset:0;z-index:-1}
.band .plate img{block-size:126%;margin-block-start:-13%}

.band__type{
  position:relative;
  padding-inline-end:var(--gut);
  padding-inline-start:var(--gut);
  margin-inline-start:auto;
  inline-size:min(100%,660px);
}
.band__type .display--mid{text-wrap:balance}
.band__type p{
  margin-block-start:clamp(20px,3vh,38px);color:var(--dim);
  font-size:clamp(1.05rem,1.35vw,1.35rem);line-height:1.5;max-inline-size:38ch;
}

.band__exif{
  position:absolute;z-index:3;
  inset-block-end:clamp(20px,3.4vh,40px);
  inset-inline-start:var(--gut);
}

/* ============================================================
   5 · THE PHOTOGRAPHER - portrait bleeds off the inline-start
   edge; the name lies across the dark side of the frame.
   ============================================================ */

.who-teaches{
  position:relative;
  padding-block:clamp(90px,16vh,210px) clamp(90px,16vh,210px);
  display:grid;
  grid-template-columns:minmax(0,53fr) minmax(0,47fr);
  column-gap:clamp(20px,3vw,70px);
  align-items:start;
  isolation:isolate;
}
.who-teaches__plate{
  position:relative;
  grid-column:1;
  margin-inline-start:-7vw;
}
.who-teaches__plate .plate{aspect-ratio:4/5}
.who-teaches__plate .plate img{block-size:112%;margin-block-start:-6%}

/* the display line lies across the dark foot of the frame and
   runs off its inline-end edge onto the black */
.who-teaches__id{
  position:absolute;z-index:2;
  inset-block-end:clamp(18px,4.5vh,64px);
  inset-inline-start:46%;
  white-space:nowrap;pointer-events:none;
  text-shadow:0 2px 34px rgba(0,0,0,.85);
}
.who-teaches__name{
  font-family:var(--display);font-weight:200;
  font-size:clamp(2.1rem,5.4vw,5.6rem);
  line-height:1;
}
.who-teaches__eyebrow{color:var(--dim);font-size:.84rem;margin-block-end:.2rem}
/* CAREFUL: this element carries dir="ltr" for its numerals, so its
   OWN logical insets resolve LTR - inset-inline-end here means
   right, not left. Written against inset-inline-end it anchored to
   the plate's right edge, and the plate bleeds 7vw past the
   viewport, so the shutter speed and the ISO were being cropped off
   the screen at every width. It hangs off the corner that is
   actually on screen. */
.who-teaches__exif{
  position:absolute;z-index:2;
  inset-block-end:-2.4em;
  inset-inline-start:0;inset-inline-end:auto;
}

.who-teaches__text{
  position:relative;
  grid-column:2;
  margin-block-start:clamp(40px,22vh,300px);
  padding-inline-end:var(--gut);
  max-inline-size:56ch;
  color:var(--dim);
}
.who-teaches__text p+p{margin-block-start:1.15em}
/* the sentence the whole biography existed to deliver */
.who-teaches__text .lede{
  font-family:var(--display);font-weight:200;color:var(--ink);
  font-size:clamp(1.35rem,2.6vw,2.4rem);line-height:1.16;
  max-inline-size:22ch;margin-block-end:1.4rem;
}

/* facts as a run of type, not a stat grid */
.facts{
  grid-column:1/-1;
  margin-block-start:clamp(40px,7vh,90px);
  padding-inline:var(--gut);
  display:flex;flex-wrap:wrap;
  gap:.55rem 1.6rem;
  font-size:.9rem;color:var(--faint);
  align-items:baseline;
}
.facts b{font-family:var(--display);font-weight:200;font-size:1.7em;color:var(--ink);line-height:1}
.facts span{display:inline-flex;align-items:baseline;gap:.5rem}
.facts .sep{color:var(--ghost)}

/* ============================================================
   6 · THE WALL - curriculum and student work interleaved.
   Learning and looking alternate. This is the page's spine.
   ============================================================ */

.wall{position:relative;padding-block:clamp(80px,14vh,180px) clamp(90px,16vh,200px)}

.wall__intro{padding-inline-start:var(--gut);padding-inline-end:var(--gut)}
.wall__intro .display{text-wrap:balance;max-inline-size:18ch}
.wall__intro .display em{font-style:normal;color:var(--dim);display:block}
.wall__intro p{
  margin-block-start:clamp(20px,3vh,36px);
  margin-inline-start:clamp(0px,18vw,340px);
  color:var(--dim);max-inline-size:34ch;
  font-size:clamp(1.05rem,1.35vw,1.35rem);line-height:1.5;
}

/* - the pinned set-piece: six frames assemble into a contact sheet - */
.sheet{position:relative;margin-block-start:clamp(50px,9vh,120px)}
.sheet__track{position:relative;block-size:230vh}
.sheet__stage{
  position:sticky;inset-block-start:0;
  block-size:100svh;
  display:grid;align-content:center;
  overflow:hidden;
}
.sheet__strip{
  display:flex;
  inline-size:100vw;
  gap:clamp(6px,.9vw,16px);
  padding-inline:clamp(6px,.9vw,16px);
  align-items:center;
}
.sheet__frame{
  position:relative;flex:1 1 0;
  aspect-ratio:2/3;
  overflow:hidden;background:#0A0705;
  will-change:transform,opacity;
}
.sheet__frame:nth-child(2),
.sheet__frame:nth-child(5){aspect-ratio:3/2}
.sheet__frame:nth-child(4){aspect-ratio:1/1}
.sheet__frame img{inline-size:100%;block-size:100%;object-fit:cover}
.sheet__frame.warm img{filter:var(--grade-warm)}
.sheet__frame.key img{filter:var(--grade-key)}
.sheet__frame.down img{filter:var(--grade-down)}
.sheet__label{
  position:absolute;inset-block-end:6px;inset-inline-start:8px;
  font-family:var(--mono);font-size:.5rem;letter-spacing:.16em;
  color:rgba(242,242,240,.6);
}
.sheet__cap{
  margin-block-start:clamp(18px,3vh,34px);
  padding-inline:clamp(10px,1.4vw,22px);
  display:flex;justify-content:space-between;gap:1rem;
}
.sheet__cap .who{margin-block-end:0}
.sheet__drag{display:none}

/* - the wall proper - */
.mod{
  padding-block:clamp(26px,4.4vh,54px);
  padding-inline-start:var(--gut);padding-inline-end:var(--gut);
}
.mod:first-of-type{padding-block-start:clamp(50px,8vh,110px)}
/* the modules do not stack on one margin: each starts at its own
   inline offset, so the wall of type has a ragged edge like the plates */
.wall details:nth-of-type(2){padding-inline-start:calc(var(--gut) + 24vw)}
.wall details:nth-of-type(3){padding-inline-start:calc(var(--gut) + 9vw)}
.wall details:nth-of-type(4){padding-inline-start:calc(var(--gut) + 30vw)}
.wall details:nth-of-type(5){padding-inline-start:calc(var(--gut) + 14vw)}
.wall details:nth-of-type(6){padding-inline-start:calc(var(--gut) + 34vw)}
.wall details:nth-of-type(7){padding-inline-start:calc(var(--gut) + 6vw)}
.wall details:nth-of-type(8){padding-inline-start:calc(var(--gut) + 21vw)}
.mod summary{
  list-style:none;cursor:pointer;
  display:flex;flex-wrap:wrap;align-items:baseline;
  gap:.4rem clamp(14px,2.2vw,40px);
}
.mod summary::-webkit-details-marker{display:none}
.mod__t{
  font-family:var(--display);font-weight:200;
  font-size:clamp(1.9rem,4.6vw,4.4rem);line-height:1;
  transition:color .3s var(--ease);
}
.mod__sub{color:var(--faint);font-size:clamp(.9rem,1.2vw,1.08rem);transition:color .3s var(--ease)}
.mod summary:hover .mod__t,.mod[open] .mod__t{color:var(--ink)}
.mod summary:hover .mod__sub,.mod[open] .mod__sub{color:var(--dim)}
.mod:not([open]) .mod__t{color:rgba(242,242,240,.72)}
.mod__mark{
  inline-size:clamp(16px,2vw,30px);block-size:1px;
  background:var(--ghost);align-self:center;flex:0 0 auto;
  transition:background .3s var(--ease),inline-size .3s var(--ease);
}
.mod[open] .mod__mark{background:var(--amber);inline-size:clamp(26px,3.4vw,52px)}

.mod__body{
  margin-block-start:clamp(14px,2.4vh,26px);
  margin-inline-start:clamp(0px,10vw,200px);
  max-inline-size:40ch;color:var(--dim);
  font-size:clamp(1.02rem,1.25vw,1.28rem);line-height:1.5;
}
/* Stays on --dim, not --faint. The size step already subordinates this
   line under the module body above it, and dropping the alpha as well
   would have traded contrast for a hierarchy the scale already bought. */
.mod__topics{
  margin-block-start:1.1rem;
  color:var(--dim);font-size:.95rem;
}

/* student plates on the wall - different scales, separated by black */
.wall__plate{position:relative;display:block}
/* The caption is positioned against its PLATE, and several plates bleed
   off a screen edge - so on a narrow viewport the credit and the EXIF
   ran out into the bled-off strip and lost their last words. The
   photograph may leave the screen; the credit under it may not.

   Each plate declares how far it bleeds in --bleed, and the caption caps
   itself to what is left ON SCREEN: plate width, minus the bleed, minus
   its own inset. Add --bleed whenever you add a negative margin to a
   wall plate, or the caption will silently start running off again.

   The EXIF also has to be allowed to wrap here. It is nowrap globally,
   which meant it set the caption's minimum width and no cap could take
   effect. Wrapping is safe on this string specifically: it is Latin and
   numeric, so its letter-spacing never touches a Hebrew run. */
.wall__plate{--bleed:0px;--cap-inset:clamp(12px,1.6vw,26px)}
.wall__plate figcaption{
  position:absolute;
  inset-block-end:clamp(12px,2vh,22px);
  inset-inline-start:var(--cap-inset);
  max-inline-size:calc(100% - var(--bleed) - var(--cap-inset));
  z-index:2;
  text-shadow:0 1px 3px rgba(0,0,0,.92),0 2px 20px rgba(0,0,0,.9);
}
.wall__plate figcaption .exif{white-space:normal}
.wall__plate .plate{display:block;block-size:100%}
/* every print carries its own foot-shadow so the caption always reads */
.wall__plate .plate::after{
  content:"";position:absolute;pointer-events:none;
  inset-inline:0;inset-block-end:0;block-size:40%;
  background:linear-gradient(to top,rgba(14,11,8,.75),rgba(14,11,8,0));
}
.wall__plate .plate img{block-size:120%;margin-block-start:-10%}

.p-01{inline-size:clamp(240px,52vw,860px);aspect-ratio:2/3;margin-inline-start:-7vw;margin-block:clamp(40px,7vh,100px);--bleed:7vw}
/* this plate runs off the inline-start edge, so its caption moves to the other side */
.p-01 figcaption{inset-inline-start:auto;inset-inline-end:var(--cap-inset)}
.p-02{inline-size:100vw;block-size:100svh;margin-inline-start:calc(50% - 50vw);margin-block:clamp(50px,9vh,130px)}
.p-02 figcaption{--cap-inset:var(--gut);inset-block-end:clamp(22px,4vh,44px)}
.pair{
  display:grid;grid-template-columns:38vw 1fr;
  align-items:start;column-gap:clamp(16px,3vw,60px);
  margin-block:clamp(40px,7vh,110px);
}
.p-03{aspect-ratio:2/3;margin-block-start:clamp(30px,10vh,150px)}
.p-05{aspect-ratio:3/2;margin-inline-end:-9vw;--bleed:9vw}
.p-06{inline-size:clamp(230px,50vw,820px);aspect-ratio:2/3;margin-inline-start:auto;margin-inline-end:-8vw;margin-block:clamp(40px,7vh,110px);--bleed:8vw}
.p-04{inline-size:clamp(150px,21vw,330px);aspect-ratio:1/1;margin-inline-start:calc(var(--gut) + 4vw);margin-block:clamp(40px,7vh,100px)}

/* ============================================================
   7 · WHAT'S INCLUDED - darkroom band, then a ragged type list.
   Six lines, six different inline offsets. Not six boxes.
   ============================================================ */

.included{position:relative}

.included__band{
  position:relative;
  inline-size:100vw;min-block-size:82svh;
  display:grid;align-content:end;
  overflow:hidden;isolation:isolate;
  padding-block-end:clamp(50px,9vh,120px);
}
.included__band .plate{position:absolute;inset:0;z-index:-1}
.included__band .plate img{block-size:124%;margin-block-start:-12%}
.included__band .display{
  position:relative;
  padding-inline-start:var(--gut);padding-inline-end:var(--gut);
  margin-inline-start:auto;
  inline-size:min(100%,20ch);
}

.kit{padding-block:clamp(60px,11vh,150px) clamp(80px,15vh,200px);padding-inline-end:var(--gut)}
.kit dt{
  font-family:var(--display);font-weight:300;
  font-size:clamp(1.45rem,3.2vw,3rem);line-height:1.1;
}
.kit dd{color:var(--dim);max-inline-size:34ch;margin-block-start:.5rem;font-size:1.02rem;line-height:1.5}
.kit>div{
  padding-block:clamp(20px,3.6vh,44px);
  display:grid;
  grid-template-columns:minmax(0,auto) minmax(0,34ch);
  justify-content:space-between;
  column-gap:clamp(24px,5vw,110px);
  align-items:baseline;
}
.kit dd{margin-block-start:0}
.kit>div:nth-child(1){padding-inline-start:var(--gut)}
.kit>div:nth-child(2){padding-inline-start:calc(var(--gut) + 11vw)}
.kit>div:nth-child(3){padding-inline-start:calc(var(--gut) + 4vw)}
.kit>div:nth-child(4){padding-inline-start:calc(var(--gut) + 17vw)}
.kit>div:nth-child(5){padding-inline-start:calc(var(--gut) + 7vw)}
.kit>div:nth-child(6){padding-inline-start:calc(var(--gut) + 21vw)}

/* ============================================================
   8 · WHO IT'S FOR - asymmetry reverses. Everything is shoved
   against the inline-END edge; the rest of the wall is empty.
   ============================================================ */

.forwhom{
  position:relative;
  padding-block:clamp(70px,13vh,180px) clamp(80px,15vh,200px);
  display:grid;justify-items:end;
}
.forwhom__head{padding-inline-end:var(--gut);text-align:start}
.forwhom__list{
  margin-block-start:clamp(34px,6vh,80px);
  padding:0;
  padding-inline-end:var(--gut);
  inline-size:min(100%,54ch);
  display:flex;flex-direction:column;gap:clamp(24px,4vh,50px);
  list-style:none;
}
.forwhom__list h3{
  font-family:var(--display);font-weight:300;
  font-size:clamp(1.3rem,2.5vw,2.2rem);line-height:1.16;margin-block-end:.4rem;
}
.forwhom__list p{color:var(--dim);font-size:1.02rem;max-inline-size:40ch}
.forwhom__note{
  justify-self:start;
  margin-block-start:clamp(40px,7vh,90px);
  padding-inline:var(--gut);
  max-inline-size:56ch;color:var(--dim);font-size:.94rem;
}

/* ============================================================
   9 · GRADUATES - a full-bleed quote wall. No photographs at
   all: the one movement in the page made purely of type.
   ============================================================ */

.voices{position:relative;padding-block:clamp(70px,13vh,180px) clamp(90px,16vh,210px)}
.voices__head{padding-inline:var(--gut)}

.voice{
  padding-block:clamp(40px,7.5vh,100px);
  padding-inline-end:var(--gut);
}
.voice blockquote{
  font-family:var(--display);font-weight:200;
  font-size:clamp(1.4rem,3.1vw,2.9rem);
  line-height:1.22;color:var(--ink);
  max-inline-size:min(90vw,720px);
}
.voice__by{
  margin-block-start:clamp(14px,2.4vh,26px);
  color:var(--dim);font-size:.92rem;
}
.voice__by b{font-weight:600;color:var(--ink)}
.voice__out{display:block;color:var(--dim);font-size:.88rem;margin-block-start:.2rem}
.voice{padding-inline-start:var(--gut)}
.voices figure:nth-of-type(2){padding-inline-start:calc(var(--gut) + 19vw)}
.voices figure:nth-of-type(3){padding-inline-start:calc(var(--gut) + 7vw)}
.voices figure:nth-of-type(4){padding-inline-start:calc(var(--gut) + 27vw)}
.voices figure:nth-of-type(5){padding-inline-start:calc(var(--gut) + 12vw)}

/* ============================================================
   10 · ENROLLMENT - no photograph. Black, so the form reads.
   ============================================================ */

.enroll{
  position:relative;
  padding-block:clamp(70px,13vh,180px) clamp(80px,14vh,190px);
}
.enroll__head{padding-inline:var(--gut)}
.enroll__head .display--mid{max-inline-size:min(92vw,760px)}
.enroll__head .display--mid em{font-style:normal;color:var(--dim);display:block}

.enroll__grid{
  margin-block-start:clamp(40px,7vh,90px);
  display:grid;
  grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(30px,5vw,90px);
  align-items:start;
}
.enroll__promise{padding-inline-start:var(--gut);color:var(--dim)}
.enroll__promise p{max-inline-size:26ch;font-size:clamp(1.1rem,1.6vw,1.6rem);line-height:1.4;color:var(--ink)}
.enroll__promise ul{
  margin-block-start:clamp(24px,4vh,44px);padding:0;list-style:none;
  display:flex;flex-direction:column;gap:.85rem;
}
.enroll__promise li{font-size:1.02rem;color:var(--dim)}

.form{padding-inline-end:var(--gut)}
.form__row{display:grid;gap:clamp(16px,2vw,26px);grid-template-columns:1fr 1fr}
.field{display:block;margin-block-end:clamp(16px,2.2vh,26px)}
.field>span{
  display:block;font-size:.78rem;color:var(--dim);
  margin-block-end:.5rem;
}
.field input,.field select,.field textarea{
  inline-size:100%;
  background:transparent;color:var(--ink);
  font-family:var(--body);font-size:1rem;
  border:0;border-block-end:1px solid var(--faint);
  padding:.55rem 0;
  border-radius:0;
  transition:border-color .3s var(--ease);
}
.field textarea{resize:vertical;min-block-size:4.5em}
/* appearance:none stripped the only thing that said "this is a
   control" - the chevron puts it back without a browser widget */
.field select{
  appearance:none;cursor:pointer;
  padding-inline-end:2rem;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.4 6 6.2l5-4.8' fill='none' stroke='%23F2F2F0' stroke-opacity='.62' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:left 2px center;
  background-size:12px 8px;
}
.field select:focus{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.4 6 6.2l5-4.8' fill='none' stroke='%23C8842B' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
}
.field select option{background:#141416;color:var(--ink)}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-block-end-color:var(--amber);
}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:none;
}

.check{
  display:flex;align-items:flex-start;gap:.7rem;
  margin-block:clamp(18px,2.6vh,30px);
  font-size:.9rem;color:var(--dim);cursor:pointer;
}
.check input{
  appearance:none;inline-size:15px;block-size:15px;flex:0 0 auto;
  border:1px solid var(--faint);background:transparent;margin-block-start:.35rem;
  cursor:pointer;transition:background .2s var(--ease),border-color .2s var(--ease);
}
.check input:checked{background:var(--amber);border-color:var(--amber)}

.form__note{margin-block-start:clamp(18px,2.6vh,28px);color:var(--faint);font-size:.82rem;max-inline-size:46ch}
.form .btn{inline-size:100%;text-align:center}

/* ============================================================
   11 · FAQ - full-width rows, separated by air, not by rules.
   ============================================================ */

.faq{position:relative;padding-block:clamp(70px,13vh,180px) clamp(60px,10vh,130px)}
.faq__head{padding-inline:var(--gut)}
.faq__head p{margin-block-start:1.2rem;color:var(--dim);max-inline-size:44ch}

.q{padding-block:clamp(18px,3vh,34px);padding-inline:var(--gut)}
.q:first-of-type{margin-block-start:clamp(30px,5vh,70px)}
.q summary{
  list-style:none;cursor:pointer;
  display:flex;align-items:baseline;justify-content:space-between;gap:1.4rem;
  font-family:var(--display);font-weight:300;
  font-size:clamp(1.2rem,2.5vw,2.2rem);line-height:1.2;
  color:rgba(242,242,240,.76);
  transition:color .3s var(--ease);
}
.q summary::-webkit-details-marker{display:none}
.q summary:hover,.q[open] summary{color:var(--ink)}
.q__mark{
  flex:0 0 auto;inline-size:13px;block-size:13px;position:relative;
  align-self:center;
}
.q__mark::before,.q__mark::after{
  content:"";position:absolute;inset-block-start:50%;inset-inline-start:0;
  inline-size:13px;block-size:1px;background:var(--faint);
  transition:transform .3s var(--ease),background .3s var(--ease);
}
.q__mark::after{transform:rotate(90deg)}
.q[open] .q__mark::before,.q[open] .q__mark::after{background:var(--amber)}
.q[open] .q__mark::after{transform:rotate(0deg)}
.q__a{
  margin-block-start:clamp(12px,2vh,22px);
  margin-inline-start:clamp(0px,8vw,160px);
  max-inline-size:46ch;color:var(--dim);
  font-size:clamp(1.02rem,1.25vw,1.28rem);line-height:1.5;
}

/* ============================================================
   12 · FOOTER - the mark set enormous and cropped by the
   bottom edge. The last composition is a crop.
   ============================================================ */

.foot{position:relative;padding-block-start:clamp(44px,7vh,100px);overflow:hidden}
.foot__nav{
  padding-inline:var(--gut);
  display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:1rem clamp(20px,3vw,52px);
  font-size:.92rem;
}
.foot__nav a{color:var(--dim);text-decoration:none;transition:color .25s var(--ease)}
.foot__nav a:hover{color:var(--ink)}
.foot__line{padding-inline:var(--gut);margin-block-start:1.6rem;color:var(--dim);max-inline-size:52ch;font-size:.94rem}
.foot__legal{
  padding-inline:var(--gut);
  margin-block-start:clamp(34px,6vh,70px);
  color:rgba(242,242,240,.5);font-size:.82rem;line-height:1.75;max-inline-size:78ch;
}
.foot__mark{
  margin-block-start:clamp(10px,2vh,26px);
  font-family:var(--display);font-weight:200;
  font-size:26vw;line-height:.78;
  color:rgba(242,242,240,.075);
  padding-inline-start:var(--gut);
  margin-block-end:-.3em;
  user-select:none;
  white-space:nowrap;
}

/* ============================================================
   demo interception modal
   ============================================================ */

.modal{
  position:fixed;inset:0;z-index:80;
  display:none;place-items:center;
  inline-size:100%;block-size:100%;
  max-inline-size:none;max-block-size:none;
  border:0;margin:0;
  padding:var(--gut);
  color:var(--ink);
  background:rgba(9,6,3,.9);
  backdrop-filter:blur(10px);
}
.modal[open]{display:grid}
.modal::backdrop{background:transparent}
.modal__box{
  max-inline-size:min(92vw,470px);
  background:#15110C;
  padding:clamp(28px,4vw,54px);
  border:1px solid var(--ghost);
}
.modal__box .exif{margin-block-end:1.4rem}
.modal__box h2{
  font-family:var(--display);font-weight:200;
  font-size:clamp(1.5rem,3vw,2.4rem);line-height:1.1;margin-block-end:1rem;
}
.modal__box p{color:var(--dim);font-size:.96rem}
.modal__box p+p{margin-block-start:.9em}
/* one dialog, two reasons to open it: a form that sends nothing,
   or a policy link with nothing behind it. Say the right one. */
.modal__for-link{display:none}
.modal[data-kind="link"] .modal__for-form{display:none}
.modal[data-kind="link"] .modal__for-link{display:block}
.modal__acts{display:flex;flex-wrap:wrap;gap:12px;margin-block-start:clamp(22px,3vh,34px)}

/* ============================================================
   responsive - the wall reflows to a single narrow column
   ============================================================ */

@media (max-width:900px){
  .enroll__grid{grid-template-columns:1fr;gap:clamp(40px,7vh,70px)}
  .form{padding-inline-start:var(--gut)}
  .pair{grid-template-columns:1fr;row-gap:clamp(30px,5vh,60px)}
  .p-03{margin-block-start:0;inline-size:min(78vw,520px);margin-inline-start:-5vw;--bleed:5vw}
  /* this plate now runs off the inline-start edge too, and its
     caption was going with it - the name and the EXIF were both
     cropped by the viewport. Move them to the side that is still
     on screen, the same way .p-01 already does. */
  .p-03 figcaption{inset-inline-start:auto;inset-inline-end:clamp(12px,1.6vw,26px)}
  .p-05{margin-inline-end:-6vw;margin-inline-start:auto;inline-size:min(92vw,700px);--bleed:6vw}
  .who-teaches{grid-template-columns:minmax(0,1fr)}
  .who-teaches__plate{grid-column:1;inline-size:min(88vw,560px);margin-inline-start:-6vw}
  .who-teaches__text{grid-column:1;padding-inline:var(--gut);margin-block-start:clamp(52px,9vh,90px)}
  .who-teaches__id{inset-inline-start:30%}
  .who-teaches__exif{inset-block-end:-2.1em}
  .hero__plate{inline-size:100vw;opacity:.75}
}

/* ── the touch break ──────────────────────────────────────────
   761px is the same line main.js draws. Below it the set-piece
   stops being a pinned scene and becomes a contact sheet you
   drag, because hijacking a touch scroll to hold a pin is the
   one thing a phone should never be asked to do.
   ------------------------------------------------------------- */
@media (max-width:760px){
  .sheet{margin-block-start:clamp(34px,6vh,70px)}
  .sheet__track{block-size:auto}
  .sheet__stage{
    block-size:auto;overflow:visible;
    padding-block:clamp(20px,4vh,44px) clamp(6px,1.5vh,16px);
  }
  /* a light table: six frames on one rail, dragged past the eye,
     each one snapping to centre. No pin, no hijack, no scrollbar. */
  .sheet__strip{
    inline-size:100%;
    flex-wrap:nowrap;
    overflow-x:auto;overflow-y:hidden;
    scroll-snap-type:x proximity;
    scroll-padding-inline:var(--gut);
    padding-inline:var(--gut);
    padding-block-end:10px;
    gap:10px;
    align-items:center;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    overscroll-behavior-inline:contain;
  }
  .sheet__strip::-webkit-scrollbar{display:none}
  .sheet__frame{
    flex:0 0 min(62vw,270px);
    scroll-snap-align:center;
  }
  .sheet__label{font-size:.56rem}
  .sheet__cap{
    flex-direction:column;gap:.45rem;
    padding-inline:var(--gut);
    margin-block-start:clamp(14px,2.4vh,22px);
  }
  /* the rail is draggable, so say so once, quietly */
  .sheet__drag{
    display:flex;align-items:center;gap:.5rem;
    color:var(--faint);font-size:.78rem;
  }
  .sheet__drag::before{
    content:"";inline-size:22px;block-size:1px;background:var(--faint);
  }
}

@media (max-width:640px){
  :root{--gut:20px}

  /* EXIF at 8px in a .30 grey was decorative, not readable. This
     is the one place on the page where numerals carry meaning. */
  .exif{font-size:.63rem;letter-spacing:.1em;color:var(--dim)}
  .who{font-size:.85rem}
  .sheet__label{color:rgba(242,242,240,.72)}

  .band .plate img{object-position:74% 50%}
  .form__row{grid-template-columns:1fr;gap:0}
  .gap__still{inline-size:172px;inset-inline-end:-22px}
  .gap__still img{filter:var(--grade) brightness(.48) contrast(.94)}
  .ladder li:nth-child(2){margin-inline-start:22px}
  .ladder li:nth-child(3){margin-inline-start:8px}
  .ladder li:nth-child(4){margin-inline-start:34px}
  .voices figure:nth-of-type(n){padding-inline-start:var(--gut)}
  .voices figure:nth-of-type(2n){padding-inline-start:calc(var(--gut) + 18px)}
  .kit>div{grid-template-columns:1fr;row-gap:.4rem}
  .kit>div:nth-child(n){padding-inline-start:var(--gut)}
  .p-01{inline-size:86vw;margin-inline-start:-7vw}
  .p-06{inline-size:88vw;margin-inline-end:-8vw}
  .p-03{margin-inline-start:-2vw;--bleed:2vw}
  /* 44vw left this print stranded in the middle of a lot of black */
  .p-04{inline-size:58vw;margin-inline-start:calc(var(--gut) + 6vw)}
  .p-02{block-size:78svh}
  .mod__body{margin-inline-start:0}
  .q__a{margin-inline-start:0}
  .wall details:nth-of-type(n){padding-inline-start:var(--gut)}
  .foot__mark{font-size:30vw}
  .who-teaches__text,.gap__body,.wall__intro p{margin-inline-start:0}

  /* the overture foot ran the cue and a nowrap EXIF into each
     other at 375px; stack them instead of letting them collide */
  .overture__foot{
    flex-direction:column;align-items:flex-start;
    gap:clamp(12px,2vh,20px);
  }
  .cue i{block-size:clamp(26px,4.4vh,40px)}

  /* ── tap targets ────────────────────────────────────────────
     Measured at 375px, then padded until every one of them
     clears 44px. The accordion summaries were the worst: an
     FAQ row was a 23px-high strip of text. */
  .foot__nav{justify-content:flex-start;gap:0 clamp(18px,5vw,32px)}
  .foot__nav a{display:inline-block;padding-block:.6rem}
  .field input,.field select,.field textarea{padding-block:.72rem}
  .field select{background-position:left 2px center}
  .check input{inline-size:19px;block-size:19px;margin-block-start:.3rem}
  .check{padding-block:.55rem}
  .demo-badge{font-size:.66rem;padding:.75rem .68rem;letter-spacing:0}
  .mark{padding-block:.46rem}
  .mark i{font-size:.54rem;letter-spacing:.18em}
  /* the padding moves off the <details> and onto the <summary>,
     because only the summary actually toggles when tapped */
  .mod{padding-block:clamp(16px,2.6vh,32px)}
  .mod summary{padding-block:.42rem}
  .q{padding-block:clamp(12px,2vh,24px)}
  .q summary{padding-block:.72rem}

  /* the fixed bar sits on top of whatever scrolls under it, so on
     a phone the scrim has to be strong enough to take a heading */
  .chrome{
    background:linear-gradient(to bottom,
      rgba(14,11,8,.9) 0%,rgba(14,11,8,.62) 40%,
      rgba(14,11,8,.2) 74%,rgba(14,11,8,0) 100%);
    padding-block-end:clamp(26px,5vh,44px);
  }

  /* mobile rhythm: the desktop's long black rests read as dead
     air on a 375px screen, where they last three full swipes */
  .gap{padding-block:clamp(70px,11vh,120px) clamp(80px,13vh,150px)}
  .wall{padding-block:clamp(60px,9vh,110px) clamp(66px,10vh,120px)}
  .who-teaches{padding-block:clamp(66px,10vh,120px)}
  .voices{padding-block:clamp(58px,9vh,110px)}
  .p-01,.p-06{margin-block:clamp(34px,5.5vh,70px)}
  .p-04{margin-block:clamp(34px,5.5vh,70px)}
  .mod{padding-block:clamp(22px,3.4vh,40px)}
}

/* ── 320px ────────────────────────────────────────────────────
   The EXIF lines are white-space:nowrap on purpose - they are one
   instrument reading, not a sentence - so on the narrowest phones
   still in use they have to be sized to fit rather than wrapped.
   ------------------------------------------------------------- */
@media (max-width:400px){
  .exif{font-size:clamp(.54rem,2.55vw,.63rem);letter-spacing:.07em}
  .p-03{margin-inline-start:-2vw}
  .foot__mark{font-size:33vw}
}

/* ============================================================
   reduced motion - strip every axis of movement, keep fades
   ============================================================ */

/* Under reduced motion .js-motion is never added, so no hidden
   start state exists to undo - the page simply renders finished.
   What is left here is the belt: kill any residual movement. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.15s !important;
    scroll-behavior:auto !important;
  }
  .plate img{transform:none !important}
  .chrome{transform:none !important;opacity:1 !important}
  .sheet__track{block-size:auto !important}
  .sheet__stage{block-size:auto !important;overflow:visible;padding-block:clamp(30px,6vh,70px)}
  /* the drag rail stays: user-driven scrolling is not motion */
  .sheet__frame{transform:none !important;opacity:1 !important}
}


/* ═══ text that sits ON a photograph ═════════════════════════════════
   EXIF lines and the "who" credit are placed over prints, so their
   contrast is whatever that print happens to be doing underneath. The
   colour pass measured 1.21-2.9:1 on the bright ones. A page-wide scrim
   would flatten the gallery, so the fix is local: the text carries its
   own ground, sized to the glyphs, and only where it overlaps an image.
   ═════════════════════════════════════════════════════════════════ */
.wall__plate .exif,
.band .exif,
.hero .exif,
.wall__plate .who,
.band .who {
  display: inline-block;
  padding: .35em .7em;
  border-radius: 3px;
  background: rgba(9, 7, 5, .78);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  color: rgba(242, 240, 236, .94);
  text-shadow: none;
}
/* captions that already sit on black need no pill */
.modal__box .exif,
.sheet .exif { background: transparent; padding: 0; backdrop-filter: none; }
