/* PARKINSON'S 101 — Cinematic Gym.
   Structure and surface only. Motion lives in motion.css / motion.js and the
   page is complete with both deleted. */

/* ---------- Wordmark (self-hosted, wordmark only) ---------- */
@font-face {
  font-family: 'Barlow Condensed Wordmark';
  src: url('assets/BarlowCondensed-Bold.woff2') format('woff2'),
       url('assets/BarlowCondensed-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --plaster: #EFEAE2;
  --plaster-deep: #E2DBD0;
  --umber: #1E1B18;
  --umber-soft: #5A534A;
  --film: #12100E;
  --on-film: #F3EEE6;
  --on-film-2: #C9C0B3;
  --blue: #1B4FD8;
  --blue-deep: #123CA8;
  --white: #FFFFFF;
  /* The same inks as channel triplets, so every wash, rule and scrim on the page
     is mixed from the token rather than from a literal that has to be kept in
     step with it by hand. */
  --umber-rgb: 30 27 24;
  --film-rgb: 18 16 14;
  --blue-rgb: 27 79 216;
  --rule: rgb(var(--umber-rgb) / 0.16);
  --rule-strong: rgb(var(--umber-rgb) / 0.5);   /* 3.2:1 on plaster — interactive borders */

  --display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --body: 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --wordmark: 'Barlow Condensed Wordmark', 'Barlow Condensed', Impact, sans-serif;

  --fs-furniture: 0.97rem;   /* 15.5px — film furniture floor: labels glanced at, not read */
  /* Furniture that is actually read off a tablet at arm's length — the runtime on
     a frame, the line that says where a lesson opens — is set a step larger. The
     audience is older adults; 15px is a caption, 17px is a fact you can use. */
  --fs-furniture-lg: 1.0625rem;  /* 17px */
  --gutter: clamp(1.25rem, 4.4vw, 3.5rem);
  --shell: 71.25rem;         /* 1140px */
  --frame-max: 95.75rem;     /* 1532px — stays under 1.25x of the 1280px source even during the 1.04 focus-pull */
  --hero-foot: 3.5rem;
  /* Height the opening frame leaves below itself for the masthead, the lede and
     both actions. The frame is capped in HEIGHT to honour it — never in width,
     because a narrowed frame drags the title off the page's own left edge. On a
     short window the letterbox simply closes further, which is what a short
     window does to a film, and the floor stops it closing to a slit. */
  --hero-reserve: 26rem;
  --hero-img-min: 16rem;
  --reel-pad: max(var(--gutter), calc((100vw - var(--shell)) / 2 + var(--gutter)));

  /* Fine grain, seamless tile. The one image-processing effect on the page. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)' opacity='0.55'/%3E%3C/svg%3E");
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
/* Nothing on this page moves on its own; the only transitions that move rather
   than tint are the play glyph and the question chevron, and under reduced
   motion those settle instantly too. Colour and filter fades are not motion. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .play-glyph,
  .faq .icon-chev { transition: none; }
}

body {
  margin: 0;
  background: var(--plaster);
  color: var(--umber);
  font-family: var(--body);
  font-size: 1.1875rem;       /* 19px */
  line-height: 1.6;
  font-weight: 400;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-underline-offset: 0.22em;
}

::selection { background: var(--blue); color: var(--white); }

img { display: block; max-width: 100%; height: auto; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 50;
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; }

a { color: var(--blue); }
a:hover { color: var(--blue-deep); }

:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 3px;
  border-radius: 1px;
}
/* Blue rings at 3px offset: the gap and the page beyond it are both paper, so
   the ring keeps 5.5:1 even around the blue action itself. Over film-black the
   blue would fall to 2.9:1, so anything inside a black frame rings in paper. */
.on-film :focus-visible { outline-color: var(--plaster); }

/* Pressed. One treatment for every control on the page, so a press feels the
   same wherever a hand lands: the control settles a hair into the paper and
   takes the ink one step on from hover. Not a transition — a press is not an
   animation, and nothing here moves under reduced motion. */
.skip:active,
.brand:active,
.menu-toggle:active,
#navigation a:active,
.action:active,
.action-text:active,
.filters button:active,
.rail:not([aria-disabled='true']):active,
.lesson:active,
.play:active,
.faq summary:active,
.colophon-links a:active { transform: translateY(1px); }

.action:active { background: var(--blue-deep); }
.action-text:active,
#navigation a:active,
.faq summary:active,
.colophon-links a:active { color: var(--blue-deep); }
.filters button[aria-pressed='false']:active {
  color: var(--umber);
  background: rgb(var(--umber-rgb) / 0.14);
}
.rail:not([aria-disabled='true']):active { background: var(--umber); color: var(--plaster); }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Film furniture: runtimes, counts, captions, slates. */
.furniture {
  font-family: var(--body);
  font-weight: 600;
  font-size: var(--fs-furniture);
  letter-spacing: 0.04em;
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
  color: var(--umber-soft);
}

.icon {
  width: 1.4em; height: 1.4em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* One drawn weight everywhere: the stroke stays 1.75px whatever the icon is scaled to. */
.icon path { vector-effect: non-scaling-stroke; }

/* ---------- Skip link ---------- */
.skip {
  position: absolute;
  top: -120px; left: var(--gutter);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  min-height: 56px;
  padding: 0 1.25rem;
  background: var(--blue);
  color: var(--white);
  font-weight: 600;
  text-decoration: none;
}
.skip:hover { color: var(--white); }
.skip:focus-visible { top: 0.75rem; color: var(--white); outline-color: var(--umber); }

/* ---------- Masthead ---------- */
.masthead {
  position: relative;
  z-index: 20;
  background: var(--plaster);
  border-bottom: 1px solid var(--rule);
}
/* The masthead stands on the content column, not on the frame: one page gutter
   serves the wordmark, the opening title and every section below it. */
.masthead-inner {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  min-height: 74px;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  min-height: 56px;
  align-content: center;
  flex-wrap: wrap;
  padding-block: 0.5rem;
  text-decoration: none;
  color: var(--umber);
  margin-right: auto;
}
.brand:hover { color: var(--umber); }
.brand-mark {
  font-family: var(--wordmark);
  font-weight: 700;
  font-size: 1.55rem;
  letter-spacing: 0.035em;
  line-height: 1;
  text-transform: uppercase;
}
.brand-by {
  font-family: var(--body);
  font-weight: 600;
  font-size: 0.9375rem;   /* 15px: the label floor holds for the byline too */
  letter-spacing: 0.14em;
  line-height: 1;
  color: var(--umber-soft);
}
.brand:hover .brand-mark { color: var(--blue); }

.menu-toggle {
  display: none;
  align-items: center;
  gap: 0.5rem;
  min-height: 56px;
  padding: 0 1rem 0 1.1rem;
  border: 1px solid var(--rule-strong);
  background: transparent;
  color: var(--umber);
  font: inherit;
  font-weight: 600;
  font-size: var(--fs-furniture);
  letter-spacing: 0.04em;
  cursor: pointer;
  border-radius: 2px;
}
.menu-toggle:hover {
  background: rgb(var(--umber-rgb) / 0.07);
  border-color: var(--umber);
}
.menu-toggle:active { background: rgb(var(--umber-rgb) / 0.14); }
.menu-toggle .icon-close { display: none; }
.menu-toggle[aria-expanded='true'] .icon-menu { display: none; }
.menu-toggle[aria-expanded='true'] .icon-close { display: block; }

#navigation ul {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
#navigation a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 56px;
  color: var(--umber);
  font-size: 1.125rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 2px solid transparent;
}
#navigation a:hover { color: var(--blue-deep); border-bottom-color: var(--blue); }
#navigation .nav-out { color: var(--blue); }
#navigation .nav-out:hover { color: var(--blue-deep); }
#navigation .icon { width: 1.05em; height: 1.05em; }

/* ---------- Hero ---------- */
#hero { padding-bottom: clamp(2.5rem, 5vw, 4rem); }

/* The opening frame: photograph and film bar stacked in one grid, so the image,
   its overlays and the bar share a single black block with no seam between them. */
#hero-photo {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  width: 100%;
  /* Full bleed to the 1.25x ceiling of the 1280px source, then capped and centred
     on the paper. The frame is never narrowed to control its height — a narrowed
     frame drags the title off the page's left edge and invents a third margin. */
  max-width: var(--frame-max);
  margin-inline: auto;
  background: var(--film);
  overflow: hidden;
  isolation: isolate;
  /* The title sizes against the frame, not the window, because the frame is
     height-capped and the two part company on short landscape viewports. */
  container-type: inline-size;
}
/* Where the letterbox is cut from the negative. The people stand in the top
   third of boxing.jpg — the highest head is 13.6% down — and the letterbox is
   shorter than the negative by an amount that changes with the window, so a
   percentage (which measures the leftover, not the negative) slides the band
   down the picture as the frame closes and decapitates everybody. A length
   measures the negative instead: the frame is full-bleed, so the negative is
   rendered 56.25cqw tall (720/1280 of the frame's own width) whatever the
   frame's height, and -5.0625cqw parks the top of the window 9% down it — a
   clear 4.6% of sky above the highest head at every height the frame takes.
   Percentages stay as the fallback for browsers without container units. */
#hero-img {
  grid-row: 1;
  grid-column: 1;
  width: 100%;
  aspect-ratio: 22 / 10;
  object-fit: cover;
  object-position: 50% 30%;
  object-position: 50% -5.0625cqw;
  /* Warm grade so the softness of the source reads as film stock, not a bad upload. */
  filter: sepia(0.24) saturate(1.5) hue-rotate(-9deg) contrast(1.06) brightness(1.02);
}
/* The photograph carries a colour-grade `filter`, which makes it a stacking
   context of its own. Grid items take z-index without being positioned, so the
   grain and the scrim are given explicit layers above it — without them the
   scrim paints underneath the photograph and never darkens anything. */
.hero-grain {
  grid-row: 1;
  grid-column: 1;
  z-index: 1;
  align-self: stretch;
  background-image: var(--grain);
  background-size: 180px 180px;
  mix-blend-mode: overlay;
  opacity: 0.58;
  pointer-events: none;
}
/* The photograph is printed at full tone and stops at its own bottom edge, where
   the film bar begins: a frame ends on a line, it does not melt. The only
   darkening is the pad the title is set on — weighted to the left where the words
   are, held to the lower part of the frame by its mask, and never denser than
   0.6, which holds paper-white type over the brightest pixel this negative could
   put behind it at better than 4:1 while the rest of the picture keeps its tone. */
.hero-scrim {
  grid-row: 1;
  grid-column: 1;
  z-index: 2;
  align-self: stretch;
  background: linear-gradient(to right,
    rgb(var(--film-rgb) / 0.60) 0%,
    rgb(var(--film-rgb) / 0.58) 46%,
    rgb(var(--film-rgb) / 0.50) 64%,
    rgb(var(--film-rgb) / 0.20) 79%,
    rgb(var(--film-rgb) / 0) 92%);
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 48%, transparent 88%);
  mask-image: linear-gradient(to top, #000 0%, #000 48%, transparent 88%);
  pointer-events: none;
}
/* The title stands on the page's content column, which is what the wordmark above
   it and every section below it stand on. The frame is full-bleed, so its own left
   edge is the window's; the inset is the distance from there to that column, and
   the max() holds the plain gutter whenever the window is narrower than the column. */
.hero-title-block {
  grid-row: 1;
  grid-column: 1;
  align-self: end;
  z-index: 3;
  padding-inline: max(var(--gutter), calc((100% - var(--shell)) / 2 + var(--gutter)));
  padding-bottom: clamp(1.5rem, 3vw, 2.75rem);
  padding-top: 0;
}
#hero-title {
  color: var(--on-film);
  font-size: clamp(2.45rem, 7.4vw, 5rem);
  font-size: clamp(2.45rem, 7.4cqi, 5rem);
  font-weight: 500;
  max-width: min(18ch, 100%);
  margin: 0;
  text-shadow: 0 2px 18px rgb(var(--film-rgb) / 0.55);
}
#hero-title [data-hero-word] { display: inline-block; }

/* Browsers without svh keep the plain 2.2:1 frame and nothing else. The cap is
   what makes the cut move, so the percentage fallback is restated here at the
   value that survives the tightest cap the page can reach. */
@supports (height: 100svh) {
  #hero-img {
    max-height: max(var(--hero-img-min), calc(100svh - var(--hero-reserve)));
    object-position: 50% 12%;
    object-position: 50% -5.0625cqw;
  }
}

/* When the letterbox closes, the band left of the negative is the people in it,
   so the title is seated on the lower third of the frame and set a step smaller
   to stay there: the faces keep the light and the words keep the floor. The lede
   below keeps its own size — the short-viewport rule restacks it, never squeezes
   it — and the bar below still carries its caption rather than standing empty. */
@media (min-width: 34.01rem) and (max-height: 47.99rem) {
  #hero-title {
    font-size: clamp(1.95rem, 4vw, 2.5rem);
    font-size: clamp(1.95rem, 4cqi, 2.5rem);
    max-width: min(22ch, 100%);
  }
  .hero-title-block { padding-bottom: clamp(0.9rem, 1.8vw, 1.4rem); }
  .hero-scrim {
    -webkit-mask-image: linear-gradient(to top, #000 0%, #000 40%, transparent 78%);
    mask-image: linear-gradient(to top, #000 0%, #000 40%, transparent 78%);
  }
}

/* Film bar: the caption is furniture printed on the letterbox, not a caption slab. */
.hero-bar {
  grid-row: 2;
  grid-column: 1;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-height: var(--hero-foot);
  /* The bar's caption closes the content column on the right, the way the title
     opens it on the left. Same inset, so the frame carries one measure. */
  padding-block: 0.5rem;
  padding-inline: max(var(--gutter), calc((100% - var(--shell)) / 2 + var(--gutter)));
  background: var(--film);
}
.hero-caption { color: var(--on-film-2); }

/* The lede reads off the same left edge as the title above it and the wordmark
   above that: `.hero-below` is a plain `.shell`, so it inherits the content
   column and adds nothing of its own. */
.hero-below {
  display: grid;
  gap: clamp(1.25rem, 2.6vw, 2rem);
  padding-top: clamp(1.25rem, 2.6vw, 2rem);
}
.lede {
  font-size: clamp(1.3rem, 2.5vw, 1.75rem);
  line-height: 1.45;
  max-width: 30ch;
  font-weight: 400;
}
.hero-cta { display: grid; gap: 1.5rem; justify-items: start; align-content: start; }

@media (min-width: 60rem) {
  .hero-below {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    align-items: start;
    column-gap: clamp(2rem, 5vw, 4.5rem);
  }
  .lede { max-width: 28ch; }
}

@media (min-width: 60rem) and (max-height: 47.99rem) {
  .hero-below { grid-template-columns: minmax(0, 1fr); }
  .lede { font-size: 1.3rem; max-width: 56ch; }
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
}
.hero-note {
  font-size: 1.125rem;
  color: var(--umber-soft);
  max-width: 34ch;
}

/* ---------- Actions ---------- */
.action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  min-height: 60px;
  padding: 0 1.6rem;
  background: var(--blue);
  color: var(--white);
  border: 0;
  border-radius: 4px;
  font-family: var(--body);
  font-size: 1.125rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 140ms ease-out;
}
.action:hover { background: var(--blue-deep); color: var(--white); }
.action .icon { width: 1.2em; height: 1.2em; }

.action-text {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 56px;
  color: var(--blue);
  font-size: 1.125rem;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
}
.action-text:hover { color: var(--blue-deep); text-decoration-thickness: 2.5px; }
.action-text .icon { width: 1.1em; height: 1.1em; }

/* ---------- Section furniture ---------- */
section { scroll-margin-top: 1rem; }

.section-head { display: grid; gap: 1rem; max-width: 46rem; }
.section-head h2 {
  font-size: clamp(2rem, 4.4vw, 3.3rem);
  font-weight: 400;
}
.section-head p {
  font-size: 1.1875rem;
  color: var(--umber-soft);
  max-width: 62ch;
}

#lessons { padding-block: clamp(3rem, 6vw, 4.75rem) clamp(2.25rem, 4vw, 3.25rem); }

/* Four words of text are not a hit area. Each filter holds at least 88px of
   width whatever its label, and they stand 14px clear of each other so a hand
   with a tremor cannot press the wrong one on the way past. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 0.875rem;
  margin-top: clamp(2rem, 4vw, 3rem);
}
.filters button {
  position: relative;
  min-width: 5.5rem;
  min-height: 56px;
  padding: 0 1rem;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--umber-soft);
  font-family: var(--body);
  font-size: 1.125rem;
  font-weight: 600;
  cursor: pointer;
}
.filters button:hover {
  color: var(--umber);
  background: rgb(var(--umber-rgb) / 0.07);
}
/* Pressed is the topic that has been marked, so the whole control takes the ink:
   umber ground, the label reversed out of it. An underline alone is a whisper at
   arm's length on a tablet; a solid ground can be read across the room, and it
   says which topic is on without borrowing the reel slate's furniture for a
   control that is not a slate. */
.filters button[aria-pressed='true'] {
  background: var(--umber);
  border-bottom-color: var(--umber);
  color: var(--plaster);
}

/* The filters, the count, the rail and its cue are all worked by site.js.
   Without the script they are furniture that does nothing, so they are not
   printed at all — but the lessons themselves are in the markup, so the list
   below stays and the page is still the lesson guide it says it is. */
html:not(.js) .filters,
html:not(.js) #result-count,
html:not(.js) .rail-controls { display: none; }

.reel-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule);
}
/* The access footnote sits with the count line so it informs the tap before it
   happens, not after the reel has already been read. */
.reel-bar-info { display: flex; flex-direction: column; gap: 0.35rem; }
#result-count { color: var(--umber); }
.reel-bar-info .footnote { max-width: 46ch; }
.rail-controls { display: flex; align-items: center; gap: 0.75rem; }
/* Where the reel has reached, beside the controls that move it. */
.reel-position { color: var(--umber); white-space: nowrap; margin-right: 0.25rem; }
.rail {
  width: 56px; height: 56px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--umber);
  border-radius: 2px;
  background: transparent;
  color: var(--umber);
  cursor: pointer;
}
.rail:hover { background: var(--umber); color: var(--plaster); }
.rail[aria-disabled='true'] {
  border-color: var(--rule);
  color: var(--umber-soft);
  opacity: 0.45;
  cursor: default;
}
.rail[aria-disabled='true']:hover { background: transparent; color: var(--umber-soft); }
.rail .icon { width: 1.5rem; height: 1.5rem; }

/* ---------- The lesson browser ---------- */
/* Two modes over one DOM. `#lessons[data-mode]` is set by site.js: `list` is a
   vertical run of frames grouped by topic — no horizontal gesture anywhere, which
   is the point, because swiping a rail of links is the wrong primary movement for
   a hand with a tremor. `reel` is the wide-viewport, all-lessons exception, the
   horizontal roll of film with its rails and position cue. */
.reel-wrap {
  background: var(--plaster-deep);
  border-bottom: 1px solid var(--rule);
  margin-top: 0;
}
#reel:focus-visible { outline-offset: -3px; }

#lesson-list {
  --lesson-w: min(76vw, 23rem);   /* 368px max */
  --reel-gap: clamp(0.9rem, 2vw, 1.5rem);
}

/* ---- reel mode: one roll of film ---- */
[data-mode='reel'] #reel {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scroll-padding-left: var(--reel-pad);
  scrollbar-width: thin;
  scrollbar-color: var(--umber-soft) var(--plaster-deep);
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  -webkit-overflow-scrolling: touch;
}
[data-mode='reel'] #reel::-webkit-scrollbar { height: 10px; }
[data-mode='reel'] #reel::-webkit-scrollbar-track { background: var(--plaster-deep); }
[data-mode='reel'] #reel::-webkit-scrollbar-thumb { background: var(--umber-soft); border-radius: 0; }

[data-mode='reel'] #lesson-list {
  display: flex;
  align-items: stretch;
  gap: var(--reel-gap);
  width: max-content;
  padding-inline: var(--reel-pad);
}
/* The groups nest inside the same row, so the strip reads as one continuous take
   while each topic is still a named group for a screen reader. */
[data-mode='reel'] .topic-group,
[data-mode='reel'] .topic-lessons {
  display: flex;
  align-items: stretch;
  gap: var(--reel-gap);
}
/* In the reel the slate is the visible marker, so the group's heading is carried
   for the accessibility tree only — the grouping is never lost non-visually.
   The group is its containing block: an absolute box with no positioned ancestor
   would sit outside the scroller's clip and widen the whole page. */
[data-mode='reel'] .topic-group { position: relative; }
[data-mode='reel'] .topic-heading {
  position: absolute;
  top: 0; left: 0;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  font-size: 1rem;
}

/* ---- list mode: a vertical contact sheet by topic ---- */
[data-mode='list'] #reel {
  overflow: visible;
  padding-block: clamp(2rem, 4.5vw, 3rem);
}
[data-mode='list'] #lesson-list {
  display: grid;
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  gap: clamp(2.75rem, 5.5vw, 4rem);
}
[data-mode='list'] .topic-slate { display: none; }
[data-mode='list'] .topic-group {
  display: grid;
  gap: clamp(1.25rem, 2.5vw, 1.75rem);
}
.topic-heading {
  font-size: clamp(1.5rem, 3.4vw, 1.95rem);
  font-weight: 400;
}
/* One column on a phone; frames never wider than 400px, whatever the column does.
   Wide vertical gaps: a mis-tap should land on paper, not on the next lesson. */
[data-mode='list'] .topic-lessons {
  display: grid;
  grid-template-columns: minmax(0, 25rem);
  gap: clamp(2rem, 4vw, 2.75rem);
}
[data-mode='list'] .lesson { width: auto; }
@media (min-width: 48rem) {
  [data-mode='list'] .topic-lessons { grid-template-columns: repeat(2, minmax(0, 25rem)); }
}
@media (min-width: 68rem) {
  [data-mode='list'] .topic-lessons { grid-template-columns: repeat(3, minmax(0, 25rem)); }
}

/* Topic slate: a narrow clapperboard between groups in the rail. It stands to
   the height of the frames beside it — the image and its two tick strips — and
   stops there, rather than running on down past the captions. */
.topic-slate {
  flex: none;
  width: 2.75rem;
  align-self: flex-start;
  height: calc(var(--lesson-w) / 1.5 + 22px);
  display: flex;
  flex-direction: column;
  background: var(--film);
  scroll-snap-align: start;
}
.topic-slate::before {
  content: '';
  display: block;
  height: 1.25rem;
  background-image: repeating-linear-gradient(115deg, var(--on-film) 0 10px, var(--film) 10px 20px);
}
/* The label hangs from the clapper stripe with daylight under the diagonals
   instead of butting against them. The span reads bottom to top, so it is turned
   through 180deg, and that turn swaps both of its own axes: its `flex-end` and
   its padding-bottom land at the slate's visual TOP, against the stripe, while
   `align-items` runs across the slate's width. Physical padding only — in a
   vertical writing mode `padding-block` resolves sideways. */
.topic-slate span {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0.85rem 0 1.4rem;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--body);
  font-weight: 600;
  font-size: var(--fs-furniture);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--on-film);
  white-space: nowrap;
}

.lesson {
  flex: none;
  width: var(--lesson-w);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  text-decoration: none;
  color: var(--umber);
}
.lesson-frame {
  position: relative;
  background: var(--film);
  overflow: hidden;
}
/* Sprocket ticks along the top and bottom edges of every frame. */
.lesson-ticks {
  height: 11px;
  background-image: repeating-linear-gradient(to right, transparent 0 12px, var(--on-film-2) 12px 16px);
  opacity: 0.6;
  transition: opacity 160ms ease-out;
}
.lesson:hover .lesson-ticks { opacity: 0.85; }
.lesson-frame img {
  width: 100%;
  /* Every frame is cut 3:2, tighter than the 16:9 source, so the reel reads as
     one roll of film rather than a row of thumbnails. */
  aspect-ratio: 3 / 2;
  object-fit: cover;
  filter: saturate(1.04) contrast(1.03) sepia(0.05);
  transition: filter 160ms ease-out;
}
.lesson:hover .lesson-frame img { filter: saturate(1.1) contrast(1.06) sepia(0.02) brightness(1.04); }

/* The window every still is printed into is fixed at 3:2; only the print inside
   it moves. `--shot-zoom` is the enlargement, `--shot-x` / `--shot-y` where that
   enlargement rests in the overflow (0 is flush left or top, 1 flush right or
   bottom). site.js sets a print per lesson so no negative is shown twice at the
   same framing. A 3:2 window is 400 CSS px at its widest, and cover-scaling a
   640px negative into it shows the negative at zoom/1.35 of natural size, so the
   largest print on the page is 1.22x. */
.lesson-crop {
  aspect-ratio: 3 / 2;
  overflow: hidden;
}
.lesson-crop img {
  width: calc(var(--shot-zoom, 1.2) * 100%);
  max-width: none;
  margin-left: calc((1 - var(--shot-zoom, 1.2)) * var(--shot-x, 0.5) * 100%);
  /* The window is two thirds as tall as it is wide, so the vertical overflow is
     two thirds of the horizontal one and a percentage margin resolves on width. */
  margin-top: calc((1 - var(--shot-zoom, 1.2)) * var(--shot-y, 0.5) * 66.667%);
}

/* A numbered lesson whose still is already in the strip is printed as the film's
   own title card rather than a second copy of that negative: paper stock inside
   the same sprocket strips, the lesson's place in its topic set large in blue,
   its title under it. The strips and the runtime chip are the furniture every
   frame carries, so the card is a frame of the same roll and not a still that
   failed to load; the paper is a step lighter than the band it sits on, so the
   card has its own edges in the reel and in the list alike. The number is the
   lesson's place in its topic set, which is the one thing the card knows that
   the photograph would not have told you — so the accent goes there. */
.card-body {
  aspect-ratio: 3 / 2;
  display: grid;
  align-content: center;
  justify-items: center;
  padding: 1rem 1.25rem 1.6rem;
  text-align: center;
  background: var(--plaster);
  border: 1px solid var(--rule-strong);
}
.card-number {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 50;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--blue);
  font-size: clamp(3.9rem, 13vw, 4.75rem);
  line-height: 0.9;
  font-variant-numeric: tabular-nums;
}
.lesson .card-title {
  font-size: clamp(1.2rem, 3.2vw, 1.35rem);
  line-height: 1.14;
  color: var(--umber);
  max-width: 17ch;
}
/* The hairline a title card sets its title under. */
.card-title::before {
  content: '';
  display: block;
  width: 2.5rem;
  height: 1px;
  margin: 1.05rem auto 0.9rem;
  background: var(--rule-strong);
}
.lesson:hover .lesson-card .card-number { color: var(--blue-deep); }
.lesson:hover .lesson-card .card-title { color: var(--umber); }

.runtime {
  position: absolute;
  right: 0; bottom: 11px;
  padding: 0.3rem 0.6rem;
  background: rgb(var(--film-rgb) / 0.86);
  color: var(--on-film);
  font-family: var(--body);
  font-weight: 600;
  font-size: var(--fs-furniture-lg);
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}
.lesson-title {
  font-size: 1.375rem;
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.2;
}
.lesson-watch {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--body);
  font-weight: 600;
  font-size: 1.125rem;
  letter-spacing: 0.04em;
  color: var(--blue);
  margin-top: auto;
}
.lesson:hover .lesson-title { color: var(--blue-deep); }
.lesson-watch .icon { width: 1.05em; height: 1.05em; }

.lessons-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 2rem;
  padding-top: clamp(1.5rem, 3vw, 2rem);
}
.footnote {
  font-size: 1.125rem;
  color: var(--umber-soft);
  max-width: 54ch;
}

/* ---------- Approach: one print and the steps written beside it ---------- */
#approach { padding-block: clamp(3.25rem, 6.5vw, 5.25rem) clamp(2rem, 4vw, 3rem); }

/* The section carries a single photograph. The other two steps are set as text in
   the same caption voice, ruled off from one another the way notes are written
   down the side of a contact sheet — a rule is a caption's own furniture, where a
   box would make three of them into a card grid. */
.sheet {
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  display: grid;
  gap: clamp(2.25rem, 4.5vw, 3.25rem);
}

.still { margin: 0; overflow: hidden; }
.still img {
  width: 100%;
  object-fit: cover;
  filter: saturate(1.04) contrast(1.04) sepia(0.05);
}
.still-coach { max-width: 28.75rem; }    /* 460px */
.still-coach img { aspect-ratio: 4 / 3; object-position: 47% 52%; }

.sheet-steps { display: grid; align-content: start; gap: clamp(1.5rem, 3vw, 2rem); }
.sheet-step {
  display: grid;
  gap: 0.7rem;
  justify-items: start;
  max-width: 36rem;
}
.sheet-step + .sheet-step {
  padding-top: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid var(--rule);
}
.sheet-step h3 {
  font-size: clamp(1.4rem, 2.4vw, 1.85rem);
  font-weight: 400;
}
.sheet-step p {
  font-size: 1.125rem;
  color: var(--umber-soft);
  max-width: 34ch;
}

.large-line {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 50;
  font-weight: 400;
  font-size: clamp(1.7rem, 3.9vw, 3rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  max-width: 20ch;
  margin-block: clamp(1rem, 2.5vw, 2rem) 0;
  padding-top: 1.75rem;
  border-top: 2px solid var(--umber);
  text-wrap: balance;
}

/* Wide enough for the two columns: the print and the closing line stand in the
   left column, the three steps run down the right and carry it to the same foot,
   so the print has notes against it rather than paper beside it. */
@media (min-width: 62rem) {
  .sheet {
    grid-template-columns: minmax(0, 30rem) minmax(0, 1fr);
    column-gap: clamp(2.5rem, 5vw, 4.5rem);
    align-items: start;
  }
  .still-coach { grid-column: 1; grid-row: 1; }
  .large-line { grid-column: 1; grid-row: 2; }
  .sheet-steps { grid-column: 2; grid-row: 1 / span 2; }
}


/* ---------- Strip ---------- */
.strip {
  background: var(--plaster-deep);
  border-block: 1px solid var(--rule);
  margin-top: clamp(3rem, 7vw, 5rem);
}
.strip-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 2rem;
  padding-block: clamp(1rem, 2.5vw, 1.5rem);
}
.strip-inner p {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 50;
  font-size: clamp(1.25rem, 2.3vw, 1.6rem);
  line-height: 1.15;
  letter-spacing: -0.015em;
}

/* ---------- Introduction film ---------- */
#start { padding-block: clamp(4rem, 9vw, 7rem); }

/* Opening, varied: a film title and the line that names the film. The sentence is
   set beside the title as a caption on its own narrow measure, resting on the
   title's foot, and the title sits down on the frame it announces instead of
   floating a section's worth of air above it. */
@media (min-width: 62rem) {
  /* The caption stands on the same column the approach section's notes stand on
     — same 30rem print column, same gutter between — so the two sections open on
     one vertical instead of each finding its own edge. */
  #start .section-head {
    max-width: 51.5rem;
    grid-template-columns: minmax(0, 30rem) minmax(0, 17rem);
    column-gap: clamp(2.5rem, 5vw, 4.5rem);
    align-items: end;
  }
  #start .section-head p { max-width: none; padding-bottom: 0.4rem; }
}

.film { margin: clamp(1.25rem, 2.2vw, 1.75rem) 0 0; max-width: 48rem; }
.film-frame {
  position: relative;
  background: var(--film);
  padding: 0.75rem;
}
.film-frame img,
.film-frame iframe,
.film-crop {
  width: 100%;
  aspect-ratio: 16 / 9;
  display: block;
}
.film-frame img {
  object-fit: cover;
  object-position: 50% 50%;
  filter: sepia(0.18) saturate(1.35) hue-rotate(-8deg) contrast(1.04) brightness(0.88);
}
.film-frame iframe { border: 0; }

/* The poster's own cut of boxing.jpg. The window is the frame's 16:9 and the
   print inside it is enlarged until a 615px column of the 1280px negative — its
   right side, the heavy bag and the ring corner — fills the window edge to edge.
   615 of 1280 is the closest this negative can be printed without passing 1.25x
   natural size at the poster's widest, 744px inside the frame's black border.
   The window keeps the frame's ratio, so the player takes its place without the
   page moving: site.js hides this window, not the photograph inside it. */
.film-crop {
  --poster-window: 615;     /* source pixels across the window */
  --poster-left: 665;       /* source pixel the window opens on */
  --poster-top: 70;         /* source pixel the window's top edge sits at */
  overflow: hidden;
}
.film-crop img {
  width: calc(1280 / var(--poster-window) * 100%);
  max-width: none;
  aspect-ratio: 16 / 9;
  margin-left: calc(var(--poster-left) / var(--poster-window) * -100%);
  /* Percentage margins resolve on the window's width, which is what the print is
     scaled against, so the vertical offset is written in the same units. */
  margin-top: calc(var(--poster-top) / var(--poster-window) * -100%);
}
.play {
  position: absolute;
  inset: 0.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  border: 0;
  margin: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
  appearance: none;
  text-decoration: none;
  color: var(--on-film);
  background: linear-gradient(to bottom, rgb(var(--film-rgb) / 0.1), rgb(var(--film-rgb) / 0.55));
}
.play-glyph {
  width: clamp(72px, 12vw, 96px);
  height: clamp(72px, 12vw, 96px);
  fill: none;
  stroke: var(--on-film);
  stroke-width: 1.75;
  stroke-linejoin: round;
  transition: transform 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
.play-glyph circle { vector-effect: non-scaling-stroke; }
.play-glyph path { fill: var(--on-film); stroke: none; }
/* Without script the control is still an <a>, and the page-wide link hover would
   repaint this whole control — glyph, label and all — blue-deep on a dark
   photograph. On film-black the control keeps the paper colour and says it is
   live by growing the glyph and underlining the label instead. */
.play:hover,
.play:active { color: var(--on-film); }
.play:hover .play-glyph { transform: scale(1.06); }
.play-label {
  font-family: var(--body);
  font-weight: 600;
  font-size: 1.125rem;
  letter-spacing: 0.04em;
  text-align: center;
  text-shadow: 0 1px 10px rgb(var(--film-rgb) / 0.8);
}
.play:hover .play-label { text-decoration: underline; }

.film figcaption {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 1.5rem;
  padding-top: 0.9rem;
}

/* ---------- Membership ---------- */
#membership {
  background: var(--plaster-deep);
  border-block: 1px solid var(--rule);
  padding-block: clamp(3.5rem, 8vw, 6rem);
}
.membership-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 2rem 3rem;
}
.membership-inner .section-head { max-width: 38rem; }
.membership-cta { display: flex; flex-direction: column; align-items: flex-start; gap: 0.85rem; }
.membership-cta .footnote { max-width: 30rem; }

/* ---------- Questions ---------- */
#questions { padding-block: clamp(4rem, 9vw, 7rem); }
/* The questions stand on the page's content column like everything else. The
   reading measure belongs to the list and the note, not to a second column drawn
   around the whole section — that column is a fourth left edge.
   Opening, varied: one wide measure line, no standfirst under it, seated
   directly on the first question rather than held off by a section's air. */
#questions .section-head { max-width: none; }
#questions .section-head h2 { font-size: clamp(2.1rem, 5vw, 3.9rem); }

.faq {
  margin-top: clamp(1.25rem, 2.2vw, 1.75rem);
  max-width: 52rem;
  border-top: 1px solid var(--rule);
}
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 72px;
  padding-block: 1rem;
  cursor: pointer;
  list-style: none;
  font-family: var(--display);
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 50;
  font-size: clamp(1.2rem, 2.1vw, 1.5rem);
  /* A question that wraps is read, not scanned: looser than the display floor. */
  line-height: 1.3;
  letter-spacing: -0.015em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--blue-deep); }
.faq .icon-chev { transition: transform 180ms ease-out; color: var(--umber-soft); }
.faq details[open] .icon-chev { transform: rotate(180deg); }
.faq p {
  padding: 0 0 1.75rem;
  max-width: 62ch;
  color: var(--umber-soft);
  font-size: 1.125rem;
}

.safety {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: 1.35rem;
  max-width: 52rem;
  border-top: 2px solid var(--umber);
  display: grid;
  gap: 0.35rem;
}
.safety-lead {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 50;
  font-size: 1.45rem;
  line-height: 1.15;
  letter-spacing: -0.015em;
}
.safety p:last-child {
  font-size: 1.125rem;
  color: var(--umber-soft);
  max-width: 54ch;
}

/* ---------- Colophon ---------- */
/* Plaster-deep, not film-black: film-black belongs to the letterbox and the
   film frame only. */
.colophon {
  background: var(--plaster-deep);
  color: var(--umber);
  border-top: 1px solid var(--rule);
  padding-block: clamp(3rem, 6vw, 4.5rem);
}
.colophon-inner {
  display: grid;
  gap: 2.5rem clamp(2rem, 5vw, 4rem);
  align-items: start;
}
@media (min-width: 52rem) {
  .colophon-inner { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr) minmax(0, 1fr); }
}
.colophon .brand { color: var(--umber); margin-right: 0; }
.colophon .brand-by { color: var(--umber-soft); }
.colophon .brand:hover .brand-mark { color: var(--blue); }
.colophon .furniture { color: var(--umber-soft); }
.colophon-line {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 50;
  font-size: 1.45rem;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin-top: 0.75rem;
  color: var(--umber);
}
.colophon-links ul { list-style: none; margin: 0; padding: 0; }
.colophon-links a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 56px;
  color: var(--blue);
  font-size: 1.125rem;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: rgb(var(--blue-rgb) / 0.45);
}
.colophon-links a:hover { color: var(--blue-deep); text-decoration-color: currentColor; }
.colophon-links .icon { width: 1.05em; height: 1.05em; }
.colophon-notes { display: grid; gap: 0.6rem; justify-items: start; }
/* A sentence that is read, not a label that is glanced at: body size. */
.colophon-notes .furniture { font-size: 1.125rem; letter-spacing: 0.01em; }

/* ---------- Narrow ---------- */
@media (max-width: 55.99rem) {
  .masthead-inner { min-height: 68px; gap: 0.75rem; }

  /* The collapse belongs to the script that can open it again. Without JS the
     nav stays stacked and visible, and the control that would open it is gone. */
  .menu-toggle { display: inline-flex; }
  html:not(.js) .menu-toggle { display: none; }

  #navigation {
    flex-basis: 100%;
    border-top: 1px solid var(--rule);
    padding-bottom: 0.75rem;
  }
  html.js #navigation { display: none; }
  html.js #navigation.is-open { display: block; }
  #navigation ul { flex-direction: column; align-items: stretch; gap: 0; }
  #navigation li + li { border-top: 1px solid var(--rule); }
  #navigation a { width: 100%; border-bottom: 0; }
  #navigation a:hover { border-bottom: 0; }
}

/* Narrow: the masthead lockup stacks so the menu control keeps its own line, and
   the opening frame becomes a true title card — clean 2.2:1 photograph above, the
   title set inside the film bar below, well clear of the image edge. */
@media (max-width: 34rem) {
  /* Stacked, the lockup's wrap line is its own width, and `align-content` now
     runs across the page instead of down it — centred, the footer wordmark left
     the left edge every other line in the footer is set on. */
  .brand { flex-direction: column; align-items: flex-start; align-content: flex-start; gap: 0.12rem; }
  .brand-mark { font-size: 1.4rem; }
  .reel-bar { flex-wrap: wrap; }
  .reel-bar-info { flex: 1 1 100%; }
  .rail-controls { margin-left: auto; }

  #hero-photo { max-width: none; }
  /* A 2.2:1 letterbox on a phone is 170px of picture under a title block the same
     size again. The frame is cut 3:2 instead — 4:3 on the narrowest phones, where
     the floor holds it — so it is 240 to 270px of photograph. A 3:2 window on a
     16:9 negative takes the sides, never the top or the bottom, so every head in
     the frame is held whatever the phone's width. */
  #hero-img {
    aspect-ratio: 3 / 2;
    min-height: 15rem;   /* 240px */
    max-height: 16.875rem;  /* 270px */
  }
  /* The title is on the black below the photograph here, so the picture needs no
     pad at all and keeps its full tone edge to edge. */
  .hero-scrim { background: none; }
  /* The black block under the photograph is the title's, so it is cut to the
     title: enough air to keep the words off the picture edge and off the
     caption, and nothing beyond that. */
  .hero-title-block {
    grid-row: 2;
    align-self: auto;
    padding: clamp(0.55rem, 2.3vw, 1.1rem) var(--gutter) 0;
  }
  #hero-title {
    font-size: clamp(1.95rem, 8vw, 2.9rem);
    max-width: 14ch;
    text-shadow: none;
  }
  /* Stacked, the bar is no longer a letterbox foot inset to the content column —
     it is the line under the title, set on the page's own gutter. */
  .hero-bar {
    grid-row: 3;
    min-height: 0;
    padding-top: 0.5rem;
    padding-bottom: clamp(0.5rem, 2.2vw, 1rem);
    padding-inline: var(--gutter);
  }
  /* The taller frame is paid for out of the air around the words, not out of the
     words: everything between the bar and the first action closes up by a few
     pixels so "Find your first lesson" still lands inside the smallest phone. */
  .hero-below { padding-top: clamp(0.75rem, 3.4vw, 1.4rem); gap: 0.9rem; }
  .hero-cta { gap: 1.1rem; }

  /* Hero foot to the lessons heading: two section paddings stacked put 88px of
     air between the micro-line and "Lessons", where the rest of the page turns a
     section on about 55. The hero gives its share back and the lessons section
     keeps its own opening. */
  #hero { padding-bottom: 0.5rem; }

  /* ---- list mode on a phone: a title card is set as a strip ---- */
  /* In the reel a title card stands in for a photograph and is cut to the same
     3:2 so the roll reads as one roll. Down a phone list that trade stops
     paying: five of the nine lessons become 250px of near-empty paper, and the
     first lesson of a later topic sits a screen and a half down. The same card
     is printed as a strip here — same stock, same sprocket ticks, same blue
     numeral, same title and runtime chip — with the numeral set beside the
     title instead of above it. Photographs keep their 3:2 frames. */
  [data-mode='list'] .lesson-card .card-body {
    aspect-ratio: auto;
    min-height: 6.25rem;         /* 100px of paper, 122px with both tick strips */
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    justify-items: start;
    column-gap: 0.85rem;
    padding: 0.9rem 1rem 0.9rem 1.1rem;
    text-align: left;
  }
  [data-mode='list'] .lesson-card .card-number {
    font-size: 2.9rem;
    line-height: 0.85;
  }
  [data-mode='list'] .lesson-card .card-title {
    max-width: none;
    /* The runtime chip keeps its own corner, so the title stops short of it —
       53px of chip and room to spare, so the two never touch at 320. */
    padding-right: 3.5rem;
  }
  /* The hairline is what a centred title is set under. Beside a numeral there is
     nothing for it to divide. */
  [data-mode='list'] .lesson-card .card-title::before { display: none; }

  /* ---- Approach: coach.jpg cut in ---- */
  /* Fitted to the 4:3 window the negative is shown whole, which on a phone is
     mostly dark ceiling and dark floor with the coach standing small between
     them. A 400px column of the 640px negative is printed through the same
     window instead, which lifts the coach clear of the empty floor at 0.84x
     natural size. Same window arithmetic as .lesson-crop. */
  .still-coach { aspect-ratio: 4 / 3; }
  .still-coach img {
    --coach-window: 400;   /* source pixels across the window */
    --coach-left: 115;     /* source pixel the window opens on */
    --coach-top: 47;       /* source pixel the window's top edge sits at */
    display: block;
    aspect-ratio: auto;
    height: auto;
    width: calc(640 / var(--coach-window) * 100%);
    max-width: none;
    margin-left: calc(var(--coach-left) / var(--coach-window) * -100%);
    /* Percentage margins resolve on the window's width, which is what the print
       is scaled against, so the vertical offset is written in the same units. */
    margin-top: calc(var(--coach-top) / var(--coach-window) * -100%);
  }
}

@media (max-width: 30rem) {
  .membership-inner .action { width: 100%; }
}

/* Four topics on a phone wrap three and one, and the fourth alone on its own line
   reads as a different kind of control. Two by two is the same four tabs, evenly
   set, with every hit area a little wider than it was. */
@media (max-width: 23.99rem) {
  .filters {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .filters button { min-width: 0; }
}
