/* tvlogo.monster: colours leaned toward the site's palette (cyan #67e8f9 for the aqua, orange for the HUD's values and
   the second button, a warmer gold, the site's dark backgrounds and muted grey); lars's layout unchanged */
  @font-face { font-family: 'Whorl Arcade'; src: url('./core/fonts/whorl-arcade.ttf') format('truetype'); }
  html, body { margin: 0; height: 100%; background: #000; color: #67e8f9; overflow: hidden; }
  body { font: 12px 'Whorl Arcade', monospace; letter-spacing: 1px; }
  #stage { position: fixed; inset: 0; }
  #stage canvas { display: block; }
  #hud { position: fixed; top: 12px; left: 12px; line-height: 1.7; white-space: pre; text-shadow: 0 0 6px #000; pointer-events: none; z-index: 6; }
  #hud b { color: #ff9a4a; font-weight: normal; }
  /* the words' glow: the studio's cyan and magenta, the banner in the planet's own colours as you arrive (main.js); red,
     gold and green only for the sound system (the band's line below) */
  :root { --g1: #67e8f9; --g2: #ff3df2; }
  #banner, #pop { position: fixed; left: 0; right: 0; text-align: center; color: #fff; pointer-events: none; white-space: pre; z-index: 6;
    text-shadow: 0 0 8px var(--g1), 0 0 18px var(--g2), 0 0 30px var(--g1); opacity: 0; transition: opacity 0.3s; }
  #pop { text-shadow: 0 0 8px #67e8f9, 0 0 18px #ff3df2; }
  #banner { top: 36%; font-size: 28px; line-height: 1.6; }
  #pop { top: 18%; font-size: 16px; }
  #banner.on, #pop.on { opacity: 1; }
  /* a pickup's sign: its name as pixel art in layers, what it does under it (main.js showSign; v0.57.0, a voxel word
     until then) */
  #sign { position: fixed; left: 50%; top: 32%; z-index: 6; pointer-events: none; text-align: center; opacity: 0; transform: translateX(-50%);
    font-size: calc(8px * var(--k)); line-height: calc(10px * var(--k)); color: #fff; text-shadow: calc(1px * var(--k)) calc(1px * var(--k)) 0 #000; white-space: nowrap; }
  #sign.on { animation: signin 3s ease-out both; }
  #sign img { display: block; margin: 0 auto; width: calc(var(--w) * var(--k) * 1px); height: calc(var(--h) * var(--k) * 1px); image-rendering: pixelated; }
  #sign .does { margin-top: calc(4px * var(--k)); }
  @keyframes signin { 0% { opacity: 0; transform: translateX(-50%) translateY(-30px) scale(.3); } 10% { opacity: 1; transform: translateX(-50%) scale(1.15); }
    18% { transform: translateX(-50%) scale(1); } 82% { opacity: 1; transform: translateX(-50%); } 100% { opacity: 0; transform: translateX(-50%) translateY(-12px); } }
  body.carding #sign { visibility: hidden; }
  /* the big words (main.js words, v0.72.0): layered pixel art high on the screen, clear of the pickups' signs, popping
     in, pulsing on the beat, blowing apart; the psychedelic ones cycling the rainbow */
  #words { position: fixed; left: 50%; top: 21%; z-index: 6; pointer-events: none; opacity: 0; transform: translate(-50%, -50%); }
  #words img { display: block; width: calc(var(--w) * var(--m) * 1px); height: calc(var(--h) * var(--m) * 1px); image-rendering: pixelated;
    transform: scale(calc(1 + var(--beat, 0) * 0.05)); filter: drop-shadow(0 0 calc(4px * var(--m)) rgba(0, 0, 0, .6)); }
  #words.on { animation: wordin .5s cubic-bezier(.2, 1.4, .4, 1) both; }
  #words.on.out { animation: wordout .4s ease-in both; }
  #words.cycle img { animation: huecycle 1s steps(8) infinite; }
  @keyframes wordin { from { opacity: 0; transform: translate(-50%, -50%) scale(.2) rotate(-8deg); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
  @keyframes wordout { from { opacity: 1; transform: translate(-50%, -50%) scale(1); } to { opacity: 0; transform: translate(-50%, -50%) scale(1.7); filter: blur(3px); } }
  @keyframes huecycle { to { filter: hue-rotate(360deg) drop-shadow(0 0 4px rgba(0, 0, 0, .6)); } }
  /* BEER GOGGLES and HIGH GRADE (main.js, v0.62.0): the screen sways and the HUD blurs; or a green haze closes in round
     the edges, breathing, and the HUD goes soft and drifts in colour */
  body.goggles #stage canvas { animation: sway 3.2s ease-in-out infinite; }
  @keyframes sway { 0%, 100% { transform: rotate(-1.1deg) scale(1.045); } 50% { transform: rotate(1.1deg) scale(1.045) translateX(6px); } }
  body.goggles #hud, body.goggles #band, body.goggles #pop, body.goggles #sign { filter: blur(1.3px); }
  body.grade #hud, body.grade #band, body.grade #pop, body.grade #sign { filter: blur(1.6px) hue-rotate(50deg); }
  #stage::after { content: ''; position: fixed; inset: 0; pointer-events: none; opacity: 0; transition: opacity 1.2s;
    background: radial-gradient(ellipse at center, rgba(90, 210, 60, 0) 35%, rgba(70, 170, 40, .4) 100%); }
  body.grade #stage::after { opacity: 1; animation: haze 4.5s ease-in-out infinite; }
  @keyframes haze { 0%, 100% { opacity: .7; } 50% { opacity: 1; } }
  @media (prefers-reduced-motion: reduce) { body.goggles #stage canvas, body.grade #stage::after { animation: none !important; } }
  /* the band: how much of the sea is land, and what the band's playing (main.js) */
  #band { position: fixed; left: 0; right: 0; top: 12px; text-align: center; pointer-events: none; z-index: 6; font-size: 14px; color: #ffc14a;
    text-shadow: 0 0 8px #e8323c, 0 0 16px #2fb34f; transition: transform 0.15s; }
  #band.up { transform: scale(1.35); }
  /* the gauge (main.js drawBand, v0.60.0): your land on a bar across the whole sea, the share that wins marked in red,
     the lock-off dashed past it, a notch for each part of the sound system (lit as it stands); what's next under it */
  #band .g-row { display: flex; align-items: center; justify-content: center; gap: 10px; }
  #band .g-now { font-weight: normal; color: #fff; min-width: 3.4em; text-align: right; }
  #band .g-bar { position: relative; width: min(340px, 46vw); height: 12px; background: rgba(0, 0, 0, .6); border: 2px solid #ffc14a; box-shadow: 0 0 0 1px #000; }
  #band .g-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: #2fb34f; transition: width .3s; }
  #band .g-fill.won { background: #ffc14a; }
  #band .g-tick { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; background: rgba(255, 255, 255, .3); }
  #band .g-tick.on { background: #fff; box-shadow: 0 0 4px #fff; }
  #band .g-win { position: absolute; top: -7px; bottom: -7px; width: 4px; margin-left: -2px; background: #e8323c; }
  #band .g-lock { position: absolute; top: -5px; bottom: -5px; width: 0; border-left: 2px dashed #ff3df2; }
  #band .g-goal { color: #e8323c; text-shadow: 0 0 6px #000; white-space: nowrap; }
  #band .g-next { margin-top: 6px; font-size: 12px; text-shadow: 0 0 6px #000, 0 0 2px #000; }
  @media (max-width: 760px) { #band .g-bar { width: 52vw; } #band .g-next { font-size: 10px; } }
  @media (min-width: 761px) and (max-width: 1180px) { #band .g-bar { width: min(260px, 26vw); } }
  @media (max-width: 760px) { #band { top: 186px; font-size: 12px; padding: 0 16px; } }   /* under the HUD on a phone */
  @media (min-width: 761px) and (max-width: 1180px) { #band { left: 300px; right: 12px; } }   /* clear of the HUD on a narrow screen */
  @media (pointer: coarse) { #help { display: none !important; } }   /* (its keys mean nothing on a phone, and it ran over the buttons) */
  #help { position: fixed; right: 12px; bottom: 12px; text-align: right; line-height: 1.7; opacity: 0.6; pointer-events: none; z-index: 6; white-space: pre; }
  #quit { display: none; position: fixed; left: 50%; top: 58%; transform: translateX(-50%); z-index: 8; font: 14px 'Whorl Arcade', monospace;
    color: #000; background: #67e8f9; border: 0; padding: 12px 18px; cursor: pointer; }
  #bar { position: fixed; left: 12px; bottom: 12px; display: flex; flex-wrap: wrap; gap: 8px; z-index: 7; }
  #bar button { font: inherit; color: #000; background: #67e8f9; border: 0; padding: 8px 10px; cursor: pointer; }
  #bar button + button { background: #ff8a3d; }
  /* touch has no P or Start: a pause button in play (Whorl's rule: QUIT TO TITLE from any game, by touch too) */
  #bar #pauseBtn { display: none; background: #ffc14a; }
  #bar #ledgerBtn { display: none; background: #ffc14a; }   /* (the ledger, on the title: main.js showLedger) */
  body.title #bar #ledgerBtn { display: block; }
  #bar #heroesBtn { display: none; background: #ff4a5a; }   /* (the world table, on the title: main.js toggleHeroes) */
  body.title #bar #heroesBtn { display: block; }
  #bar #retryBtn { display: none; background: #67e8f9; }   /* (game over: the island you died on again, main.js retry) */
  body.retry #bar { z-index: 11; }
  body.retry #bar #retryBtn { display: block; }
  @media (pointer: coarse) { body.playing #bar #pauseBtn { display: block; } }
  /* the play stats' line on the title (main.js showStats): shown only on the game's website */
  #stats { position: fixed; left: 0; right: 0; top: 62%; text-align: center; z-index: 7; padding: 0 16px; line-height: 1.8; color: #67e8f9; text-shadow: 0 0 6px #000; }
  #stats .stats-btn { font: inherit; color: #67e8f9; background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline; text-underline-offset: .3em; }
  #stats .stats-btn.off { color: #8a8a99; }
  #stats .kb { opacity: 0.6; }
  /* The scorecard at an island's end (main.js): a postcard home from the island (v0.51.0; Erik, 15 October 2026: each
     scorecard like the back of a vacation postcard, with a flip). It drops in picture side up, the island just won seen
     from above with GREETINGS FROM its ocean across it, and flips over to its back: cream card in an airmail border,
     POST CARD across the top, the message on the left (the island's points written in, each on a dotted leader, the
     total, a P.S. on how it went, the penguin's sign-off), and on the right the stamp (the island's own picture, the
     ocean's colours), a postmark with today's date, the next island as the address, and the time with its grade
     stamped in a ring. At the slam the rank thumps down across the message in red ink. The score show's beats are
     FLOE STATE's (v0.50.0): the band through a wall until the slam, the screen shaking, fireworks, the island dimmed.
     As pixel art since v0.54.0 (Erik, 15 October 2026: make the postcard more pixel graphics like): it's laid out on a
     grid of its own pixels, 342 by 228 (215 by 344 on an upright phone), every size a whole number of them, its words
     in the house font at the font's own size (8 pixels, 16 for the big ones), and shown at --k screen pixels to its
     pixel (main.js pixelScale: whole device pixels where it can). The photo, the stamp, the postmark, the grade's ring
     and the rank's rubber stamp are pixel art drawn in main.js (src/pixelart.js) and scaled up nearest; the airmail
     border steps down its diagonal a pixel at a time, the corners are notched and the shadows hard. */
  :root { --k: 2; --ink: #22305a; --paper: #f4e9cf; --red: #c8202f; }
  .px { image-rendering: crisp-edges; image-rendering: pixelated; }
  #card { position: fixed; left: 50%; top: 50%; z-index: 9; pointer-events: none; transform: translate(-50%, -50%); visibility: hidden;
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0); transition: box-shadow .4s; }
  #card.show { visibility: visible; box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .45); }
  #card .z { zoom: var(--k); font-size: 8px; line-height: 10px; letter-spacing: 0; perspective: 900px; }
  #card .tilt { position: relative; width: var(--cw); height: var(--ch); }
  #card.show .tilt { animation: drop .6s cubic-bezier(.2, 1.25, .4, 1) both; }
  @keyframes drop { 0% { transform: translateY(-115vh) rotate(-16deg); } 100% { transform: none; } }
  #card .flipper { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform .85s cubic-bezier(.45, 0, .2, 1); }
  #card.show .flipper { pointer-events: auto; cursor: pointer; }   /* (a tap or a click turns it over: main.js turnCard) */
  #card.flipped .flipper { transform: rotateY(180deg); }
  #card.slammed .flipper { animation: thump .3s ease-out; }
  @keyframes thump { 0% { transform: rotateY(180deg); } 30% { transform: rotateY(180deg) translateY(2px); } 100% { transform: rotateY(180deg); } }
  #card .face { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; filter: drop-shadow(3px 4px 0 rgba(0, 0, 0, .55)); }
  /* (the corners notched a pixel at a time) */
  #card .face .in { position: absolute; inset: 0; box-sizing: border-box; overflow: hidden;
    clip-path: polygon(0 2px, 1px 2px, 1px 1px, 2px 1px, 2px 0, calc(100% - 2px) 0, calc(100% - 2px) 1px, calc(100% - 1px) 1px, calc(100% - 1px) 2px, 100% 2px,
      100% calc(100% - 2px), calc(100% - 1px) calc(100% - 2px), calc(100% - 1px) calc(100% - 1px), calc(100% - 2px) calc(100% - 1px), calc(100% - 2px) 100%,
      2px 100%, 2px calc(100% - 1px), 1px calc(100% - 1px), 1px calc(100% - 2px), 0 calc(100% - 2px)); }
  /* the picture side: the island in a white photo border, the greeting over it on a band darkening in steps */
  #card .front .in { background: #fbf7ee; }
  #card .front .pic { position: absolute; left: 5px; top: 5px; width: calc(var(--cw) - 10px); height: calc(var(--ch) - 10px); background: #0d0b10; }
  #card .greet { position: absolute; left: 5px; right: 5px; bottom: 5px; padding: 12px 4px 4px; text-align: center; color: #fff; text-shadow: 1px 1px 0 #000;
    background: linear-gradient(rgba(0, 0, 0, 0) 0 3px, rgba(0, 0, 0, .25) 3px 6px, rgba(0, 0, 0, .45) 6px 9px, rgba(0, 0, 0, .65) 9px); }
  #card .greet small { display: block; font-size: 8px; color: #ffc14a; }
  #card .greet big { display: block; font-size: 16px; line-height: 20px; }
  #card .greet > span { display: block; color: var(--oc, #67e8f9); }
  #card .wavy { --amp: 2px; }
  /* the writing side: cream card with a grain of specks, the airmail border */
  #card .back { transform: rotateY(180deg); }
  #card .back .in { color: var(--ink); padding: 5px 6px; display: flex; flex-direction: column; gap: 3px; border: 6px solid transparent; image-rendering: pixelated;
    background: var(--grain) 0 0 / 32px 32px padding-box, linear-gradient(var(--paper), var(--paper)) padding-box, var(--air) 0 0 / 16px 16px border-box; }
  #card .pc-head { text-align: center; letter-spacing: 6px; padding-bottom: 2px; border-bottom: 1px solid rgba(34, 48, 90, .35); }
  #card .pc-body { flex: 1; min-height: 0; display: grid; grid-template-columns: 196px 1fr; gap: 0 6px; }
  #card .pc-msg { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
  #card .pc-side { border-left: 1px solid rgba(34, 48, 90, .35); padding-left: 5px; position: relative; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
  #card .dear, #card .ps, #card .sign { color: #6a4a2a; }
  #card .r { display: flex; align-items: flex-end; gap: 2px; opacity: 0; transform: translateX(-6px); transition: opacity .15s ease-out, transform .25s cubic-bezier(.2, 1.35, .4, 1); }
  #card .r.on { opacity: 1; transform: none; }
  #card .r > span { min-width: 0; white-space: nowrap; }
  #card .r .lead { flex: 1; min-width: 4px; height: 1px; margin-bottom: 1px; background: linear-gradient(90deg, rgba(34, 48, 90, .5) 1px, transparent 1px) 0 0 / 2px 1px repeat-x; }
  #card .r b { font-weight: normal; white-space: nowrap; color: #6a7090; }
  #card .r.settled b { color: var(--ink); }
  /* (paid as it went: a pixel tick after the figure) */
  #card .r.paid b::after { content: ''; display: inline-block; width: 1px; height: 1px; margin: 0 5px 3px 2px; vertical-align: bottom; color: #2f8f4a;
    box-shadow: 4px -4px, 3px -3px, 4px -3px, 2px -2px, 3px -2px, 0 -1px, 1px -1px, 2px -1px, 1px 0; }
  #card .total { display: flex; justify-content: space-between; align-items: flex-end; margin-top: 1px; padding-top: 2px; border-top: 1px solid rgba(34, 48, 90, .5); }
  #card .total b { font-weight: normal; font-size: 16px; line-height: 16px; }
  #card.slammed .total b { animation: slam .4s cubic-bezier(.2, 1.35, .4, 1); }
  #card .quip { color: var(--red); opacity: 0; transition: opacity .3s .5s; }
  #card.slammed .quip { opacity: 1; }
  #card .sign { margin-top: auto; text-align: right; }
  #card .stamp { align-self: flex-end; line-height: 0; }
  #card .postmark { position: absolute; top: 2px; right: 38px; opacity: .72; }
  #card .addr { display: flex; flex-direction: column; margin-top: 2px; }
  #card .addr span { border-bottom: 1px solid rgba(34, 48, 90, .3); padding: 1px 0; }
  #card .addr small { color: #6a4a2a; font-size: 8px; }
  #card .r.time { margin-top: auto; justify-content: space-between; align-items: center; flex-wrap: wrap; }
  #card .grade { opacity: 0; }
  #card .r.settled .grade { opacity: 1; animation: pxstamp .45s cubic-bezier(.2, 1.35, .4, 1); }
  #card .newbest { flex-basis: 100%; text-align: right; color: var(--red); animation: blink .6s steps(2) infinite; }
  #card .newbest.was { color: #6a4a2a; animation: none; }   /* (not beaten: the best there, from the ledger) */
  /* the rank, a rubber stamp in red ink across the message (drawn tilted, a pixel at a time) */
  #card .rubber { position: absolute; left: 12px; bottom: 6px; opacity: 0; pointer-events: none; }   /* (over the P.S., clear of the total and the line under it) */
  #card.slammed .rubber { opacity: .9; animation: pxstamp .5s cubic-bezier(.2, 1.35, .4, 1); }
  @keyframes pxstamp { 0% { opacity: 0; transform: scale(2.6); } 60% { opacity: .95; transform: scale(.94); } 100% { transform: scale(1); } }
  #card .skip { position: absolute; left: 0; right: 0; top: calc(100% + 6px); text-align: center; color: #67e8f9; text-shadow: 1px 1px 0 #000; animation: blink 1.2s ease-in-out infinite; }
  #card .skip span { display: block; }
  /* on an upright phone the postcard stands upright: the stamp and address over the message */
  @media (orientation: portrait) {
    #card .pc-body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; gap: 4px; }
    #card .pc-side { order: -1; border-left: 0; padding-left: 0; border-bottom: 1px solid rgba(34, 48, 90, .35); padding-bottom: 4px; display: grid; grid-template-columns: 1fr auto; gap: 2px 6px; }
    #card .stamp { grid-column: 2; grid-row: 1 / span 2; align-self: start; }
    #card .postmark { right: 40px; top: -4px; }
    #card .addr { grid-column: 1; grid-row: 1; margin-top: 0; }
    #card .r.time { grid-column: 1; grid-row: 2; margin-top: 0; }
  }
  /* An ocean's three postcards together and the run's album (main.js showOcean, showAlbum; v0.53.0, FLOE STATE's planet
     grade fitted to the postcards): after an ocean's third island its postcards are dealt onto the table picture side
     up, fanned, each with its island, time and grade, and the ocean's grade thumps down across them in its ink. After
     the fifteenth, and at game over, every postcard you sent home, a row to an ocean with the ocean's grade at its end.
     Pixel art as the postcard is since v0.54.0: each card on the table drawn and turned a pixel at a time, every size
     a whole number of the card's pixels at --k (the album's own --k, main.js showAlbum, so its rows fit). */
  #spread { position: fixed; inset: 0; z-index: 9; pointer-events: none; display: none; flex-direction: column; align-items: center; justify-content: center;
    gap: calc(8px * var(--k)); padding: 16px; box-sizing: border-box; background: rgba(0, 0, 0, .5); font-size: calc(8px * var(--k)); line-height: calc(10px * var(--k));
    letter-spacing: 0; color: #fff; text-shadow: calc(1px * var(--k)) calc(1px * var(--k)) 0 #000; }
  #spread.on { display: flex; }
  #spread .head { text-align: center; }
  #spread .head small { display: block; color: #ffc14a; font-size: inherit; }
  #spread .head big { display: block; font-size: calc(16px * var(--k)); line-height: calc(20px * var(--k)); }
  #spread .head span { color: var(--oc, #67e8f9); }
  #spread .wavy { --amp: calc(2px * var(--k)); }
  #spread .px { width: calc(var(--w) * var(--k) * 1px); height: calc(var(--h) * var(--k) * 1px); }
  #spread .table { position: relative; display: flex; justify-content: center; align-items: center; gap: calc(4px * var(--k)); max-width: 100%; }
  #spread .tc { display: flex; flex-direction: column; align-items: center; gap: calc(2px * var(--k)); opacity: 0; transform: translateY(-110vh);
    transition: transform .55s cubic-bezier(.2, 1.25, .4, 1), opacity .1s; }
  #spread .tc.in { opacity: 1; transform: translateY(calc(var(--y, 0px) * var(--k))); }
  #spread .tc img { filter: drop-shadow(calc(3px * var(--k)) calc(3px * var(--k)) 0 rgba(0, 0, 0, .55)); }
  #spread .tc .best { color: #ffc14a; }   /* (the ledger under each: main.js bestLine) */
  #spread .tc .best.new { color: #ff4a5a; animation: blink .6s steps(2) infinite; }
  /* the ocean's grade: a big rubber stamp across the three, in the grade's ink on the card's cream */
  #spread .rubber { position: absolute; left: 50%; top: calc(50% - 6px * var(--k)); opacity: 0; transform: translate(-50%, -50%); }   /* (centred on the cards, above their lines) */
  #spread.stamped .rubber { opacity: .95; animation: ostamp .5s cubic-bezier(.2, 1.35, .4, 1); }
  @keyframes ostamp { 0% { opacity: 0; transform: translate(-50%, -50%) scale(2.6); } 60% { opacity: .95; transform: translate(-50%, -50%) scale(.94); }
    100% { transform: translate(-50%, -50%) scale(1); } }
  #spread .foot { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(2px * var(--k)) calc(12px * var(--k)); opacity: 0; transition: opacity .3s .4s; }
  #spread.stamped .foot, #spread.album .foot, #spread.ledger .foot, #spread.heroes .foot { opacity: 1; }
  #spread .new { color: #ff4a5a; animation: blink .6s steps(2) infinite; }
  #spread .skip { color: #67e8f9; animation: blink 1.2s ease-in-out infinite; }
  /* the album: a row to an ocean, its postcards small, its grade at the end */
  #spread .rows { display: flex; flex-direction: column; gap: calc(2px * var(--k)); max-width: 100%; }
  #spread .row { display: grid; grid-template-columns: calc(96px * var(--k)) auto calc(21px * var(--k)); align-items: center; gap: calc(1px * var(--k)) calc(6px * var(--k));
    opacity: 0; transform: translateX(-40px); transition: opacity .15s, transform .35s cubic-bezier(.2, 1.35, .4, 1); }
  #spread .row.in { opacity: 1; transform: none; }
  #spread .row .oc { color: var(--oc, #67e8f9); }
  #spread .row .cards { display: flex; gap: calc(2px * var(--k)); }
  #spread .th { filter: drop-shadow(calc(2px * var(--k)) calc(2px * var(--k)) 0 rgba(0, 0, 0, .55)); }
  #spread .row .grade.none { visibility: hidden; }
  #spread .row .grades { display: flex; gap: calc(2px * var(--k)); }   /* (the ledger's: an ocean's A-side grade and its B-side's, v0.73.0) */
  #spread .slot { display: flex; flex-direction: column; align-items: center; }
  /* the world table (main.js showHeroes, v0.64.0): rank, initials, score, the island reached; this device's in gold,
     yours flashing; and the initials' letters, each with a button up and down for a touch screen */
  #spread .heroes { display: flex; flex-direction: column; gap: calc(1px * var(--k)); }
  #spread .hr { display: grid; grid-template-columns: calc(16px * var(--k)) calc(30px * var(--k)) calc(72px * var(--k)) calc(78px * var(--k)); gap: calc(6px * var(--k)); align-items: baseline;
    opacity: 0; transform: translateX(calc(-8px * var(--k))); transition: opacity .25s, transform .25s; }
  #spread .hr.in { opacity: 1; transform: none; }
  #spread .hr span { color: var(--oc, #67e8f9); text-align: right; }
  #spread .hr em { font-style: normal; text-align: right; }
  #spread .hr i { font-style: normal; color: #aaa1ab; }
  #spread .hr.mine b { color: #ffc14a; }
  #spread .hr.now { color: #ff4a5a; animation: blink .6s steps(2) infinite; }
  #spread .hr.empty { grid-template-columns: auto; color: #aaa1ab; }
  #spread .entry { display: flex; gap: calc(6px * var(--k)); align-items: center; pointer-events: auto; }
  #spread .entry .letter { display: flex; flex-direction: column; align-items: center; gap: calc(2px * var(--k)); }
  #spread .entry .letter b { font-size: calc(16px * var(--k)); line-height: calc(20px * var(--k)); color: #fbf7ee; }
  #spread .entry .letter.on b { color: #ffc14a; animation: blink .6s steps(2) infinite; }
  #spread .entry button { font: inherit; color: #67e8f9; background: rgba(10, 12, 24, .85); border: 2px solid #67e8f9; min-width: 44px; min-height: 32px; cursor: pointer; }
  #spread .entry .ok { color: #ffc14a; border-color: #ffc14a; min-height: 44px; }
  /* the run's map between islands (main.js showMap, v0.76.0; the island itself, src/atlas.js, v0.80.0): the island on the
     left, the crews' moves, the islands on offer and the heat beside it (under it, upright); the moves in one by one, the
     picks once they're done; diving into the island picked, the rest fades and the island fills the screen under its card */
  #spread .board { display: grid; grid-template-columns: auto minmax(0, calc(210px * var(--k))); gap: calc(8px * var(--k)); align-items: center; }
  #spread .panel { display: flex; flex-direction: column; align-items: center; gap: calc(6px * var(--k)); }
  #spread canvas.atlas { pointer-events: auto; cursor: pointer; display: block; width: min(62vw, calc((100vh - 140px) * 1.389)); aspect-ratio: 1000 / 720; height: auto;
    border: 2px solid rgba(255, 255, 255, .14); filter: drop-shadow(calc(3px * var(--k)) calc(3px * var(--k)) 0 rgba(0, 0, 0, .55)); }
  #spread.map .head, #spread.map .panel, #spread.map .foot, #spread.map .skip { transition: opacity .5s; }
  #spread.diving .head, #spread.diving .panel, #spread.diving .foot, #spread.diving .skip { opacity: 0; }
  #spread.diving canvas.atlas { position: fixed; inset: 0; width: 100vw; height: 100vh; aspect-ratio: auto; border: 0; filter: none; z-index: 1; }
  #spread .dive { position: fixed; inset: 0; z-index: 2; display: grid; place-items: center; pointer-events: none; opacity: 0; transition: opacity .6s; }
  #spread.loaded .dive { opacity: 1; }
  #spread .dive .card { background: rgba(7, 6, 15, .82); border: 3px solid var(--oc, #67e8f9); padding: calc(8px * var(--k)) calc(12px * var(--k)); display: grid; gap: calc(5px * var(--k)); justify-items: center; text-align: center; max-width: 86vw; }
  #spread .dive small { display: block; color: #ffc14a; font-size: inherit; }
  #spread .dive big { display: block; font-size: calc(16px * var(--k)); line-height: calc(20px * var(--k)); color: var(--oc, #67e8f9); }
  #spread .dive .land { color: #aaa1ab; }
  #spread .dive canvas.shape { image-rendering: pixelated; width: calc(96px * var(--k) * 1.5); height: calc(68px * var(--k) * 1.5); }
  #spread .dive .bar { width: calc(144px * var(--k)); height: calc(5px * var(--k)); border: 2px solid #fbf7ee; position: relative; }
  #spread .dive .bar i { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--oc, #67e8f9); }
  #spread .dive .go { color: #67e8f9; animation: blink 1.2s ease-in-out infinite; }
  /* PENGSTAGRAM between islands (v0.84.0, main.js showFeed): the crews' posts down a phone's feed, one by one, each
     with its face in pixel art and its name in its colour; a reply set in under the post it answers */
  #spread .feed { display: flex; flex-direction: column; gap: calc(5px * var(--k)); width: min(94vw, calc(320px * var(--k))); padding: calc(6px * var(--k));
    background: rgba(7, 6, 15, .9); border: calc(2px * var(--k)) solid #fbf7ee; box-shadow: calc(3px * var(--k)) calc(3px * var(--k)) 0 rgba(0, 0, 0, .55); text-align: left; }
  #spread .post { display: grid; grid-template-columns: calc(24px * var(--k)) 1fr; column-gap: calc(5px * var(--k)); align-items: start;
    opacity: 0; transform: translateY(calc(5px * var(--k))); transition: opacity .2s, transform .2s; }
  #spread .post.in { opacity: 1; transform: none; }
  #spread .post.reply { margin-left: calc(20px * var(--k)); }
  #spread .post .face { grid-row: span 3; }
  #spread .post .who { color: var(--pc); }
  #spread .post .who i { font-style: normal; color: #6a6f8a; }
  #spread .post .says { color: #fbf7ee; overflow-wrap: anywhere; }
  #spread .post .likes { color: #aaa1ab; }
  #spread .heatline { display: flex; align-items: center; gap: calc(4px * var(--k)); }
  #spread .moves { display: flex; flex-direction: column; align-items: center; gap: calc(2px * var(--k)); text-align: center; }
  #spread .mv { opacity: 0; transform: translateY(calc(-4px * var(--k))); transition: opacity .2s, transform .2s; }
  #spread .mv.in { opacity: 1; transform: none; }
  #spread .mv.lost { color: #ff4a5a; }
  #spread .mv.held { color: #ffc14a; }
  #spread .mv.warn { color: #9fd07a; }
  #spread .picks { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(4px * var(--k)); opacity: .25; transition: opacity .3s; }
  #spread.ready .picks { opacity: 1; }
  #spread .picks button { pointer-events: auto; cursor: pointer; font: inherit; color: #fbf7ee; text-shadow: inherit; background: rgba(10, 12, 24, .85); border: 2px solid var(--hc);
    display: grid; grid-template-columns: auto auto; column-gap: calc(5px * var(--k)); align-items: center; justify-content: start; padding: calc(3px * var(--k)) calc(5px * var(--k)); min-height: 44px; max-width: calc(184px * var(--k)); text-align: left; }
  #spread .picks button b { grid-row: span 2; font-size: calc(16px * var(--k)); line-height: calc(16px * var(--k)); color: var(--hc); }
  #spread .picks button small { font-size: inherit; color: var(--hc); }
  #spread .picks .nw { white-space: nowrap; }
  #spread.ready .picks button.on { border-color: #fbf7ee; background: rgba(46, 52, 84, .92); }
  #spread.ready .picks button.on b { animation: blink .6s steps(2) infinite; }
  #spread.map .foot { opacity: 1; }
  #spread.map .foot span { white-space: nowrap; }   /* (the ledger's: a card and its best time) */
  @media (orientation: portrait) {
    #spread .table { flex-direction: column; gap: calc(2px * var(--k)); }
    #spread .tc.in { transform: none; }
    #spread .row { grid-template-columns: auto calc(21px * var(--k)); }
    #spread .row .oc { grid-column: 1 / -1; }
    #spread .board { grid-template-columns: auto; justify-items: center; }
    #spread canvas.atlas { width: 94vw; }
  }
  /* The map, rebuilt (v0.85.0; Erik, 25 October 2026: the island and place selection screen and the transition to zoom
     in don't look good at all). The island full screen at a whole number of device pixels to a map pixel (main.js
     overviewCam), its ocean dithering into space; the head over its top left, the standings under the island, the
     console on its right (along the bottom, held upright): a solid panel with a border in the ocean's colours, each
     island on offer a card with its holder's face, its name and its sea's shape. Once you pick, the console makes way
     for PENGSTAGRAM at sea and the camera follows the boat; then the dive. Nothing jumps: the canvas is full screen
     from the start */
  #spread.map { display: block; padding: 0; background: #0d0b10; }
  #spread.map.boat { background: transparent; }   /* (v0.86.0: the map's on the boat's chart table, in the 3D world behind) */
  body.aboard #words { visibility: hidden; }   /* (the island's big words left behind with it) */
  #spread.map .board { display: contents; }
  #spread.map canvas.atlas { position: fixed; inset: 0; width: 100vw; height: 100vh; aspect-ratio: auto; border: 0; filter: none; z-index: 0; image-rendering: pixelated; }
  #spread.map .head { position: fixed; left: 16px; top: 10px; z-index: 2; text-align: left; padding: calc(3px * var(--k)) calc(6px * var(--k)); background: #0d0b10;
    border: calc(2px * var(--k)) solid var(--oc); box-shadow: inset 0 0 0 calc(1px * var(--k)) #000, calc(3px * var(--k)) calc(3px * var(--k)) 0 #000; }
  #spread.map .head big { font-size: calc(16px * var(--k)); }
  #spread.map .panel { position: fixed; right: 16px; top: 50%; transform: translateY(-50%); z-index: 2; width: calc(236px * var(--k)); max-height: calc(100vh - 24px); overflow: hidden;
    align-items: stretch; gap: calc(5px * var(--k)); padding: calc(5px * var(--k)); background: #0d0b10;
    border: calc(2px * var(--k)) solid var(--oc); box-shadow: inset 0 0 0 calc(1px * var(--k)) #000, calc(3px * var(--k)) calc(3px * var(--k)) 0 #000; }
  #spread.map .moves { align-items: flex-start; text-align: left; border-bottom: calc(1px * var(--k)) solid #2b2531; padding-bottom: calc(4px * var(--k)); }
  #spread.map .moves:empty { display: none; }
  #spread.map .picks { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
  #spread.map .picks button { display: grid; grid-template-columns: auto auto 1fr auto; grid-template-rows: auto auto auto; column-gap: calc(4px * var(--k)); align-items: center;
    max-width: none; min-height: 44px; padding: calc(3px * var(--k)); background: #18141c; border: calc(2px * var(--k)) solid #2b2531; box-shadow: inset 0 0 0 calc(1px * var(--k)) #000; }
  #spread.map .picks button b { grid-row: 1 / span 3; }
  #spread.map .picks button .face { grid-row: 1 / span 3; }
  #spread.map .picks button span { grid-column: 3; color: #fbf7ee; white-space: nowrap; overflow: hidden; }
  #spread.map .picks button .nm i { font-style: normal; color: #ffc14a; }
  #spread.map .picks button .io { color: var(--io); }
  #spread.map .picks button small { grid-column: 3; color: var(--hc); white-space: nowrap; overflow: hidden; }
  #spread.map .picks button .thumb { grid-column: 4; grid-row: 1 / span 3; outline: calc(1px * var(--k)) solid #000; }
  #spread.map .shares { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: calc(2px * var(--k)) calc(6px * var(--k)); border-top: calc(1px * var(--k)) solid #2b2531; padding-top: calc(4px * var(--k)); }
  #spread.map .shares .bar { flex-basis: 100%; object-fit: contain; }
  /* the dive's card, solid and framed as the console is, its sea's shape bigger */
  #spread.map .dive .card { background: #0d0b10; border: calc(2px * var(--k)) solid var(--oc); box-shadow: inset 0 0 0 calc(1px * var(--k)) #000, calc(4px * var(--k)) calc(4px * var(--k)) 0 #000; padding: calc(8px * var(--k)) calc(12px * var(--k)); }
  #spread.map .dive canvas.shape { width: calc(96px * var(--k) * 2); height: calc(68px * var(--k) * 2); outline: calc(1px * var(--k)) solid #000; }
  #spread.map.ready .picks button.on { border-color: var(--hc); background: #22253a; }
  #spread.map .heatline { justify-content: center; }
  #spread.map .skip { position: fixed; left: 16px; bottom: 6px; z-index: 2; }
  #spread.sailing .head, #spread.sailing .panel, #spread.sailing .skip, #spread.map.diving .head, #spread.map.diving .panel, #spread.map.diving .skip { opacity: 0; }
  #spread.map .feed.voyage { display: none; }
  #spread.sailing .feed.voyage { display: flex; position: fixed; right: 16px; top: 50%; transform: translateY(-50%); z-index: 3; width: min(42vw, calc(300px * var(--k))); max-height: calc(100vh - 24px); overflow: hidden; }
  #spread .feed .fhead { display: flex; flex-direction: column; color: var(--oc); border-bottom: calc(1px * var(--k)) solid #2b2531; padding-bottom: calc(3px * var(--k)); }
  #spread .feed .fhead b { font-weight: normal; color: #fbf7ee; font-size: calc(16px * var(--k)); line-height: calc(18px * var(--k)); }
  @media (orientation: portrait) {
    #spread.map .panel { left: 8px; right: 8px; top: auto; bottom: 30px; transform: none; width: auto; max-height: 46vh; }
    #spread.map .skip { display: none; }
    #spread.map .head { left: 8px; right: 8px; top: 8px; }
    #spread.sailing .feed.voyage { left: 8px; right: 8px; top: auto; bottom: 8px; transform: none; width: auto; max-height: 50vh; }
  }
  @keyframes huecycle { to { filter: hue-rotate(360deg); } }
  @keyframes wave { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(calc(var(--amp) * -1)); } }
  @keyframes slam { 0% { transform: scale(3); } 100% { transform: scale(1); } }
  @keyframes blink { 50% { opacity: .2; } }
  .wavy { display: inline-block; white-space: nowrap; --amp: 4px; animation: huecycle 1.6s linear infinite; }
  .wavy .w { display: inline-block; white-space: nowrap; }
  .wavy .w span { display: inline-block; color: hsl(calc(var(--i) * 32 + 300) 100% 62%); will-change: transform; animation: wave 1.1s ease-in-out infinite; animation-delay: calc(var(--i) * -.08s); }
  /* the slam shakes the screen */
  @keyframes shake { 0%, 100% { transform: none; } 20% { transform: translate(-8px, 4px); } 40% { transform: translate(7px, -5px); } 60% { transform: translate(-5px, -3px); } 80% { transform: translate(4px, 3px); } }
  #stage.shake { animation: shake .4s linear; }
  /* while the card's up, nothing else talks over it */
  body.carding #pop, body.carding #help { visibility: hidden; }
  body.spreading #hud, body.spreading #band, body.spreading #banner, body.spreading #stats { visibility: hidden; }   /* (the spread has the whole screen) */
  body.spreading #bar #view, body.spreading #bar #ocean { visibility: hidden; }   /* (they turn the island, which the spread covers; on a phone they sat over the map's foot) */
  @media (prefers-reduced-motion: reduce) { #words.on, #words.on.out, #words.cycle img { animation: none !important; } #words.on { opacity: 1; } #words.on.out { opacity: 0; } }
  @media (prefers-reduced-motion: reduce) { .wavy, .wavy .w span, #card .tilt, #card .flipper, #card .grade, #card .rubber, #spread .rubber, #stage.shake { animation: none !important; } #card .flipper, #spread .tc, #spread .row, #spread .hr { transition: none; } #spread .hr.now, #spread .entry .letter.on b { animation: none !important; } }
  /* ---------- tvlogo.monster (v0.86.1): the words and the credit line fit a phone ----------
     The big words and the pops wrap and shrink to the screen; on a phone the HUD wraps too, and the band, the pops and
     the banner stack under it (main.js layoutVars sets --hud-b, --band-b, --band-own-b and --bar-h: where the HUD, the
     band and the buttons end). The site's thanks line sits under the band (a desktop) or over the buttons (a phone), on
     one line, and its note ("Game by lars ...") gives way to the help's own last two lines once the game is up. */
  #banner, #pop { white-space: pre-wrap; padding: 0 12px; }
  #banner { font-size: min(28px, 6.2vw); }
  #pop { font-size: min(16px, 3.9vw); top: max(18%, calc(var(--hud-b, 0px) + 8px)); }   /* (under the HUD's long lines) */
  body #lars-thanks[data-corner=tr] { top: calc(var(--band-own-b, 46px) + 10px); right: max(12px, env(safe-area-inset-right)); }
  @media not (pointer: coarse) { body #lars-credit.gone ~ #lars-note { display: none; } }   /* (the help says it) */
  @media (max-width: 760px), (max-height: 500px) {
    #hud { font-size: 10px; line-height: 1.5; white-space: pre-wrap; }
    #band { font-size: 12px; }
    #band .g-next, #pop { line-height: 1.35; }
    body #lars-thanks[data-corner=tr] { top: auto; bottom: calc(var(--bar-h, 48px) + 6px); right: max(12px, env(safe-area-inset-right));
      max-width: calc(100vw - 24px); white-space: nowrap; text-align: right; }
    body #lars-note { bottom: calc(var(--bar-h, 48px) + 30px); white-space: normal; max-width: calc(100vw - 24px); }
  }
  @media (max-width: 760px) {   /* an upright phone: the HUD, then the band, then the pops and the banner */
    #hud { right: 52px; }
    #band { top: calc(var(--hud-b, 174px) + 10px); }
    #pop { top: calc(var(--band-b, 230px) + 8px); }
    #banner { top: max(36%, calc(var(--band-b, 230px) + 56px)); }
  }
  @media (max-height: 500px) and (min-width: 761px) {   /* a phone on its side: the HUD on the left, the band and the pops beside it */
    #hud { max-width: 42vw; }
    #band { left: calc(42vw + 24px); right: 52px; }
    #band .g-bar { width: min(200px, 22vw); }
    #pop { left: calc(42vw + 24px); right: 52px; top: calc(var(--band-own-b, 60px) + 6px); }
    #banner { top: max(36%, calc(var(--hud-b, 160px) + 8px)); font-size: min(28px, 6.2vw, 5.6vh); }
  }
