/* The home page ("Main Page" in the brand board): the keyhole and its
 * filters, the typewriter and its sheets, the popular strip on parchment,
 * the Create Mission folder. Loaded by the home page alone, after
 * tokens.css and components.css: the pieces (pills, the torn sheet and
 * slab, the folder, the marks) are components.css's, and this sheet only
 * places them. The url() rule there holds here too: a picture named in
 * this sheet is renamed when its pixels change.
 *
 * Motion is scroll-driven CSS, no script: a browser without it, and anyone
 * who asked for reduced motion, gets the same page standing still.
 */
.home-page { overflow-x: clip; background: var(--void-black) url(/web/images/bg-top.webp) center top / 100% auto no-repeat; }

/* ---- hero: the headline, and the filters around the keyhole ---- */
.hero { width: var(--container); margin: 0 auto; padding: var(--space-16) 0 var(--space-48); text-align: center; }
/* A landscape window is short for its width, so the kicker, the headline
   and the keyhole (--kw) shrink with its height too: the whole keyhole is
   on the first screen from about 730px tall (wider than 960px: the
   phone rule below keeps its own size). Words on the keyhole and its
   cards are sized from --kw, so they shrink with it. */
.hero-kicker { margin: 0; font-family: var(--font-display); font-size: clamp(1.25rem, min(3vw, 4vh), 3rem); }
/* The kicker's label: the same worn strip as the headline's highlights
   ("your" and "mission"), the whole box, with room around the words. */
.hero-kicker .worn { padding: .14em .55em .18em; }
/* The board's red on black, and only here: 1.7:1 against the page, so
   whoever asks the browser for more contrast reads it in cream. Body copy
   stays cream and tan. */
.hero h1 { max-width: 17ch; margin: var(--space-16) auto 0; color: var(--headline-red); font-size: clamp(2.6rem, min(7.8vw, 8vh), 8.5rem); font-weight: 400; line-height: 1.08; text-wrap: balance; }
@media (prefers-contrast: more) { .hero h1 { color: var(--type-on-dark); } }

/* The keyhole in the middle and nothing else: it is the one way in. Looked
   at, it lights up and four rooms are pinned around it, placed from the
   keyhole's own width (--kw) so they keep their distance at every size.
   The 140px is the header and the hero's spacing, which do not shrink. */
.keyhole-stage { --kw: clamp(200px, min(21vw, 44vh - 140px), 340px); position: relative; display: grid; justify-items: center; margin-top: var(--space-32); }
.keyhole-door { display: block; position: relative; z-index: 2; color: var(--aged-paper); text-decoration: none; outline-offset: 12px; }

/* Three pictures: the wall and the agents inside a box clipped to the
   frame's hollow (its outline, read off the frame's own pixels), the frame
   over them. clip-path, never overflow: a hidden box is a scroll container,
   and the layers' view() timelines would track that instead of the page.
   The wall is drawn larger than the hollow by what it travels, so no edge
   of it ever shows. */
.keyhole { position: relative; width: var(--kw); aspect-ratio: 3 / 5; filter: drop-shadow(0 30px 50px var(--scrim)); }
.keyhole-hole { position: absolute; inset: 0; background: var(--panel); clip-path: polygon(53.7% 5%, 67.8% 7.6%, 73.1% 10.2%, 76.6% 12.8%, 79.5% 15.4%, 82% 18%, 83.8% 20.6%, 85.3% 23.2%, 86.4% 25.8%, 86.8% 28.4%, 87% 31%, 86.5% 33.6%, 85.8% 36.2%, 83.8% 38.8%, 81.4% 41.4%, 78.6% 44%, 76.1% 46.6%, 75.9% 49.2%, 76.6% 51.8%, 77.5% 54.4%, 78.2% 57%, 79.2% 59.6%, 79.9% 62.2%, 80.7% 64.8%, 81.4% 67.4%, 81.8% 70%, 82.4% 72.6%, 83.2% 75.2%, 83.7% 77.8%, 84.1% 80.4%, 84.4% 83%, 84.8% 85.6%, 85.8% 88.2%, 86.1% 90.8%, 62.5% 93.4%, 20.7% 93.4%, 14.3% 90.8%, 15% 88.2%, 15.5% 85.6%, 16.2% 83%, 17% 80.4%, 17.8% 77.8%, 18.5% 75.2%, 19.1% 72.6%, 19.8% 70%, 20.8% 67.4%, 21.4% 64.8%, 22.2% 62.2%, 23% 59.6%, 23.7% 57%, 24.5% 54.4%, 25.3% 51.8%, 25.8% 49.2%, 24.2% 46.6%, 21% 44%, 18.5% 41.4%, 16.3% 38.8%, 14.7% 36.2%, 13.5% 33.6%, 13% 31%, 12.9% 28.4%, 13.3% 25.8%, 14.2% 23.2%, 15.7% 20.6%, 17.6% 18%, 19.8% 15.4%, 23% 12.8%, 27.3% 10.2%, 33.9% 7.6%, 49.3% 5%); }
.keyhole-wall { position: absolute; top: -7%; left: -10%; width: 120%; height: auto; }
/* Their heads in the round, their coats running under the frame's foot. */
.keyhole-agents { position: absolute; bottom: -4%; left: 1%; width: 98%; height: auto; }
.keyhole-frame { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Unlooked at, the picture is dim; looked at, it comes up and the keyhole
   steps closer. Touch has no hover, so it stays dim there. */
.keyhole { transform-origin: 50% 38%; transition: transform .9s cubic-bezier(.2, .7, .2, 1), filter .9s; }
.keyhole-wall, .keyhole-agents { filter: brightness(.5); transition: filter .9s; }
.keyhole-stage:has(.keyhole-door:hover) .keyhole-wall, .keyhole-stage:has(.keyhole-door:focus-visible) .keyhole-wall,
.keyhole-stage:has(.keyhole-door:hover) .keyhole-agents, .keyhole-stage:has(.keyhole-door:focus-visible) .keyhole-agents { filter: none; }
.keyhole-stage:has(.keyhole-door:hover) .keyhole, .keyhole-stage:has(.keyhole-door:focus-visible) .keyhole { transform: scale(1.1); }
/* A slow red glow behind the frame says the keyhole is alive. */
.keyhole-door::before { content: ""; position: absolute; inset: -12% -40% -4%; background: radial-gradient(closest-side, color-mix(in srgb, var(--brand-mark-red) 70%, transparent), transparent); opacity: 0; pointer-events: none; }

/* The caption sits inside the hollow, over the agents' coats, so it zooms
   with the keyhole and never ends up behind the frame. */
.keyhole-caption { position: absolute; z-index: 1; right: 0; bottom: 11%; left: 0; margin: 0; font-size: clamp(.9rem, calc(var(--kw) * .06), 1.2rem); white-space: nowrap; text-shadow: 0 1px 6px var(--void-black), 0 0 14px var(--void-black); pointer-events: none; }
.keyhole-caption span { display: inline-block; overflow: hidden; }
.keyhole-caption .go { display: none; font-size: 1.45em; }
.keyhole-stage:has(.keyhole-door:hover) .look, .keyhole-stage:has(.keyhole-door:focus-visible) .look { display: none; }
.keyhole-stage:has(.keyhole-door:hover) .go, .keyhole-stage:has(.keyhole-door:focus-visible) .go { display: inline-block; }

/* The pinned rooms: hidden in the dark until the keyhole is looked at, then
   they slide out from behind it. Two a side, the lower pair nearer the
   narrow stem, each leaning its own way. */
.hero-card { --lean: 0deg; --from: 0px; position: absolute; z-index: 1; width: calc(var(--kw) * .62); margin: 0; padding: 6px 6px 8px; background: var(--aged-paper); color: var(--ink); box-shadow: 0 10px 26px var(--scrim); opacity: 0; filter: grayscale(.6); transform: translateX(var(--from)) rotate(var(--lean)) scale(.9); transition: opacity .8s, transform .9s cubic-bezier(.2, .7, .2, 1); pointer-events: none; }
.hero-card img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; filter: sepia(.35) contrast(1.05); }
.hero-card figcaption { margin-top: 8px; font-size: clamp(.7rem, calc(var(--kw) * .05), .95rem); font-weight: 700; line-height: 1.2; }
/* Markup order: featured, then the three newest. */
.hero-card:nth-of-type(1) { --lean: -5deg; --from: 120px; right: calc(50% + var(--kw) * .68); top: calc(var(--kw) * .27); }
.hero-card:nth-of-type(2) { --lean: 4deg; --from: -120px; left: calc(50% + var(--kw) * .68); top: calc(var(--kw) * .32); }
.hero-card:nth-of-type(3) { --lean: 3deg; --from: 120px; right: calc(50% + var(--kw) * .51); top: calc(var(--kw) * .97); }
.hero-card:nth-of-type(4) { --lean: -3deg; --from: -120px; left: calc(50% + var(--kw) * .51); top: calc(var(--kw) * 1.03); }
.keyhole-stage:has(.keyhole-door:hover) .hero-card, .keyhole-stage:has(.keyhole-door:focus-visible) .hero-card { opacity: .6; transform: rotate(var(--lean)); }
@media (hover: none) {
  .hero-card { opacity: .5; transform: rotate(var(--lean)); }
  /* No hover to wait for: the caption already says where it goes. */
  .keyhole-caption .look { display: none; }
  .keyhole-caption .go { display: inline-block; }
}

@media (prefers-reduced-motion: no-preference) {
  .keyhole-door::before { animation: keyhole-breathe 4s ease-in-out infinite; }
  .keyhole-caption .look { border-right: 2px solid var(--aged-paper); animation: caption-type 2.2s steps(12) 1s both, caption-blink .9s step-end infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .keyhole, .keyhole-wall, .keyhole-agents, .hero-card { transition: none; }
}
@keyframes keyhole-breathe { 50% { opacity: .55; } }
@keyframes caption-type { from { width: 0; } to { width: 12.5ch; } }
@keyframes caption-blink { 50% { border-color: transparent; } }

/* ---- the typewriter: one sheet, the featured room ---- */
.typewriter { padding-bottom: 0; }
.paper-feed { position: relative; z-index: 1; width: min(calc(var(--tw) * .694), var(--container)); margin: 0 auto; }
.popular-track:focus-visible { outline: 3px solid var(--aged-paper); outline-offset: 3px; }
/* The sheet (a .torn-sheet) is at least half the machine's width tall
   (paper for it to roll out later); the body fills it, so START comes to
   rest just above the roller's bar (the roller covers the sheet's last
   22px). Positioned, so its screen-reader text is placed inside it. */
.paper-card { position: relative; display: flex; flex-direction: column; box-sizing: border-box; min-height: calc(var(--tw) * .5); padding: var(--space-64) clamp(var(--space-32), 4.5vw, var(--space-64)) calc(22px + var(--space-32)); text-align: left; }
.paper-kicker { margin: 0 0 var(--space-8); color: var(--brand-mark-red); font-size: var(--text-sm); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
/* The title on its torn strip (a .strip-title), stepped down by --fit
   when it is long (titleFit in landing_page.dart). */
.paper-card h3 { --fit: 1; align-self: flex-start; max-width: 100%; margin: 0 0 var(--space-24); font-size: calc(clamp(var(--text-xl), 2.6vw, 2.6rem) * var(--fit)); }
/* The print a little wider than the brief beside it; the body fills the
   sheet, so both columns reach its foot. */
.paper-body { display: grid; flex: 1; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); align-items: stretch; gap: clamp(var(--space-24), 3vw, var(--space-48)); }
/* The cover is a .print on the sheet. */
.paper-side { display: flex; flex-direction: column; gap: var(--space-24); min-width: 0; }
.paper-cover { aspect-ratio: 4 / 3; }
.paper-text { display: flex; flex-direction: column; gap: var(--space-24); min-width: 0; padding-top: var(--space-8); }
/* START at the brief's foot, on the right, just above the roller. */
.paper-text .start-button { align-self: flex-end; margin-top: auto; font-size: clamp(var(--text-xl), 2.2vw, 2.25rem); }
/* Under the print: the stars and their number, then the escapes. */
.paper-stats { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-8) var(--space-24); margin: 0; font-size: clamp(var(--text-sm), 1.05vw, var(--text-base)); }
.paper-rating { display: inline-flex; align-items: center; gap: var(--space-8); }
.paper-rating strong { color: var(--brand-mark-red); }
.paper-escapes { font-style: italic; }
.paper-concept { display: -webkit-box; margin: 0; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 10; font-size: clamp(var(--text-sm), 1.1vw, var(--text-lg)); line-height: 1.6; }

/* The typewriter, wider than the sheet, overlapping its foot: the roller
   holds the paper. --tw is the picture's width; its roller's top is 11.94%
   of that below the picture's top (215px of 1800), so the machine is pulled
   up until the roller covers the sheet's last 22px. It shows down to half
   its ASDF row (QWERTY's foot is 1032px of the picture's 1532, ASDF's
   1140: halfway, .603 --tw below its top; the picture is .851 --tw tall,
   so .248 of it is left below) and fades from there; the Popular slab's top tear, at its highest
   .126 of the slab down (the slab is 1.365 --card), comes in 8px under
   that row — the margin on .popular. */
/* The machine is a picture over the sheet's foot: it lets the pointer
   through, or it would take START's hover and click from it. */
.typewriter-bed { --machine: url(/web/images/typewriter-only.webp); position: relative; z-index: 2; width: var(--container); margin: calc(-1 * (22px + var(--tw) * .1194)) auto 0; pointer-events: none; }
/* The board's shadow on the machine: its body darkens from the carriage
   down to the keys, drawn over the picture and cut to the machine's own
   shape (the picture as the mask), so the page around it is untouched.
   The template sets --machine to the picture's cache-busted address and
   the <img> asks for it the same way (crossorigin), as a mask does: one
   download, not two. */
.typewriter-bed::after { content: ""; position: absolute; top: 0; left: 50%; width: var(--tw); aspect-ratio: 1800 / 1532; translate: -50% 0; background: linear-gradient(180deg, transparent 34%, color-mix(in srgb, var(--void-black) 45%, transparent) 58%, color-mix(in srgb, var(--void-black) 70%, transparent) 80%); -webkit-mask: var(--machine) center / 100% 100% no-repeat; mask: var(--machine) center / 100% 100% no-repeat; pointer-events: none; }
.typewriter-art { display: block; width: var(--tw); height: auto; margin: 0 auto; filter: brightness(.72); -webkit-mask-image: linear-gradient(180deg, var(--void-black) 61%, transparent 93%); mask-image: linear-gradient(180deg, var(--void-black) 61%, transparent 93%); }
/* Over the machine's body, right of the ribbon, as the board sets it. */
/* On the machine's flat front, right of its centre button and inside its
   body: placed from the picture (--tw wide, centred in the bed), .12 of the
   picture in from its right edge and at most .3 of it wide. */
.typewriter-aside { position: absolute; z-index: 1; top: 37%; right: calc((100% - var(--tw)) / 2 + var(--tw) * .12); display: grid; gap: var(--space-8); width: min(22rem, var(--tw) * .3); }
.tagline { max-width: 24rem; margin: 0; color: var(--paper-dim); font-size: var(--text-lg); line-height: 1.4; }
.tagline mark { display: inline-block; margin-top: var(--space-4); padding: 0 .18em; background: var(--aged-paper); color: var(--brand-mark-red); font-size: var(--text-xl); letter-spacing: .06em; text-transform: uppercase; }

/* ---- popular rooms: a .torn-slab, the strip inside ---- */
/* The slab's art (torn-edge-v6) has its top tear's rise to the right cut
   to half the board's, so the strip is not left a dark wedge, and its one
   vertical step eased into a slope. Above the top tear the typewriter
   shows through; below the bottom one, Create Mission. "Popular" crosses
   the top tear at the left, "rooms" the bottom one at the right. */
/* --tw: the typewriter picture's width, ten of the twelve columns; the
   sheet, its overlap and the popular slab's are measured from it. */
/* --word: the size of "Popular" and "rooms". */
.home-page { --card: min(62vw, 600px); --tw: var(--span-10); --word: clamp(3rem, 8.5vw, 7rem); }
/* Over the machine, its shadow cast up onto it. */
.popular { z-index: 3; margin-top: calc(-1 * (var(--tw) * .248 - 8px + var(--card) * .172)); padding: 0; overflow-x: clip; }
/* The heading's box makes no layer of its own: "rooms" and the link are
   over the photographs, "Popular" goes under the slab. */
.popular-heading { position: absolute; inset: 0; width: var(--container); margin: 0 auto; pointer-events: none; }
.popular-heading h2 { font-size: var(--word); line-height: .9; text-shadow: 0 2px 16px var(--scrim); }
.popular-heading h2 span { position: absolute; display: block; }
/* "Popular" is tucked behind the slab, as the board sets it: the tear on
   the left is about a third of a card down the slab, and the word's
   baseline (.78em below its top) sits about .24em above it, so the tear and the
   photographs lie over its foot. Under the slab's own layers (-1), still
   over the typewriter (.popular is a layer above it). */
.popular-word-a { z-index: -2; top: calc(var(--card) * .34 - 1.02em); left: 0; }
/* "rooms" hangs just below the slab's bottom tear, all of it in view: its
   letters start .25em down its box (measured), 8px under the slab's foot. */
.popular-word-b { z-index: -2; right: 0; top: calc(100% - .25em + var(--space-4)); }
/* Where the section's reading ends, "Popular" top left to "rooms" bottom
   right: the way to every room sits under "rooms", on the black below the
   bottom tear, the board's cream rule leading into it. */
/* Under "rooms" (whose .9em box ends .65 --word below the slab's foot). */
.popular .text-link { position: absolute; z-index: 1; right: 0; top: calc(100% + var(--word) * .65 + var(--space-16)); display: flex; align-items: center; gap: var(--space-16); padding: var(--space-8) 0; font-size: var(--text-xl); font-weight: 400; pointer-events: auto; }
.popular .text-link::before { content: ""; width: calc(var(--col) * 2); height: 2px; background: var(--aged-paper); }
/* The photographs fill the slab, top to foot, in its .torn-cut. */
.popular-strip .feed-arrow { position: absolute; top: 50%; z-index: 2; border-radius: var(--radius-full); background: var(--scrim); color: var(--aged-paper); translate: 0 -50%; }
.popular-strip [data-prev] { left: var(--space-16); }
.popular-strip [data-next] { right: var(--space-16); }
/* The side padding lets the first and the last card reach the centre. */
/* --shown cards across the strip, edge to edge (4 on a laptop up, 3 on a
   small one, 2 on a phone). */
.popular-track { --shown: 4; display: flex; gap: var(--space-8); padding-inline: 0; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none; }
.popular-track::-webkit-scrollbar { display: none; }
/* `clip`, not `hidden`: a hidden box is a scroll container, and the card's
   own picture would then measure itself against the card, never the strip. */
/* The slab's full height (1.365 --card), a --shown-th of the strip wide. */
.popular-card { position: relative; flex: 0 0 calc((100% - (var(--shown) - 1) * var(--space-8)) / var(--shown)); height: calc(var(--card) * 1.365); overflow: clip; background: var(--panel-raised); color: var(--aged-paper); text-decoration: none; scroll-snap-align: start; }
/* The picture starts 12% down the card, where the top tear is at its
   highest (torn-inner-v6's outline, 12.6% of the sheet at its highest), and
   is held by its top centre: a subject's head is not lost under the tear,
   and no band of card shows above it anywhere along the strip. */
.popular-card img { position: absolute; inset: 12% 0 0; width: 100%; height: 88%; object-fit: cover; object-position: 50% 0; }
/* Dark where the words are (the old 4:3 frame's foot, three quarters down),
   lighter again below them, down to the tear. */
/* Dark behind the caption (about 78% to 90% down the card), lighter again
   under it, so the foot of the photograph is a picture down to the tear,
   not a black band. */
.popular-card::after { position: absolute; inset: 0; content: ""; background: linear-gradient(180deg, transparent 46%, color-mix(in srgb, var(--void-black) 75%, transparent) 74%, color-mix(in srgb, var(--void-black) 75%, transparent) 90%, color-mix(in srgb, var(--void-black) 35%, transparent)); }
/* Between two photographs, the torn edge's cream, as on the board. */
.popular-card + .popular-card { box-shadow: calc(-1 * var(--space-8)) 0 0 var(--torn-paper); }
.popular-card:focus-visible { outline: 3px solid var(--aged-paper); outline-offset: -3px; }
/* The caption sits at the card's foot, just above the bottom tear (its
   highest point is .142 --card above the slab's foot, torn-inner-v6), on
   the card's dark fade: the title, then the escape rate under it, so the
   rates line up across the strip and a short title leaves no gap. */
.popular-caption { position: absolute; z-index: 1; right: var(--space-24); bottom: calc(var(--card) * .142 + var(--space-16)); left: var(--space-24); display: grid; gap: var(--space-8); }
.popular-rate { color: var(--paper-dim); font-size: var(--text-sm); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.popular-caption strong { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; font-family: var(--font-display); font-size: clamp(1.1rem, 1.45vw, 1.45rem); font-weight: 400; line-height: 1.15; text-shadow: 0 1px 8px var(--void-black); }

/* ---- create mission: the folder (components.css) on the lower backdrop ---- */
/* Pulled up under the Popular slab, so the backdrop shows through below its
   bottom tear (the slab is above it); the section's padding brings the
   heading back out from under the slab. */
.create-stage { position: relative; isolation: isolate; margin-top: calc(var(--card) * -.3); }
/* Room for "rooms" and its link, hanging below the slab, above the heading. */
.create-stage .create-section { width: var(--container); padding-top: calc(var(--card) * .3 + var(--word) * .65 + var(--space-96) + var(--space-48)); padding-bottom: var(--space-64); }
/* The backdrop runs down to the footer bar, so the bar's splatter lands on it. */
.home-page .site-footer { margin-top: 0; }
.create-stage .create-section h2 { margin-bottom: var(--space-32); font-size: clamp(2.6rem, 7.5vw, 6rem); }
.create-stage .create-panel { width: 100%; }

/* ---- motion: tied to the scroll position, never to a clock ---- */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    /* The wall drifts behind the frame as the page passes it; the agents,
       nearer, drift further. */
    .keyhole-wall { animation: keyhole-drift linear both; animation-timeline: view(); }
    .keyhole-agents { animation: agents-drift linear both; animation-timeline: view(); }
    /* The strip and its heading slide sideways as the page scrolls by. */
    .popular-track { animation: strip-slide linear both; animation-timeline: view(); }
    .popular-word-a { animation: word-right linear both; animation-timeline: view(); }
    .popular-word-b { animation: word-left linear both; animation-timeline: view(); }
  }
}
@keyframes keyhole-drift { from { transform: translateY(-4%); } to { transform: translateY(4%); } }
@keyframes agents-drift { from { transform: translateY(-9%); } to { transform: translateY(9%); } }
/* Leftward only: the strip opens at its first card, and a slide to the
   right would open a gap before it. */
@keyframes strip-slide { from { transform: none; } to { transform: translateX(-10%); } }
/* Small enough that the two words never meet. */
@keyframes word-right { from { transform: translateX(-4%); } to { transform: translateX(4%); } }
@keyframes word-left { from { transform: translateX(4%); } to { transform: translateX(-4%); } }

@media (max-width: 1100px) { .popular-track { --shown: 3; } }
/* Two across a phone: a smaller title, closer to the card's edges. */
@media (max-width: 640px) {
  .popular-track { --shown: 2; }
  .popular-caption { right: var(--space-16); bottom: calc(var(--card) * .142 + var(--space-8)); left: var(--space-16); gap: var(--space-4); }
  .popular-caption strong { font-size: var(--text-base); }
  .popular-rate { font-size: var(--text-xs); }
  /* Over the photographs, clear of the caption strips. */
  .popular-strip .feed-arrow { top: 36%; }
}

/* 960, not the site's 780: the fanned filters need about 1000px of hero
   (keyhole, two strokes, two pills and their outward margins), and a
   tablet in between would push the right-hand pill off the page. */
@media (max-width: 960px) {
  .home-page { background-size: auto 1200px; }
  .hero { padding-top: var(--space-16); }
  .hero h1 { max-width: none; }
  .keyhole-stage { --kw: min(54vw, 240px); margin-top: var(--space-24); }
  /* No room beside a phone's keyhole: the rooms stay in the library. */
  .hero-card { display: none; }
  /* A phone swipes the sheets; the arrows would only take their width. The
     sheet is narrower than the roller that holds it. */
  .paper-feed { width: auto; margin-inline: var(--page-margin); }
  /* The sheet is nearly the machine's width here, so the paper rests stand
     on its corners: its foot clears their full height (the roller's 22px
     plus the machine's top, .1194 --tw). Tall and narrow, it stretches the
     torn top too, so the words start below the deepest bite. */
  .paper-card { padding: var(--space-64) var(--space-24) calc(22px + var(--tw) * .1194 + var(--space-16)); }
  .paper-body { grid-template-columns: 1fr; }
  .typewriter-aside { position: static; width: auto; justify-items: center; margin-top: var(--space-16); text-align: center; }
  .paper-card h3 { font-size: calc(var(--text-xl) * var(--fit)); }
  /* The tagline sits under the machine here, so the slab does not come up
     over it. */
  .popular { margin-top: var(--space-16); }
  .popular .text-link { font-size: var(--text-base); }
  .create-stage .create-section { padding-top: calc(var(--card) * .3 + var(--word) * .65 + var(--space-64) + var(--space-48)); padding-bottom: var(--space-64); }
}
