/* ============================================================
   DOUBLOON STUDIO · SECTIONS
   The words over each film scene, the quill headlines, the depth
   layer, and the three sections after the film (shaping, about,
   contact). Uses tokens only (css/tokens.css): no color value and no
   font name in this file.

   Placement: each .scene__words carries data-place, which decides
   where its words sit over the film. Change the attribute in
   index.html to move a scene's words to a calmer part of its picture:
   low-start, low-end, high-start, high-end, mid-start, low-wide,
   center.
   ============================================================ */

/* ---------- quill headlines ---------- */

@property --ink {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 115%;
}

.quill {
  --quill-density: linear-gradient(97deg,
      var(--mask-ink) 0%, var(--mask-thin) 21%, var(--mask-ink) 36%,
      var(--mask-thin) 57%, var(--mask-ink) 73%, var(--mask-thin) 100%);
  font-family: var(--font-quill);
  font-weight: var(--weight-quill);
  line-height: var(--leading-quill);
  letter-spacing: var(--tracking-quill);
  color: var(--quill-ink);
  /* a slight bleed at the edge of the ink, and a dark halo so the line
     holds over a bright frame. Both are still, never animated. */
  text-shadow: 0 0 0.5px var(--quill-bleed), 0 0.02em 0.14em var(--quill-halo);
  text-wrap: balance;
  /* room for swashes, so the mask never trims a stroke. The first
     letter swings left past the text edge, so the left padding is
     pulled back by a matching margin: the mask gets room and the text
     still lines up with the words under it. */
  padding: 0.12em 0.25em 0.18em;
  margin-block: -0.12em -0.18em;
  margin-inline-start: -0.25em;
  /* uneven ink: a still mask that lets the line run a little lighter
     in places, as a pen does when it runs low */
  -webkit-mask-image: var(--quill-density);
  mask-image: var(--quill-density);
}

.section h2.quill {
  color: var(--quill-ink);
}

/* The write-on. sections.js adds quill-armed to <html> only when motion
   is allowed, then is-written to each line as its words come in. With
   scripts off, or under reduced motion, the lines are simply there. */
html.quill-armed .quill {
  --ink: -12%;
  -webkit-mask-image:
    linear-gradient(100deg, var(--mask-ink) calc(var(--ink) - 7%), var(--mask-clear) calc(var(--ink) + 3%)),
    var(--quill-density);
  mask-image:
    linear-gradient(100deg, var(--mask-ink) calc(var(--ink) - 7%), var(--mask-clear) calc(var(--ink) + 3%)),
    var(--quill-density);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

html.quill-armed .quill.is-written {
  animation: quill-write 1.05s linear forwards;
}

/* uneven pen speed: quick strokes with small pauses between them */
@keyframes quill-write {
  0%   { --ink: -12%; }
  13%  { --ink: 19%; }
  21%  { --ink: 23%; }
  43%  { --ink: 52%; }
  51%  { --ink: 55%; }
  77%  { --ink: 87%; }
  85%  { --ink: 90%; }
  100% { --ink: 115%; }
}

/* On the film's stage, a scene's words come in when its beat arrives:
   the headline writes on first, then the rest follows. They leave at
   the cut, with no fade. */
html.film-on .scene .words > :not(.quill):not(.scene__mark):not(.yours__head) {
  opacity: 0;
}

html.film-on .scene[data-current] .words > :not(.quill):not(.scene__mark):not(.yours__head) {
  opacity: 1;
  transition: opacity 0.45s ease 0.8s;
}

/* ---------- the continue cue at a film stop ---------- */

/* At each of the film's seven stops one cue shows: the control (Start
   yours, Continue, or scene 7's own control) and a small moving hint
   that a swipe or scroll works too. It shows once the stop has
   settled (data-state="held") and is gone while the film runs between
   stops. The cue and the hint carry the hidden attribute in the page;
   js/film.js removes it when the film runs. */
.film-next {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 1rem;
}

.film-next .words__link {
  margin-top: 1.25rem;
  font-family: inherit;
  cursor: pointer;
}

.film-hint {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: 1.25rem;
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  text-shadow: 0 1px 10px var(--words-halo);
}

.film-hint[hidden],
.film-next[hidden] {
  display: none;
}

/* a short track with a bead running down it, the way a page scrolls;
   on a touch screen it runs up, the way a finger swipes */
.film-hint__mark {
  position: relative;
  width: 2px;
  height: 1.6rem;
  border-radius: 1px;
  background: var(--rule);
  overflow: hidden;
}

.film-hint__mark::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 2px;
  height: 0.55rem;
  border-radius: 1px;
  background: var(--accent);
  animation: film-hint-down 1.6s ease-in-out infinite;
}

.film-hint__swipe {
  display: none;
}

@media (pointer: coarse) {
  .film-hint__wheel { display: none; }
  .film-hint__swipe { display: inline; }
  .film-hint__mark::after { animation-name: film-hint-up; }
}

@keyframes film-hint-down {
  0%   { transform: translateY(-0.6rem); opacity: 0; }
  25%  { opacity: 1; }
  75%  { opacity: 1; }
  100% { transform: translateY(1.65rem); opacity: 0; }
}

@keyframes film-hint-up {
  0%   { transform: translateY(1.65rem); opacity: 0; }
  25%  { opacity: 1; }
  75%  { opacity: 1; }
  100% { transform: translateY(-0.6rem); opacity: 0; }
}

/* on the stage: only at a stop that has settled (the selectors are
   long so they outrank the words' own fade in, above) */
html.film-on .film-stage > .scene:not([data-current][data-state="held"]) .scene__words .words .film-next,
html.film-on .film-stage > .scene:not([data-current][data-state="held"]) .scene__words .words .film-hint {
  opacity: 0;
  visibility: hidden;
  transition: none;
}

html.film-on .film-stage > .scene[data-current][data-state="held"] .scene__words .words .film-next,
html.film-on .film-stage > .scene[data-current][data-state="held"] .scene__words .words .film-hint {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.35s ease 0.15s, visibility 0s;
}

/* On the stage a scene is exactly one screen tall, so its words must
   fit one screen (the stacked layout let a scene grow). Headlines are
   capped by screen height as well as width, and the long scenes
   (the argument, the four steps, the name field) set tighter. */
html.film-on .film-stage .scene .scene__words[data-place] {
  padding-bottom: max(1.5rem, 6svh);
}

html.film-on .film-stage .scene__words .quill {
  font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 10svh);
}

html.film-on .film-stage .steps {
  gap: 0.5rem;
  margin-top: 0.6rem;
}

html.film-on .film-stage .steps__item {
  margin-left: calc(var(--depth) * 0.6rem);
  margin-top: 0;
}

html.film-on .film-stage .steps__item p:not(.steps__name),
html.film-on .film-stage .words--argument p:not(.scene__mark):not(.quill) {
  font-size: min(var(--size-body), max(var(--size-small), 2.3svh));
  line-height: 1.45;
}

html.film-on .film-stage .steps__n {
  font-size: 1.45rem;
}

html.film-on .film-stage .words--yours {
  gap: 0.75rem;
}

/* short screens (a small phone with its toolbars showing). 44rem, not
   40: at 390 by 664 the four steps and their continue cue did not fit. */
@media (max-height: 44rem) {
  html.film-on .film-stage .scene__words .quill {
    font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 8svh);
  }

  html.film-on .film-stage .steps__item p:not(.steps__name),
  html.film-on .film-stage .words--argument p:not(.scene__mark):not(.quill) {
    font-size: var(--size-label);
  }

  html.film-on .film-stage .scene .scene__words[data-place] {
    padding-top: 3.75rem;
  }

  html.film-on .film-stage .yours__note {
    font-size: var(--size-label);
  }

  html.film-on .film-stage .film-next .words__link,
  html.film-on .film-stage .film-hint {
    margin-top: 0.75rem;
  }

  html.film-on .film-stage .steps {
    gap: 0.35rem;
  }
}

/* ---------- scene words: placement over the film ---------- */

/* The scene's own view timeline, so the depth layer inside can drift
   with the page. Not visual; the scene shell is otherwise untouched. */
.scene {
  view-timeline: --scene block;
}

/* ".scene" in front outranks the base rule that pushes even scenes to
   the right; placement here comes from data-place instead. */
.scene .scene__words[data-place] {
  align-self: stretch;
  justify-self: stretch;
  max-width: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  padding: 4.5rem 1rem 12vh;
  text-align: left;
  /* the words box covers the scene; only the words themselves take
     taps, so the film's own controls stay reachable */
  pointer-events: none;
}

.words,
.brand {
  pointer-events: auto;
}

.words {
  position: relative;
  max-width: 34rem;
}

[data-place="low-start"] > .words  { align-self: end;    justify-self: start; }
[data-place="low-end"] > .words    { align-self: end;    justify-self: start; }
[data-place="high-start"] > .words { align-self: start;  justify-self: start; }
[data-place="high-end"] > .words   { align-self: start;  justify-self: start; }
[data-place="mid-start"] > .words  { align-self: center; justify-self: start; }
[data-place="low-wide"] > .words   { align-self: end;    justify-self: stretch; max-width: 64rem; }
[data-place="center"] > .words     { align-self: center; justify-self: stretch; max-width: 64rem; }
/* scene 7: the words keep to the top and the foot of the screen, and
   the middle stays clear for the coin and the name written on it */
[data-place="frame"] > .words      { align-self: stretch; justify-self: stretch; max-width: 64rem; }

.brand {
  position: absolute;
  top: 0.9rem;
  left: 1rem;
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text);
  text-shadow: 0 1px 10px var(--words-halo);
}

.scene__mark {
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  text-shadow: 0 1px 10px var(--words-halo);
}

.scene__mark span {
  color: var(--accent);
  margin-right: 0.5em;
}

.scene__words .quill {
  font-size: calc(var(--size-quill-scene) * var(--quill-scale));
  margin-top: 0.15em;
  margin-bottom: 0.25em;
}

.words p:not(.scene__mark):not(.quill) {
  text-shadow: 0 0 2px var(--words-halo), 0 1px 16px var(--words-halo);
}

.words p + p {
  margin-top: 0.8em;
}

.words__lede {
  margin-bottom: 1.4rem;
}

/* one plain outlined link; flat fill on hover */
.words__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: 1.25rem;
  padding: 0 1.15rem;
  border: 1px solid var(--accent);
  border-radius: 2px;
  color: var(--text);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  text-decoration: none;
  background: var(--scrim);
}

.words__link:hover,
.words__link:focus-visible {
  background: var(--action);
  border-color: var(--action);
  color: var(--on-action);
}

.signoff {
  font-size: calc(var(--size-quill-section) * 0.85 * var(--quill-scale));
  margin-top: 0.3em;
}

/* ---------- scene 5: four steps at four depths ---------- */

.steps {
  list-style: none;
  padding: 0;
  margin-top: 1.1rem;
  display: grid;
  gap: 0.9rem;
}

.steps__item {
  --depth: 0;
  margin-left: calc(var(--depth) * 1rem);
  margin-top: calc(var(--depth) * 0.35rem);
  padding-left: 0.95rem;
  border-left: 1px solid var(--rule);
}

.steps__item:nth-child(2) { --depth: 1; }
.steps__item:nth-child(3) { --depth: 2; }
.steps__item:nth-child(4) { --depth: 3; }

.steps__item p {
  margin-top: 0.15rem;
}

.steps__name {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

.steps__n {
  font-family: var(--font-quill);
  font-size: 1.9rem;
  line-height: 1;
  letter-spacing: 0;
  color: var(--quill-ink);
}

/* ---------- scene 6: the work ---------- */

.work {
  list-style: none;
  padding: 0;
  margin-top: 1.4rem;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.4rem 0;
}

.work__coin {
  width: clamp(4.25rem, 19vw, 8.5rem);
  margin-right: -0.5rem;
}

/* lying where they fell: no two at the same turn or depth */
.work__coin:nth-child(1) { transform: rotate(-17deg) translateY(0.3rem); }
.work__coin:nth-child(2) { transform: rotate(24deg) scale(0.86); }
.work__coin:nth-child(3) { transform: rotate(-5deg) translateY(0.55rem) scale(1.06); }
.work__coin:nth-child(4) { transform: rotate(38deg) scale(0.8) translateY(-0.2rem); }
.work__coin:nth-child(5) { transform: rotate(-31deg) scale(0.93) translateY(0.4rem); }

.work__coin img {
  width: 100%;
  height: auto;
}

/* Readable words over the film (owner decisions 2026-10-12, 11:06).
   Scene 2 has no fade: the owner took it out the same afternoon ("i
   dont like 2, it added a background to it, i think it was fine
   before"), and its words are as they were before 189e748. Scene 6: on a
   tall screen a soft dark fade behind the words; on any landscape screen
   the words move up into the dark water above the coins, in a column
   that stops short of the hero coin's fall (the row of five client coins stays at the foot). The
   fade is a wide ellipse with no edge, behind the words only. */
#s6-sand .words {
  isolation: isolate;
}

/* (2026-10-14) drawn as a soft-edged gradient, not a blurred shape: a
   large blur filter on the film's fixed stage is one of the things
   Safari on iPhone composites badly, so the stage carries no filter */
#s6-sand .words::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: calc(-9rem - var(--fade-blur)) calc(-9rem - var(--fade-blur)) calc(-6rem - var(--fade-blur)) calc(-9rem - var(--fade-blur));
  background: radial-gradient(closest-side,
    var(--fade-core-color) 40%,
    color-mix(in srgb, var(--fade-ink) calc(var(--fade-core) * 0.8), transparent) 58%,
    color-mix(in srgb, var(--fade-ink) calc(var(--fade-core) * 0.5), transparent) 70%,
    color-mix(in srgb, var(--fade-ink) calc(var(--fade-core) * 0.2), transparent) 83%,
    transparent 100%);
  pointer-events: none;
}

@media (orientation: landscape) {
  #s6-sand .words::before {
    content: none;
  }

  [data-place="low-wide"] > .words--work {
    align-self: stretch;
    display: flex;
    flex-direction: column;
  }

  .words--work > :not(.work) {
    max-width: calc(34vw - 1rem);
  }

  .words--work .work {
    margin-top: auto;
  }

  /* the words in the water must end above the coins, so they take the
     stage's height rules: a smaller headline and a trimmed top */
  html.film-on .film-stage #s6-sand .scene__words[data-place],
  #s6-sand .scene__words[data-place] {
    padding-top: 3.5rem;
  }

  #s6-sand .quill {
    font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 8svh);
  }

  #s6-sand .words--work p:not(.scene__mark):not(.quill) {
    font-size: min(var(--size-body), max(var(--size-label), 2.3svh));
    line-height: 1.4;
  }
}

@media (orientation: landscape) and (min-width: 48em) {
  .words--work > :not(.work) {
    max-width: 28vw;
  }
}

/* (2026-10-13) in the new sand loop the hero coin's lower rim sits just
   above the scene mark on a tall screen, so the words sit a little lower */
@media (orientation: portrait) {
  html.film-on .film-stage #s6-sand .scene__words[data-place] {
    padding-bottom: max(1.25rem, 3svh);
  }

  /* (2026-10-13) the mark sat at 4.48 against 4.5 over the coin's rim at
     430 by 932; a tighter second halo lifts it without moving it */
  #s6-sand .scene__mark {
    text-shadow: 0 1px 10px var(--words-halo), 0 0 4px var(--words-halo);
  }
}

@media (orientation: landscape) and (max-height: 30rem) {
  html.film-on .film-stage #s6-sand .scene__words[data-place],
  #s6-sand .scene__words[data-place] {
    padding-top: 2.5rem;
  }
}

/* ---------- scenes 4 and 5: words on the float and on the sand ----------
   (2026-10-13) Scene 4's words sit over the float (F) and scene 5's over
   the sand (L6), so they come in only once that stop has settled
   (data-words="held"); the clips that lead into the stop (A4a, A4b, SA;
   SB) run with no words over them, because the coin passes through the
   middle of the frame. Where they rest, they keep clear of the gold:
   - Large landscape screens: scene 4 takes the open water left of the
     floating coin (the coin fills 0.39 to 0.61 of the frame's width
     through the loop, so the column ends at 0.36), and scene 5 takes
     the water above the coins (the gold starts at 0.36 of the frame's
     height), its four steps side by side. The frame is cover-fitted, so
     its width on screen is max(100vw, 177.78svh) and its height
     max(100svh, 56.25vw).
   - Everywhere else (phones either way up, small or square screens)
     there is no open water big enough for the words, so they lie over
     the gold.
   Neither takes a fade: the owner took the soft dark fade out of both
   (2026-10-13, "i want to try it without the color behind it"). Scene 2
   keeps none; scene 6 keeps its own. */
html.film-on .film-stage > .scene:not([data-state="held"]) > .scene__words[data-words="held"] {
  opacity: 0;
  visibility: hidden;
  transition: none;
}

html.film-on .film-stage > .scene[data-state="held"] > .scene__words[data-words="held"] {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.35s ease, visibility 0s;
}

@media (orientation: landscape) and (min-width: 52em) and (min-height: 40rem) {
  /* scene 5: the step names take the full text color, because the
     light falls on the right end of the row */
  html.film-on .film-stage #s5-under .steps__name {
    color: var(--text);
    text-shadow: 0 0 2px var(--words-halo), 0 1px 6px var(--words-halo), 0 0 14px var(--words-halo), 0 0 22px var(--words-halo);
  }

  /* scene 4: a column from the screen's left padding (6vw) to 0.36 of
     the frame, less 1.5rem of water beside the coin */
  html.film-on .film-stage #s4-fall .scene__words[data-place] {
    padding-top: 4rem;
    padding-bottom: 4rem;
  }

  html.film-on .film-stage #s4-fall [data-place="low-end"] > .words,
  html.film-on .film-stage #s4-fall .words {
    align-self: center;
    justify-self: start;
    max-width: calc(44vw - 0.14 * max(100vw, 177.78svh) - 1.5rem);
  }

  html.film-on .film-stage #s4-fall .quill:not(.signoff) {
    font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 7svh);
  }

  /* scene 5: above the line where the gold starts, 0.36 of the frame's
     height: 50svh - 0.14 * max(100svh, 56.25vw) from the top */
  html.film-on .film-stage #s5-under .scene__words[data-place] {
    padding-top: 3.5rem;
    padding-bottom: 0;
  }

  html.film-on .film-stage #s5-under .words--steps {
    max-width: none;
    width: 100%;
    max-height: calc(50svh - 0.14 * max(100svh, 56.25vw) - 3.5rem);
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "mark mark" "head next" "steps steps";
    align-items: end;
    column-gap: 2rem;
  }

  html.film-on .film-stage #s5-under .words--steps > .scene__mark { grid-area: mark; }
  html.film-on .film-stage #s5-under .words--steps > .quill { grid-area: head; font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 6.5svh); }
  html.film-on .film-stage #s5-under .words--steps > .film-next { grid-area: next; }
  html.film-on .film-stage #s5-under .words--steps > .film-next .words__link { margin-top: 0; }

  html.film-on .film-stage #s5-under .steps {
    grid-area: steps;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1.5rem;
    margin-top: 0.5rem;
  }

  /* the light falls in a shaft over the right end of the water, so on a
     wide screen the row keeps to the darker left 72 percent (84 on a
     tablet held sideways, where the short text needs the width) */
  @media (min-width: 52em) {
    html.film-on .film-stage #s5-under .steps {
      width: 84%;
    }
  }

  @media (min-width: 70em) {
    html.film-on .film-stage #s5-under .steps {
      width: 72%;
    }
  }

  html.film-on .film-stage #s5-under .steps__item {
    margin-left: 0;
  }

  html.film-on .film-stage #s5-under .steps__item p:not(.steps__name) {
    font-size: var(--size-small);
    line-height: 1.4;
  }
}

/* A tablet held sideways (1024 by 768) takes the same positions with the
   short text: its four step columns are about 205px wide, where the full
   text would run to five lines and reach the coins. */
@media (orientation: landscape) and (min-width: 52em) and (max-width: 70em) and (min-height: 40rem) {
  #s4-fall .words__full,
  #s5-under .words__full {
    display: none;
  }

  #s4-fall .words__short,
  #s5-under .words__short {
    display: block;
    text-shadow: 0 0 2px var(--words-halo), 0 1px 6px var(--words-halo);
  }

  html.film-on .film-stage #s4-fall .quill:not(.signoff) {
    font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 5.4svh);
  }
}

/* A phone held sideways (844 by 390). The frame is cover-fitted, so the
   gold takes the middle of the screen and the water is a strip across the
   top, a column to the left of the middle coin and a block to the right
   of it. Scene 4 takes the left column as on a large screen, with the
   short text. Scene 5 puts the mark, headline and first step in the left
   column, the headline running on one line across the strip above the
   middle coin, and steps 2 to 4 in the water to the right; Continue
   sits at the foot on its own fill. Short text throughout: the full text
   does not fit the 230px column. */
@media (orientation: landscape) and (min-width: 40em) and (max-height: 30rem) {
  /* :root in front of each selector outranks the older small-landscape
     block further down this file, which this one replaces for 40em and up */
  #s4-fall .words__full,
  #s5-under .words__full {
    display: none;
  }

  #s4-fall .words__short,
  #s5-under .words__short {
    display: block;
    text-shadow: 0 0 2px var(--words-halo), 0 1px 6px var(--words-halo);
  }

  :root.film-on .film-stage #s4-fall .scene__words[data-place],
  :root.film-on .film-stage #s5-under .scene__words[data-place] {
    padding-top: 2.5rem;
    padding-bottom: 1rem;
  }

  :root.film-on .film-stage #s4-fall .words {
    align-self: center;
    justify-self: start;
    max-width: calc(44vw - 0.14 * max(100vw, 177.78svh) - 1.5rem);
  }

  :root.film-on .film-stage #s4-fall .quill:not(.signoff) {
    font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 7svh);
  }

  :root.film-on .film-stage #s4-fall .words--argument p:not(.scene__mark):not(.quill) {
    font-size: var(--size-label);
    line-height: 1.35;
  }

  :root.film-on .film-stage #s4-fall .signoff {
    font-size: 2rem;
  }

  :root.film-on .film-stage #s5-under .words--steps {
    position: relative;
    align-self: stretch;
    justify-self: start;
    display: flex;
    flex-direction: column;
    max-width: 15rem;
  }

  :root.film-on .film-stage #s5-under .quill {
    font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 7svh);
    white-space: nowrap;
  }

  :root.film-on .film-stage #s5-under .steps {
    display: contents;
  }

  :root.film-on .film-stage #s5-under .steps__item {
    margin: 0.5rem 0 0;
    padding: 0;
    border: 0;
  }

  :root.film-on .film-stage #s5-under .steps__item:nth-child(n+2) {
    position: absolute;
    right: -30.9rem;
    width: 14rem;
    margin: 0;
  }

  :root.film-on .film-stage #s5-under .steps__item:nth-child(2) {
    top: 0.9rem;
  }

  :root.film-on .film-stage #s5-under .steps__item:nth-child(3) {
    top: 4.6rem;
  }

  :root.film-on .film-stage #s5-under .steps__item:nth-child(4) {
    top: 7.2rem;
  }

  :root.film-on .film-stage #s5-under .steps__name {
    color: var(--text);
    line-height: 1.1;
    text-shadow: 0 0 2px var(--words-halo), 0 1px 6px var(--words-halo), 0 0 14px var(--words-halo), 0 0 22px var(--words-halo);
  }

  /* step 2 sits in the shaft of light; its name takes two more halo
     layers (and more) so it holds 4.5 against the brightest frames (2026-10-13) */
  :root.film-on .film-stage #s5-under .steps__item:nth-child(2) .steps__name {
    text-shadow: 0 0 2px var(--ink-sea), 0 0 4px var(--ink-sea), 0 0 6px var(--ink-sea), 0 0 9px var(--ink-sea), 0 0 12px var(--ink-sea), 0 0 7px var(--words-halo), 0 1px 6px var(--words-halo), 0 0 10px var(--words-halo), 0 0 14px var(--words-halo), 0 0 22px var(--words-halo), 0 0 30px var(--words-halo);
  }

  :root.film-on .film-stage #s5-under .steps__n {
    font-size: 1.15rem;
    line-height: 1;
  }

  :root.film-on .film-stage #s5-under .steps__item p:not(.steps__name) {
    font-size: var(--size-label);
    line-height: 1.35;
    margin-top: 0.1rem;
  }

  /* the shaft of light falls on the right-hand steps, so they take a
     wider soft halo than the rest */
  :root.film-on .film-stage #s5-under .steps__item:nth-child(n+2) p {
    text-shadow: 0 0 2px var(--words-halo), 0 1px 6px var(--words-halo), 0 0 14px var(--words-halo), 0 0 22px var(--words-halo);
  }

  :root.film-on .film-stage #s5-under .words--steps > .film-next {
    margin-top: auto;
  }

  #s5-under .film-next .film-hint {
    background: var(--scrim);
  }
}

/* ---------- scenes 4 and 5 on a tall screen (2026-10-13) ----------
   Owner decisions, 4:17 to 4:30 PM: Midnight Sea for the ground; "i want
   something more elegant" (no bands behind the words); "words around the
   coin", chosen from the mockups: nothing over the coin. On a tall
   screen (the ones that get the 1080 by 1920 file) scene 4 puts its mark
   and headline in the water above the coin, starting below the Skip link,
   and the short body, the sign-off and Continue in the dark water below
   it (in the float loop the coin covers about 30 to 70 percent of the
   frame's height). Scene 5 puts everything above the coin, which the
   camera tilt (css/film.css) has moved down; Continue sits at the foot
   on its own fill, over the sand. No fade and no band behind the words:
   scene 4 takes a faint darkening at the top screen edge only. Both show
   the short text (.words__short); the full text (.words__full) is the
   one on large screens, and one of the two is display: none at a time,
   so a screen reader reads only the one that shows. */
.words__short {
  display: none;
}

@media (max-aspect-ratio: 1/1) {
  .words__full {
    display: none;
  }

  .words__short {
    display: block;
  }

  #s4-fall .scene__words::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: 0 0 auto 0;
    height: 36%;
    background: linear-gradient(to bottom, var(--top-shade), var(--top-shade-clear));
    pointer-events: none;
  }

  #s4-fall .words--argument,
  #s5-under .words--steps {
    align-self: stretch;
    justify-self: start;
    display: flex;
    flex-direction: column;
    max-width: 34rem;
  }

  #s4-fall .words--argument .words__short {
    margin-top: auto;
  }

  #s4-fall .quill:not(.signoff),
  #s5-under .quill {
    text-shadow: 0 0 0.5px var(--quill-bleed), 0 1px 10px var(--quill-halo);
  }

  #s4-fall .words__short {
    text-shadow: 0 0 2px var(--words-halo), 0 1px 6px var(--words-halo);
  }

  #s5-under .steps {
    grid-template-columns: minmax(0, 1fr);
  }

  #s5-under .steps__item {
    margin-left: 0;
    margin-top: 0;
    padding-left: 0;
    border-left: 0;
  }

  #s5-under .steps__item p:not(.steps__name) {
    text-shadow: 0 0 2px var(--words-halo), 0 1px 6px var(--words-halo);
  }

  #s5-under .words--steps > .film-next {
    margin-top: auto;
  }

  /* the foot is the coin's room below: the stage's own bottom padding
     goes, so the body, the sign-off and Continue sit clear of the gold */
  html.film-on .film-stage #s4-fall .scene__words[data-place],
  html.film-on .film-stage #s5-under .scene__words[data-place] {
    padding-bottom: 0.9rem;
  }

  #s4-fall .signoff {
    margin-top: 0;
  }

  /* the step names are small caps, so they take the full text color and
     the wider soft halo against the specks in the water */
  #s5-under .steps__name {
    color: var(--text);
    text-shadow: 0 0 2px var(--words-halo), 0 1px 6px var(--words-halo), 0 0 14px var(--words-halo);
  }

  /* the four steps, compact, in the water above the coin */
  html.film-on .film-stage #s5-under .steps {
    gap: 0.6rem;
    margin-top: 0.5rem;
  }

  html.film-on .film-stage #s5-under .steps__n {
    font-size: 1.15rem;
  }

  html.film-on .film-stage #s5-under .steps__name {
    line-height: 1.1;
  }

  html.film-on .film-stage #s5-under .steps__item p:not(.steps__name) {
    font-size: min(var(--size-body), 1rem);
    line-height: 1.35;
    margin-top: 0.1rem;
  }

  /* over the sand at the foot, the hint sits on a fill */
  #s5-under .film-next .film-hint {
    min-height: 44px;
    padding: 0 0.85rem;
    background: var(--scrim);
  }

  /* a short tall screen: a smaller headline keeps scene 4's two lines
     above the coin */
  @media (max-height: 44rem) {
    html.film-on .film-stage #s4-fall .quill:not(.signoff),
    html.film-on .film-stage #s5-under .quill {
      font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 7svh);
    }

    html.film-on .film-stage #s5-under .steps {
      gap: 0.45rem;
    }

    html.film-on .film-stage #s5-under .steps__item p:not(.steps__name) {
      font-size: 0.9375rem;
    }

    /* 375 by 667: one body line box touched the coin's rim by 1 px
       when the coin sinks lowest, so the sign-off tucks up 0.5rem and
       the body drops 8 px away from the coin (2026-10-13) */
    #s4-fall .signoff {
      margin-top: -0.5rem;
    }
  }

  /* a tablet standing up: the coin is cover-fitted larger here, so the
     headline is capped and the body takes a wider column to stay on two
     lines below the coin */
  @media (min-width: 37.5rem) {
    html.film-on .film-stage #s4-fall .quill:not(.signoff),
    html.film-on .film-stage #s5-under .quill {
      font-size: 3.5rem;
    }

    html.film-on .film-stage #s4-fall .signoff {
      font-size: 3rem;
    }

    #s4-fall .words--argument,
    #s5-under .words--steps {
      max-width: 46rem;
    }
  }
}

/* Scene 5 with the film off, on a phone (reduced motion, no scripts,
   ?film=off): the still already stands tilted with water above it, but
   the compact rules above are written for film-on, so the words ran
   over the coin's top. These repeat the tilted layout's values, so the
   steps sit above the coin the same way (2026-10-13). */
@media (max-aspect-ratio: 1/1) and (max-width: 37.4375rem) {
  html:not(.film-on) #s5-under .scene__words[data-place] {
    padding-top: 3.75rem;
    padding-bottom: 0.9rem;
  }

  html:not(.film-on) #s5-under .quill {
    font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 8svh);
  }

  html:not(.film-on) #s5-under .steps {
    gap: 0.6rem;
    margin-top: 0.5rem;
  }

  html:not(.film-on) #s5-under .steps__n {
    font-size: 1.15rem;
  }

  html:not(.film-on) #s5-under .steps__name {
    line-height: 1.1;
  }

  html:not(.film-on) #s5-under .steps__item p:not(.steps__name) {
    font-size: min(var(--size-body), 1rem);
    line-height: 1.35;
    margin-top: 0.1rem;
  }

  @media (max-height: 44rem) {
    html:not(.film-on) #s5-under .steps {
      gap: 0.45rem;
    }

    html:not(.film-on) #s5-under .steps__item p:not(.steps__name) {
      font-size: 0.9375rem;
    }
  }
}

/* ---------- scene 7: the name written on the coin ---------- */

.words--yours {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: 1.25rem;
  justify-items: start;
  min-height: 100%;
}

.yours__head { grid-row: 1; }

.yours {
  grid-row: 3;
  display: grid;
  gap: 0.45rem;
  width: min(100%, 24rem);
}

.yours__go {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 1rem;
}

.yours__go .words__link {
  margin-top: 0.25rem;
}

/* A phone on its side (or any short, wide window): the coin is in the
   middle of the screen and the words used to run across it. The coin's
   left edge sits at about 37% of the screen width at any wide shape
   (the film frame is as wide as the screen), so the words take the left
   third and keep clear of it; the oval is never covered. Type and gaps
   are a step smaller so heading, field, note and control all fit the
   short height, and the hint drops under the control when it is tight. */
@media (orientation: landscape) and (max-height: 30rem) {
  .scene .scene__words[data-place="frame"][data-owner] {
    padding-right: 65vw;
    padding-top: 2.75rem;
    padding-bottom: 0.75rem;
  }

  .scene .scene__words[data-place="frame"] > .words--yours {
    gap: 0.4rem;
  }

  .words--yours .quill {
    font-size: min(calc(var(--size-quill-scene) * var(--quill-scale)), 7.5svh);
  }

  .yours {
    gap: 0.3rem;
  }

  .yours__input {
    padding-block: 0.4rem;
    font-size: 1rem;
  }

  .yours__note {
    font-size: var(--size-label);
    line-height: 1.3;
  }

  .yours .words__link {
    margin-top: 0.15rem;
    padding-block: 0.55rem;
  }

  html.film-on .film-stage .words--yours {
    gap: 0.4rem;
  }

  html.film-on .film-stage .scene .scene__words[data-place="frame"] {
    padding-top: 2.75rem;
  }
}

/* The name sits in the blank oval of the coin in the L7 clip (and its
   still). The frame box is the video frame as object-fit: cover lays
   it over the scene, so a share of the frame is a place on the coin at
   any window size. The oval's flat floor, measured on the clip's first
   frame (1920 by 1080), runs x 771 to 1177 and y 459 to 611, square to
   the camera, with round ends; the oval box below is that floor. On a
   screen taller than wide the phone file plays: the middle 607.5 by
   1080 of the same frame (x 656 to 1263.5), so there the frame box is
   9:16 and the floor runs x 115 to 521 of its width. js/sections.js
   keeps the letters, their relief and their shadow inside it, clear of
   the rim on every side. */
.coin-name {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  container-type: size;
  transition: opacity 0.3s ease;
}

.coin-name__defs {
  position: absolute;
  width: 0;
  height: 0;
}

/* the colors of the relief, read by the SVG filter in index.html */
.coin-struck__face { flood-color: var(--coin-polish); flood-opacity: 0.05; }
.coin-struck__light { flood-color: var(--coin-light); }
.coin-struck__shade { flood-color: var(--coin-shadow); }
.coin-struck__drop { flood-color: var(--coin-shadow); flood-opacity: 0.78; }
.coin-struck__edge { flood-color: var(--coin-engrave); flood-opacity: 0.9; }

.coin-name__frame {
  position: absolute;
  left: 50%;
  top: 50%;
  width: max(100cqw, 177.9167cqh);
  height: max(100cqh, 56.2061cqw);
  transform: translate(-50%, -50%);
}

.coin-name__oval {
  position: absolute;
  left: 40.156%;
  top: 42.5%;
  width: 21.146%;
  height: 14.074%;
}

@media (max-aspect-ratio: 1/1) {
  .coin-name__frame {
    width: max(100cqw, 56.25cqh);
    height: max(100cqh, 177.7778cqw);
  }

  .coin-name__oval {
    left: 18.93%;
    width: 66.831%;
  }
}

/* The name, typed and then struck (2026-10-13). While it is typed each
   letter is a faint guide mark scribed on the field: a thin line in
   the color of the coin's own engraving, no relief. "Make it yours"
   punches the letters in one at a time (js/sections.js): each one turns
   to punched metal, raised out of the gold by the filter (#coin-struck),
   lit from the upper left like the oval's rim, with a crisp dark edge
   in the engraving's color and a firm shadow at its foot. The script
   sets the size and the place. */
.coin-name__text {
  position: absolute;
  left: 0;
  top: 0;
  max-width: none;
  margin: 0;
  font-family: var(--font-punch);
  font-weight: 400;
  font-size: 100px;
  line-height: 1;
  letter-spacing: 0;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  color: transparent;
  transform-origin: 0 0;
  /* the script measures the name right after sizing it; the reduced
     motion rule in base.css would otherwise turn the size change into
     a short transition and the measure would read the old size */
  transition-property: none;
}

.coin-name__text * {
  transition-property: none;
}

.coin-name__line {
  display: block;
}

/* each letter is struck a hair off true; the script sets --r, --y and
   --gap from the letter's place in the name. Until it is struck it is
   a scribed guide mark. */
.coin-name__ch {
  display: inline-block;
  margin-right: var(--gap, 0);
  transform: translateY(var(--y, 0)) rotate(var(--r, 0deg));
  color: transparent;
  -webkit-text-stroke: max(0.6px, 0.014em) var(--coin-engrave);
  opacity: 0.5;
}

/* a new mark comes in as it is typed */
.coin-name__ch.is-rising {
  animation: coin-rise 150ms ease-out both;
}

@keyframes coin-rise {
  from { opacity: 0; }
}

/* struck: the letter lands with a quick press, a touch larger, then
   settles into the gold */
.coin-name__ch.is-struck {
  color: var(--coin-face);
  -webkit-text-stroke: 0 transparent;
  opacity: 1;
  filter: url(#coin-struck);
  animation: coin-punch 170ms cubic-bezier(0.2, 0.8, 0.3, 1) both;
}

.coin-name__ch.is-struck.is-quiet {
  animation: none;
}

@keyframes coin-punch {
  0% { transform: translateY(var(--y, 0)) rotate(var(--r, 0deg)) scale(1.14); }
  55% { transform: translateY(var(--y, 0)) rotate(var(--r, 0deg)) scale(0.97); }
  100% { transform: translateY(var(--y, 0)) rotate(var(--r, 0deg)) scale(1); }
}

/* after the last letter, one glint sweeps the oval */
.coin-name__glints {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

.coin-name__sweep {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  overflow: hidden;
}

.coin-name__sweep::before {
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: 0;
  width: 30%;
  background: linear-gradient(100deg, var(--coin-glint-clear) 0, var(--coin-glint) 50%, var(--coin-glint-clear) 100%);
  opacity: 0;
  animation: coin-sweep 650ms ease-in-out both;
}

@keyframes coin-sweep {
  0% { opacity: 0; transform: translateX(-110%) skewX(-14deg); }
  20% { opacity: 0.55; }
  80% { opacity: 0.55; }
  100% { opacity: 0; transform: translateX(340%) skewX(-14deg); }
}

@media (prefers-reduced-motion: reduce) {
  .coin-name__ch.is-rising,
  .coin-name__ch.is-struck { animation: none; }
  .coin-name__sweep { display: none; }
}

/* on the stage the name shows only while the coin rests on its loop */
html.film-on #s7-yours:not([data-state="held"]) .coin-name {
  opacity: 0;
  transition: none;
}

.yours__label,
.card__field label {
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

.yours__note {
  font-size: var(--size-small);
  color: var(--text-muted);
}

.yours .words__link {
  justify-self: start;
  margin-top: 0.5rem;
}

/* ---------- fields (scene 7 and the contact card) ---------- */

.yours__input,
.card input,
.card select,
.card textarea {
  width: 100%;
  min-height: 48px;
  padding: 0.6rem 0.75rem;
  font: inherit;
  color: var(--text);
  background: var(--field-bg);
  border: 1px solid var(--field-border);
  border-radius: 3px;
}

.card textarea {
  min-height: 8.5rem;
  resize: vertical;
}

.yours__input:hover,
.card input:hover,
.card select:hover,
.card textarea:hover {
  border-color: var(--accent);
}

/* ---------- depth layer: specks drifting at three speeds ---------- */

.specks {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: clip;
  pointer-events: none;
}

.specks i {
  position: absolute;
  inset: -30% 0;
  background-repeat: repeat;
}

/* forge: embers */
.specks--ember i:nth-child(1) {
  background-image:
    radial-gradient(circle at 21% 33%, var(--speck-ember) 0 0.8px, var(--speck-clear) 1.4px),
    radial-gradient(circle at 74% 79%, var(--speck-ember) 0 0.7px, var(--speck-clear) 1.3px);
  background-size: 137px 163px;
  opacity: 0.6;
}

.specks--ember i:nth-child(2) {
  background-image:
    radial-gradient(circle at 63% 18%, var(--speck-ember) 0 1.2px, var(--speck-clear) 2.2px),
    radial-gradient(circle at 12% 71%, var(--speck-ember) 0 1px, var(--speck-clear) 2px);
  background-size: 229px 271px;
  opacity: 0.75;
}

.specks--ember i:nth-child(3) {
  background-image: radial-gradient(circle at 38% 52%, var(--speck-ember) 0 1.4px, var(--speck-clear) 4px);
  background-size: 383px 419px;
  opacity: 0.85;
}

/* water: bubbles, drawn as thin rings */
.specks--bubble i:nth-child(1) {
  background-image: radial-gradient(circle at 30% 40%, var(--speck-clear) 0 1.2px, var(--speck-bubble) 1.5px 2px, var(--speck-clear) 2.4px);
  background-size: 149px 181px;
  opacity: 0.7;
}

.specks--bubble i:nth-child(2) {
  background-image:
    radial-gradient(circle at 70% 25%, var(--speck-clear) 0 2.5px, var(--speck-bubble) 3px 3.8px, var(--speck-clear) 4.3px),
    radial-gradient(circle at 18% 82%, var(--speck-clear) 0 1.6px, var(--speck-bubble) 2px 2.6px, var(--speck-clear) 3px);
  background-size: 241px 293px;
}

.specks--bubble i:nth-child(3) {
  background-image: radial-gradient(circle at 46% 60%, var(--speck-clear) 0 4.5px, var(--speck-bubble) 5.2px 6.3px, var(--speck-clear) 7px);
  background-size: 397px 457px;
}

/* the last coin: fine gold dust */
.specks--dust i:nth-child(1) {
  background-image: radial-gradient(circle at 27% 37%, var(--speck-dust) 0 0.7px, var(--speck-clear) 1.3px);
  background-size: 113px 139px;
  opacity: 0.6;
}

.specks--dust i:nth-child(2) {
  background-image: radial-gradient(circle at 66% 22%, var(--speck-dust) 0 1px, var(--speck-clear) 1.8px);
  background-size: 211px 239px;
  opacity: 0.7;
}

.specks--dust i:nth-child(3) {
  background-image: radial-gradient(circle at 41% 58%, var(--speck-dust) 0 1.3px, var(--speck-clear) 3px);
  background-size: 359px 401px;
  opacity: 0.8;
}

/* ---------- after the film: all writing in coin gold ----------
   Owner decision 2026-10-13: "any writing below the page" takes the
   gold of the coin. Read as every block after the film (the sections
   from "What sets the quote." to the footer) and the footer on the
   small pages. The two text roles are pointed at --text-page inside
   those blocks, as is the quill ink of the headings, so every rule
   that names them follows, muted text included. Link underlines, field borders and the focus ring keep
   their own roles. Nothing inside the film is touched. */

.film-track ~ .section,
.fact-card {
  --text: var(--text-page);
  --text-muted: var(--text-page);
  --quill-ink: var(--text-page);
  color: var(--text-page);
}

/* ---------- after the film: how a project is shaped ---------- */

.shaping {
  display: grid;
  gap: 1.5rem;
}

.shaping__list {
  border-top: 1px solid var(--rule);
}

.shaping__row {
  display: grid;
  gap: 0.25rem;
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--rule);
}

.shaping__row dt {
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--accent);
}

.shaping__row dd {
  margin: 0;
  max-width: var(--measure);
}

.shaping .words__link {
  justify-self: start;
  margin-top: 0;
}

/* ---------- about ---------- */

.about {
  display: grid;
  gap: 2rem;
  max-width: 60rem;
}

.about__photo {
  position: relative;
  width: min(100%, 17rem);
}

.about__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: 10rem 10rem 4px 4px;
}

/* ---------- contact card ---------- */

.contact {
  display: grid;
  gap: 2rem;
  max-width: 66rem;
}

.contact__head p {
  max-width: 26em;
}

.card {
  display: grid;
  gap: 1.1rem;
  padding: 1.5rem 1rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 6px;
}

.card__field {
  display: grid;
  gap: 0.4rem;
}

/* honeypot: off screen for people, skipped by keyboards and readers */
.card__trap {
  position: absolute;
  left: -6000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.card__send {
  justify-self: start;
  min-height: 48px;
  padding: 0 1.5rem;
  font: inherit;
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--on-action);
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  cursor: pointer;
}

.card__send:hover,
.card__send:focus-visible {
  background: var(--accent-bright);
  border-color: var(--accent-bright);
}

.card__send:disabled {
  cursor: progress;
  opacity: 0.6;
}

/* Live region for the send result. Empty until a send fails. */
.card__status {
  color: var(--text);
}

.card__status:empty {
  display: none;
}

.card__fine {
  font-size: var(--size-small);
  color: var(--text-muted);
}

/* ---------- wider screens ---------- */

@media (min-width: 48em) {
  .scene .scene__words[data-place] {
    padding: 5rem 6vw 12vh;
  }

  .brand {
    left: 6vw;
  }

  [data-place="low-end"] > .words,
  [data-place="high-end"] > .words {
    justify-self: end;
  }

  [data-place="high-end"] > .words {
    margin-top: 6vh;
  }

  .words--argument {
    max-width: 38rem;
  }

  .steps__item {
    margin-left: calc(var(--depth) * 3.25rem);
    margin-top: calc(var(--depth) * 0.8rem);
  }

  .work__coin {
    margin-right: -0.9rem;
  }

  /* on the stage, the four steps sit two by two, still stepping down */
  html.film-on .film-stage .words--steps {
    max-width: 52rem;
  }

  html.film-on .film-stage .steps {
    grid-template-columns: 1fr 1fr;
    column-gap: 2.5rem;
    row-gap: 0.9rem;
  }

  html.film-on .film-stage .steps__item {
    margin-left: 0;
    margin-top: calc(var(--depth) * 0.6rem);
  }

  /* shaping: heading held on the left, the list runs out to the edge */
  .section--shaping {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: 5vw;
    align-items: start;
  }

  .section--shaping > h2 {
    position: sticky;
    top: 16vh;
  }

  .shaping__list {
    margin-right: -6vw;
  }

  .shaping__row {
    grid-template-columns: 12rem minmax(0, 1fr);
    gap: 2rem;
    padding-right: 6vw;
  }

  /* about: the photo slot rides up over the section above */
  .about {
    grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
    column-gap: 5vw;
    align-items: start;
  }

  .about__photo {
    margin-top: -22vh;
    justify-self: end;
  }

  .contact {
    grid-template-columns: minmax(0, 4fr) minmax(0, 6fr);
    column-gap: 5vw;
    align-items: start;
  }

  .card {
    grid-template-columns: 1fr 1fr;
    padding: 2rem;
    column-gap: 1.25rem;
  }

  .card__field--wide,
  .card__send,
  .card__status,
  .card__fine {
    grid-column: 1 / -1;
  }
}

/* ---------- the work: one coin per client site ----------
   A row of coins on wide screens that wraps on a phone. The coin and
   the name under it are one link; the name is its accessible name. */

.section--work {
  padding-block: 12vh 10vh;
}

.clients {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 2rem 1.5rem;
}

.clients__item {
  width: clamp(8.5rem, 40vw, 24rem);
}

.clients__link {
  display: grid;
  justify-items: center;
  gap: 0.6rem;
  padding: 0.5rem;
  border-radius: 4px;
  color: var(--text);
  text-align: center;
  text-decoration: none;
}

.clients__coin {
  width: min(100%, 22rem);
  height: auto;
}

.clients__name {
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.clients__place {
  margin-top: -0.4rem;
  font-size: var(--size-small);
  color: var(--text-muted);
}

a.clients__link[href]:hover .clients__name {
  color: var(--accent);
}

@media (prefers-reduced-motion: no-preference) {
  .clients__coin {
    transition: transform 0.25s ease;
  }

  a.clients__link[href]:hover .clients__coin,
  a.clients__link[href]:focus-visible .clients__coin {
    transform: translateY(-4px);
  }
}

/* phones: one coin per row so the struck name reads */
@media (max-width: 39.99em) {
  .clients {
    flex-direction: column;
    align-items: center;
    gap: 2.5rem;
  }

  .clients__item {
    width: min(78vw, 20rem);
  }
}

/* ---------- motion that rides the scroll (an extra layer) ---------- */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .specks i {
      --drift: 5vh;
      animation: speck-drift linear both;
      animation-timeline: --scene;
    }

    .specks i:nth-child(2) { --drift: 11vh; }
    .specks i:nth-child(3) { --drift: 19vh; }
    .specks--bubble i:nth-child(3) { --drift: 28vh; }

    /* C2 entry reveals: the words after the film rise as they arrive */
    .reveal {
      animation: words-rise linear both;
      animation-timeline: view();
      animation-range: entry 5% entry 65%;
    }
  }
}

@keyframes speck-drift {
  from { transform: translate3d(0, var(--drift), 0); }
  to   { transform: translate3d(0, calc(var(--drift) * -1), 0); }
}

@keyframes words-rise {
  from { opacity: 0; transform: translate3d(0, 1.25rem, 0); }
  to   { opacity: 1; transform: none; }
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html.quill-armed .quill {
    --ink: 115%;
    -webkit-mask-image: var(--quill-density);
    mask-image: var(--quill-density);
  }

  html.quill-armed .quill.is-written {
    animation: none;
  }
}

/* ---------- footer fact card: thumb-sized links ---------- */

.fact-card dd a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* A phone on its side, scenes 1, 4 and 5 (2026-10-12). At 844 by 390,
   667 by 375 and 932 by 430 the film stage is under 30rem tall, so the
   words are tightened to leave the Continue cue and its hint fully on
   screen with clear space above them. Scene 5's four steps sit two by
   two at any width here (the 667 wide screen stacked them and ran the
   cue 126 px off the bottom). The hint is brighter and haloed over the
   coals. Scene 7 has its own block above and is not touched. Portrait
   and desktop do not match this query. */
@media (orientation: landscape) and (max-height: 30rem) {
  html.film-on .film-stage #s1-crucible .film-hint,
  html.film-on .film-stage #s4-fall .film-hint,
  html.film-on .film-stage #s5-under .film-hint {
    color: var(--text);
    text-shadow: 0 0 3px var(--words-halo), 0 1px 12px var(--words-halo), 0 0 22px var(--words-halo);
  }

  html.film-on .film-stage #s4-fall .scene__words[data-place],
  html.film-on .film-stage #s5-under .scene__words[data-place] {
    padding-top: 2.5rem;
    padding-bottom: 0.75rem;
  }

  html.film-on .film-stage #s4-fall .words p:not(.scene__mark):not(.quill) {
    font-size: var(--size-label);
    line-height: 1.35;
  }

  html.film-on .film-stage #s4-fall .words p + p {
    margin-top: 0.4rem;
  }

  html.film-on .film-stage #s4-fall .signoff {
    margin-top: 0.1rem;
    font-size: min(var(--size-quill-scene), 6svh);
  }

  html.film-on .film-stage #s4-fall .film-next .words__link,
  html.film-on .film-stage #s4-fall .film-hint {
    margin-top: 0.9rem;
  }

  html.film-on .film-stage #s5-under .words--steps {
    max-width: none;
  }

  html.film-on .film-stage #s5-under .steps {
    grid-template-columns: 1fr 1fr;
    column-gap: 1.5rem;
    row-gap: 0.3rem;
    margin-top: 0.4rem;
  }

  html.film-on .film-stage #s5-under .steps__item {
    margin-left: 0;
    margin-top: calc(var(--depth) * 0.35rem);
  }

  html.film-on .film-stage #s5-under .steps__item p:not(.steps__name) {
    font-size: var(--size-label);
    line-height: 1.35;
    margin-top: 0.05rem;
  }

  html.film-on .film-stage #s5-under .steps__n {
    font-size: 1.2rem;
  }

  html.film-on .film-stage #s5-under .film-next .words__link,
  html.film-on .film-stage #s5-under .film-hint {
    margin-top: 0.5rem;
  }
}
