/* ============================================================
   THE INTERIOR CHASSIS (wave 1 of design completion).
   Blocks: B1 .pagehead, B2 .prose, B5 .ctaband, plus the 404.
   The homepage keeps its own sheets; interior pages load this one.
   Class names grep-checked against every sheet before coining (the
   .tl collision lesson).
   ============================================================ */

/* ---- the shared dark ground: the menu's world, quoted exactly.
   Used by the interior CTA band and the 404. ---- */
.menuground {
  position: relative;
  background: radial-gradient(120% 130% at 50% 40%, #171243 0%, #0b0724 55%, #070517 100%);
  color: var(--on-dark);
}
.menuground::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(120, 140, 255, .07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(120, 140, 255, .05) 1px, transparent 1px);
  background-size: 46px 46px;
}
.menuground::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background: repeating-linear-gradient(180deg, rgba(8, 6, 28, .28) 0 1px, transparent 1px 3px);
}
.menuground > * { position: relative; z-index: 1; }

/* ============================================================
   B1: the pagehead. A DARK hero on the menu's ground (Nick, 16
   September: a paper top under the dark chrome read as starting
   partway down the page; every interior opens dark now). Title set
   left, the photograph breaking the right edge, media optional.
   ============================================================ */
.pagehead { container-type: inline-size;
  /* clear the fixed brand mark and menu button */
  padding-top: clamp(92px, 11vh, 112px); }
.pagehead h1, .pagehead__title { color: #fff; }
.pagehead__lede { color: var(--on-dark); }
.pagehead__grid {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  padding-block: clamp(3.6rem, 8vh, 6.5rem) clamp(3rem, 7vh, 5.5rem);
}
.pagehead h1, .pagehead__title {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(2.5rem, 5vw, 4.6rem);
  line-height: .98; letter-spacing: -.035em;
  max-width: 14ch; text-wrap: balance;
}
.pagehead__lede {
  margin-top: clamp(1.2rem, 2.4vw, 1.7rem);
  font-family: var(--f-prose);
  font-size: clamp(1.08rem, 1.35vw, 1.32rem); line-height: 1.55;
  max-width: 44ch; text-wrap: pretty;
}
/* the edge break: the photograph runs from its column to the viewport's
   right edge. cqi, not vw: 100vw counts the scrollbar (the recorded
   trap); the section is the inline-size container. */
.pagehead__media { position: relative; min-width: 0; }
.pagehead__media img {
  display: block; object-fit: cover;
  height: clamp(300px, 30cqi, 460px);
  width: calc(100% + (100cqi - min(100cqi, var(--container))) / 2 + var(--container-pad));
  max-width: none;
}
@media (max-width: 860px) {
  .pagehead__grid { grid-template-columns: 1fr; gap: 1.9rem; padding-block: clamp(2.6rem, 6vh, 4rem) clamp(2.4rem, 5vh, 3.4rem); }
  /* full bleed below the title on small screens */
  .pagehead__media img { width: calc(100% + 2 * var(--container-pad)); margin-inline: calc(-1 * var(--container-pad)); height: clamp(220px, 52cqi, 340px); }
}

/* ============================================================
   B2: prose. The reading voice for every interior. 68ch, the page's
   own faces, the statement blockquote is the giving story's approved
   accent-bar treatment, links are the paper marker link.
   ============================================================ */
.pagebody { background: var(--paper); color: var(--ink); container-type: inline-size;
  padding-block: clamp(3rem, 8vh, 5.5rem) clamp(4.5rem, 10vh, 7.5rem); }
.prose { max-width: 68ch; font-family: var(--f-prose); font-size: clamp(1.05rem, 1.18vw, 1.18rem); line-height: 1.65; }
.prose p { text-wrap: pretty; }
.prose p + p { margin-top: 1.3em; }
.prose h2 {
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.45rem, 2vw, 1.9rem); letter-spacing: -.02em; line-height: 1.15;
  margin: 2.4em 0 .75em;
}
.prose h3 {
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.15rem, 1.5vw, 1.35rem); letter-spacing: -.015em;
  margin: 2em 0 .6em;
}
.prose ul, .prose ol { margin: 1.3em 0; padding-left: 1.25em; }
.prose li + li { margin-top: .55em; }
.prose li::marker { color: var(--accent-ink); }
.prose blockquote {
  margin: 2.1em 0; padding-left: clamp(1rem, 2vw, 1.4rem);
  border-left: 4px solid var(--accent);
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.28rem, 1.8vw, 1.66rem); line-height: 1.38; letter-spacing: -.015em;
  max-width: 40ch;
}
.prose img { display: block; margin: 2em 0; }
/* a photograph breaking the right edge mid-flow: the prose block's one
   breakout option (a block style at implementation) */
.prose .figure-breakout { margin: 2.4em 0; }
.prose .figure-breakout img {
  margin: 0; object-fit: cover;
  height: clamp(260px, 26cqi, 400px);
  width: calc(100% + (100cqi - min(100cqi, var(--container))) / 2 + var(--container-pad));
  max-width: none;
}
@media (max-width: 1000px) {
  .prose .figure-breakout img { width: calc(100% + 2 * var(--container-pad)); margin-inline: calc(-1 * var(--container-pad)); }
}
.prose a {
  color: var(--accent-ink);
  text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 2px;
  text-decoration-color: var(--accent);
  transition: color var(--dur-1) var(--ease-out);
}
/* re-keys on hover (main.js), resolving to ink */
.prose a:hover, .prose a:focus-visible { color: var(--ink); }

/* ============================================================
   B5: the interior CTA band. The ask's world at interior weight:
   heading left, the action column right. The homepage ask keeps the
   page's one deliberate centring; interiors stay asymmetric.
   ============================================================ */
.ctaband { padding-block: clamp(5rem, 13vh, 8.5rem); }
.ctaband__inner {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
}
.ctaband h2 {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(2rem, 3.6vw, 3.2rem); line-height: 1.02; letter-spacing: -.03em;
  color: #fff; max-width: 14ch; text-wrap: balance;
}
.ctaband__act p {
  font-family: var(--f-prose); font-size: clamp(1.02rem, 1.2vw, 1.16rem); line-height: 1.6;
  color: var(--on-dark); max-width: 38ch; text-wrap: pretty;
}
.ctaband__row { display: flex; align-items: center; flex-wrap: wrap; gap: 1.5rem; margin-top: 1.5rem; }
@media (max-width: 860px) {
  .ctaband__inner { grid-template-columns: 1fr; gap: 1.6rem; }
}

/* ============================================================
   B3: the split section. One heading set left, copy beside imagery,
   the photograph breaking the container edge; --rev flips the image to
   the left edge. Ground stays paper by default. Explicit collapse.
   ============================================================ */
.splitb { background: var(--paper); color: var(--ink); container-type: inline-size;
  padding-block: clamp(3.5rem, 9vh, 6.5rem); }
.splitb__grid { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.splitb h2 {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.7rem, 2.9vw, 2.7rem); line-height: 1.04; letter-spacing: -.03em;
  max-width: 16ch; text-wrap: balance;
}
.splitb__copy p {
  margin-top: clamp(1rem, 2vw, 1.4rem);
  font-family: var(--f-prose); font-size: clamp(1.02rem, 1.16vw, 1.16rem); line-height: 1.62;
  max-width: 52ch; text-wrap: pretty;
}
.splitb__media { position: relative; min-width: 0; }
.splitb__media img { display: block; object-fit: cover;
  height: clamp(300px, 28cqi, 440px);
  width: calc(100% + (100cqi - min(100cqi, var(--container))) / 2 + var(--container-pad));
  max-width: none;
}
/* reversed: the image breaks the LEFT edge instead */
.splitb--rev .splitb__grid > .splitb__media { order: -1; }
.splitb--rev .splitb__media img {
  margin-left: calc(-1 * ((100cqi - min(100cqi, var(--container))) / 2 + var(--container-pad)));
}
@media (max-width: 860px) {
  .splitb__grid { grid-template-columns: 1fr; gap: 1.7rem; }
  .splitb__media { order: -1; }
  .splitb__media img, .splitb--rev .splitb__media img {
    width: calc(100% + 2 * var(--container-pad)); margin-inline: calc(-1 * var(--container-pad));
    height: clamp(210px, 48cqi, 320px);
  }
}

/* ============================================================
   B9 (first form): the people band. A full-bleed photograph, graded
   down, the copy landing bottom left: the giving overlay's grammar at
   interior weight.
   ============================================================ */
.peopleband { position: relative; overflow: hidden; color: #fff;
  display: grid; align-items: end; min-height: clamp(420px, 62vh, 640px); }
.peopleband__img { position: absolute; inset: 0; }
.peopleband__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.peopleband__img::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(5, 4, 16, .16) 22%, rgba(5, 4, 16, .88) 92%); }
@media (max-width: 700px) {
  /* the phone crop pushes the copy up into the photograph's bright zone:
     the grade runs deeper there (measured to AA on painted pixels) */
  .peopleband__img::after {
    background: linear-gradient(180deg, rgba(5, 4, 16, .22) 12%, rgba(5, 4, 16, .92) 78%); }
}
.peopleband__copy { position: relative; z-index: 1; padding-block: clamp(2.2rem, 6vh, 3.6rem); }
.peopleband h2 {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.7rem, 2.9vw, 2.7rem); line-height: 1.04; letter-spacing: -.03em;
  max-width: 16ch;
}
.peopleband p {
  margin-top: clamp(.9rem, 1.8vw, 1.2rem);
  font-family: var(--f-prose); font-size: clamp(1.02rem, 1.16vw, 1.16rem); line-height: 1.6;
  max-width: 54ch; text-wrap: pretty;
}

/* ============================================================
   B15: the accreditation, full. The footer strip's big sibling: the
   heading and Adrian's complete paragraph left, the two certification
   marks beside it.
   ============================================================ */
.accredfull { background: var(--paper); color: var(--ink);
  padding-block: clamp(3.5rem, 9vh, 6.5rem); border-top: 1px solid var(--rule); }
.accredfull__grid { display: grid; grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.accredfull h2 {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.7rem, 2.9vw, 2.7rem); line-height: 1.04; letter-spacing: -.03em;
  max-width: 18ch; text-wrap: balance;
}
.accredfull p {
  margin-top: clamp(1rem, 2vw, 1.4rem);
  font-family: var(--f-prose); font-size: clamp(1.02rem, 1.16vw, 1.16rem); line-height: 1.62;
  max-width: 62ch; text-wrap: pretty;
}
.accredfull__marks { display: flex; align-items: center; justify-content: flex-end;
  gap: clamp(1.4rem, 3vw, 2.4rem); flex-wrap: wrap; }
.accredfull__marks img { display: block; width: clamp(88px, 9vw, 128px); height: auto; }
@media (max-width: 860px) {
  .accredfull__grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .accredfull__marks { justify-content: flex-start; }
}

/* ============================================================
   B10: cards (.cardrow). Exactly as many cards as content, never more
   than three. Hover pairs the border resolve with a lift.
   ============================================================ */
.cardrow { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6.5rem); }
.cardrow > .container > h2 {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.7rem, 2.9vw, 2.7rem); line-height: 1.04; letter-spacing: -.03em;
  max-width: 16ch; text-wrap: balance; margin-bottom: clamp(1.5rem, 3.5vh, 2.4rem);
}
.cardrow__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem); }
.cardb { display: block; color: inherit; text-decoration: none;
  border: 1px solid var(--rule); border-radius: 6px; overflow: hidden; position: relative; }
/* the optional media slot: an image at the card's top, full bleed to
   its edges, for cards that explain a process or show a scene */
.cardb__media { display: block; aspect-ratio: 16 / 9; overflow: hidden; }
.cardb__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cardb__body { display: block; padding: clamp(1.4rem, 2.5vw, 2rem); }
/* the hover belongs to LINKED cards only: an unlinked card that lifts is
   a false affordance (carrier catch) */
/* linked cards take the lock corners (below); an unlinked card has no hover */
.cardb h3 { font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.1rem, 1.5vw, 1.3rem); letter-spacing: -.015em; }
.cardb p { margin-top: .7rem; font-family: var(--f-prose);
  font-size: clamp(.98rem, 1.1vw, 1.08rem); line-height: 1.58; color: var(--ink-soft); }
.scheme-dark .cardb p { color: var(--on-dark); }
@media (max-width: 860px) { .cardrow__grid { grid-template-columns: 1fr; } }

/* ============================================================
   Gallery (.galleryb). Asymmetric spans, photographs square like every
   photograph on the site, no captions.
   ============================================================ */
.galleryb { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6.5rem); }
.galleryb__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(.8rem, 1.5vw, 1.2rem); }
.galleryb figure { margin: 0; }
.galleryb img { width: 100%; height: clamp(240px, 26vw, 380px); object-fit: cover; display: block; }
.galleryb figure:nth-child(4n+1) { grid-column: span 7; }
.galleryb figure:nth-child(4n+2) { grid-column: span 5; }
.galleryb figure:nth-child(4n+3) { grid-column: span 5; }
.galleryb figure:nth-child(4n) { grid-column: span 7; }
@media (max-width: 860px) {
  .galleryb figure { grid-column: span 12 !important; }
  .galleryb img { height: clamp(200px, 52vw, 300px); }
}

/* ============================================================
   List (.listb). The genuinely ordered case (a process), which is what
   unlocks the numbers: machine-voice ordinals, hairline rows, the
   heading in its own left column.
   ============================================================ */
.listb { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6.5rem); }
.listb__grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.listb h2 { font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.7rem, 2.9vw, 2.7rem); line-height: 1.04; letter-spacing: -.03em;
  max-width: 14ch; text-wrap: balance; }
.listb ol { list-style: none; margin: 0; padding: 0; }
.listb li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1.2rem;
  padding-block: 1.2rem; border-top: 1px solid var(--rule); }
.listb li:last-child { border-bottom: 1px solid var(--rule); }
.listb__num { font-family: var(--f-machine); font-size: .68rem; letter-spacing: .16em;
  color: var(--accent-ink); padding-top: .45em; }
.listb h3 { font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.08rem, 1.4vw, 1.25rem); letter-spacing: -.015em; }
.listb li p { margin-top: .35rem; font-family: var(--f-prose);
  font-size: clamp(.98rem, 1.1vw, 1.08rem); line-height: 1.55; color: var(--ink-soft);
  max-width: 48ch; }
@media (max-width: 860px) { .listb__grid { grid-template-columns: 1fr; gap: 1.4rem; } }

/* ============================================================
   The quote band (.quoteband). Big, unboxed, CENTRED ON PURPOSE
   (Nick's call, 16 September): its job is breaking up two similar
   sections, so it reads as a breath, never a card. Two forms of ONE
   block: a quotation (real marks in the text, attribution name plus
   role) or a bare statement (no marks, no figcaption). The old
   statement band is retired into this block, which also retires the
   third dark ground the carrier flagged.
   ============================================================ */
.quoteband { background: var(--paper); color: var(--ink);
  padding-block: clamp(4rem, 10vh, 7rem); }
.quoteband figure { margin: 0; }
.quoteband blockquote { margin: 0 auto; max-width: 24ch; text-align: center;
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.7rem, 3vw, 2.8rem); line-height: 1.25; letter-spacing: -.025em;
  text-wrap: pretty; }
.quoteband figcaption { margin-top: 1.2rem; text-align: center;
  font-family: var(--f-prose); font-size: .95rem; color: var(--ink-soft); }

/* ============================================================
   B7: the portfolio roll (.filmroll). Film cards in the wall's own
   grammar: dark 16:9 frames, the live ring arriving on hover with a
   gentle push in, name and cause as metadata under the frame.
   ============================================================ */
.filmroll { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6.5rem); }
.filmroll__row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem); }
.filmcard { display: block; text-decoration: none; color: inherit; }
.filmcard__frame { display: block; /* a span is inline and ignores
    aspect-ratio: the recorded VidZero span trap, paid again here */
  position: relative; aspect-ratio: 16 / 9; border-radius: 6px;
  overflow: hidden; background: #0b0b10;
  box-shadow: inset 0 0 0 1px rgba(8, 6, 28, .2);
  transition: box-shadow var(--dur-1) var(--ease-out); }
.filmcard__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* the hover is the lock corners (defined once, below the scheme rules) */
.filmcard__meta { display: flex; align-items: baseline; gap: .9em; margin-top: .75rem; }
.filmcard__name { font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1rem, 1.2vw, 1.14rem); letter-spacing: -.01em; }
.filmcard__cause { font-family: var(--f-machine); font-size: .62rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
@media (max-width: 860px) {
  .filmroll__row { grid-template-columns: 1fr; }
}

/* ============================================================
   The shared block header (.blockhead). Every content block can open
   with any combination of heading, subheading, paragraph and CTA: one
   vocabulary, the same on every block, per the WordPress playbook's
   standardised controls. Absent parts simply are not authored.
   ============================================================ */
/* Asymmetric, per the site's own grammar (Nick, 16 September: a full
   stacked column before the cards read unbalanced): the heading and
   subheading lead left, and the paragraph, CTA or link sit as the
   right-hand counterweight. Absent parts are simply not authored. */
.blockhead { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 1rem clamp(1.5rem, 4vw, 4rem); align-items: end;
  margin-bottom: clamp(1.6rem, 4vh, 2.6rem); }
.blockhead h2 {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.7rem, 2.9vw, 2.7rem); line-height: 1.04; letter-spacing: -.03em;
  max-width: 16ch; text-wrap: balance;
}
.blockhead__sub {
  margin-top: .65rem;
  font-family: var(--f-prose); font-size: clamp(1.05rem, 1.3vw, 1.24rem); line-height: 1.5;
  color: var(--ink-soft); max-width: 46ch; text-wrap: pretty;
}
.blockhead__aside { display: flex; flex-direction: column; align-items: flex-start;
  gap: 1.1rem; justify-content: flex-end; }
.blockhead__aside p {
  margin: 0; font-family: var(--f-prose);
  font-size: clamp(1rem, 1.14vw, 1.12rem); line-height: 1.6;
  color: var(--ink); max-width: 42ch; text-wrap: pretty;
}
.blockhead__aside--end { align-items: flex-end; }
.blockhead__cta { display: flex; align-items: center; flex-wrap: wrap; gap: 1rem 1.5rem; }
/* inside the list block's left column the header stacks plainly, the
   paragraph and CTA following the heading */
.listb .blockhead { display: block; }
.listb .blockhead__aside { margin-top: 1.4rem; }
@media (max-width: 1000px) {
  .blockhead { grid-template-columns: 1fr; align-items: start; }
  .blockhead__aside, .blockhead__aside--end { align-items: flex-start; }
}

/* ============================================================
   The dark scheme (.scheme-dark). One class, one meaning, every block:
   the flat deep ink ground (the menu's world stays reserved for the
   hero, the CTA band and the 404).
   ============================================================ */
.scheme-dark { background: #0B0724; color: var(--on-dark); }
.scheme-dark h2, .scheme-dark h3, .scheme-dark .filmcard__name { color: #fff; }
/* the scheme class sits ON the block element itself, so every selector
   naming the block class needs the same-element compound form beside
   the descendant form (the blockquote pair below had it; the list and
   figcaption forms were missing it, caught by the kit gate) */
.scheme-dark .blockhead__sub, .scheme-dark .blockhead__aside p,
.scheme-dark .cardb p, .scheme-dark .listb li p, .listb.scheme-dark li p,
.scheme-dark .quoteband figcaption, .quoteband.scheme-dark figcaption { color: var(--on-dark); }
.scheme-dark .quoteband blockquote, .scheme-dark.quoteband blockquote { color: #fff; }
.scheme-dark .cardb, .scheme-dark.cardrow .cardb {
  background: rgba(240, 238, 252, .05); border-color: rgba(240, 238, 252, .16); }
.scheme-dark .listb li, .listb.scheme-dark li { border-color: rgba(240, 238, 252, .18); }
.scheme-dark .listb li:last-child, .listb.scheme-dark li:last-child { border-color: rgba(240, 238, 252, .18); }
.scheme-dark .listb__num { color: var(--accent-on-dark, #8FA3FF); }
.scheme-dark .filmcard__cause { color: var(--on-dark); }
.scheme-dark .filmcard__frame { box-shadow: inset 0 0 0 1px rgba(240, 238, 252, .14); }
/* links inside a dark block take the dark link colours automatically */
.scheme-dark .plink {
  color: var(--accent-on-dark, #8FA3FF);
  text-decoration-color: var(--accent-on-dark, #8FA3FF);
}
.scheme-dark .plink:hover, .scheme-dark .plink:focus-visible { color: #fff; }

/* ============================================================
   Gallery lightbox option: figures become buttons when the block is
   flagged, opening full size in the site's shared lightbox.
   ============================================================ */
.galleryb__item { display: block; width: 100%; padding: 0; border: 0;
  background: none; cursor: zoom-in; }
.galleryb__item:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.lightbox__frame img { width: 100%; height: 100%; object-fit: contain;
  display: block; background: #000; }
.lightbox__frame video { width: 100%; height: 100%; object-fit: contain;
  display: block; background: #000; }

/* ============================================================
   B6: the FAQ block (.faqb). The conversation's in-list accordion as
   an interior block: hairline rows, one open at a time, the answer
   resolving from soft (the rack-focus arrival), a drawn chevron.
   ============================================================ */
.faqb { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6.5rem); }
/* this block sits AFTER the scheme rules in the sheet, so its own
   ground must re-assert the dark scheme explicitly (cascade order) */
.faqb.scheme-dark { background: #0B0724; color: var(--on-dark); }
.faqb__item { border-top: 1px solid var(--rule); }
.faqb__item:last-child { border-bottom: 1px solid var(--rule); }
.faqb__q { display: flex; justify-content: space-between; align-items: center; gap: 1.2rem;
  width: 100%; padding: 1.2rem 0; background: none; border: 0; text-align: left; cursor: pointer;
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.08rem, 1.5vw, 1.3rem); letter-spacing: -.015em; color: inherit; }
.faqb__q:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.faqb__q::after { content: ""; flex: none; width: 9px; height: 9px; margin-right: .3rem;
  border-right: 2px solid var(--accent-ink); border-bottom: 2px solid var(--accent-ink);
  rotate: 45deg; translate: 0 -2px;
  transition: rotate var(--dur-1) var(--ease-out), translate var(--dur-1) var(--ease-out); }
.faqb__item.is-open .faqb__q::after { rotate: 225deg; translate: 0 2px; }
.faqb__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .45s var(--ease-out); }
.faqb__item.is-open .faqb__a { grid-template-rows: 1fr; }
.faqb__a > div { overflow: hidden; }
.faqb__a p { margin: 0; padding: 0 0 1.3rem;
  font-family: var(--f-prose); font-size: clamp(1rem, 1.12vw, 1.1rem); line-height: 1.6;
  color: var(--ink-soft); max-width: 60ch; text-wrap: pretty;
  filter: blur(6px); opacity: .2;
  transition: filter .45s var(--ease-out), opacity .45s var(--ease-out); }
.faqb__item.is-open .faqb__a p { filter: blur(0); opacity: 1; }
.scheme-dark .faqb__item, .scheme-dark .faqb__item:last-child { border-color: rgba(240, 238, 252, .18); }
.scheme-dark .faqb__q { color: #fff; }
.scheme-dark .faqb__q::after { border-color: var(--accent-on-dark, #8FA3FF); }
.scheme-dark .faqb__a p { color: var(--on-dark); }
@media (prefers-reduced-motion: reduce) {
  .faqb__a, .faqb__a p, .faqb__q::after { transition: none; }
  .faqb__a p { filter: none; opacity: 1; }
}

/* ============================================================
   B16: the feature film (.filmb). ONE film at full width, mounted in
   the wall's own object: the dark monitor bezel (16px body, 6px
   screen, the work wall's exact grade). The whole frame is the play
   control and opens the film in the shared lightbox; the meta line
   under the frame reuses the roll's grammar.
   Defined after the scheme rules, so the dark ground re-asserts.
   ============================================================ */
.filmb { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6.5rem); }
.filmb.scheme-dark { background: #0B0724; color: var(--on-dark); }
.filmb__frame { display: block; width: 100%; padding: clamp(10px, 1.1vw, 18px);
  border: 0; cursor: pointer;
  background: linear-gradient(158deg, #1b1b22, #0d0d12); border-radius: 16px;
  box-shadow: 0 30px 70px rgba(0, 0, 0, .35), inset 0 0 0 1px rgba(255, 255, 255, .06); }
.filmb__frame:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.filmb__screen { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: 6px;
  overflow: hidden; background: #000;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .8), inset 0 0 40px rgba(0, 0, 0, .6); }
.filmb__screen img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.filmb__screen::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(4, 4, 10, .15), transparent 40%, transparent 62%, rgba(4, 4, 10, .5)); }
.filmb__play { position: absolute; inset: 0; z-index: 1; display: grid; place-items: center; }
.filmb__play::before, .filmb__play::after { content: ""; grid-area: 1 / 1; }
.filmb__play::before { width: clamp(64px, 7vw, 84px); aspect-ratio: 1; border-radius: 50%;
  background: rgba(7, 5, 23, .6); box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .9);
  transition: box-shadow var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out), scale var(--dur-1) var(--ease-out); }
.filmb__play::after { width: 0; height: 0; border-block: 11px solid transparent;
  border-left: 19px solid #fff; translate: 3px 0; }
.filmb__frame:hover .filmb__play::before, .filmb__frame:focus-visible .filmb__play::before {
  box-shadow: inset 0 0 0 2px var(--accent); background: rgba(7, 5, 23, .78); scale: 1.06; }
.filmb .filmcard__meta { margin-top: .9rem; }
@media (prefers-reduced-motion: reduce) {
  .filmb__play::before { transition: none; }
  .filmb__frame:hover .filmb__play::before, .filmb__frame:focus-visible .filmb__play::before { scale: none; }
}

/* the milestone form of the list block: authored ordinals (CALL 01,
   FILM 100) instead of the counted 01..04. One shared column width
   keeps the copy edge straight while the labels differ in length. */
.listb--milestones .listb__num { min-width: 11ch; }

/* ============================================================
   B9 (second form): the people grid (.peoplegrid). Portrait cards,
   4:5, name and role in the site's metadata voice; a person without a
   photograph becomes a credit line (the end-credits form), bottom
   aligned so every name sits on the one row.
   Defined after the scheme rules, so the dark ground re-asserts.
   ============================================================ */
.peoplegrid { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6.5rem); }
.peoplegrid.scheme-dark { background: #0B0724; color: var(--on-dark); }
.peoplegrid__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem); align-items: end;
  list-style: none; margin: 0; padding: 0; }
.personcard { display: block; }
.personcard__photo { display: block; aspect-ratio: 4 / 5; overflow: hidden;
  border-radius: 6px; background: #0b0b10; }
.personcard__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.personcard__name { display: block; margin-top: .8rem;
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1rem, 1.2vw, 1.14rem); letter-spacing: -.01em; }
.personcard__role { display: block; margin-top: .3rem;
  font-family: var(--f-machine); font-size: .62rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
/* the credit form: no photograph, a hairline instead */
.personcard--credit { border-top: 1px solid var(--rule); padding-top: .85rem; }
.scheme-dark .personcard__name { color: #fff; }
.scheme-dark .personcard__role { color: var(--on-dark); }
.scheme-dark .personcard--credit { border-color: rgba(240, 238, 252, .18); }
@media (max-width: 860px) {
  .peoplegrid__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* a page that carries the full accreditation section suppresses the
   footer's short strip: one statement of it per page */
.foot--noaccred .foot__accred { display: none; }

/* ============================================================
   The 404: the scene that does not exist. Content set left, the
   footer's Play from start control reused as a plain link home.
   ============================================================ */
.missing { min-height: 100dvh; display: grid; align-items: center; padding-block: clamp(5rem, 14vh, 9rem); }
.missing h1 {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(2.4rem, 5.4vw, 4.8rem); line-height: .98; letter-spacing: -.035em;
  color: #fff; max-width: 14ch; text-wrap: balance;
}
.missing__line {
  margin-top: 1.2rem;
  font-family: var(--f-prose); font-size: clamp(1.05rem, 1.25vw, 1.2rem); line-height: 1.6;
  color: var(--on-dark); max-width: 44ch; text-wrap: pretty;
}
.missing__home {
  display: inline-flex; align-items: center; gap: .6em;
  margin-top: 1.6rem; padding: 1.05rem 0; min-height: 44px;
  font-family: var(--f-machine); font-size: .68rem;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--on-dark); text-decoration: none;
  transition: color var(--dur-1) var(--ease-out);
}
/* the label re-keys on hover (main.js), like the footer's Play from start */
.missing__home:hover, .missing__home:focus-visible { color: #fff; }

/* ============================================================
   B18: the portfolio grid (.filmgrid). The roll's film cards laid
   in alternating rows of two (wide and narrow, one shared height)
   and three, so the archive reads as a cut rather than a table.
   main.js assigns the row classes to whatever the cause filter
   leaves showing; without JS every card is a third.
   Defined after the scheme rules, so the dark ground re-asserts.
   ============================================================ */
.filmgrid { background: var(--paper); color: var(--ink);
  padding-block: clamp(3rem, 8vh, 5.5rem) clamp(4.5rem, 10vh, 7.5rem); }
.filmgrid.scheme-dark { background: #0B0724; color: var(--on-dark); }
.filmfilter { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin-bottom: clamp(1.8rem, 4.5vh, 2.8rem); }
.filmfilter__label { margin-right: .6rem; font-family: var(--f-prose); font-weight: 600;
  font-size: .95rem; color: var(--ink-soft); }
.filmfilter button { position: relative; isolation: isolate; min-height: 44px; padding: .5rem 1.1rem;
  border: 1px solid rgba(26, 20, 66, .22); border-radius: 999px; background: none; cursor: pointer;
  font-family: var(--f-prose); font-weight: 500; font-size: .95rem; color: var(--ink);
  transition: color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out); }
/* the chosen cause fills from its centre: a colour change with a form */
.filmfilter button::before { content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit;
  background: var(--ink); transform: scale(.6); opacity: 0;
  transition: transform .35s var(--ease-out), opacity .2s; }
.filmfilter button:hover::before { transform: scale(1); opacity: .07; }
/* the pressed chip also carries the ink as its own background, landing
   once the fill has finished, so its ground is real (and measurable) */
.filmfilter button[aria-pressed="true"] { color: #fff; border-color: var(--ink);
  background-color: var(--ink); transition: color var(--dur-1) var(--ease-out), background-color 0s .35s; }
.filmfilter button[aria-pressed="true"]::before { transform: scale(1); opacity: 1; }
.filmfilter button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.scheme-dark .filmfilter__label { color: var(--on-dark); }
.scheme-dark .filmfilter button { color: var(--on-dark); border-color: rgba(240, 238, 252, .24); }
.scheme-dark .filmfilter button::before { background: #fff; }
.scheme-dark .filmfilter button[aria-pressed="true"] { color: #0B0724; border-color: #fff; background-color: #fff; }

.filmgrid__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1.8rem, 3vw, 2.6rem) clamp(1rem, 2vw, 1.5rem);
  list-style: none; margin: 0; padding: 0; }
.filmgrid__grid > li { grid-column: span 4; display: flex; min-width: 0; }
.filmgrid__grid > li[hidden] { display: none; }
.filmgrid__grid .filmcard { display: flex; flex-direction: column; width: 100%; }
.filmgrid__grid > li.is-wide { grid-column: span 7; }
/* the narrow partner shares the wide card's height: its frame takes
   whatever the row leaves above the meta line */
.filmgrid__grid > li.is-narrow { grid-column: span 5; }
.filmgrid__grid > li.is-narrow .filmcard__frame { aspect-ratio: auto; flex: 1 1 auto; min-height: 0; }
.filmgrid__grid > li.is-narrow .filmcard__frame img { position: absolute; inset: 0; }
/* a filter that leaves one film shows it full width in the cinema
   letterbox (2.39:1): a feature, not a leftover beside a gap */
.filmgrid__grid > li.is-solo { grid-column: 1 / -1; }
.filmgrid__grid > li.is-solo .filmcard__frame { aspect-ratio: 2.39 / 1; }
.filmgrid__empty { font-family: var(--f-prose); font-size: 1.05rem; color: var(--ink-soft); }
@media (max-width: 1000px) {
  .filmgrid__grid > li, .filmgrid__grid > li.is-wide, .filmgrid__grid > li.is-narrow { grid-column: span 6; }
  .filmgrid__grid > li.is-narrow .filmcard__frame { aspect-ratio: 16 / 9; flex: none; }
  .filmgrid__grid > li.is-narrow .filmcard__frame img { position: static; }
}
@media (max-width: 640px) {
  .filmgrid__grid > li, .filmgrid__grid > li.is-wide, .filmgrid__grid > li.is-narrow { grid-column: span 12; }
  /* phones: the causes run as one row that scrolls sideways, bled to the
     screen edges, instead of stacking four rows above the films */
  .filmfilter { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    margin-inline: calc(-1 * var(--container-pad)); padding: 4px var(--container-pad);
    scroll-padding-inline: var(--container-pad); }
  .filmfilter::-webkit-scrollbar { display: none; }
  .filmfilter button { flex: none; }
  .filmfilter__label { flex: none; }
}
@media (prefers-reduced-motion: reduce) {
  .filmfilter button, .filmfilter button::before { transition: none; }
}

/* ============================================================
   The single film. B1's film form: the name as the page title, the
   client and cause as a details list where the photograph sits.
   Then B16's lead form: the wall's monitor pulled up across the
   dark-to-paper join, so the film sits on both grounds. ONE token
   sets the pull and the header's matching extra padding, so the
   overlap always pays for its own gap.
   ============================================================ */
:root { --film-pull: clamp(5rem, 12vw, 13rem); }
.pagehead--film { padding-bottom: var(--film-pull); }
.pagehead--film .pagehead__grid { align-items: end; }
.filmdetails { justify-self: end; display: grid; grid-template-columns: auto auto;
  gap: .9rem 2.2rem; margin: 0; }
.filmdetails dt { font-family: var(--f-prose); font-size: .95rem; color: var(--on-dark-soft); }
.filmdetails dd { margin: .2rem 0 0; font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.1rem, 1.5vw, 1.35rem); letter-spacing: -.015em; color: #fff; }
.filmdetails__back { grid-column: 1 / -1; }
.filmdetails__back .mlink { display: inline-block; }
.filmb--lead { position: relative; z-index: 1; margin-top: calc(-1 * var(--film-pull));
  padding-top: 0;
  background: linear-gradient(180deg, transparent var(--film-pull), var(--paper) var(--film-pull)); }
/* the part of the monitor on the dark ground keeps its edge: a stronger
   hairline and a top-lit rim, so it reads as sitting in front of the
   header, not cut into it */
.filmb--lead .filmb__frame { box-shadow: 0 30px 70px rgba(0, 0, 0, .35),
  inset 0 0 0 1px rgba(255, 255, 255, .22), inset 0 1px 0 rgba(255, 255, 255, .34); }
@media (max-width: 860px) {
  .filmdetails { justify-self: start; }
}

/* screen-reader-only text: a heading or live status a sighted reader
   gets from the layout itself */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* standalone links (a block header's CTA link, the CTA band's email, the
   single film's way back) reach the 44px touch floor at every width,
   tablets in landscape included */
.blockhead__cta .plink, .ctaband__row .mlink, .filmdetails__back .mlink { padding-block: .6rem; }

/* the lead form's optional explainer under the film: the heading in its
   own left column, the copy beside it (the list block's 5/7 split), so
   the page keeps one heading set left */
.filmnotes { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(1.4rem, 5vw, 4.5rem); align-items: start;
  margin-top: clamp(3rem, 8vh, 5rem); }
.filmnotes h2 { font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.7rem, 2.9vw, 2.7rem); line-height: 1.04; letter-spacing: -.03em;
  max-width: 14ch; text-wrap: balance; }
.filmnotes p { font-family: var(--f-prose); font-size: clamp(1.02rem, 1.16vw, 1.16rem);
  line-height: 1.62; max-width: 58ch; text-wrap: pretty; }
.filmnotes p + p { margin-top: 1.1em; }
.pagehead--film .pagehead__lede { max-width: 38ch; }
@media (max-width: 860px) {
  .filmnotes { grid-template-columns: 1fr; }
}

/* ============================================================
   THE LOCK CORNERS: the hover for every card, picture and video
   (Nick's pick, 29 September). The four focus-lock corners of the
   Start a project button close in; on a picture they're white inside
   the frame while its edges darken, on a text card they're the accent
   just outside the card, closing onto its edge. Drawn by one
   pseudo-element from eight gradients (colour from currentColor, arm
   length and weight from --lk-len and --lk-w), so a block needs no
   extra markup.
   ============================================================ */
.filmcard__frame::after, .galleryb__item::after, .filmb__screen::before, a.cardb::after {
  content: ""; position: absolute; inset: 26px; z-index: 2; pointer-events: none;
  background:
    linear-gradient(currentColor, currentColor) left top / var(--lk-len, 20px) var(--lk-w, 2px) no-repeat,
    linear-gradient(currentColor, currentColor) left top / var(--lk-w, 2px) var(--lk-len, 20px) no-repeat,
    linear-gradient(currentColor, currentColor) right top / var(--lk-len, 20px) var(--lk-w, 2px) no-repeat,
    linear-gradient(currentColor, currentColor) right top / var(--lk-w, 2px) var(--lk-len, 20px) no-repeat,
    linear-gradient(currentColor, currentColor) left bottom / var(--lk-len, 20px) var(--lk-w, 2px) no-repeat,
    linear-gradient(currentColor, currentColor) left bottom / var(--lk-w, 2px) var(--lk-len, 20px) no-repeat,
    linear-gradient(currentColor, currentColor) right bottom / var(--lk-len, 20px) var(--lk-w, 2px) no-repeat,
    linear-gradient(currentColor, currentColor) right bottom / var(--lk-w, 2px) var(--lk-len, 20px) no-repeat;
  color: #fff; opacity: 0;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .45));
  transition: inset .35s var(--ease-out), opacity .2s var(--ease-out); }
/* the edges darken behind the corners on a picture */
.filmcard__frame::before, .galleryb__item::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  box-shadow: inset 0 0 90px rgba(5, 4, 16, .55); opacity: 0;
  transition: opacity .3s var(--ease-out); }
.galleryb__item { position: relative; overflow: hidden; }
.filmcard:hover .filmcard__frame::after, .filmcard:focus-visible .filmcard__frame::after,
.galleryb__item:hover::after, .galleryb__item:focus-visible::after,
.filmb__frame:hover .filmb__screen::before, .filmb__frame:focus-visible .filmb__screen::before {
  inset: 12px; opacity: 1; }
.filmcard:hover .filmcard__frame::before, .filmcard:focus-visible .filmcard__frame::before,
.galleryb__item:hover::before, .galleryb__item:focus-visible::before { opacity: 1; }
/* the feature video's corners sit above its grade and below the play
   ring, and scale with the frame so they hold their weight at full width */
.filmb__screen::before { inset: 4.5%; z-index: 1; --lk-len: clamp(22px, 4.5cqi, 56px); --lk-w: 3px; }
.filmb__screen { container-type: inline-size; }
.filmb__frame:hover .filmb__screen::before, .filmb__frame:focus-visible .filmb__screen::before { inset: 2.2%; }
/* cards: accent corners just outside the card, closing onto its edge,
   so they read against the page whether the card has a photo or not.
   The card stops clipping so the corners can sit outside it; its photo
   keeps the rounded top itself. */
a.cardb { overflow: visible; }
a.cardb .cardb__media { border-radius: 6px 6px 0 0; }
a.cardb::after { inset: -18px; color: var(--accent-ink); filter: none; }
.scheme-dark a.cardb::after { color: var(--accent-on-dark, #8FA3FF); }
a.cardb:hover::after, a.cardb:focus-visible::after { inset: -8px; opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .filmcard__frame::after, .galleryb__item::after, .filmb__screen::before, a.cardb::after,
  .filmcard__frame::before, .galleryb__item::before { transition: none; }
}

/* ============================================================
   B3's image option (Nick, 29 September): full bleed (the default,
   the photograph running to the viewport edge) or INSET, where it
   stays inside the container with the kit's 6px media corner, at
   every width, phones included.
   ============================================================ */
.splitb.splitb--inset .splitb__media img { width: 100%; margin-inline: 0; border-radius: 6px; }

/* ============================================================
   B3's optional services list: the services a split covers, as a
   hairline list under its copy (What We Do's service groups).
   ============================================================ */
.splitb__list { list-style: none; margin: clamp(1.3rem, 2.6vw, 1.8rem) 0 0; padding: 0;
  max-width: 44ch; border-top: 1px solid var(--rule); }
.splitb__list li { padding: .75rem 0; border-bottom: 1px solid var(--rule);
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.02rem, 1.3vw, 1.18rem); letter-spacing: -.01em; }
.splitb.scheme-dark .splitb__list, .splitb.scheme-dark .splitb__list li { border-color: rgba(240, 238, 252, .18); }
.splitb.scheme-dark .splitb__list li { color: #fff; }

/* ============================================================
   B11: the project ledger (.ledger). The hundred as a wall of
   monitors: every charity is a screen in the work wall's own bezel
   (scaled down), mounted on the paper set. A charity with a film
   shows its still and opens the project (the lock corners on hover);
   one with no film to watch shows the Vidzero standby ident, because
   an empty screen reads as a loading failure. The name and cause sit
   under every screen in the same place. Cause filter; CMS rows; a
   lone filter result takes a double-width screen.
   Defined after the scheme rules, so the dark ground re-asserts.
   ============================================================ */
.ledger { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6.5rem); }
.ledger.scheme-dark { background: #0B0724; color: var(--on-dark); }
.ledger__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.4rem, 2.6vw, 2rem) clamp(.8rem, 1.4vw, 1.1rem);
  list-style: none; margin: 0; padding: 0; }
.ledger__grid > li { min-width: 0; }
.ledger__grid > li[hidden] { display: none; }
.ledger__grid > li.is-solo { grid-column: span 2; }
.ledger__item { display: block; }
/* the monitor: the wall's bezel at wall-tile scale */
.ledger__mon { display: block; padding: clamp(5px, .55vw, 8px); border-radius: 10px;
  background: linear-gradient(158deg, #1b1b22, #0d0d12);
  box-shadow: 0 14px 30px rgba(28, 20, 6, .22), inset 0 0 0 1px rgba(255, 255, 255, .07); }
.ledger__mon .filmcard__frame { border-radius: 4px; box-shadow: none; }
.ledger .filmcard__meta { margin-top: .7rem; }
/* standby: the channel ident on the indigo screen, scanlines over it */
.ledger__standby { display: grid; place-items: center;
  background: radial-gradient(120% 140% at 30% 25%, #1c1650 0%, #0b0724 58%, #070517 100%); }
.ledger__standby::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(8, 6, 28, .34) 0 1px, transparent 1px 3px); }
.ledger__ident { position: relative; font-family: var(--f-display); font-weight: 800;
  font-size: clamp(.9rem, 1.2vw, 1.1rem); letter-spacing: -.03em; color: rgba(255, 255, 255, .78); }
.ledger__ident .dot { color: var(--accent); }
.scheme-dark .ledger__mon { box-shadow: 0 14px 30px rgba(0, 0, 0, .4), inset 0 0 0 1px rgba(255, 255, 255, .1); }
@media (max-width: 1000px) { .ledger__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 700px) {
  .ledger__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* two narrow columns: the cause sits under the name, so a long name
     never squeezes it sideways */
  .ledger .filmcard__meta { flex-direction: column; align-items: flex-start; gap: .25rem; }
}

/* ============================================================
   The credits roll (.credits): With Thanks played as film credits
   (Nick's call, 29 September, from his own idea for the retired
   credits footer). A dark screen; once the section comes into view
   the roll plays upward at credits pace and settles with the ident
   centred. Role left of centre, name right of it: the classic split,
   and the one deliberate centring on an interior page besides the
   quote band. main.js arms it (.is-armed) and sets --from, --to and
   --dur from the measured roll; without JS or under reduced motion
   it stays a static list. The pause control satisfies moving content
   that runs longer than five seconds.
   ============================================================ */
/* the ground continues the page title's menu world, so the page reads as
   one dark space ending in the credits, then the footer's paper */
.credits { padding-block: clamp(2rem, 6vh, 4rem) clamp(2.5rem, 7vh, 4.5rem); }
.credits__roll { max-width: 760px; margin-inline: auto; text-align: center; }
.credits__group { margin-bottom: clamp(3rem, 8vh, 5rem); }
.credits__group h3 { font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1.15rem, 1.6vw, 1.4rem); letter-spacing: -.02em; color: #fff;
  margin-bottom: 1.3rem; text-wrap: balance; }
.credits__list { margin: 0; }
.credits__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.6rem; align-items: baseline; margin-block: .55rem; }
.credits__row dt { text-align: right; font-family: var(--f-prose); font-size: clamp(.92rem, 1.1vw, 1.02rem);
  color: var(--on-dark-soft); }
.credits__row dd { margin: 0; text-align: left; font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.05rem, 1.4vw, 1.22rem); letter-spacing: -.01em; color: #fff; }
.credits__names { list-style: none; margin: 0; padding: 0; }
.credits__names li { margin-block: .5rem; font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.05rem, 1.4vw, 1.22rem); letter-spacing: -.01em; color: #fff; }
.credits__end { margin: 0; font-family: var(--f-display); font-weight: 800;
  font-size: clamp(2.2rem, 4.5vw, 3.4rem); letter-spacing: -.035em; color: #fff; }
.credits__end .dot { color: var(--accent); }
.credits__ctl { display: flex; justify-content: flex-start; margin-top: 1.4rem; }
.credits__btn { display: inline-flex; align-items: center; gap: .6em; min-height: 44px; padding: .6rem 0;
  background: none; border: 0; cursor: pointer;
  font-family: var(--f-machine); font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--on-dark); transition: color var(--dur-1) var(--ease-out); }
.credits__btn:hover, .credits__btn:focus-visible { color: #fff; }
.credits__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.credits__ctl[hidden] { display: none; }
/* armed: the roll plays inside a fixed screen with soft top and bottom edges */
.credits.is-armed .credits__screen { position: relative; height: min(66dvh, 620px); overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 13%, #000 87%, transparent);
          mask-image: linear-gradient(180deg, transparent, #000 13%, #000 87%, transparent); }
.credits.is-armed .credits__roll { position: absolute; left: 0; right: 0; top: 0;
  transform: translateY(var(--from, 100%)); }
.credits.is-rolling .credits__roll { animation: credits-roll var(--dur, 40s) linear forwards; }
.credits.is-paused .credits__roll { animation-play-state: paused; }
@keyframes credits-roll {
  from { transform: translateY(var(--from, 100%)); }
  to { transform: translateY(var(--to, -100%)); }
}
@media (max-width: 640px) {
  .credits__row { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 1rem; }
}

/* ============================================================
   B12: the form (.formb). The site's first form. Labels above, errors
   below, a placeholder never stands in for a label. The field being
   typed in gets the lock corners (the site's focus device, the same
   corners the button and the cards use), closing in onto its box.
   The aside carries the email and what happens next. main.js checks
   the required fields on submit, writes each error under its field,
   links it with aria-describedby and moves focus to the first one.
   ============================================================ */
:root { --error: #9A2B2B; }
.formb { background: var(--paper); color: var(--ink); padding-block: clamp(3.5rem, 9vh, 6rem); }
.formb__grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 6vw, 5.5rem); align-items: start; }
.formb form { display: grid; gap: clamp(1.3rem, 2.6vh, 1.7rem); }
.formb__pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(1rem, 2vw, 1.5rem); }
.field { display: grid; gap: .5rem; min-width: 0; align-content: start; }
.field label { font-family: var(--f-prose); font-weight: 600; font-size: 1rem; color: var(--ink); }
.field__opt { font-weight: 400; color: var(--ink-soft); }
.field__box { position: relative; display: block; }
.field input, .field textarea { display: block; width: 100%; min-height: 52px; padding: .8rem 1rem;
  font: inherit; font-family: var(--f-prose); font-size: 1.05rem; line-height: 1.5; color: var(--ink);
  background: var(--label); border: 1px solid rgba(26, 20, 66, .28); border-radius: 6px;
  caret-color: var(--accent-ink); transition: border-color var(--dur-1) var(--ease-out); }
.field textarea { min-height: 170px; resize: vertical; }
.field input:hover, .field textarea:hover { border-color: rgba(26, 20, 66, .5); }
.field input:focus, .field textarea:focus { outline: none; border-color: var(--accent-ink); }
/* the corners and the border carry focus: no extra outline ring */
.field input:focus-visible, .field textarea:focus-visible { outline: none; }
/* the lock corners on the field in focus */
.field__box::after { content: ""; position: absolute; inset: -12px; pointer-events: none; opacity: 0;
  color: var(--accent-ink);
  background:
    linear-gradient(currentColor, currentColor) left top / 16px 2px no-repeat,
    linear-gradient(currentColor, currentColor) left top / 2px 16px no-repeat,
    linear-gradient(currentColor, currentColor) right top / 16px 2px no-repeat,
    linear-gradient(currentColor, currentColor) right top / 2px 16px no-repeat,
    linear-gradient(currentColor, currentColor) left bottom / 16px 2px no-repeat,
    linear-gradient(currentColor, currentColor) left bottom / 2px 16px no-repeat,
    linear-gradient(currentColor, currentColor) right bottom / 16px 2px no-repeat,
    linear-gradient(currentColor, currentColor) right bottom / 2px 16px no-repeat;
  transition: inset .3s var(--ease-out), opacity .2s var(--ease-out); }
.field__box:focus-within::after { inset: -6px; opacity: 1; }
.field__err { margin: 0; font-family: var(--f-prose); font-size: .95rem; line-height: 1.45; color: var(--error); }
.field__err[hidden] { display: none; }
/* a field with an error is red throughout, focused or not */
.field.is-invalid input, .field.is-invalid textarea,
.field.is-invalid input:focus, .field.is-invalid textarea:focus { border-color: var(--error); }
.field.is-invalid .field__box::after { color: var(--error); }
.formb__submit { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; margin-top: .4rem; }
.formb__submit .vf__cta { border: 0; cursor: pointer; font: inherit; }
.formb__note { margin: 0; font-family: var(--f-prose); font-size: .95rem; color: var(--ink-soft); }
.formb__aside { display: grid; gap: 1.4rem; padding-top: .3rem; }
.formb__aside h2 { font-family: var(--f-display); font-weight: 800; font-size: clamp(1.35rem, 2vw, 1.7rem);
  letter-spacing: -.02em; line-height: 1.15; }
.formb__aside p { margin: 0; font-family: var(--f-prose); font-size: clamp(1.02rem, 1.16vw, 1.14rem); line-height: 1.6;
  color: var(--ink-soft); max-width: 40ch; }
.formb__mail { justify-self: start; padding-block: .45rem; font-family: var(--f-display); font-weight: 800; font-size: clamp(1.2rem, 1.9vw, 1.6rem); letter-spacing: -.02em; }
@media (max-width: 860px) {
  .formb__grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) { .formb__pair { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .field__box::after, .field input, .field textarea { transition: none; } }

/* ============================================================
   B8: the logo strip (.logostrip). Real marks only, redrawn as single
   ink-colour marks from the supplied files (white plates dropped,
   cropped to the mark), so six very different logos sit at one
   weight. A single row with hairline dividers; not links. Width decides
   whether it stays centred or becomes a seamless marquee.
   At implementation the client uploads marks and the theme applies
   the same one-colour treatment.
   ============================================================ */
.logostrip { background: var(--paper); color: var(--ink); padding-block: clamp(3rem, 8vh, 5rem); }
.logostrip { --logo-cell: clamp(10rem, 14vw, 14rem); }
.logostrip__viewport { overflow-x: auto; border-block: 1px solid var(--rule); }
.logostrip__viewport:focus-visible { outline: 2px solid currentColor; outline-offset: .25rem; }
.logostrip__row { list-style: none; margin: 0; padding: 0; display: flex;
  overflow-x: auto; border-block: 1px solid var(--rule); }
.logostrip__viewport .logostrip__row { overflow: visible; border: 0; }
.logostrip__row li { flex: 1 0 var(--logo-cell); min-width: var(--logo-cell);
  display: grid; place-items: center; min-height: clamp(6rem, 11vw, 8.25rem);
  padding: 1rem clamp(.8rem, 1.6vw, 1.4rem); border-left: 1px solid var(--rule); }
.logostrip__row li:first-child { border-left: 0; }
.logostrip.is-scrolling .logostrip__viewport { overflow: hidden; }
.logostrip.is-scrolling .logostrip__row { width: max-content; }
.logostrip.is-scrolling .logostrip__row li { flex: 0 0 var(--logo-cell); }
.logostrip.is-scrolling .logostrip__row li:first-child { border-left: 1px solid var(--rule); }
/* each mark's width and height attributes are set by area, so six
   very different shapes carry one visual weight */
.logostrip__row img { display: block; max-width: 100%; height: auto; opacity: .9; }

/* ============================================================
   B17: the article card (.postcard). The roll's card with a body:
   the still (lock corners on hover), the date, the title, one line.
   ============================================================ */
.postgrid { background: var(--paper); color: var(--ink); padding-block: clamp(3rem, 8vh, 5.5rem) clamp(4rem, 10vh, 7rem); }
/* defined after the scheme rules, so the dark ground re-asserts */
.postgrid.scheme-dark { background: #0B0724; color: var(--on-dark); }
.postgrid__grid { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(2rem, 4vw, 3rem) clamp(1rem, 2vw, 1.5rem); }
.postcard { display: block; color: inherit; text-decoration: none; }
.postcard__date { display: block; margin-top: .9rem; font-family: var(--f-prose); font-size: .92rem; color: var(--ink-soft); }
.postcard h3 { margin-top: .35rem; font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.1rem, 1.45vw, 1.3rem); letter-spacing: -.015em; line-height: 1.25; text-wrap: balance;
  min-height: 2.5em; }
.postcard p { margin-top: .5rem; font-family: var(--f-prose); font-size: clamp(.98rem, 1.05vw, 1.05rem);
  line-height: 1.55; color: var(--ink-soft); max-width: 44ch; }
.scheme-dark .postcard__date, .scheme-dark .postcard p { color: var(--on-dark); }
.scheme-dark .postcard h3 { color: #fff; }
@media (max-width: 1000px) { .postgrid__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .postgrid__grid { grid-template-columns: 1fr; } }

/* B7 with two projects: the pair takes the row between them */
.filmroll__row:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 860px) { .filmroll__row:has(> :nth-child(2):last-child) { grid-template-columns: 1fr; } }

/* B1's post form: the article title left, its date and reading time in
   the details list on the right, both sitting on the bottom line */
.pagehead--post .pagehead__grid { align-items: end; }
.pagehead--post h1 { max-width: 18ch; font-size: clamp(2.2rem, 4.2vw, 3.8rem); }
