/* the utter — how it looks. (How it moves is in utter.js.)
   The letter and the film's pages are laid out like the Canva guide on a laptop: a 1440 x 810 page, where --u is
   one Canva point (the letter's body text is 30u, a film page's 34u). Phones get their own arrangement of the same
   elements. Every screen fills the screen, edge to edge. */

/* ------------------------------------------------------------------ type */

@font-face {
  font-family: "utter serif";   /* Noto Serif, semi-condensed, regular: the Canva's typeface */
  src: url("../fonts/noto-serif-sc-latin.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "utter serif";
  src: url("../fonts/noto-serif-sc-latin-ext.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0300-0303, U+0309, U+0323,
    U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "utter serif";
  src: url("../fonts/noto-serif-sc-greek.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF, U+1F00-1FFF;
}
@font-face {
  font-family: "utter serif";
  src: url("../fonts/noto-serif-sc-cyrillic.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116, U+0460-052F, U+1C80-1C8A, U+20B4,
    U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* Its italic, the same width and weight, Latin only: the titles of Yrsa's books and of Black Is King, on the
   partners' page about her (Oct 26, 2026). Its heights are the regular's, so a line's highlight sits the same. */
@font-face {
  font-family: "utter serif";
  src: url("../fonts/noto-serif-sc-italic-latin.woff2") format("woff2");
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* The first letter of a name: Tangerine Bold, by Toshi Omagari, the utter's choice (Oct 23, 2026) in place of the
   Canva's Sloop Script Pro, which needs a paid licence. Renamed "Utter Script 3" as cut by tools/make_fonts.py. */
@font-face {
  font-family: "utter script 3";
  src: url("../fonts/utter-script-3.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+0041-005A, U+0061-007A, U+00C0-00D6, U+00D8-00F6, U+00F8-00FF, U+0100-017F;
}
@font-face {
  font-family: "utter sans italic";   /* IBM Plex Sans Italic, renamed as its licence asks: the tagline */
  src: url("../fonts/utter-sans-italic-latin.woff2") format("woff2");
  font-display: swap;
}

/* ------------------------------------------------------------------ colours and units */

:root {
  --ink: #001a15;      /* the darkest green: the desk, the film's dark */
  --lime: #e4f83f;     /* the name, the letter's words */
  --pale: #d9f79d;     /* the highlight behind the film's words */
  --teal: #2a5d57;     /* the film's words */
  --shade: rgba(0, 26, 21, 0.5);
  --vh: 1vh;
  --u: min(100vw / 1440, var(--vh) * 100 / 810);
  --serif: "utter serif", "Noto Serif", Georgia, serif;
  --script: "utter script 3", "utter serif", Georgia, serif;
  /* The capital, set as the Canva sets its N: as tall as Sloop's (its size over the serif's), lifted so its lowest
     point sits on the serif's line, and hung to the left by this share of its width, so that the serif of "Name"
     lands where the Canva's does (worked out in tools/fit_capitals.py). How far the serif tucks under it is
     measured for each name (utter.js). */
  --cap-size: 1.748em;
  --cap-lift: -0.0069em;
  --cap-hang: 0.218;
  --tagline: "utter sans italic", "Helvetica Neue", Arial, sans-serif;
  --tooth: url("../img/paper-tooth.webp");   /* cotton paper, lit from the top left (tools/make_textures.py) */
  color-scheme: dark;
}
@supports (height: 1dvh) {
  :root { --vh: 1dvh; }
}
@media (orientation: portrait) {
  :root { --u: min(100vw / 760, var(--vh) * 100 / 1250); }
}

/* The Canva sets Noto Serif this much tighter than the font's own spacing. Declared on every element: a
   spacing in em is fixed where it is declared, so inherited from the top it would not grow with the type. */
*, *::before, *::after {
  box-sizing: border-box;
  letter-spacing: -0.021em;
  word-spacing: 0.018em;
}

html, body {
  margin: 0;
  height: 100%;
  background: var(--ink);
  color: var(--lime);
  font-family: var(--serif);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-kerning: normal;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body { overflow: hidden; overscroll-behavior: none; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
button:focus-visible { outline: 1px solid currentColor; outline-offset: 0.35em; }
p, h1 { margin: 0; font: inherit; }
img, video { display: block; }

.sprite, .defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.hidden-label {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

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

.screen {
  position: fixed;
  inset: 0;
  overflow: hidden;
  visibility: hidden;
}
.screen.is-on { visibility: visible; }
.desk { z-index: 10; }
.letter { z-index: 5; }
.film { z-index: 4; }

/* The Canva page: 1440 x 810 points, centred on the screen. */
.frame {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(1440 * var(--u));
  height: calc(810 * var(--u));
  transform: translate(-50%, -50%);
}

/* Until the script takes over, the envelope waits out of sight (and shows anyway if the script never comes). */
.pre .envelope, .pre .hint { opacity: 0; animation: late-show 0.8s 3.5s forwards; }
@keyframes late-show { to { opacity: 1; } }

/* ------------------------------------------------------------------ 1. the envelope */

.desk {
  --ew: min(88vw, calc(75 * var(--vh)), 640px);   /* the envelope's width; it is 69% as tall */
  --e: calc(var(--ew) / 100);
  --eh: calc(69 * var(--e));
  --et: calc(1.1 * var(--e));   /* its thickness, a card inside */
  background:
    radial-gradient(62% 56% at 50% 42%, rgba(38, 88, 70, 0.5), rgba(0, 26, 21, 0) 72%),
    var(--ink);
}

.envelope {   /* dark green paper, lime ink: the utter's choice (Oct 23, 2026) */
  position: absolute;
  left: 50%;
  top: 47%;
  width: var(--ew);
  height: var(--eh);
  margin: calc(var(--eh) / -2) 0 0 calc(var(--ew) / -2);
  --paper: #143c30;
  --liner: #cdec7a;
  --env-ink: rgba(228, 248, 63, 0.86);
  --env-name: #e4f83f;
}

/* Paper: its colour, the light falling across it, and the cotton tooth blended into the colour. */
.paper {
  background-color: var(--paper);
  background-image:
    linear-gradient(128deg, rgba(255, 255, 255, 0.13) 0%, rgba(255, 255, 255, 0) 44%, rgba(0, 0, 0, 0.1) 100%),
    var(--tooth);
  background-size: 100% 100%, 384px 384px;
  background-blend-mode: normal, soft-light;
}
.liner {   /* the lining: darker deep inside the pocket */
  background-color: var(--liner);
  background-image:
    linear-gradient(to bottom, rgba(0, 0, 0, 0.34), rgba(0, 0, 0, 0.08) 52%, rgba(0, 0, 0, 0.2)),
    var(--tooth);
  background-size: 100% 100%, 384px 384px;
  background-blend-mode: normal, soft-light;
}

.env-shadow {   /* the soft shadow on the desk */
  position: absolute;
  left: 3%;
  right: 3%;
  top: 10%;
  bottom: -4%;
  border-radius: 8% / 12%;
  background: rgba(0, 6, 4, 0.62);
  filter: blur(calc(2.2 * var(--e)));
}

.env-body { position: absolute; inset: 0; transform-style: preserve-3d; }
.env-face {
  position: absolute;
  inset: 0;
  border-radius: calc(0.55 * var(--e));
  overflow: hidden;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.3),
    inset 0 -1px 0 rgba(0, 0, 0, 0.12),
    0 1px 1.5px rgba(0, 0, 0, 0.28);
}
/* Which face shows is switched by utter.js as the envelope passes edge-on: Safari's engine does not reliably
   hide the face turned away (it showed the back, mirrored, over the address). The two faces lie the envelope's
   thickness apart; utter.js sets it back by half of that, so the side facing up lies where a flat one would. */
.env-front { transform: translateZ(calc(var(--et) / 2)); }
.env-back { transform: rotateY(180deg) translateZ(calc(var(--et) / 2)); visibility: hidden; }
.env-body.is-turned .env-front { visibility: hidden; }
.env-body.is-turned .env-back { visibility: inherit; }   /* inherit, not visible: hidden with the envelope */
.env-edge {   /* the folded edges: darker at both creases, the light along the fold */
  position: absolute;
  background-color: var(--paper);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.env-edge-l, .env-edge-r {
  left: 50%;
  top: 0;
  bottom: 0;
  width: var(--et);
  margin-left: calc(var(--et) / -2);
  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.26), rgba(255, 255, 255, 0.1) 50%, rgba(0, 0, 0, 0.26));
}
.env-edge-t, .env-edge-b {
  top: 50%;
  left: 0;
  right: 0;
  height: var(--et);
  margin-top: calc(var(--et) / -2);
  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.26), rgba(255, 255, 255, 0.1) 50%, rgba(0, 0, 0, 0.26));
}
.env-edge-l { transform: rotateY(-90deg) translateZ(calc(var(--ew) / 2)); }
.env-edge-r { transform: rotateY(90deg) translateZ(calc(var(--ew) / 2)); }
.env-edge-t { transform: rotateX(90deg) translateZ(calc(var(--eh) / 2)); }
.env-edge-b { transform: rotateX(-90deg) translateZ(calc(var(--eh) / 2)); }
.env-face::after, .env-edge::after {   /* a side turned away from the light, darker (utter.js sets --dim) */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: #000;
  opacity: var(--dim, 0);
}
.env-face::after { will-change: opacity; }   /* its own layer: the face under it is not painted again */
.sheen {   /* light running across the paper as it turns */
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(105deg, rgba(255, 255, 255, 0) 32%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 68%) var(--sheen-x, 100%) 0 / 260% 100% no-repeat;
}

/* The address side. */
.env-from {
  position: absolute;
  left: calc(7 * var(--e));
  top: calc(7.2 * var(--e));
  display: flex;
  flex-direction: column;
  font-size: max(11px, calc(2.4 * var(--e)));
  line-height: 1.45;
  color: var(--env-ink);
}

.stamp {
  position: absolute;
  right: calc(6.6 * var(--e));
  top: calc(6.2 * var(--e));
  width: calc(15 * var(--e));
  height: auto;
  aspect-ratio: 100 / 120;
  transform: rotate(1.2deg);
  filter: drop-shadow(0 calc(0.14 * var(--e)) calc(0.22 * var(--e)) rgba(0, 0, 0, 0.26));
}
.stamp-paper { fill: #f6f3ea; }
.stamp-frame { fill: none; stroke: rgba(0, 26, 21, 0.2); stroke-width: 0.5; }
.stamp-word { fill: #2a5d57; font-family: var(--serif); font-size: 6.4px; letter-spacing: 0.25px; }

.postmark {   /* the postmark beside the stamp, its lines running across it; no year in it (Yrsa, Oct 27, 2026) */
  position: absolute;
  left: calc(68.4 * var(--e));
  top: calc(12.6 * var(--e));
  width: calc(30 * var(--e));
  height: auto;
  aspect-ratio: 150 / 60;
  transform: rotate(-8deg);
  color: var(--env-ink);
  opacity: 0.86;
  overflow: visible;
}
.pm-ring { fill: none; stroke: currentColor; stroke-width: 1.5; }
.pm-thin { stroke-width: 0.9; }
.pm-arc { fill: currentColor; font-family: var(--serif); font-size: 6.1px; letter-spacing: 0.85px; word-spacing: 0; }
.pm-wave { fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; }

.env-to {
  position: absolute;
  left: calc(6 * var(--e));
  right: calc(6 * var(--e));
  top: calc(46.5 * var(--e) - 0.888em);   /* baseline 46.5 hundredths of the width down */
  font-size: calc(11.8 * var(--e));
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  color: var(--env-name);
}
.env-rule {
  position: absolute;
  left: calc(27 * var(--e));
  width: calc(46 * var(--e));
  top: calc(50.2 * var(--e));
  height: max(1px, calc(0.16 * var(--e)));
  background: var(--env-name);
  opacity: 0.5;
}

/* The back: the folds, and the flap with its shadow. */
.seams { position: absolute; inset: 0; width: 100%; height: 100%; }
.seam-side { fill: rgba(0, 0, 0, 0.05); }
.seam-bottom { fill: rgba(255, 255, 255, 0.045); stroke: rgba(0, 0, 0, 0.15); stroke-width: 1; vector-effect: non-scaling-stroke; }
.seam-lip { fill: none; stroke: rgba(255, 255, 255, 0.4); stroke-width: 1; vector-effect: non-scaling-stroke; }
.flap-shade { fill: rgba(0, 0, 0, 0.3); }
.flap {   /* it reaches a little past the pocket's edges everywhere, as a real flap overlaps them */
  position: absolute;
  inset: 0;
  clip-path: polygon(0 0, 100% 0, 100% 2.2%, 55.52% 56%, 53.4% 58.4%, 51.5% 59.4%, 50% 59.75%, 48.5% 59.4%, 46.6% 58.4%, 44.48% 56%, 0 2.2%);
  background-image:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0) 55%, rgba(0, 0, 0, 0.04)),
    var(--tooth);
}
.flap-mark {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(27.5 * var(--e));
  text-align: center;
  font-size: max(10.5px, calc(2.3 * var(--e)));
  color: var(--env-ink);
}

/* The same envelope once turned over, in loose parts. */
.env-open { position: absolute; inset: 0; visibility: hidden; }
.ov-inside { position: absolute; inset: 0; z-index: 1; border-radius: calc(0.55 * var(--e)); }
.ov-pocket {
  position: absolute;
  inset: 0;
  z-index: 3;
  clip-path: polygon(0 1.5%, 42.07% 53%, 50% 45%, 57.93% 53%, 100% 1.5%, 100% 100%, 0 100%);
}
.ov-flap-shade { position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%; overflow: visible; }
.ov-flap { z-index: 4; transform-origin: 50% 0; }
.ov-flap.is-inside {   /* seen from inside once it has swung up: the lining */
  background-color: var(--liner);
  background-image: linear-gradient(to top, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0) 70%), var(--tooth);
}
.ov-flap.is-inside .flap-mark { visibility: hidden; }

/* The card that comes out: a print of the next screen's photograph, which then grows into that screen. */
.card {
  position: fixed;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  z-index: 2;
  visibility: hidden;
  overflow: hidden;
  background: var(--ink);
  box-shadow: 0 calc(0.4 * var(--e)) calc(1.6 * var(--e)) rgba(0, 0, 0, calc(0.4 * var(--lift, 1)));
}
.card img {
  position: absolute;
  left: 0;
  top: 0;
  max-width: none;
  object-fit: cover;
  transform-origin: 50% 50%;
}

.env-button {
  position: absolute;
  inset: 0;
  z-index: 8;
  cursor: pointer;
}
.env-button:focus-visible { outline: none; }
.desk:has(.env-button:focus-visible) .env-front { box-shadow: 0 0 0 2px var(--lime); }
.hint {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(47% + var(--eh) / 2 + max(24px, 4.4 * var(--vh)));
  z-index: 7;
  text-align: center;
  font-size: max(13px, calc(17 * var(--u)));
  letter-spacing: 0.04em;
  color: var(--lime);
  opacity: 0.7;
  pointer-events: none;
}

/* ------------------------------------------------------------------ the name: a script capital, then the serif */

.name .initial {
  font-family: var(--script);
  font-size: var(--cap-size);
  vertical-align: var(--cap-lift);
  line-height: 0;          /* the capital's tall swashes must not push the line apart */
  letter-spacing: 0;
}

/* ------------------------------------------------------------------ 2. the letter (Canva page 1) */

.letter {
  --m: max(20px, calc(70 * var(--u)));   /* the margin of the corner lines */
  background: var(--ink);
}
.letter-photo { position: absolute; inset: 0; overflow: hidden; }
.letter-photo picture, .letter-photo img { width: 100%; height: 100%; }
.letter-photo img { object-fit: cover; object-position: 50% 29%; transform-origin: 50% 45%; }
.letter-scrim {   /* the lines at the top sit higher in the sky than the Canva's, where it is brighter: toned down to the Canva's */
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(0, 26, 21, 0.19), rgba(0, 26, 21, 0) 22%);
}

.corner {
  position: absolute;
  z-index: 2;
  font-size: calc(21 * var(--u));
  line-height: 1;
  white-space: nowrap;
  color: var(--lime);
  text-shadow: 0 0 0.7em rgba(0, 26, 21, 0.55);
}
.letter-mark { left: var(--m); top: calc(var(--m) + env(safe-area-inset-top)); }
.letter-mark {   /* the Canva edges it in ink, a third of a point wide, outside the letters (the year it edged too is
                   gone: Yrsa, Oct 27, 2026) */
  -webkit-text-stroke: 0.032em var(--ink);
  paint-order: stroke fill;
}
.letter-from { left: var(--m); bottom: calc(var(--m) + env(safe-area-inset-bottom)); }
.letter-enter {
  right: var(--m);
  bottom: calc(var(--m) + env(safe-area-inset-bottom));
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 0.3em;
}
.letter-enter::before {   /* a bigger target than the words */
  content: "";
  position: absolute;
  inset: -0.9em -0.8em;
}
.arrow {
  width: 1.02em;
  height: 0.4em;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: max(1px, calc(1.1 * var(--u)));
  stroke-linecap: round;
  stroke-linejoin: round;
}
.arrow path { vector-effect: non-scaling-stroke; }
@media (hover: hover) {
  .letter-enter:hover .arrow { transform: translateX(0.22em); }
  .arrow { transition: transform 0.45s cubic-bezier(0.3, 0.7, 0.2, 1); }
}

.letter-frame > * { position: absolute; }
.letter-head {
  left: 0;
  right: 0;
  top: 0;
  height: calc(490 * var(--u));
}
.letter-name {   /* a long name shrinks to the Canva name's own footprint: the rule and 50 points either side */
  position: absolute;
  isolation: isolate;
  left: calc(335 * var(--u));
  right: calc(335 * var(--u));
  bottom: calc(20.2 * var(--u) - 0.112em);   /* last baseline 469.8u down the page */
  font-size: calc(224.5 * var(--u));
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  /* Room round the letters for the capital's swashes, so the reveal below never cuts them; the padding is taken
     back by the margin, so the name sits exactly where it did. */
  padding: 0.42em 0.6em;
  margin: -0.42em -0.6em;
  --reveal: 140%;   /* written in from the left: 0% hides it, 140% shows it all */
  -webkit-mask-image: linear-gradient(100deg, #000 calc(var(--reveal) - 38%), transparent var(--reveal));
  mask-image: linear-gradient(100deg, #000 calc(var(--reveal) - 38%), transparent var(--reveal));
}
/* The Canva's outline round the name: an ink copy of it, laid exactly under it and stroked 2 points (on a
   224.5-point name) past its edges. One copy under the whole name, so where the capital's loops cross themselves
   or meet the serif, the outline stays behind them, as on the Canva. */
.name-ink {
  position: absolute;
  inset: 0;
  z-index: -1;
  padding: inherit;
  color: var(--ink);
  -webkit-text-stroke: 0.0178em var(--ink);
  pointer-events: none;
}
.letter-rule {
  position: absolute;
  left: calc(50% - 335 * var(--u));
  width: calc(670 * var(--u));
  top: calc(487.5 * var(--u));
  height: max(1px, calc(1.5 * var(--u)));
  background: var(--lime);
}
.letter-message {
  left: 0;
  right: 0;
  top: calc(523.2 * var(--u));
  font-size: calc(30 * var(--u));
  line-height: 1.39;
  text-align: center;
  text-shadow: 0 0 0.6em rgba(0, 26, 21, 0.6);
}
.letter-message span { display: block; }

/* ------------------------------------------------------------------ 3. the film */

.film {
  --m: max(20px, calc(70 * var(--u)));   /* the margin of the corners, as on the letter */
  background: var(--ink);
  touch-action: pan-y pinch-zoom;   /* a sideways swipe is the page's: it turns the page */
}
.page { position: absolute; inset: 0; visibility: hidden; opacity: 0; }
.page.is-current { visibility: visible; opacity: 1; }
.page-media { position: absolute; inset: 0; overflow: hidden; background: var(--ink); }
.page-media picture, .page-media img, .page-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.page-media img:not(.poster) { transform-origin: 50% 50%; }
.page-media::after {   /* a soft dark at the foot, so the arrows read over any photograph or film */
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 26, 21, 0.42), rgba(0, 26, 21, 0.2) max(40px, 7%),
    rgba(0, 26, 21, 0.07) max(76px, 13%), rgba(0, 26, 21, 0) max(112px, 19%));
}

/* Page 2: the title. */
.page--title .page-media::after {   /* a soft dark behind the wordmark and at the foot, for the lime to read */
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(42% 46% at 50% 44%, rgba(0, 26, 21, 0.34), rgba(0, 26, 21, 0) 72%),
    linear-gradient(to top, rgba(0, 26, 21, 0.5), rgba(0, 26, 21, 0) 34%);
}
.title-frame > * { position: absolute; }
.title-mark, .end-mark {
  --reveal: 140%;   /* written in from the top left, as the hand writes it */
  -webkit-mask-image: linear-gradient(120deg, #000 calc(var(--reveal) - 40%), transparent var(--reveal));
  mask-image: linear-gradient(120deg, #000 calc(var(--reveal) - 40%), transparent var(--reveal));
}
.title-mark {
  left: calc(50% - 241.5 * var(--u));
  top: calc(113 * var(--u));
  width: calc(483 * var(--u));
  height: calc(438 * var(--u));
  fill: var(--lime);
  stroke: var(--ink);
  stroke-width: 3px;
  stroke-linejoin: round;
  paint-order: stroke fill;
  overflow: visible;
}
.title-tagline {
  left: 0;
  right: 0;
  top: calc(602.2 * var(--u) - 0.875em);
  font-family: var(--tagline);
  font-size: calc(41 * var(--u));
  line-height: 1;
  letter-spacing: 0;
  word-spacing: 0;
  text-align: center;
  text-shadow: 0 0 0.5em rgba(0, 26, 21, 0.6), 0 0.03em 0.06em rgba(0, 26, 21, 0.5);
}
.title-question {
  left: 0;
  right: 0;
  top: calc(769.5 * var(--u) - 0.888em);
  font-size: calc(33 * var(--u));
  line-height: 1;
  text-align: center;
  text-shadow: 0 0 calc(18 * var(--u)) rgba(0, 26, 21, 0.6);
}
/* The partners' title page (the utter, Oct 24, 2026): a line about the series under the tagline, then the question
   with the credit under it, the credit on the line where the guests' question sits. */
.title-about {   /* small type over the bright middle of the film: a dark edge, as the tagline has, for it to read */
  left: 0;
  right: 0;
  top: calc(655 * var(--u) - 0.888em);
  font-size: max(12px, calc(26 * var(--u)));
  line-height: 1;
  text-align: center;
  text-shadow: 0 0 0.6em rgba(0, 26, 21, 0.75), 0 0.03em 0.08em rgba(0, 26, 21, 0.8);
}
.title-foot { left: 0; right: 0; top: calc(700 * var(--u)); text-align: center; }
.title-foot .title-question { position: static; }
.title-by {
  margin-top: calc(17 * var(--u));
  font-size: max(11.5px, calc(22 * var(--u)));
  line-height: 1;
  text-shadow: 0 0 calc(18 * var(--u)) rgba(0, 26, 21, 0.6);
}

/* The text pages (pages 3, 4 and 5, and for partners the page about Yrsa): the words on one continuous highlight,
   drawn by utter.js from the lines as they fall. */
.text-frame { display: flex; align-items: center; justify-content: center; }
.copy {
  --measure: 31.2em;
  position: relative;
  isolation: isolate;
  max-width: var(--measure);
  font-size: calc(34 * var(--u));
  line-height: 1.39;
  text-align: center;
  color: var(--teal);
}
.copy--wide { --measure: 36.5em; }
.copy p { margin: 0; text-wrap: pretty; }   /* no word left alone on a last line, where the browser can */
/* On the page about Yrsa, even lines at every size, as phones have on every page (Oct 26, 2026): her sentences are
   long, and a short last line between two full ones leaves a sliver of the film between them, where her head shows. */
[data-page="author"] .copy p { text-wrap: balance; }
/* And there her words never cover her (Yrsa, Oct 26, 2026: "Is there a way the text wouldn't cover me up on that
   page"). Where she stands in the kitchen film, measured on every frame its loop shows: from 51.9% of the laptops'
   film's width, and from 66.7% of the phones' film's height (that one cut closer, so she stands at its foot). The film
   covers the screen, so where she falls on it is worked out from the film's size there (README, Films). */
@media (orientation: landscape) {
  /* Beside her: the words take the screen from the corners' margin to half that short of her (her box takes in the
     window post beside her), centred there, and a little smaller than on the other pages (28 for 34), so the
     narrower column keeps to about the height the other pages' words take. */
  .page[data-page="author"] .text-frame {
    --film-w: max(100vw, calc(100 * var(--vh) * 16 / 9));
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    transform: none;
    padding: var(--m) calc(50vw - (0.519 - 0.5) * var(--film-w) + var(--m) / 2) var(--m) calc(var(--m) + env(safe-area-inset-left));
  }
  .page[data-page="author"] .copy { font-size: calc(28 * var(--u)); }
}
.copy .blank { height: 1.39em; }
.copy:not(.is-shaped) p > span {   /* until the shape is drawn, or if scripts are off: a plain highlight per line */
  background: var(--pale);
  padding: 0.06em 0.373em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.hl-shape {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 1px;
  overflow: visible;
  z-index: -1;
  fill: var(--pale);
  pointer-events: none;
}

/* ------------------------------------------------------------------ the arrows */

/* At the foot of every page, in the corner where the letter's "Enter the utter" was: back, where you are, next.
   On the first page there is no way back, on the last no way on: those arrows give up their place, not their room. */
.pager {
  --pg: max(44px, calc(54 * var(--u)));   /* each arrow's round button, a finger's width at least */
  position: absolute;
  z-index: 20;
  right: calc(var(--m) + env(safe-area-inset-right));
  bottom: calc(var(--m) - (var(--pg) - 1.2em) / 2 + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: max(6px, calc(10 * var(--u)));
  font-size: max(12px, calc(19 * var(--u)));
  line-height: 1;
  color: var(--lime);
  text-shadow: 0 0 0.7em rgba(0, 26, 21, 0.7);
}
.pager[hidden] { display: none; }
.pg-btn {
  width: var(--pg);
  height: var(--pg);
  display: grid;
  place-items: center;
  border: 1px solid rgba(228, 248, 63, 0.6);
  border-radius: 50%;
  background: rgba(0, 26, 21, 0.3);
  transition: background-color 0.3s ease, border-color 0.3s ease, opacity 0.3s ease;
}
.pg-btn:focus-visible { outline-offset: 3px; }
.pg-btn.is-gone { visibility: hidden; }
.pg-arrow {
  width: calc(var(--pg) * 0.44);
  height: calc(var(--pg) * 0.17);
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4px;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.45s cubic-bezier(0.3, 0.7, 0.2, 1);
}
.pg-arrow path { vector-effect: non-scaling-stroke; }
.pg-back .pg-arrow { transform: scaleX(-1); }
.pg-count {
  min-width: 3.4em;
  text-align: center;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  white-space: nowrap;
}
.pg-of { opacity: 0.6; }
@media (hover: hover) {
  .pg-btn:hover { border-color: var(--lime); background: rgba(0, 26, 21, 0.5); }
  .pg-next:hover .pg-arrow { transform: translateX(0.18em); }
  .pg-back:hover .pg-arrow { transform: scaleX(-1) translateX(0.18em); }
}

/* ------------------------------------------------------------------ 4. the last page: the voice note */

.page--end {
  background:
    radial-gradient(60% 56% at 50% 44%, rgba(38, 88, 70, 0.42), rgba(0, 26, 21, 0) 72%),
    var(--ink);
}
.end-frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.end-mark {
  width: calc(230 * var(--u));
  height: calc(230 * 373.7 / 412 * var(--u));
  fill: var(--lime);
  overflow: visible;
}
.end-call {
  margin-top: calc(38 * var(--u));
  font-size: calc(62 * var(--u));
  line-height: 1.1;
  text-shadow: 0 0 0.5em rgba(0, 26, 21, 0.6);
}
/* LISTEN and the player share one place: the button until the voice starts, then the player. */
.voice-box {
  width: min(calc(620 * var(--u)), 90vw);
  margin-top: calc(50 * var(--u));
  display: grid;
  place-items: center;
}
.voice-box > * { grid-area: 1 / 1; }
.listen {   /* the very obvious button: lime, round-ended, a slow ring going out from it */
  display: inline-flex;
  align-items: center;
  gap: 0.75em;
  padding: 1em 1.7em 1em 1.45em;
  border-radius: 999px;
  background: var(--lime);
  color: var(--ink);
  font-size: max(15px, calc(22 * var(--u)));
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 0.5em 1.6em rgba(0, 0, 0, 0.35);
  animation: call 2.8s ease-out 1.2s infinite;
  transition: transform 0.35s cubic-bezier(0.3, 0.7, 0.2, 1);
}
@keyframes call {
  0% { box-shadow: 0 0 0 0 rgba(228, 248, 63, 0.5), 0 0.5em 1.6em rgba(0, 0, 0, 0.35); }
  70%, 100% { box-shadow: 0 0 0 1.1em rgba(228, 248, 63, 0), 0 0.5em 1.6em rgba(0, 0, 0, 0.35); }
}
.listen:focus-visible { outline: 2px solid var(--lime); outline-offset: 0.35em; }
.listen-icon { width: 0.8em; height: 0.94em; fill: currentColor; }
.listen-word { letter-spacing: 0.18em; margin-right: -0.18em; }
.listen-length { font-size: 0.86em; letter-spacing: 0.06em; font-variant-numeric: tabular-nums; opacity: 0.72; }
@media (hover: hover) {
  .listen:hover { transform: scale(1.04); }
}
/* Each version's last words: the ask, a button (round-ended like LISTEN, drawn in outline so LISTEN stays the obvious
   one) that opens an email to the utter, its address under it, then for guests Yrsa's name, its capital in the
   script as a guest's name has it on the envelope. */
.end-close {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: calc(60 * var(--u));
}
.end-ask, .end-sign {
  font-size: calc(30 * var(--u));
  line-height: 1.3;
  text-shadow: 0 0 0.6em rgba(0, 26, 21, 0.6);
}
.end-button {
  margin-top: calc(24 * var(--u));
  display: inline-flex;
  align-items: center;
  padding: 0.9em 2.3em;
  border: max(1px, calc(1.5 * var(--u))) solid var(--lime);
  border-radius: 999px;
  color: var(--lime);
  font-size: max(15px, calc(22 * var(--u)));
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.35s ease, color 0.35s ease;
}
.end-button span { letter-spacing: 0.18em; margin-right: -0.18em; }
.end-button:focus-visible { outline: 2px solid var(--lime); outline-offset: 0.35em; }
@media (hover: hover) {
  .end-button:hover { background: var(--lime); color: var(--ink); }
}
.end-sign { margin-top: calc(38 * var(--u)); }
.end-mail {
  margin-top: calc(34 * var(--u));
  font-size: max(13px, calc(24 * var(--u)));
  line-height: 1.3;
  text-shadow: 0 0 0.6em rgba(0, 26, 21, 0.6);
}
.end-mail a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
/* For guests the address sits close under YES, as part of it, with Yrsa's name still to come. */
[data-version="guest"] .end-mail { margin-top: calc(16 * var(--u)); }
/* A phone held sideways (under 480 px high): the wordmark and the gaps give way, so the guests' seven lines fit with
   room above and below. */
@media (orientation: landscape) and (max-height: 480px) {
  .end-mark { width: calc(180 * var(--u)); height: calc(180 * 373.7 / 412 * var(--u)); }
  .end-call { margin-top: calc(28 * var(--u)); }
  .voice-box { margin-top: calc(36 * var(--u)); }
  .end-close { margin-top: calc(44 * var(--u)); }
}

/* ------------------------------------------------------------------ the player */

.player {
  width: 100%;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);   /* the button, the line; then whatever this screen has */
  grid-auto-flow: column;
  grid-auto-columns: auto;
  align-items: center;
  column-gap: max(16px, calc(26 * var(--u)));
  font-size: max(11.5px, calc(15 * var(--u)));
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lime);
  text-shadow: 0 0 10px rgba(0, 26, 21, 0.6);
  visibility: hidden;
  opacity: 0;
}
.player.is-on { visibility: visible; opacity: 1; }
.player * { letter-spacing: inherit; }
.pl-btn { min-height: 40px; padding: 0 2px; text-transform: uppercase; white-space: nowrap; }
.pl-play { min-width: 4.6em; text-align: left; }
.pl-track {
  position: relative;
  height: 40px;
  cursor: pointer;
  touch-action: none;
  outline: none;
}
.pl-rail {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  margin-top: -0.5px;
  background: rgba(228, 248, 63, 0.32);
  box-shadow: 0 0 6px rgba(0, 26, 21, 0.5);
  transition: opacity 0.8s ease;
}
.pl-done {
  position: absolute;
  inset: 0;
  background: var(--lime);
  transform-origin: 0 50%;
  transform: scaleX(0);
}
.pl-knob {
  position: absolute;
  top: 50%;
  left: 0;
  width: 9px;
  height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: var(--lime);
  transform: scale(0);
  transition: transform 0.25s ease;
}
.pl-track:hover .pl-knob, .pl-track:focus-visible .pl-knob, .is-scrubbing .pl-knob { transform: scale(1); }
.pl-track:focus-visible .pl-rail { box-shadow: 0 0 0 3px rgba(228, 248, 63, 0.25); }
.pl-time { margin: 0; white-space: nowrap; font-variant-numeric: tabular-nums; letter-spacing: 0.06em; }
.pl-sep { opacity: 0.55; }
.pl-sound { display: flex; align-items: center; gap: 12px; }
.pl-mute { min-width: 4.4em; text-align: left; }
.pl-mute[aria-pressed="true"] { opacity: 0.6; }
.pl-vol { position: relative; width: 60px; height: 32px; cursor: pointer; touch-action: none; outline: none; }
.pl-vol-rail {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  margin-top: -0.5px;
  background: rgba(228, 248, 63, 0.32);
}
.pl-vol-done { position: absolute; inset: 0; background: var(--lime); transform-origin: 0 50%; }
.pl-vol:focus-visible .pl-vol-rail { box-shadow: 0 0 0 3px rgba(228, 248, 63, 0.25); }
.no-volume .pl-sound { display: none; }

/* Left alone while it plays, the player dims to its line. */
.player .pl-btn, .player .pl-time, .player .pl-sound { transition: opacity 0.8s ease; }
.is-idle .player .pl-btn, .is-idle .player .pl-time, .is-idle .player .pl-sound { opacity: 0; }
.is-idle .player .pl-rail { opacity: 0.65; }
.is-idle .film, .is-idle .player, .is-idle .player * { cursor: none; }

.noscript { position: fixed; inset: 0; display: grid; place-items: center; padding: 24px; text-align: center; }

/* ------------------------------------------------------------------ the grain over everything */

.grain {
  position: fixed;
  inset: -100px;
  z-index: 50;
  pointer-events: none;
  background: url("../img/film-grain.webp") 0 0 / 160px 160px;
  opacity: 0.085;
  animation: grain 0.9s steps(1) infinite;
}
@keyframes grain {
  0% { transform: translate(0, 0); }
  11% { transform: translate(-37px, 21px); }
  22% { transform: translate(43px, -54px); }
  33% { transform: translate(-71px, -9px); }
  44% { transform: translate(18px, 63px); }
  55% { transform: translate(-29px, -77px); }
  66% { transform: translate(64px, 34px); }
  77% { transform: translate(-58px, 48px); }
  88% { transform: translate(29px, -26px); }
}
html.is-still .grain, html.is-still .listen { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .grain, .listen { animation: none; }
  .listen, .pg-btn, .pg-arrow, .end-button { transition: none; }
}

/* ------------------------------------------------------------------ phones held upright */

@media (orientation: portrait) {
  .frame { left: 0; top: 0; width: 100%; height: 100%; transform: none; }

  /* The letter becomes a tall poster: the same photo and words, stacked. */
  .letter { --m: 6vw; }
  .letter-photo img { object-position: 50% 50%; }
  .corner { font-size: max(11.5px, 3.3vw); }
  .letter-scrim { background: linear-gradient(to bottom, rgba(0, 26, 21, 0.5), rgba(0, 26, 21, 0) 22%); }   /* small lines: more */
  .letter-head { top: 0; height: calc(46 * var(--vh)); }
  .letter-name {
    left: 5vw;
    right: 5vw;
    bottom: calc(0px - 0.112em);
    font-size: 25vw;
  }
  .letter-rule { left: 14vw; width: 72vw; top: calc(46 * var(--vh) + 3.6vw); height: 1px; }
  .letter-message { top: calc(46 * var(--vh) + 9vw); font-size: 4.7vw; }

  /* The title page: the wordmark and the tagline in a column; the question at the foot, above the arrows. */
  .title-frame {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0 6vw calc(14 * var(--vh));
  }
  .title-frame > * { position: static; }
  .title-mark { width: 70vw; height: calc(70vw * 373.7 / 412); }
  .title-tagline { margin-top: 3.6vw; font-size: 7.4vw; }
  .title-question {
    position: absolute;
    left: 6vw;
    right: 6vw;
    top: auto;
    bottom: calc(max(14px, 2 * var(--vh)) + 44px + max(20px, 3 * var(--vh)) + env(safe-area-inset-bottom));
    font-size: 4.6vw;
    line-height: 1.3;
    text-wrap: balance;
  }
  /* The partners' title page has two lines more: the same sizes as the guests' on a screen at least 1.72 times as
     tall as it is wide (a phone), smaller on a tablet or a short phone, so the column never meets the foot. */
  [data-version="partner"] .title-frame { --t: min(1vw, calc(0.58 * var(--vh))); }
  [data-version="partner"] .title-mark { width: calc(70 * var(--t)); height: calc(70 * var(--t) * 373.7 / 412); }
  [data-version="partner"] .title-tagline { margin-top: calc(3.6 * var(--t)); font-size: calc(7.4 * var(--t)); }
  .title-about {
    max-width: 84vw;
    margin-top: calc(6 * var(--t));
    font-size: calc(4.2 * var(--t));
    line-height: 1.35;
    text-wrap: balance;
  }
  .title-foot {
    position: absolute;
    left: 6vw;
    right: 6vw;
    top: auto;
    bottom: calc(max(14px, 2 * var(--vh)) + 44px + max(20px, 3 * var(--vh)) + env(safe-area-inset-bottom));
  }
  .title-foot .title-question { font-size: calc(4.6 * var(--t)); }
  .title-by { margin-top: calc(2.4 * var(--t)); font-size: max(11.5px, calc(3.4 * var(--t))); }

  .text-frame { padding: 0 16px; }
  .copy { max-width: min(var(--measure), calc(100vw - 32px - 0.746em)); }
  .copy p, .letter-message span { text-wrap: balance; }   /* even lines, no stray last word */
  /* The page about Yrsa: her words above her, centred in the screen's top down to a margin short of her head (the
     copy's own margins centre it there, and never push it off the top). */
  .page[data-page="author"] .text-frame {
    --film-h: max(calc(100 * var(--vh)), calc(100vw * 944 / 532));
    align-items: flex-start;
    padding-top: 16px;
    padding-bottom: calc(50 * var(--vh) - (0.667 - 0.5) * var(--film-h) + 16px);
  }
  .page[data-page="author"] .copy { margin-block: auto; }

  .pager {
    right: calc(max(12px, 3.5vw) + env(safe-area-inset-right));
    bottom: calc(max(14px, 2 * var(--vh)) + env(safe-area-inset-bottom));
    gap: 4px;
    font-size: max(12px, 3.4vw);
  }

  /* The last page in one column, sized by the screen's width, or by its height where that is the tighter (a
     tablet held upright, a short phone): --e is 1vw on a 390 x 844 phone. */
  .page--end { --e: min(1vw, calc(0.5 * var(--vh))); }
  .end-mark { width: calc(44 * var(--e)); height: calc(44 * var(--e) * 373.7 / 412); }
  .end-call { margin-top: calc(6 * var(--e)); font-size: calc(9.4 * var(--e)); }
  .voice-box { width: 88vw; margin-top: calc(9 * var(--e)); }
  .listen { font-size: max(15px, calc(4.3 * var(--e))); }
  .player { column-gap: 14px; font-size: max(11px, 3vw); }
  .end-close { margin-top: calc(10 * var(--e)); }
  .end-ask { max-width: 86vw; font-size: calc(4.4 * var(--e)); text-wrap: balance; }
  .end-button { margin-top: calc(4 * var(--e)); font-size: max(15px, calc(4.3 * var(--e))); }
  .end-sign { margin-top: calc(6.5 * var(--e)); font-size: calc(5 * var(--e)); }
  .end-mail { margin-top: calc(5.5 * var(--e)); font-size: max(13px, calc(3.9 * var(--e))); }
  [data-version="guest"] .end-mail { margin-top: calc(3 * var(--e)); }
}
