/* Stub's site: the app's own paper, inks and faces (the Stub design system), the card held up under one lamp, and nothing
   fetched from anyone else. Words are set level; only the cards, as objects, tilt. Every card is the app's own print with
   its corners, notches and perforation cut through, so its shadow is drawn from its own shape (`--card-shadow`). */
@font-face { font-family: "Host Grotesk"; src: url("fonts/HostGrotesk-Variable.ttf") format("truetype"); font-weight: 300 800; font-display: swap; }
@font-face { font-family: "Newsreader"; src: url("fonts/Newsreader-Variable.ttf") format("truetype"); font-weight: 200 800; font-display: swap; }
@font-face { font-family: "Newsreader"; src: url("fonts/Newsreader-Italic-Variable.ttf") format("truetype"); font-weight: 200 800; font-style: italic; font-display: swap; }
@font-face { font-family: "Fragment Mono"; src: url("fonts/FragmentMono-Regular.ttf") format("truetype"); font-weight: 400; font-display: swap; }

:root {
  --paper: #f0ede6; --cream: #f5f0e1; --ink: #1a1a1a; --ink-soft: rgba(26, 26, 26, 0.76); --grey: #5a574e;
  --hairline: rgba(26, 26, 26, 0.14); --wash: rgba(26, 26, 26, 0.06); --orange: #d4622b; --shadow: 59, 42, 18;
  --lamp: 255, 250, 238; --glow: 226, 164, 86;
  --words: "Host Grotesk", system-ui, sans-serif; --reading: "Newsreader", Georgia, serif; --numbers: "Fragment Mono", ui-monospace, monospace;
  /* Springs: one with the overshoot a card has when it is put down, one gentler for things arriving on the page. */
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1); --arrive: cubic-bezier(0.22, 1.18, 0.36, 1); --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  /* A card on the paper: a hairline of contact that draws the cut edge, notch and all, and the soft shadow under it. */
  --card-shadow: drop-shadow(0 0.5px 0.6px rgba(var(--shadow), 0.34)) drop-shadow(0 12px 16px rgba(var(--shadow), 0.15));
  --card-lifted: drop-shadow(0 0.5px 0.6px rgba(var(--shadow), 0.3)) drop-shadow(0 22px 26px rgba(var(--shadow), 0.2));
  --bar: 56px;
  color-scheme: light;
}
@media (prefers-contrast: more) { :root { --grey: #48463f; --ink-soft: #1a1a1a; --hairline: rgba(26, 26, 26, 0.3); } }

* { box-sizing: border-box; }
html { background: var(--paper); -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body { margin: 0; background: var(--paper); color: var(--ink); font: 400 18px/1.55 var(--words); -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; font-kerning: normal; }
::selection { background: rgba(212, 98, 43, 0.24); }
a { color: inherit; text-decoration-color: var(--orange); text-underline-offset: 3px; }
a, button { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; border-radius: 6px; }
img, video { max-width: 100%; height: auto; display: block; }
[id] { scroll-margin-top: calc(var(--bar) + env(safe-area-inset-top, 0px) + 8px); }
.wrap { max-width: 1180px; margin: 0 auto; padding-left: max(20px, env(safe-area-inset-left, 0px));
  padding-right: max(20px, env(safe-area-inset-right, 0px)); }
.figure { font: 400 13px/1.4 var(--numbers); letter-spacing: 0.02em; }
.skip { position: absolute; left: 12px; top: 12px; z-index: 30; background: var(--ink); color: var(--paper); padding: 10px 16px;
  border-radius: 999px; font-size: 15px; text-decoration: none; transform: translateY(-160%); }
.skip:focus-visible { transform: none; }

/* The bar: transparent over the opening; once the page moves under it, the paper behind frosts and a rule appears. */
.bar { position: sticky; top: 0; z-index: 20; padding-top: env(safe-area-inset-top, 0px);
  transition: background-color 0.35s var(--ease), box-shadow 0.35s var(--ease), backdrop-filter 0.35s var(--ease); }
.bar.lifted { background: rgba(240, 237, 230, 0.78); box-shadow: 0 0.5px 0 var(--hairline);
  -webkit-backdrop-filter: saturate(1.8) blur(18px); backdrop-filter: saturate(1.8) blur(18px); }
.top { display: flex; justify-content: space-between; align-items: center; gap: 20px; min-height: var(--bar); }
.wordmark { font: 500 23px/1 var(--words); letter-spacing: -0.03em; text-decoration: none; padding-block: 10px; }
.top nav { display: flex; gap: 6px; font-size: 15px; }
.top nav a { display: inline-flex; align-items: center; min-height: 44px; padding-inline: 10px; text-decoration: none; color: var(--ink-soft); white-space: nowrap;
  border-radius: 999px; transition: color 0.2s, background-color 0.2s; }
.top nav a:hover { color: var(--ink); background: var(--wash); }
@media (max-width: 600px) {
  .wordmark { font-size: 21px; }
  .top nav { gap: 0; font-size: 14px; margin-right: -8px; }
  .top nav a { padding-inline: 7px; }
}
@media (max-width: 360px) { .top nav a[href="#cinemas"] { display: none; } }

h1 { font: 500 clamp(50px, 8vw, 112px)/0.93 var(--words); letter-spacing: -0.04em; margin: 0; text-wrap: balance; position: relative; isolation: isolate; }
h1 em { font: italic 400 1em/0.93 var(--reading); letter-spacing: -0.02em; }
h2 { font: 500 clamp(34px, 4.6vw, 60px)/1.0 var(--words); letter-spacing: -0.035em; margin: 0 0 22px; text-wrap: balance; }
h3 { font: 500 clamp(24px, 2.4vw, 30px)/1.1 var(--words); letter-spacing: -0.025em; margin: 0 0 12px; text-wrap: balance; }
.lede { font: 400 clamp(20px, 2vw, 24px)/1.45 var(--reading); margin: 28px 0 0; max-width: 27em; text-wrap: pretty; }
.reading { font: 400 clamp(19px, 1.7vw, 21px)/1.5 var(--reading); color: var(--ink-soft); margin: 0; max-width: 32em; text-wrap: pretty; }
.lede, .reading { hanging-punctuation: first; }
.store { display: inline-flex; align-items: center; gap: 10px; margin-top: 34px; background: var(--ink); color: var(--paper);
  font: 500 16px/1 var(--words); padding: 0 26px; min-height: 54px; border-radius: 999px; text-decoration: none;
  transition: transform 0.45s var(--spring), background-color 0.2s; }
.store[href]:hover { transform: translateY(-2px); }
.store[href]:active { transform: scale(0.97); transition-duration: 0.12s; }
.store[aria-disabled="true"] { background: var(--cream); color: var(--ink); box-shadow: inset 0 0 0 0.75px var(--hairline), 0 1px 0 rgba(255, 255, 255, 0.6); cursor: default; }
.note { font-size: 14px; color: var(--grey); margin: 12px 0 0; }

/* The opening: on the page's own paper, the card held up under one warm lamp, its shadow falling on the page. The
   headline's orange plate prints a little off register, under the ink as a printer lays it, the offset in the type's own
   measure so it is the same misregistration at every size. */
.opening { padding-block: 8px 88px; }
/* Nothing runs past the page's sides, so a swipe only ever scrolls down: the lamp's glow and the closing hand are wider
   than a phone. Clipped, not hidden, so nothing becomes a scroller of its own and the bar stays put. */
.opening, main, footer { overflow-x: hidden; overflow-x: clip; }
.hero { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: 56px; align-items: center; padding-block: 32px 24px; }
.ghost { position: absolute; inset: 0; transform: translate(0.055em, 0.045em); color: var(--orange); opacity: 0.5; mix-blend-mode: multiply;
  pointer-events: none; z-index: 0; }
h1 .type { position: relative; z-index: 1; }
/* The hero's card: the app's own print of The Odyssey, both faces, cut out, held up and turning slowly, a band of light
   crossing it from the one lamp. It is an object: the two faces sit a card's thickness apart with the edge between them
   in the strip's ink darkened, as the app draws it (CardEdge), so it shows when the card leans or goes edge-on. A tap
   turns it over about its long axis with a spring; each face darkens as it turns from the lamp; its shadow lies on the
   paper and narrows as it goes edge-on. A pointer takes the lean over, as a hand would; for anyone who asks for less
   motion it holds still and the turn is a cut. */
@property --turn { syntax: "<angle>"; inherits: true; initial-value: 0deg; }
@property --light { syntax: "<percentage>"; inherits: true; initial-value: 70%; }
@property --rx { syntax: "<angle>"; inherits: true; initial-value: 2deg; }
@property --ry { syntax: "<angle>"; inherits: true; initial-value: -6deg; }
.held { --front: url("assets/hero.webp"); --back: url("assets/hero-back.webp");
  margin: 0; justify-self: center; width: min(400px, 82vw); position: relative; --turn: 0deg;
  transition: --turn 1.1s cubic-bezier(0.3, 1.3, 0.42, 1); }
.held.turned { --turn: 180deg; }
.held::before { content: ""; position: absolute; inset: -14% -24% -4%; z-index: 0; pointer-events: none;
  background: radial-gradient(closest-side, rgba(var(--lamp), 1), rgba(var(--lamp), 0.7) 45%, rgba(var(--lamp), 0) 100%),
    radial-gradient(closest-side, rgba(var(--glow), 0.2), rgba(var(--glow), 0) 100%); }
/* The shadow on the paper: the card's own silhouette, blurred (the blur is on the box, the silhouette inside it, so the
   mask cuts the shape and not the softness), and narrowed as the card goes edge-on. */
.cast { position: absolute; inset: 0 0 auto; aspect-ratio: 900 / 1440; z-index: 0; pointer-events: none; filter: blur(16px);
  transform: translate(2%, 5%) scale(0.93);
  transform: translate(2%, 5%) scale(0.93) scaleX(calc(0.14 + 0.86 * sqrt(pow(cos(var(--turn)), 2)))); }
.cast::before { content: ""; position: absolute; inset: 0; background: rgba(var(--shadow), 0.42);
  -webkit-mask: var(--front) center / 100% 100% no-repeat; mask: var(--front) center / 100% 100% no-repeat; }
.turn { display: block; width: 100%; padding: 0; margin: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer;
  position: relative; z-index: 1; perspective: 1400px; border-radius: 5% / 3.1%; touch-action: manipulation; }
.turn:focus-visible { outline-offset: 10px; }
.card3d { --rx: 2deg; --ry: -6deg; --light: 70%; display: block; position: relative; transform-style: preserve-3d;
  transform: rotateX(var(--rx)) rotateY(calc(var(--ry) + var(--turn))) rotate(-1.2deg);
  transition: --rx 0.7s var(--spring), --ry 0.7s var(--spring), --light 0.7s var(--ease), scale 0.5s var(--spring); }
.turn:active .card3d { scale: 0.985; transition-duration: 0.7s, 0.7s, 0.7s, 0.12s; }
.face { position: absolute; inset: 0; display: block; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.face.front { --art: var(--front); position: relative; transform: translateZ(1.5px); }
.face.back { --art: var(--back); transform: rotateY(180deg) translateZ(1.5px); }
.face img { width: 100%; }
/* The face turning from the lamp: darker the nearer it is to edge-on. */
.face::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: rgb(20, 14, 6); opacity: 0;
  -webkit-mask: var(--art) center / 100% 100% no-repeat; mask: var(--art) center / 100% 100% no-repeat; }
.face.front::after { opacity: calc((1 - cos(var(--turn) + var(--ry))) * 0.42); }
.face.back::after { opacity: calc((1 + cos(var(--turn) + var(--ry))) * 0.42); }
.edge { position: absolute; inset: 0; display: block; background: #151b25; transform: translateZ(var(--z));
  -webkit-mask: var(--front) center / 100% 100% no-repeat; mask: var(--front) center / 100% 100% no-repeat; }
.sheen { position: absolute; inset: 0; pointer-events: none;
  -webkit-mask: var(--art) center / 100% 100% no-repeat; mask: var(--art) center / 100% 100% no-repeat;
  background: linear-gradient(105deg, transparent 0%, transparent calc(var(--light) - 22%), rgba(255, 238, 205, 0.34) var(--light),
    transparent calc(var(--light) + 22%), transparent 100%);
  mix-blend-mode: soft-light; }
@media (prefers-reduced-motion: no-preference) {
  .card3d:not(.followed) { animation: hold 11s ease-in-out infinite, sweep 11s ease-in-out infinite; }
  .js .hero-words { animation: arrive 1s var(--arrive) both; }
  .js .held { animation: arrive 1.2s var(--arrive) 0.12s both; }
}
@media (prefers-reduced-motion: reduce) { .held, .card3d { transition: none; } }
/* The lean and the light start and end at rest, so a pointer leaving hands the card back without a jump. */
@keyframes hold { 0%, 100% { --rx: 2deg; --ry: -6deg; } 50% { --rx: -2deg; --ry: 8deg; } }
@keyframes sweep { 0%, 100% { --light: 70%; } 50% { --light: 20%; } }
@keyframes arrive { from { opacity: 0; transform: translateY(28px); } }
.held figcaption { position: relative; z-index: 1; display: flex; justify-content: space-between; align-items: center; gap: 8px 16px;
  flex-wrap: wrap; margin-top: 30px; font-size: 15px; color: var(--grey); }
.said { display: inline-flex; align-items: center; gap: 8px; color: var(--ink-soft); }
.said svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
@media (max-width: 880px) {
  .hero { grid-template-columns: minmax(0, 1fr); gap: 52px; padding-top: 20px; }
  .opening { padding-bottom: 40px; }
}

section { padding-block: 104px; }
main > section + section { border-top: 0.5px solid var(--hairline); }
@media (max-width: 640px) { section { padding-block: 72px; } }
.intro { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; align-items: end; margin-bottom: 60px; }
.intro h2 { margin: 0; }
@media (max-width: 880px) { .intro { grid-template-columns: minmax(0, 1fr); gap: 18px; margin-bottom: 40px; } }

/* Arriving: each thing comes up onto the page once, as it is reached, with a little of a card's spring; side by side, the
   later ones a beat behind. Without the script, or for anyone who asks for less motion, everything is simply there. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] { opacity: 0; transform: translateY(32px);
    transition: opacity 0.8s var(--ease) var(--d, 0ms), transform 1.05s var(--arrive) var(--d, 0ms); }
  .js [data-reveal].shown { opacity: 1; transform: none; }
}
.split > :nth-child(2), .three > :nth-child(2) { --d: 110ms; }
.three > :nth-child(3) { --d: 220ms; }

/* The wall: the cards as objects pinned to it, each a fraction off level; a pointer straightens one and lifts it. */
.wall { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 48px 32px; }
.wall li { margin: 0; }
.wall li:nth-child(4n+2) { --d: 70ms; } .wall li:nth-child(4n+3) { --d: 140ms; } .wall li:nth-child(4n+4) { --d: 210ms; }
.wall img, .strip img, .ages img, .stamped .whole, .fan img { width: 100%; filter: var(--card-shadow);
  transition: transform 0.55s var(--spring), filter 0.4s var(--ease); }
/* On the wall and the strip a card leans toward a pointer in depth (--lx, --ly, set by the page) and lifts off the pin. */
.wall img, .strip img { transform: perspective(900px) translateY(var(--lift, 0px)) rotateX(var(--lx, 0deg)) rotateY(var(--ly, 0deg)) rotate(var(--tilt, 0deg)); }
.wall li:nth-child(4n+1) img { --tilt: -0.8deg; }
.wall li:nth-child(4n+2) img { --tilt: 0.6deg; }
.wall li:nth-child(4n+3) img { --tilt: -0.4deg; }
.wall li:nth-child(4n+4) img { --tilt: 0.9deg; }
@media (hover: hover) {
  .wall li:hover img, .strip li:hover img { --tilt: 0deg; --lift: -8px; filter: var(--card-lifted); }
}
.wall span, .strip span { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-top: 16px; font-size: 15px; }
.wall b { font: 400 13px/1.6 var(--numbers); color: var(--grey); }
@media (max-width: 960px) {
  .wall { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .wall li { --d: 0ms; } .wall li:nth-child(3n+2) { --d: 70ms; } .wall li:nth-child(3n) { --d: 140ms; }
}
@media (max-width: 640px) {
  .wall { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 34px 18px; }
  .wall li { --d: 0ms; } .wall li:nth-child(2n) { --d: 70ms; }
  .wall span { flex-direction: column; gap: 2px; margin-top: 12px; }
}

/* Details: words and their picture side by side, the picture trading sides as the page goes down (`flip` puts it on the
   left); on a phone, always the words first, then what they are about. */
.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 80px; align-items: center; }
.split.flip > :first-child { order: 2; }
@media (max-width: 880px) { .split { grid-template-columns: minmax(0, 1fr); gap: 40px; } .split.flip > :first-child { order: 0; } }
figure { margin: 0; }
.phone img { width: min(330px, 100%); margin: 0 auto; border-radius: 13.6% / 6.3%; transform: rotate(0.6deg);
  box-shadow: 0 0 0 0.75px var(--hairline), 0 1px 1px rgba(var(--shadow), 0.12), 0 26px 52px rgba(var(--shadow), 0.2); }

/* The stamp: the whole card, and a loupe over its stamp, the print at half again its size, with a glass's rim and gleam. */
.stamped { justify-self: center; width: min(340px, 74%); margin-bottom: 72px; }
.stamped .art { position: relative; display: block; transform: rotate(-1deg); }
.loupe { position: absolute; left: 75.8%; top: 89.5%; width: 72%; aspect-ratio: 1; transform: translate(-50%, -50%) rotate(2deg);
  border-radius: 50%; overflow: hidden; background: var(--paper);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.85), 0 0 0 4.75px rgba(var(--shadow), 0.22), 0 20px 36px rgba(var(--shadow), 0.3),
    0 3px 6px rgba(var(--shadow), 0.2); }
.loupe img { width: 100%; height: 100%; }
.loupe::after { content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 32% 24%, rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0) 38%),
    radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0) 62%, rgba(var(--shadow), 0.16) 100%); }
.stamped figcaption { display: flex; justify-content: space-between; gap: 6px 14px; flex-wrap: wrap; margin-top: 30%; font-size: 15px;
  color: var(--grey); }
@media (max-width: 880px) { .stamped { width: min(300px, 72%); justify-self: start; margin-left: 4%; } }

/* The years: four cards from 2019 to this one, set on a line like a timeline, the oldest first. */
.ages { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 40px 32px; }
.ages li { display: flex; flex-direction: column; gap: 22px; }
.ages li:nth-child(1) img { --tilt: -1.4deg; } .ages li:nth-child(2) img { --tilt: 0.8deg; }
.ages li:nth-child(3) img { --tilt: -0.5deg; } .ages li:nth-child(4) img { --tilt: 1deg; }
.ages img { transform: rotate(var(--tilt)); }
.ages li:nth-child(2) { --d: 90ms; } .ages li:nth-child(3) { --d: 180ms; } .ages li:nth-child(4) { --d: 270ms; }
.ages .figure { position: relative; color: var(--grey); padding-top: 16px; border-top: 1px solid var(--hairline); }
.ages .figure::before { content: ""; position: absolute; left: 0; top: -4px; width: 7px; height: 7px; border-radius: 50%; background: var(--ink); }
@media (max-width: 760px) { .ages { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 36px 18px; } }

/* The light: the pearl card under the app's own lamp, thirteen prints cross-faded; the lamp's gleam on top, and the card
   turning a few degrees toward it. It is a slider: drag, arrow keys, the phone's tilt, or the scroll. */
.lit { justify-self: center; width: min(380px, 100%); }
.lit-card { position: relative; display: block; aspect-ratio: 800 / 1280; touch-action: pan-y; cursor: ew-resize;
  -webkit-user-select: none; user-select: none; border-radius: 5% / 3.1%;
  transform: perspective(1200px) rotateY(calc((var(--lamp, 0.3) - 0.5) * 14deg)); transition: transform 0.35s var(--ease); }
.lit-card img { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; -webkit-user-drag: none; }
.lit-card img:first-of-type { opacity: 1; }
/* Its shadow is a still silhouette under it, not a filter on the prints, so the cross-fade never redraws a shadow. */
.lit-shadow { position: absolute; inset: 0; filter: blur(12px); transform: translateY(12px) scale(0.97); }
.lit-shadow span { position: absolute; inset: 0; background: rgba(var(--shadow), 0.26);
  -webkit-mask: url("assets/light/00.webp") center / 100% 100% no-repeat; mask: url("assets/light/00.webp") center / 100% 100% no-repeat; }
.glare { position: absolute; inset: 0; pointer-events: none; mix-blend-mode: soft-light;
  background: radial-gradient(55% 38% at calc(var(--lamp, 0.3) * 100%) 32%, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0) 70%);
  -webkit-mask: url("assets/light/00.webp") center / 100% 100% no-repeat; mask: url("assets/light/00.webp") center / 100% 100% no-repeat; }
.lit figcaption { display: flex; justify-content: space-between; align-items: center; gap: 10px 16px; flex-wrap: wrap; margin-top: 30px;
  font-size: 15px; }
.lit-note { color: var(--grey); margin: 12px 0 0; }
.pill { font: 500 14px/1 var(--words); color: var(--ink); background: var(--wash); border: 0; border-radius: 999px; padding: 0 16px;
  min-height: 40px; cursor: pointer; transition: background-color 0.2s, transform 0.4s var(--spring); }
.pill:hover { background: rgba(26, 26, 26, 0.1); }
.pill:active { transform: scale(0.95); transition-duration: 0.1s; }

/* The press: one film in nine treatments, a strip that runs off both edges of the page and starts where the words do; a
   finger runs along it, paddles step it two cards at a time. */
.gallery { --inset: max(20px, env(safe-area-inset-left, 0px), calc((100vw - 1180px) / 2 + 20px)); }
.strip { list-style: none; margin: 0; padding: 10px var(--inset) 26px; display: grid; grid-auto-flow: column;
  grid-auto-columns: clamp(168px, 21vw, 232px); gap: 28px; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-padding-inline: var(--inset); scrollbar-width: none; }
.strip::-webkit-scrollbar { display: none; }
.strip:focus-visible { outline-offset: -4px; }
.strip li { scroll-snap-align: start; }
.strip li:nth-child(2) { --d: 60ms; } .strip li:nth-child(3) { --d: 120ms; } .strip li:nth-child(4) { --d: 180ms; }
.strip li:nth-child(5) { --d: 240ms; } .strip li:nth-child(n+6) { --d: 300ms; }
.strip span { justify-content: flex-start; color: var(--grey); font-size: 14px; }
.paddles { display: flex; justify-content: flex-end; gap: 12px; }
.paddles[hidden] { display: none; }
.paddles button { display: grid; place-items: center; width: 44px; height: 44px; border: 0; border-radius: 50%; padding: 0;
  background: var(--wash); color: var(--ink); cursor: pointer; transition: background-color 0.2s, opacity 0.2s, transform 0.4s var(--spring); }
.paddles button:hover { background: rgba(26, 26, 26, 0.1); }
.paddles button:active { transform: scale(0.92); transition-duration: 0.1s; }
.paddles button:disabled { opacity: 0.32; cursor: default; background: var(--wash); transform: none; }
.paddles svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* Privacy: three plain statements, set large. */
.privacy h2 { max-width: 12em; margin-bottom: 52px; }
.three { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 44px; }
.three > div { border-top: 2px solid var(--ink); padding-top: 22px; }
@media (max-width: 880px) { .three { grid-template-columns: minmax(0, 1fr); gap: 36px; } }

/* For cinemas: the link as it would be written, set on a slip, with a way to take it. */
.code { min-width: 0; }
pre { font: 400 13px/1.7 var(--numbers); background: var(--cream); border-radius: 14px; padding: 22px 24px; overflow-x: auto; margin: 0;
  box-shadow: inset 0 0 0 0.75px var(--hairline), 0 1px 0 rgba(255, 255, 255, 0.6); white-space: pre; tab-size: 2; }
.code figcaption { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px;
  font-size: 14px; color: var(--grey); }
.copy { font: 500 14px/1 var(--words); color: var(--ink); background: var(--wash); border: 0; border-radius: 999px; padding: 0 16px;
  min-height: 36px; cursor: pointer; transition: background-color 0.2s, transform 0.4s var(--spring); }
.copy:hover { background: rgba(26, 26, 26, 0.1); }
.copy:active { transform: scale(0.95); transition-duration: 0.1s; }

/* The coda: three nights fanned like a hand of tickets, and where to get Stub. A pointer opens the hand a little. */
.coda { text-align: center; padding-block: 112px 120px; }
.coda h2 { margin-bottom: 0; }
.fan { position: relative; width: min(560px, 100%); height: clamp(230px, 33vw, 330px); margin: 0 auto 56px; }
.fan img { position: absolute; bottom: 0; left: 50%; width: clamp(128px, 19vw, 196px); transform-origin: 50% 120%; }
.fan img:nth-child(1) { transform: translateX(-50%) rotate(-11deg) translateX(-12%); }
.fan img:nth-child(2) { transform: translateX(-50%) translateY(-5%); z-index: 1; }
.fan img:nth-child(3) { transform: translateX(-50%) rotate(11deg) translateX(12%); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .fan:hover img:nth-child(1) { transform: translateX(-50%) rotate(-16deg) translateX(-16%); }
  .fan:hover img:nth-child(2) { transform: translateX(-50%) translateY(-9%); }
  .fan:hover img:nth-child(3) { transform: translateX(-50%) rotate(16deg) translateX(16%); }
}

footer { padding-block: 36px calc(48px + env(safe-area-inset-bottom, 0px)); border-top: 0.5px solid var(--hairline); font-size: 14px;
  color: var(--grey); display: flex; justify-content: space-between; gap: 8px 20px; flex-wrap: wrap; }

@media (prefers-reduced-motion: reduce) {
  .wall img, .strip img, .fan img, .store, .paddles button, .copy, .pill, .lit-card { transition: none; }
  .wall li:hover img, .strip li:hover img { --lift: 0px; }
}

/* The unissued ticket: a ticket handed over by a cinema's link, shown when Stub is not on this phone yet (add/). */
.ticket { position: relative; background: var(--cream); border-radius: 4px; padding: 26px 64px 26px 26px; max-width: 520px;
  box-shadow: 6px 8px 0 rgba(212, 98, 43, 0.12), 0 10px 30px rgba(var(--shadow), 0.1); transform: rotate(-1.2deg); }
.ticket .admit { font: 400 12px/1 var(--numbers); color: var(--grey); }
.ticket .film { font: 500 34px/1.05 var(--words); letter-spacing: -0.03em; margin: 14px 0 10px; text-wrap: balance; }
.ticket .place { font: 400 19px/1.3 var(--reading); color: var(--ink-soft); }
.ticket .fields { display: flex; gap: 26px; margin-top: 18px; flex-wrap: wrap; }
.ticket .fields .v { font: 400 16px/1.2 var(--numbers); color: var(--ink-soft); }
.ticket .fields .l { font-size: 12px; color: var(--grey); margin-top: 3px; }
.ticket .perf { position: absolute; right: 34px; top: 12px; bottom: 12px; width: 5px;
  background: radial-gradient(circle, rgba(138, 133, 120, 0.6) 2.2px, transparent 2.6px) 0 0 / 5px 12px repeat-y; }
@media (prefers-reduced-motion: no-preference) { .ticket { animation: put-down 0.7s cubic-bezier(0.34, 1.4, 0.5, 1) both; } }
@keyframes put-down { from { transform: translateY(-16px) rotate(-3deg); } to { transform: rotate(-1.2deg); } }
/* The Add to Stub landing: the words and the ticket side by side; on a phone, the ticket first, then what to do. */
.hero.handed { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
@media (max-width: 860px) {
  .hero.handed { grid-template-columns: minmax(0, 1fr); }
  .hero.handed #ticket-place { order: -1; }
  .hero.handed h1 { font-size: clamp(40px, 11vw, 56px); }
}
