/* Inter, served from /fonts (variable weight, Latin and Latin Extended), is the one typeface */
@font-face { font-family: Inter; font-style: normal; font-weight: 100 900; font-display: swap; src: url(/fonts/inter-latin.woff2) format("woff2");
  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: Inter; font-style: normal; font-weight: 100 900; font-display: swap; src: url(/fonts/inter-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
:root {
  --font: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* Connections theme: warm marquee. --bg is the flat fallback and the colour for
     text on dark fills; --bg-fun is the page background. */
  --bg: #fff0dc;
  --bg-fun: linear-gradient(165deg, #ffe6bd 0%, #ffd2c4 50%, #f8c4de 100%);
  --fg: #2a1a1e;
  --muted: #6d5648;
  --card: #ffffff;
  --card-border: #f0d9c6;
  --selected: #8a1f4a;
  --selected-fg: #fff;
  --accent: #b4235a;
  --on-accent: #fff;
  --yellow: #f3c94e;
  --green: #9ecf63;
  --blue: #86b7e8;
  --purple: #bb8ad8;
  --coral: #f2a08c;
  --shadow: 0 1px 2px rgba(0,0,0,.06), 0 4px 14px rgba(0,0,0,.05);
  --radius: 18px;
  --max: 760px;
  --gap: 8px;
  /* everything but the 4x4 board: header, meta, message, mistakes, controls, credit row */
  --chrome: 236px;
  --cols: 4;
  /* tiles are full-frame portrait photos, --photo times as tall as wide: the height is what the
     page height allows, capped by what the width allows */
  --photo: 1.5;
  --tile-w: calc((min(100vw, var(--max)) - 32px - (var(--cols) - 1) * var(--gap)) / var(--cols));
  --tile-h: min(clamp(90px, calc((100vh - var(--chrome)) / var(--cols) - var(--gap)), 300px), calc(var(--tile-w) * var(--photo)));
  /* faces are a fixed share of the tile, or less when a two-line name needs the room
     (2.3 = two lines at 1.15; 7px = the name's margin plus the tile border) */
  --tile-pad: 6px;
  --name-size: clamp(.72rem, 1.75vw, .92rem);
  --face: min(calc(var(--tile-h) * .6), calc(var(--tile-h) - 2.3 * var(--name-size) - 2 * var(--tile-pad) - 7px));
  --board-w: calc(var(--cols) * var(--tile-h) / var(--photo) + (var(--cols) - 1) * var(--gap));
}
@supports (height: 100dvh) {
  :root { --tile-h: min(clamp(90px, calc((100dvh - var(--chrome)) / var(--cols) - var(--gap)), 300px), calc(var(--tile-w) * var(--photo))); }
}
/* Strands theme: cool lagoon */
body.strands-game {
  --bg: #e2f1f8;
  --bg-fun: linear-gradient(165deg, #c6f1e2 0%, #cbe5ff 50%, #dcd3ff 100%);
  --fg: #151c2e;
  --muted: #4d5a73;
  --card-border: #cbdaee;
  --selected: #25348a;
  --accent: #2b4acb;
}
/* Hive theme: honey and meadow */
body.theme-find {
  --bg: #fff5d0;
  --bg-fun: linear-gradient(165deg, #fff3b8 0%, #fbe6a6 45%, #d9ebb6 100%);
  --fg: #2a2110;
  --muted: #6b5a33;
  --card-border: #e6d49c;
  --selected: #3d2c0c;
  --accent: #7a4d00;
}
/* Six degrees theme: silver screen, with a ticket-red accent */
body.theme-arrange {
  --bg: #eef0f3;
  --bg-fun: linear-gradient(165deg, #f3f4f6 0%, #dfe4ec 50%, #eedfe1 100%);
  --fg: #1b1e24;
  --muted: #59616d;
  --card-border: #cbd2dc;
  --selected: #1b1e24;
  --accent: #b3261e;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #251a1d; --bg-fun: linear-gradient(165deg, #2e2016 0%, #2c1820 50%, #26192f 100%);
    --fg: #f3eae5; --muted: #ab9a90; --card: #35272b; --card-border: #4d3a40;
    --selected: #f3eae5; --selected-fg: #251a1d; --accent: #ff9ab8; --on-accent: #2a1018;
    --shadow: 0 1px 2px rgba(0,0,0,.4);
  }
  :root:not([data-theme="light"]) body.strands-game {
    --bg: #151c27; --bg-fun: linear-gradient(165deg, #11261f 0%, #131e30 50%, #1d1a38 100%);
    --fg: #e8eef6; --muted: #94a2b8; --card: #212b3a; --card-border: #34425c;
    --selected: #e8eef6; --selected-fg: #151c27; --accent: #9db4ff; --on-accent: #0f1630;
  }
  :root:not([data-theme="light"]) body.theme-find {
    --bg: #221c10; --bg-fun: linear-gradient(165deg, #2b2410 0%, #2a2012 45%, #1c2a1a 100%);
    --fg: #f4ecd8; --muted: #b3a37c; --card: #33291a; --card-border: #54452a;
    --selected: #f4ecd8; --selected-fg: #221c10; --accent: #ffc94d; --on-accent: #2a1c00;
  }
  :root:not([data-theme="light"]) body.theme-arrange {
    --bg: #17191d; --bg-fun: linear-gradient(165deg, #1f2126 0%, #15171b 50%, #221a1c 100%);
    --fg: #eceef1; --muted: #9aa2ad; --card: #272b31; --card-border: #3d434c;
    --selected: #eceef1; --selected-fg: #17191d; --accent: #ff8f80; --on-accent: #2b0d09;
  }
}
* { box-sizing: border-box; }
html, body { margin: 0; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; touch-action: manipulation; }
button, select { -webkit-tap-highlight-color: transparent; }
button, input, select, textarea { font-family: inherit; }
body {
  background: var(--bg-fun, var(--bg)) fixed; color: var(--fg);
  font-family: var(--font);
  line-height: 1.4; min-height: 100vh; display: flex; flex-direction: column;
  /* clear of the notch and home bar when it runs full screen from the Home Screen */
  padding: env(safe-area-inset-top) max(16px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}
@supports (height: 100dvh) { body { min-height: 100dvh; } }
main { max-width: var(--max); width: 100%; margin: 0 auto; flex: 1; transition: opacity .24s ease; }
/* switching games from the menu: the board fades out, the next one fades in once its faces load */
main.switching { opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { main { transition: none; } }
header.top { max-width: var(--max); width: 100%; margin: 0 auto; padding: 10px 0 4px; display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: nowrap; }
.brand { display: flex; align-items: baseline; gap: 10px; flex-wrap: nowrap; }
h1 { margin: 0; font-size: 1.15rem; letter-spacing: -0.01em; color: var(--accent); }
.modes { display: flex; gap: 2px; align-items: center; flex: none; margin-left: auto; }
.modes .btn { margin: 0 0 0 4px; }
/* New is a plus in a circle, drawn like the find field's magnifier */
.circle-btn { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; margin-left: 4px; padding: 0;
  border: 1.5px solid var(--accent); border-radius: 50%; background: none; color: var(--accent); cursor: pointer; }
.circle-btn svg { width: 22px; height: 22px; display: block; }
.circle-btn:hover, .circle-btn[aria-expanded="true"] { background: var(--accent); color: var(--on-accent); }
/* New game menu: a column of levels per board size */
.menu-wrap { position: relative; display: inline-flex; }
.menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 6; display: grid; grid-template-columns: repeat(var(--menu-cols, 1), auto);
  gap: 2px 6px; padding: 8px; background: var(--card); border: 1px solid var(--card-border); border-radius: 16px; box-shadow: var(--shadow); }
.menu.left { right: auto; left: 0; }
.menu-item { font: inherit; font-size: .88rem; padding: 6px 18px; border: 0; border-radius: 10px; background: none; color: var(--fg); cursor: pointer; white-space: nowrap; text-align: center; }
.menu-item:hover:not(:disabled), .menu-item:focus-visible { background: var(--bg); outline: none; }
.menu-item:disabled { opacity: .35; cursor: default; }
.chip-group { display: inline-flex; gap: 0; margin-right: 10px; }
.brand .chip-group { margin-right: 0; }
/* header links are plain text: bold for the active one, nothing else */
.chip { border: 0; background: none; color: var(--muted); border-radius: 6px; padding: 4px 6px; cursor: pointer; font: inherit; font-size: .9rem; }
.chip:hover { color: var(--fg); }
.chip.active { color: var(--accent); font-weight: 700; }
/* the game names follow the title on its line; a long list scrolls sideways rather than pushing New away */
.brand { min-width: 0; }
/* the current game's icon, circled at the far left, opens a menu of the other games; the game's name follows it */
.brand { align-items: center; }
.games-wrap .circle-btn { margin-left: 0; }
#game-group .menu-item { display: flex; align-items: center; gap: 9px; text-align: left; padding-left: 12px; }
/* the name is the logo: serif, like the title, and only a click target */
.game-name { font-size: 1.15rem; font-weight: 700; letter-spacing: -0.01em; color: var(--accent); white-space: nowrap;
  background: none; border: 0; border-radius: 0; padding: 0; cursor: pointer; text-decoration: none; -webkit-tap-highlight-color: transparent; }
.game-name:focus, .game-name:active { outline: none; background: none; }
.game-name:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* each game has a line icon, drawn like the header's: in the circle, and before the name in the menu and on the entry card */
.game-icon { width: 1.25em; height: 1.25em; flex: none; display: block; }
#game-group .game-icon { width: 20px; height: 20px; }
.entry-head h2 { display: flex; align-items: center; gap: 8px; }
.entry-head .game-icon { width: 1.15em; height: 1.15em; }
/* share and help are line icons in the text colour */
.chip.icon { display: inline-flex; align-items: center; padding: 4px 5px; }
.chip.icon svg { width: 19px; height: 19px; display: block; }
/* phones: New stays flush top right; if the row is too narrow the game names wrap under the title instead */
@media (max-width: 480px) { header.top { gap: 6px; align-items: flex-start; } .brand { gap: 0 6px; } .chip { padding: 4px; } .chip.icon { padding: 4px 2px; } .circle-btn { margin-left: 2px; } }
@media (max-width: 380px) { h1 { font-size: 1.05rem; } .brand .chip { font-size: .85rem; padding: 4px 3px; } }
.row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0 0 6px; min-height: 30px; }
.btn.small { padding: 4px 12px; font-size: .85rem; }
.hints { display: flex; gap: 10px; align-items: baseline; margin-right: auto; }
.hints-label { color: var(--muted); font-size: .85rem; margin-right: -2px; }
/* hints are underlined links; once used, the answer shows in bold with no underline */
.hint { font: inherit; font-size: .85rem; padding: 2px 0; border: 0; background: none; color: var(--accent); cursor: pointer;
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.hint:hover:not(:disabled) { text-decoration-thickness: 2px; }
.hint.revealed { text-decoration: none; cursor: default; font-weight: 700; }
.hint.on { font-weight: 700; }
.hint:disabled:not(.revealed) { opacity: .45; cursor: default; }
.hint-extra { display: contents; }
/* The find field has its own row under the game: a magnifier in a circle at the
   right until it is clicked or holds text, then a field across the whole row. The
   match count floats just above its right end, so nothing on the page moves.
   16px so phones don't zoom the page when it takes focus. */
.find-row { position: relative; display: flex; justify-content: flex-end; margin: 8px 0 4px; }
/* the credit, centred under the grid; the open field and a game's own controls sit over it */
.credit { position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 1; pointer-events: none; white-space: nowrap;
  font-size: .68rem; color: color-mix(in srgb, var(--muted) 60%, transparent); }
.credit a { color: inherit; text-decoration: none; pointer-events: auto; }
.credit a:hover { text-decoration: underline; color: var(--muted); }
.find-row:has(.find:focus, .find:not(:placeholder-shown), .mq-ask) .credit { visibility: hidden; }
/* a game's own controls at the left of the row (Marquee's Show cast); they step aside while the field is open */
.find-extra { position: absolute; left: 0; top: 0; z-index: 3; display: flex; align-items: center; gap: 8px; height: 30px; }
.find-left { position: absolute; left: 0; top: 0; z-index: 3; display: flex; align-items: center; gap: 6px; height: 30px; }
.find-left .circle-btn { margin: 0; }
.find-row:has(.find:focus, .find:not(:placeholder-shown)) .find-left { display: none; }
.find-extra:empty, body:not(.theme-lights) .find-extra, .find-row:has(.find:focus, .find:not(:placeholder-shown)) .find-extra { display: none; }
.find-extra .circle-btn { margin: 0; }
.circle-btn:disabled { opacity: .35; cursor: default; background: none; color: var(--accent); }
.find-wrap { position: relative; flex: 1; height: 30px; }
.find { position: absolute; right: 0; top: 0; z-index: 4; width: 30px; height: 30px; padding: 0; font: inherit; font-size: 16px; border-radius: 999px;
  border: 1.5px solid var(--accent); background: var(--card); color: var(--fg); cursor: pointer; transition: width .2s ease; }
.find::placeholder { color: transparent; }
.find:focus, .find:not(:placeholder-shown) { width: 100%; padding: 0 36px 0 14px; cursor: text; }
.find:focus::placeholder { color: var(--muted); }
.find:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.find-icon { position: absolute; right: 0; top: 0; z-index: 5; width: 30px; height: 30px; padding: 7px; color: var(--accent); pointer-events: none; }
.typed { position: absolute; right: 6px; bottom: calc(100% + 6px); z-index: 4; font-size: .85rem; padding: 3px 10px;
  border-radius: 999px; background: var(--accent); color: var(--on-accent); white-space: nowrap;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* a top row with nothing showing in it (the modes have no hints) takes no room */
.row:not(:has(> :not(.hidden))) { display: none; }
/* Strands: the row above the board is as wide as the board, so the magnifier sits flush right with the grid */
/* the search icon rides the status line, at the bottom right of the grid; the credit stays where it was */
.strands-game .find-row { margin-top: -19px; margin-bottom: 24px; }
.strands-game .credit { top: calc(50% + 26px); }
.strands-game .status { padding-right: 40px; padding-left: 40px; }
.strands-game .row, .strands-game .find-row { max-width: var(--board, 402px); margin-left: auto; margin-right: auto; }
.tile.match { outline: 3px solid var(--accent); outline-offset: -3px; }
.meta { color: var(--muted); font-size: .85rem; margin: 0 auto 0 0; }
.games { font: inherit; font-size: .85rem; font-weight: 600; color: var(--fg); background: transparent; border: 0;
  border-radius: 6px; padding: 2px 4px 2px 0; margin-right: 6px; max-width: 60%; cursor: pointer;
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
/* the puzzle picker follows the game names on the top line */
.brand .games { flex: none; margin: 0; padding: 2px 0; font-size: .9rem; font-weight: 400; max-width: 12em; field-sizing: content; }   /* as wide as the chosen puzzle, not the longest */
.hidden { display: none !important; }
/* read by screen readers, not shown (the page title in the header) */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

.grid { display: grid; grid-template-columns: repeat(var(--cols), 1fr); gap: var(--gap); width: var(--board-w); max-width: 100%; margin: 0 auto; }
.tile {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--card) 78%, transparent); border: 1px solid var(--card-border); border-radius: min(var(--radius), calc(var(--tile-h) * .2));
  padding: var(--tile-pad); cursor: pointer; font: inherit; color: inherit;
  transition: transform .08s ease, background .12s ease; height: var(--tile-h); text-align: center; overflow: hidden;
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
.tile:active { transform: scale(.97); }
.tile img { width: var(--face); height: var(--face); border-radius: 50%; object-fit: cover; background: var(--card-border); display: block; flex: none; }
/* names break at spaces; only a long word (Mahershala) is hyphenated, never a short surname */
.tile .name { font-size: var(--name-size); line-height: 1.15; margin-top: 5px; font-weight: 600; overflow-wrap: anywhere;
  hyphens: auto; hyphenate-limit-chars: 10 5 5; -webkit-hyphenate-limit-before: 5; -webkit-hyphenate-limit-after: 5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tile.selected { background: var(--selected); color: var(--selected-fg); border-color: var(--selected); }
.tile.shake { animation: shake .4s; }
.tile.bounce { animation: bounce .35s; }
@keyframes shake { 0%,100% { transform: translateX(0);} 25% { transform: translateX(-5px);} 75% { transform: translateX(5px);} }
@keyframes bounce { 0%,100% { transform: translateY(0);} 50% { transform: translateY(-8px);} }
@media (max-width: 420px) {
  :root { --tile-pad: 4px; }
  .tile .name { margin-inline: -2px; }   /* a little more line for long surnames */
}
/* Connections and Strands: full-frame photos like Marquee's, the name over the foot of the photo */
.grid .tile { padding: 0; justify-content: flex-end; border: 0; border-radius: min(10px, calc(var(--tile-h) * .08)); background: #2a211d; color: #fff; }
.grid .tile img { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 0; object-fit: cover; object-position: 50% 22%; background: #2a211d; pointer-events: none; }
.grid .tile .name { position: relative; z-index: 1; width: 100%; margin: 0; padding: 20px 4px 6px; color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .85);
  background: linear-gradient(transparent, rgba(0, 0, 0, .74) 55%); -webkit-line-clamp: 3; }
/* selected and found tiles are a ring over the photo, the name band in the same colour */
.grid .tile::after { content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; pointer-events: none; }
.grid .tile.selected { background: #2a211d; color: #fff; }
.grid .tile.selected::after { box-shadow: inset 0 0 0 4px var(--selected); }
.grid .tile.selected .name { background: var(--selected); color: var(--selected-fg); text-shadow: none; }
/* an outline would sit under the photo, so a type-to-find match and an outlined cast are drawn on the ring too */
.grid .tile.match { outline: none; }
.grid .tile.match::after { box-shadow: inset 0 0 0 4px var(--accent); }
.grid .tile.hinted { outline: none; }
.grid .tile.hinted::after { outline: 3px dashed #fff; outline-offset: -6px; }

.solved { display: flex; flex-direction: column; gap: var(--gap); width: var(--board-w); max-width: 100%; margin-left: auto; margin-right: auto; }
.solved:not(:empty) { margin-bottom: var(--gap); }
.group {
  display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: center; height: var(--tile-h); overflow: hidden;
  border-radius: var(--radius); padding: 8px 12px; color: #1d1b19; animation: pop .3s ease;
}
@keyframes pop { from { transform: scale(.96); opacity: .2; } to { transform: scale(1); opacity: 1; } }
.group.d0 { background: var(--yellow); } .group.d1 { background: var(--green); }
.group.d2 { background: var(--blue); } .group.d3 { background: var(--purple); }
.group .poster { height: calc(var(--tile-h) - 16px); width: calc((var(--tile-h) - 16px) * 2 / 3); border-radius: 10px; object-fit: cover; background: rgba(0,0,0,.1); }
.group .poster.empty { display: flex; align-items: center; justify-content: center; font-size: 1.6rem; }
.group > div { min-width: 0; }
.group h3 { margin: 0 0 4px; font-size: 1.05rem; }
.group h3 small { font-weight: 400; opacity: .75; }
.group .faces { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: .85rem; }
.group .faces span { display: inline-flex; align-items: center; gap: 5px; }
.group .faces img { width: 20px; height: 30px; border-radius: 3px; object-fit: cover; object-position: 50% 22%; }
@media (max-width: 480px), (max-height: 480px) {
  .group { gap: 8px; padding: 6px 8px; }
  .group h3 { font-size: .9rem; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .group .faces { font-size: .72rem; gap: 2px 8px; }
  .group .faces span { gap: 4px; }
  .group .faces img { width: 14px; height: 21px; border-radius: 2px; }
}

.message { min-height: 1.4em; text-align: center; margin: 8px 0 2px; font-weight: 600; }
.mistakes { display: flex; justify-content: center; align-items: center; gap: 10px; color: var(--muted); font-size: .9rem; }
/* mistakes left are numbered circles, like Marquee's doors */
.conn-foot { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin: 8px 0; }
.conn-foot:not(:has(> :not(.hidden))) { display: none; }
.conn-foot .mistakes { justify-content: flex-start; }
.conn-foot .controls { margin: 0; flex-wrap: nowrap; gap: 6px; }
.conn-foot .controls .circle-btn { margin: 0; width: 34px; height: 34px; }
.circle-btn.primary { background: var(--accent); color: var(--on-accent); }
.circle-btn:disabled { opacity: .35; cursor: default; background: none; color: var(--accent); }
.circle-btn.primary:disabled { background: var(--accent); color: var(--on-accent); }
.dots { display: inline-flex; gap: 6px; }
.dots span { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: 1.5px solid var(--accent); border-radius: 50%;
  color: var(--accent); font-size: .85rem; transition: opacity .2s; }
.dots span.gone { opacity: .25; text-decoration: line-through; }

.controls { display: flex; justify-content: center; gap: 10px; margin: 8px 0; flex-wrap: wrap; }
.btn { font: inherit; font-size: .9rem; padding: 8px 18px; border-radius: 999px; cursor: pointer; border: 1.5px solid var(--accent); background: transparent; color: var(--accent); }
.btn.primary { background: var(--accent); color: var(--on-accent); }
.btn:disabled { opacity: .35; cursor: default; }
@media (max-width: 360px) { .controls { gap: 8px; } .controls .btn { padding: 8px 12px; } }
/* touch screens: the header links, hints and buttons keep their look but get a finger-sized
   hit area (about 44px tall) */
@media (pointer: coarse) {
  .chip, .hint, .btn { position: relative; }
  .chip::after, .hint::after, .btn::after { content: ""; position: absolute; inset: -8px -2px; }
  .hint::after { inset: -10px -5px; }
  .btn::after { inset: -6px 0; }
  .games { padding-block: 11px; margin-block: -9px; }
  .menu-item { padding-block: 10px; }
}

.results { text-align: center; border-top: 1px solid var(--card-border); padding-top: 16px; margin-top: 8px; }
.results h2 { margin: 0 0 8px; }
.emoji { font-size: 1.4rem; line-height: 1.3; margin: 0; font-family: inherit; }
.decoys { list-style: none; padding: 0; margin: 8px auto 0; text-align: left; max-width: 480px; font-size: .9rem; color: var(--muted); }
.decoys li { padding: 6px 0; border-bottom: 1px dashed var(--card-border); }
.decoys b { color: var(--fg); }


.modal { position: fixed; inset: 0; background: rgba(0,0,0,.45); display: flex; align-items: center; justify-content: center; padding: 16px; z-index: 10; }
.modal-card { background: var(--card); color: var(--fg); border-radius: 24px; padding: 24px; max-width: 460px; width: 100%; box-shadow: var(--shadow);
  max-height: calc(100vh - 32px); overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
@supports (height: 100dvh) { .modal-card { max-height: calc(100dvh - 32px); } }
.modal-card h2 { margin-top: 0; }
.modal-card li { margin: 8px 0; }
.modal-card ul { padding-left: 18px; }
@media (max-width: 480px) {
  .modal-card { padding: 18px 20px; border-radius: 20px; font-size: .92rem; }
  .modal-card h2 { margin-bottom: 8px; }
  .modal-card li { margin: 6px 0; }
}
.share-card { text-align: center; }
.share-card p { color: var(--muted); font-size: .9rem; }
.qr { display: flex; justify-content: center; margin: 8px 0; }
.qr svg { width: 200px; height: 200px; background: #fff; padding: 8px; border-radius: 8px; }
.share-urls { list-style: none; padding: 0 !important; margin: 8px 0 16px; }
.share-urls li { font-size: 1rem; padding: 4px 0; }
.share-urls a { color: inherit; }
/* the entry card, one small card in the middle of the screen: the game's name with its two
   buttons stacked beside it, then the rules (the first time, and from the ?) or the picks
   (Make New Game); the game behind stays on screen, under the same dim as the other modals */
.entry-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin: 0 0 6px; }
.entry-head h2 { margin: 0; padding-top: 10px; }
.entry-actions, .entry-foot { --entry-btn: 12em; }
.entry-actions { flex: none; display: flex; flex-direction: column; gap: 10px; }
.entry-actions .btn, .entry-foot .btn { width: var(--entry-btn); padding-inline: 10px; font-weight: 700; }
#entry-today.dim { opacity: .55; }
.entry-foot { display: flex; justify-content: flex-end; margin: 18px 0 0; }
html.entry-open, html.entry-open body { overflow: hidden; }
#entry { overscroll-behavior: contain; touch-action: none; }
.entry-card { max-height: 100%; overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; }
.entry-card { max-width: 380px; padding: 18px 18px 16px; font-size: .88rem; line-height: 1.35; border-radius: 18px;
  border: 1px solid var(--card-border); box-shadow: 0 6px 28px rgba(0, 0, 0, .35); }
.entry-card h2 { font-size: 1.2rem; margin: 0 0 6px; }
/* the rules: short lines, one each, without bullets, smaller than the card's text, with a little air above */
.entry-card ul { list-style: none; padding: 0; margin: 12px 0 10px; font-size: .8rem; line-height: 1.4; }
.entry-card li { margin: 3px 0; }
.help-foot { color: var(--muted); font-size: .78rem; margin: 0 0 6px; }
.help-foot.tmdb { font-size: .7rem; opacity: .75; }
.help-foot a { color: inherit; }
/* a control the rules name is drawn as it is in the game: the eye, Moneyshot's buttons, Marquee's numbered doors */
.help-ic { width: 1.15em; height: 1.15em; vertical-align: -.22em; display: inline-block; }
.help-door { display: inline-flex; align-items: center; justify-content: center; width: 1.4em; height: 1.4em; margin: 0 2px;
  border: 1.5px solid currentColor; border-radius: 50%; font-size: .72em; font-style: normal; vertical-align: -.3em; }
.entry-row { margin: 12px 0 0; }
.entry-label { display: block; margin: 0 0 6px; font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.picks { display: flex; flex-wrap: wrap; gap: 6px; }
.pick { font: inherit; font-size: .82rem; padding: 4px 11px; border-radius: 999px; border: 1px solid var(--card-border); background: none; color: var(--fg); cursor: pointer; }
.pick:hover:not(:disabled) { border-color: var(--accent); }
/* a picked chip is outlined in the accent; the filled accent is kept for Play Today's Game */
.pick.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); color: var(--accent); font-weight: 600; }
.pick:disabled { opacity: .3; cursor: default; }
/* on a phone the name and the buttons beside it come down a size, so both fit across the card */
@media (max-width: 400px) {
  .entry-card { padding-inline: 14px; }
  .entry-card .entry-head h2 { font-size: 1.05rem; }
  .entry-actions .btn, .entry-foot .btn { font-size: .82rem; }
}

/* ---------------------------------------------------------------- strands */
.board { position: relative; }
.strand-lines { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; overflow: visible; }
.strands-game #grid { position: relative; z-index: 1; }   /* the lines show only between the tiles */
.strand-lines polyline { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.strand-lines .chain-line { stroke: #fff; stroke-width: 10; }
.strand-lines .found-line { stroke-width: 10; }

/* the 4x4 board: game.js (fit) sizes --strand-h and --board so the whole game
   fits the viewport without scrolling */
.strands-game { --gap: 6px; }
.strands-game .board { max-width: var(--board, 402px); margin: 0 auto; }
.grid.strands { touch-action: none; user-select: none; -webkit-user-select: none; width: auto; }
.grid.strands.done { touch-action: auto; }
.grid.strands .tile { height: var(--strand-h, 132px); border-radius: min(10px, calc(var(--strand-h, 132px) * .08)); }
/* names stay hidden until a tile is picked; the slide that rises over the photo is white, greyer the further off */
.grid.strands .tile .name { display: none; }
.grid.strands .tile.selected .name { display: block; background: color-mix(in srgb, #fff calc((1 - var(--heat, 0)) * 100%), #e5484d); color: #1d1b19; text-shadow: none; }
.grid.strands .tile.selected::after { box-shadow: inset 0 0 0 4px color-mix(in srgb, #fff calc((1 - var(--heat, 0)) * 100%), #e5484d); }
.grid.strands .tile.found .name { display: block; }
.grid.strands .tile .name { font-size: clamp(.66rem, calc(var(--strand-h, 132px) * .09), .85rem); padding: 18px 3px 5px; line-height: 1.12; }
/* the name slide is always a third of the tile, two lines at most, centred */
.grid.strands .tile.selected .name, .grid.strands .tile.found .name { display: flex; align-items: center; justify-content: center; overflow: hidden; -webkit-line-clamp: none;
  height: calc(var(--strand-h, 132px) / 3); box-sizing: border-box; padding: 4px 3px; font-size: clamp(.6rem, calc(var(--strand-h, 132px) * .075), .8rem); line-height: 1.1; }
.grid.strands .tile.long-name .name { font-size: clamp(.52rem, calc(var(--strand-h, 132px) * .062), .7rem); overflow-wrap: normal; }
/* game.js sets --strand to the film's own colour.
   tracing: two or more chain tiles from the same film, halfway to the found colour */
.tile.found { cursor: default; }
.tile.found::after { box-shadow: inset 0 0 0 4px var(--strand, var(--blue)); }
.tile.found .name { background: var(--strand, var(--blue)); color: #1d1b19; text-shadow: none; }
.tile.hinted { outline: 3px dashed var(--fg); outline-offset: -4px; }
.tile.hinted.match { outline: 3px solid var(--accent); outline-offset: -3px; }   /* a type-to-find match still shows on an outlined cast */
.tile .badge {
  position: absolute; top: 6px; left: 6px; z-index: 3; width: 18px; height: 18px; border-radius: 50%;
  background: var(--fg); color: var(--bg); font-size: .65rem; font-weight: 700; line-height: 18px; text-align: center;
}
.tile.selected .badge { background: var(--selected-fg); color: var(--selected); }
/* the number sits in the corner, touching the 4px ring: no gap between them */
.grid.strands .tile .badge { top: 4px; left: 4px; width: 20px; height: 20px; line-height: 20px; border-radius: 0 0 50% 0; }
.grid.strands .tile.selected .badge { background: color-mix(in srgb, #fff calc((1 - var(--heat, 0)) * 100%), #e5484d); color: #1d1b19; }   /* the slide's own white or red */
.tile.found .badge { background: var(--strand, var(--blue)); color: #1d1b19; }

/* One status slot under the board: the message (or the chain being traced) and
   the list of found films share it, so the board gets the rest of the page. */
.strands-game .status { display: grid; grid-template-columns: minmax(0, 1fr); margin-top: 5px; }
.strands-game .status > * { grid-area: 1 / 1; }
/* the instruction over the board; found film titles take its place line by line beneath it */
.strands-intro { max-width: var(--board, 402px); margin: 4px auto 6px; text-align: center; font-size: .9rem; line-height: 1.3; color: var(--muted); }
.strands-intro.gone { display: none; }
.strands-game #found { max-width: var(--board, 402px); width: 100%; margin: 0 auto; justify-content: flex-start; align-content: flex-start; align-self: stretch; }
/* before any film is found the instruction has the slot: the circles sit at the end of its second line */
.strands-game #found.empty { align-content: flex-end; }
/* the instruction and the found titles share one two-line slot, so the board never moves */
.strands-game .strands-top { display: grid; align-items: center; min-height: 52px; max-width: var(--board, 402px); margin: 4px auto 8px; }
.strands-game .strands-top { grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; }
.strands-game .strands-top > * { grid-area: 1 / 1; }
/* the mistake circles keep a column of their own on the right, level with the second line */
.strands-game .strands-top > .strand-misses { grid-area: 1 / 2; align-self: end; margin-bottom: 2px; }
/* seven faded ✕ circles on the right of the two-line slot; each wrong four fills the next one in */
.strand-misses { display: flex; gap: 4px; }
.strand-misses i { width: 15px; height: 15px; border: 1.5px solid var(--muted); border-radius: 50%; box-sizing: border-box; position: relative; opacity: .4; transition: opacity .2s, background .2s; }
.strand-misses i::before, .strand-misses i::after { content: ""; position: absolute; left: 50%; top: 50%; width: 8px; height: 1.6px; background: var(--muted); border-radius: 1px; }
.strand-misses i::before { transform: translate(-50%, -50%) rotate(45deg); }
.strand-misses i::after { transform: translate(-50%, -50%) rotate(-45deg); }
.strand-misses i.on { opacity: 1; background: #e5484d; border-color: #e5484d; }   /* a mistake: red */
.strand-misses i.on::before, .strand-misses i.on::after { background: #fff; height: 2px; }
.strand-misses i.back { animation: regain .9s ease; }   /* a life won back */
@keyframes regain { 0%, 40% { transform: scale(1.5); opacity: 1; border-color: var(--green); background: var(--green); } }
@media (prefers-reduced-motion: reduce) { .strand-misses i.back { animation: none; } }
/* in the header the hints drop their label; on a narrow screen they wrap under the title */
.brand .hints { margin: 0 0 0 6px; gap: 8px; }
.brand .hints .hints-label { display: none; }
.hints-up .brand { flex-wrap: wrap; row-gap: 2px; }
.strands-game .strands-intro { margin: 0 auto; width: 100%; text-align: left; align-self: end; }
.strands-game .message { min-height: 24px; margin: 0; font-size: .88rem; line-height: 24px; }
.strands-game .message.chain { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.found-list { display: flex; flex-wrap: wrap; gap: 4px 6px; justify-content: center; align-items: center; min-height: 24px; }
.pill { font-size: .75rem; line-height: 1.3; padding: 2px 10px; border-radius: 999px; background: var(--strand, var(--blue)); color: #1d1b19;
  max-width: 17em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pill.new { animation: flicker .7s steps(1, end); }
@keyframes flicker { 0%, 30%, 60% { opacity: 0; } 15%, 45%, 75%, 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .pill.new { animation: none; } }
.pill small { opacity: .7; }
/* the start: until Start the tiles are empty frames, and the card sits over them */
.grid.strands.unstarted .tile > * { visibility: hidden; }
.grid.strands.unstarted .tile { background: color-mix(in srgb, var(--fg) 7%, transparent); border-color: color-mix(in srgb, var(--fg) 10%, transparent); cursor: default; }
.lineup-start { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 16px; text-align: center; }
.lineup-start p { margin: 0; }
.lineup-start-label { font-size: .75rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.lineup-start-rule { font-size: 1.15rem; line-height: 1.35; }
.lineup-start-btn { min-width: 9em; padding: 10px 28px; font-size: 1rem; }
/* Start deals the faces onto the board, one after another */
.grid.strands.dealing .tile { animation: deal .42s cubic-bezier(.2, .8, .3, 1.2) both; animation-delay: calc(var(--i, 0) * 45ms); }
@keyframes deal { from { opacity: 0; transform: translateY(10px) scale(.9); } }
/* the end: the reel lights one film's lineup at a time and dims the rest */
.grid.strands .tile { transition: opacity .35s ease, filter .35s ease, transform .08s ease; }
.grid.strands .tile.dim { opacity: .16; filter: grayscale(1); }
.grid.strands .tile.lit { animation: lineup .5s ease both; animation-delay: calc(var(--n, 0) * 110ms); }
@keyframes lineup { 40% { transform: scale(1.07); } }
.strand-lines polyline { transition: opacity .35s ease; }
.strand-lines .dim { opacity: .1; }
.strands-game #found.away { visibility: hidden; }
.lineup-caption { margin: 0; max-width: var(--board, 402px); width: 100%; align-self: end; line-height: 1.25; overflow: hidden; }
.lineup-caption b { font-size: 1.15rem; color: var(--strand, var(--fg)); white-space: nowrap; }
.lineup-caption small { color: var(--muted); }
.lineup-caption span { display: block; font-size: .78rem; color: var(--muted); }
/* out of lives: the four red ✕s, big, in the middle of the screen over everything */
.lineup-lost { position: fixed; inset: 0; z-index: 90; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
  background: rgba(8, 6, 12, .62); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); cursor: pointer; transition: opacity .35s ease; animation: fade-in .25s ease; }
.lineup-lost.gone { opacity: 0; }
.lineup-lost p { margin: 0; font-size: clamp(1.6rem, 7vw, 2.4rem); font-weight: 700; color: #fff; text-shadow: 0 2px 12px rgba(0,0,0,.6);
  animation: fade-in .4s ease .7s both; }
.lineup-lost-xs { display: flex; gap: clamp(6px, 2vw, 14px); }
.lineup-lost-xs i { position: relative; width: clamp(34px, 10.5vw, 72px); aspect-ratio: 1; border-radius: 50%; background: #e5484d;
  box-shadow: 0 6px 24px rgba(229, 72, 77, .45); animation: x-in .38s cubic-bezier(.2, .9, .3, 1.4) both; }
.lineup-lost-xs i:nth-child(2) { animation-delay: .07s; } .lineup-lost-xs i:nth-child(3) { animation-delay: .14s; } .lineup-lost-xs i:nth-child(4) { animation-delay: .21s; }
.lineup-lost-xs i:nth-child(5) { animation-delay: .28s; } .lineup-lost-xs i:nth-child(6) { animation-delay: .35s; } .lineup-lost-xs i:nth-child(7) { animation-delay: .42s; }
.lineup-lost-xs i::before, .lineup-lost-xs i::after { content: ""; position: absolute; left: 50%; top: 50%; width: 52%; height: 9%; background: #fff; border-radius: 99px; }
.lineup-lost-xs i::before { transform: translate(-50%, -50%) rotate(45deg); }
.lineup-lost-xs i::after { transform: translate(-50%, -50%) rotate(-45deg); }
@keyframes x-in { from { opacity: 0; transform: scale(.3); } }
@keyframes fade-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .grid.strands.dealing .tile, .grid.strands .tile.lit, .lineup-lost, .lineup-lost p, .lineup-lost-xs i { animation: none; } }
.strands-game .controls { margin: 5px 0 2px; }
.strands-game .controls .btn { padding: 5px 16px; font-size: .85rem; }

/* ------------------------------------------------------------------ modes */
/* modes.js draws a whole game into #mode-root and sizes it through --T (see fit) */
.mode { max-width: 460px; margin: 0 auto; }
.m-bar { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: .9rem; color: var(--muted); }
.m-bar b { color: var(--fg); }
.m-score { display: inline-block; font-variant-numeric: tabular-nums; }
.m-score.pop { animation: score .5s ease; color: var(--fg); font-weight: 700; }
@keyframes score { 0% { transform: scale(1); } 35% { transform: scale(1.35); } 100% { transform: scale(1); } }

/* hive: a circle per group, then the centre actor with six around */
.m-groups { display: flex; align-items: center; justify-content: space-between; gap: 3px; margin: 2px 0 0; }
.m-groups i { display: grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid color-mix(in srgb, var(--fg) 25%, transparent); font-size: .58rem; font-weight: 700; font-style: normal; line-height: 1; font-variant-numeric: tabular-nums; color: var(--muted); transition: background .3s, border-color .3s, color .3s; }
.m-groups i.g3 { width: 21px; height: 21px; font-size: .66rem; }
.m-groups i.g4 { width: 26px; height: 26px; font-size: .74rem; }
.m-groups i.on { background: var(--yellow); border-color: var(--selected); color: #1d1b19; }
.m-groups i.missed { border-style: dashed; }
.hive { position: relative; width: calc(var(--T, 96px) * 4); max-width: 100%; aspect-ratio: 1 / 1.2; margin: 0 auto; }
/* full-frame portrait photos, the name over the foot of each */
.hive .node { position: absolute; width: 21.5%; height: auto; aspect-ratio: 2 / 3; translate: -50% -50%; padding: 0; border: 0; border-radius: 8px;
  background: #2a211d; color: #fff; overflow: hidden; justify-content: flex-end; box-shadow: 0 0 0 1.5px var(--card-border); transition: box-shadow .12s ease; }
.hive .node:disabled { cursor: default; }
.hive .node img { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 0; object-fit: cover; object-position: 50% 22%; }
.hive .node .name { position: relative; z-index: 1; width: 100%; margin: 0; padding: 18px 3px 5px; font-size: clamp(.62rem, calc(var(--T, 96px) * .12), .82rem); line-height: 1.1;
  color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .85); background: linear-gradient(transparent, rgba(0, 0, 0, .74) 55%); -webkit-line-clamp: 3; }
.hive .node.selected { box-shadow: 0 0 0 4px var(--selected); }
.hive .node.selected .name { background: var(--selected); color: var(--selected-fg); text-shadow: none; }
.hive .node.match { outline: none; box-shadow: 0 0 0 4px var(--accent); }
.m-line { min-height: 1.4em; margin: 2px 0 0; text-align: center; font-size: .9rem; font-weight: 600; }
.m-line small { font-weight: 400; opacity: .75; }
.m-line.picking { font-size: 1rem; }
.m-line.bad { color: var(--muted); }
.m-line em { display: inline-block; margin-left: 4px; padding: 0 8px; border-radius: 999px; background: var(--yellow); color: #1d1b19; font-style: normal; font-weight: 700; animation: pop .3s ease; }
.m-found { display: flex; flex-direction: column; gap: 5px; margin-top: 6px; font-size: .85rem; }
.m-found div { display: flex; gap: 8px; align-items: baseline; }
.m-found b { flex: 0 1 auto; min-width: 0; }
.m-found div:first-child:not(.missed) { animation: pop .3s ease; }
.m-found b small { font-weight: 400; opacity: .7; }
.m-found span { color: var(--muted); flex: 0 2 auto; min-width: 4.5em; }
.m-found i { margin-left: auto; font-style: normal; font-weight: 700; font-variant-numeric: tabular-nums; }
.m-found .missed { opacity: .55; }
.m-after { display: flex; justify-content: center; margin: 12px 0 0; }
.m-after .btn { padding: 4px 12px; font-size: .8rem; border-color: transparent; text-decoration: underline; text-underline-offset: 3px; }
.mode-game .message { margin: 2px 0 0; }

/* --------------------------------------------------------------- marquee */
/* a black page whatever the colour scheme: the faces are the only light */
body.theme-lights {
  --bg: #000; --bg-fun: #000;
  --fg: #f5efe6; --muted: #958b80; --card: #17130f; --card-border: #2c251d;
  --selected: #ffd27a; --selected-fg: #140c00; --accent: #ffc24d; --on-accent: #1a1000;
  --shadow: 0 1px 2px rgba(0,0,0,.6);
  --bulb: #ffcf6b;
  color-scheme: dark;
}
.mode-marquee { max-width: none; }
/* the search sits just under the wall's bottom right corner and opens across the wall's width:
   #mode-root steps out of the way so its parts and the find row line up in one column */
body.theme-lights main { display: flex; flex-direction: column; }
body.theme-lights #mode-root { display: contents; }
body.theme-lights .mq-sign { width: 100%; }
body.theme-lights .mq-wall { align-self: center; }   /* as wide as its photos, so the find row can match it */
body.theme-lights .find-row { order: 1; align-self: center; width: var(--grid-w, 100%); max-width: 100%; margin: 6px 0 0; }
body.theme-lights .status { order: 2; }
/* Marquee ends on the wall itself, and Lineup on its board: no results panel (title, emoji row, share) under them */
body.theme-lights #results, body.strands-game #results { display: none; }
.mq-ask { display: flex; align-items: center; gap: 6px; font-size: .88rem; white-space: nowrap; }
.mq-ask .btn { padding: 3px 12px; font-size: .82rem; }
.mq-ask .btn:first-of-type { margin-left: 4px; }
/* the sign: a backlit letter board with track lines, in an amber frame with a row of
   bulbs top and bottom and neon fins at the sides. Nothing on it blinks; two
   bulbs flicker faintly. */
.mq-sign { position: relative; max-width: min(100%, 640px); margin: 4px auto 14px; padding: 20px; border-radius: 10px;
  background: linear-gradient(#e99a40, #c4691d);
  box-shadow: 0 0 0 2px #ffc66e, 0 0 28px 6px rgba(255, 150, 50, .4); }
.mq-board { min-width: 0; padding: 4px 14px 2px; border: 3px solid #2a1b0c; border-radius: 3px; text-align: center; color: #141414;
  /* five panels across, lit a touch brighter at the top; modes.js tints random cells of the
     panel-by-row grid a little off-white (--panels) */
  background: repeating-linear-gradient(90deg, transparent 0 calc(20% - 1px), rgba(0, 0, 0, .07) calc(20% - 1px) 20%),
    linear-gradient(rgba(255, 255, 255, .2), rgba(110, 90, 60, .07)), var(--panels, none);
  background-color: #fcfaf4;
  box-shadow: inset 0 0 18px rgba(255, 255, 255, .9), 0 0 14px rgba(255, 240, 210, .6);
  /* the sign keeps its own lettering: Inter is for the page, not the signage */
  font-family: "DIN Condensed", "Avenir Next Condensed", "Roboto Condensed", "Arial Narrow", Impact, sans-serif; font-weight: 700; text-transform: uppercase; }
.mq-kicker, .mq-board h2 { display: block; border-bottom: 2px solid #c9c2b3; }
.mq-kicker { padding: 3px 0 1px; font-size: .78rem; letter-spacing: .16em; color: #5a5048; }
/* the title band is always the height of a full-size line; modes.js shrinks a long title's letters
   inside it, so changing films never moves the sign */
.mq-board h2, .mq-board h3 { --title: clamp(1.7rem, 6.4vw, 2.7rem); margin: 0; padding: 4px 0 0; white-space: nowrap; overflow: hidden;
  height: calc(var(--title) * 1.15 + 4px); line-height: calc(var(--title) * 1.15);
  font-family: inherit; font-size: var(--title); letter-spacing: .05em; color: #141414;
  /* slotted plastic letters standing a little proud of the board: lit from above, a soft shadow below */
  text-shadow: 0 -1px 0 rgba(255, 255, 255, .7), 0 1px 0 #8f887d, 0 2px 2px rgba(0, 0, 0, .16); }
/* each letter hangs on the board a little crooked (modes.js gives it a turn of up to 2 degrees) */
.mq-board h2 span, .mq-board h3 span { display: inline-block; }
/* a worn letter: the same letter laid over it in dark grey, showing only on one side (modes.js picks the side) */
.mq-board .worn { position: relative; }
.mq-board .worn::after { content: attr(data-c); position: absolute; inset: 0; color: var(--wear); text-shadow: none;
  -webkit-mask-image: linear-gradient(var(--a), #000 0 18%, transparent 55%); mask-image: linear-gradient(var(--a), #000 0 18%, transparent 55%); }
.mq-board h2:last-child, .mq-board h3:last-child { border-bottom: 0; }
/* a title going up for the first time: each letter dropped into its slot in turn (modes.js staggers
   the delays, a little longer between words), waiting unseen until its turn */
.mq-board h2.spell span { animation: mq-hang 240ms cubic-bezier(.3, 1.5, .5, 1) backwards; }
@keyframes mq-hang { from { opacity: 0; translate: 0 -.3em; } }
/* the frame's bulbs, placed by modes.js at an even spacing all the way round: glass with a hot
   spot up and to the left, each at its own brightness (--b); a dead one is dark glass */
.mq-bulb { position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; filter: brightness(var(--b, 1));
  background: radial-gradient(circle at 36% 34%, #fff 0 15%, #fff3cc 32%, #ffcd66 62%, #e38a28 100%);
  box-shadow: 0 0 7px 2px rgba(255, 185, 80, .55); }
/* the two flickering bulbs (modes.js): never darker than about four-fifths of their own glow,
   on uneven beats so the pair never fall into step */
.mq-bulb.flicker { animation: mq-flicker 2.9s steps(1, end) infinite; }
.mq-bulb.flicker ~ .mq-bulb.flicker { animation-duration: 3.7s; animation-delay: -1.3s; }
@keyframes mq-flicker {
  0%, 100% { filter: brightness(var(--b, 1)); }
  11% { filter: brightness(calc(var(--b, 1) * .84)); }
  14% { filter: brightness(var(--b, 1)); }
  17% { filter: brightness(calc(var(--b, 1) * .9)); }
  19%, 52% { filter: brightness(var(--b, 1)); }
  55% { filter: brightness(calc(var(--b, 1) * .87)); }
  60%, 78% { filter: brightness(var(--b, 1)); }
  80% { filter: brightness(calc(var(--b, 1) * .82)); }
  82% { filter: brightness(calc(var(--b, 1) * .93)); }
  85% { filter: brightness(var(--b, 1)); }
}
@media (prefers-reduced-motion: reduce) { .mq-bulb.flicker { animation: none; } }
/* the twelve that go out on a miss are a size up, so they can be counted */
.mq-bulb.miss { width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px; box-shadow: 0 0 9px 3px rgba(255, 190, 90, .65); }
.mq-bulb.out { filter: none; background: radial-gradient(circle at 36% 34%, #7a5a38 0 12%, #4a2e12 48%, #2a1806 100%); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .5); }
/* Two little boxes stand in front of the big sign, each overlapping its frame by 18px (never the
   board): the cinemas on top, the cast's big bulbs underneath. Dark inside, framed in the sign's
   amber, a shadow under them; the cinemas have a tiny word over them. modes.js lays no frame
   bulbs behind them. */
.mq-theaters, .mq-dots { z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 1px; border: 3px solid #e99a40; border-radius: 10px;
  background: radial-gradient(120% 140% at 50% 100%, #2a1607, #120a04);
  box-shadow: 0 0 0 2px #ffc66e, 0 6px 14px 2px rgba(0, 0, 0, .65), 0 0 22px 4px rgba(255, 150, 50, .35), inset 0 2px 8px rgba(0, 0, 0, .8); }
.mq-tag { font: 600 .55rem/1 "Avenir Next", "Helvetica Neue", sans-serif; letter-spacing: .32em; margin-right: -.32em; text-transform: uppercase; color: #f0b35e; }
/* hanging below the sign's bottom edge, so the sign keeps that much more room under it */
.mq-dots { position: absolute; left: 50%; bottom: 0; translate: -50% calc(100% - 18px); padding: 6px 10px; }
.mq-sign:has(> .mq-dots) { margin-bottom: 30px; }
.mq-lamps { display: flex; gap: 9px; }
/* a clear glass bulb seen face on: a glint up on the left, and a coiled filament in the middle,
   dull while it's off and white-hot once it's lit */
.mq-dots i { position: relative; width: 20px; height: 20px; border-radius: 50%; transition: background .3s, box-shadow .3s;
  background: radial-gradient(circle at 34% 30%, rgba(255, 255, 255, .35) 0 9%, transparent 22%), radial-gradient(circle, #4a2e14 0 30%, #2a180a 70%, #170c04);
  box-shadow: inset 0 0 0 1px rgba(255, 210, 150, .18), inset 0 -2px 4px rgba(0, 0, 0, .6); }
.mq-dots i::after { content: ""; position: absolute; left: 32%; right: 32%; top: 36%; height: 26%; border: 1.5px solid rgba(190, 140, 80, .45); border-bottom: 0;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0; transition: border-color .3s, filter .3s; }
.mq-dots i.on { background: radial-gradient(circle at 34% 30%, #fff 0 9%, transparent 22%), radial-gradient(circle, #fff 0 18%, #fff3c4 36%, #ffd27a 64%, #f29a2e);
  box-shadow: 0 0 8px 3px #ffd27a, 0 0 20px 6px rgba(255, 190, 80, .7); }
.mq-dots i.on::after { border-color: #fff; filter: drop-shadow(0 0 2px #fff) drop-shadow(0 0 3px #ffb347); }
/* a fresh game: a little letter board stands in front of the middle of the wall saying what to
   do, framed like the boxes on the sign, with a neon Start under it; the show runs on around it */
.mq-start { position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 3; width: max-content; max-width: 92%;
  display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 12px 12px 16px; border: 3px solid #e99a40; border-radius: 10px;
  background: radial-gradient(120% 140% at 50% 100%, #2a1607, #120a04);
  box-shadow: 0 0 0 2px #ffc66e, 0 10px 28px 6px rgba(0, 0, 0, .75), 0 0 22px 4px rgba(255, 150, 50, .35); }
.mq-start .mq-board { padding: 4px 14px 2px; }
.mq-rule { display: block; padding: 3px 0 0; font-size: clamp(1.1rem, 4.6vw, 1.6rem); line-height: 1.2; letter-spacing: .05em; white-space: nowrap;
  text-shadow: 0 -1px 0 rgba(255, 255, 255, .7), 0 1px 0 #8f887d, 0 2px 2px rgba(0, 0, 0, .16); }
.mq-rule + .mq-rule { border-top: 2px solid #c9c2b3; }
.mq-rule span { display: inline-block; }
.mq-start { cursor: default; }   /* the wall hides the pointer for its spotlight; not over the card */
.mq-start .mq-neon { min-width: 8em; cursor: pointer; }

/* the theaters: a neon numeral in a neon ring per film, arrows either side. Pink tubes
   for a dark theater, green once you lit it cleanly, yellow if it took misses, red if
   Show cast lit it; the one on the sign burns brightest. Now and then one of them
   buzzes (modes.js, at random). They sit in the box in front of the top of the sign. */
.mq-theaters { position: relative; align-self: center; margin: 6px auto -18px; padding: 5px 6px 4px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
.mq-theaters + .mq-sign { margin-top: 0; }
.mq-doors { display: flex; justify-content: center; align-items: center; gap: 8px; }
.mq-theaters button { font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.mq-door { --neon: #ff4fa8; --tube: #ffc2e2; width: 30px; height: 30px; padding: 0; border-radius: 50%; background: none;
  border: 2px solid var(--tube); color: var(--tube); font-family: "Avenir Next", "Helvetica Neue", sans-serif; font-size: .95rem; font-weight: 500;
  text-shadow: 0 0 2px #fff, 0 0 6px var(--neon), 0 0 12px var(--neon);
  box-shadow: 0 0 4px var(--neon), 0 0 10px var(--neon), inset 0 0 4px var(--neon);
  filter: brightness(.55) saturate(.8); }
.mq-door:hover { filter: brightness(.85); }
.mq-door.lit { --neon: #2bff6a; --tube: #c4ffd2; }
.mq-door.missed { --neon: #ffd21f; --tube: #fff3b0; }
.mq-door.given { --neon: #ff2a2a; --tube: #ffc0b8; }
.mq-door.on { filter: none; color: #fff; border-color: #fff;
  text-shadow: 0 0 2px #fff, 0 0 8px var(--neon), 0 0 16px var(--neon), 0 0 26px var(--neon);
  box-shadow: 0 0 6px var(--neon), 0 0 16px var(--neon), 0 0 28px var(--neon), inset 0 0 6px var(--neon); }
.mq-theaters .mq-arrow { width: 34px; height: 34px; padding: 0; border: 0; background: none; font-size: 2.6rem; line-height: 34px;
  translate: 0 -.1em;   /* the chevron's ink sits low in its line: lift it level with the numbers */
  color: #ffc2e2; text-shadow: 0 0 6px #ff4fa8, 0 0 12px #ff4fa8; opacity: .8; }
.mq-arrow:hover { opacity: 1; color: #fff; }
/* touch-action: a finger dragged over the wall moves the spotlight instead of scrolling */
.mq-wall { touch-action: none; position: relative; display: grid; grid-template-columns: repeat(var(--cols), var(--T, 80px)); gap: 4px; justify-content: center; }
/* whole photos, full colour underneath; the shade on top greys and dims everything
   outside a soft-edged circle at the pointer (modes.js sets --x, --y and --R) */
.mode-marquee .bulb { height: auto; padding: 0; border: 0; border-radius: 3px; background: #111; overflow: hidden; justify-content: flex-start; transition: none; }
.mode-marquee .bulb:active { transform: none; }
.mode-marquee .bulb img { width: var(--T, 80px); height: calc(var(--T, 80px) * 1.5); border-radius: 0; object-fit: cover; background: #111; }
/* the name stays hidden until the pointer rests on the photo (or a key lands on it) */
.mode-marquee .bulb .name { position: absolute; inset: auto 0 0; margin: 0; padding: 18px 4px 5px; color: rgba(245, 236, 222, .72); text-shadow: 0 1px 2px #000;
  background: linear-gradient(transparent, rgba(0, 0, 0, .6) 50%); font-size: clamp(.58rem, calc(var(--T, 80px) * .13), .8rem); font-weight: 500;
  display: flex; flex-direction: column; gap: 0; line-height: 1; -webkit-line-clamp: unset; opacity: 0; transition: opacity .2s ease-out; }
.mode-marquee .bulb .name span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* on a touch screen the name sits at the top of the photo, above the finger */
@media (pointer: coarse) {
  .mode-marquee .bulb .name { inset: 0 0 auto; padding: 5px 4px 18px; background: linear-gradient(rgba(0, 0, 0, .6) 50%, transparent); }
}
/* modes.js adds .rest once the pointer has stopped on a photo; fade in slowly, out quickly */
/* once shown the name is full white, on a darker band, so it reads over any photo (a lit face's too) */
.mode-marquee .bulb.rest .name, .mode-marquee .bulb:focus-visible .name { opacity: 1; color: #fff; font-weight: 600;
  text-shadow: 0 1px 3px #000, 0 0 2px #000; transition: opacity .6s ease-in; }
/* the spotlight is the pointer: no arrow or hand over the photos */
.mq-wall, .mode-marquee .bulb, .mode-marquee .bulb:disabled { cursor: none; }
.mq-shade { --hole: radial-gradient(circle var(--R, 140px) at var(--x, -9999px) var(--y, -9999px), transparent 72%, #000 100%);
  position: absolute; inset: -2px; z-index: 1; pointer-events: none;
  -webkit-backdrop-filter: grayscale(1) brightness(.28); backdrop-filter: grayscale(1) brightness(.28);
  -webkit-mask-image: var(--hole); mask-image: var(--hole); }
@supports not ((backdrop-filter: none) or (-webkit-backdrop-filter: none)) { .mq-shade { background: rgba(0, 0, 0, .72); } }
/* found casts, and type-to-find matches, sit above the shade */
.mode-marquee .bulb.lit, .mode-marquee .bulb.given, .mode-marquee .bulb.match { z-index: 2; }
.mode-marquee .bulb.lit { box-shadow: 0 0 0 3px var(--bulb), 0 0 22px 4px rgba(255, 190, 80, .5); }
.mode-marquee .bulb.lit:not(.rest, :focus-visible) .name { color: rgba(255, 207, 107, .8); }
.mode-marquee .bulb.given { filter: brightness(.75); }
.mq-wall.wrap .bulb.given { filter: none; }   /* the wrap lights everyone in full */
/* after the game the theaters change slowly: the letters come up and the cast warms into colour */
.mq-sign.fade .mq-kicker, .mq-sign.fade h2 { animation: letters-in 1.4s ease-out; }
/* one face at a time: modes.js staggers the delays in a random order; each waits dark until its turn */
.mq-wall.fade .bulb.lit, .mq-wall.fade .bulb.given { animation: cast-in 1.2s ease-out backwards; }
@keyframes letters-in { from { opacity: 0; } }
@keyframes cast-in { from { filter: grayscale(1) brightness(.25); } }
.mode-marquee .bulb.dud img { filter: grayscale(1) brightness(.5); }
.mode-marquee .bulb.dud::after { content: ""; position: absolute; inset: 0; box-shadow: inset 0 0 0 2px #a02828; pointer-events: none; }
.mode-marquee .bulb.match { outline: 3px solid var(--accent); outline-offset: -3px; }
/* one gentle fade each, no flashing */
.mode-marquee .bulb.ignite { animation: ignite .6s ease-out; }
.mode-marquee .bulb.fizzle img { animation: fizzle .6s ease-out; }
@keyframes ignite { from { filter: grayscale(1) brightness(.3); } to { filter: none; } }
@keyframes fizzle { from { filter: sepia(1) hue-rotate(-45deg) saturate(4) brightness(.8); } to { filter: grayscale(1) brightness(.5); } }
/* the bonus round: the wall shows one film's cast at a time, with neon arrows either side of it
   (outside the photos where the page has room, over their edges where it hasn't), and under it a
   neon Pick this one on a card like Start's; once picked, the card says Right or Not quite instead */
.mq-wall .mq-arrow.mq-side { position: absolute; top: 50%; z-index: 4; width: 36px; height: 72px; padding: 0; border: 0; border-radius: 8px;
  background: none; cursor: pointer; font-size: 3.4rem; line-height: 64px; color: #ffc2e2; text-shadow: 0 0 6px #ff4fa8, 0 0 12px #ff4fa8;
  opacity: .8; translate: 0 -50%; -webkit-tap-highlight-color: transparent; }
.mq-side.left { right: calc(100% + 4px); }
.mq-side.right { left: calc(100% + 4px); }
@media (max-width: 720px) {
  .mq-wall .mq-arrow.mq-side { background: rgba(0, 0, 0, .55); }
  .mq-side.left { right: auto; left: 2px; }
  .mq-side.right { left: auto; right: 2px; }
}
/* under the wall, not over it: a card in the page's flow, centred like the buttons below it */
.mq-start.mq-pick { position: static; translate: none; align-self: center; margin: 14px auto 0; padding: 10px; }
.mq-pick.blank { visibility: hidden; }
.mq-pick + .mq-after { margin-top: 12px; }
.mq-pick span.mq-neon { cursor: default; }
.mq-neon.right { --neon: #2bff6a; border-color: #c4ffd2; }
.mq-neon.wrong { --neon: #ff2a2a; border-color: #ffc0b8; }
/* the Bonus round button, Back to the wall, Start and Pick this one: a pink neon tube */
.mq-after { align-self: center; display: flex; justify-content: center; margin: 16px 0 2px; }
.mq-neon { --neon: #ff4fa8; padding: 8px 22px 7px; border: 2px solid #ffd0e8; border-radius: 999px; background: none; color: #fff; cursor: pointer;
  font: 600 .92rem/1 "Avenir Next", "Helvetica Neue", sans-serif; letter-spacing: .16em; text-transform: uppercase; -webkit-tap-highlight-color: transparent;
  text-shadow: 0 0 2px #fff, 0 0 8px var(--neon), 0 0 16px var(--neon);
  box-shadow: 0 0 6px var(--neon), 0 0 16px var(--neon), inset 0 0 6px var(--neon); }
.mq-neon:hover { filter: brightness(1.2); }
/* phones: a narrower frame, and all the doors on one row */
@media (max-width: 520px) {
  .mq-sign { padding: 20px; }
  .mq-board { padding: 3px 8px 2px; }
  .mq-doors { gap: 4px; }
  .mq-door { width: 28px; height: 28px; }
  .mq-theaters .mq-arrow { width: 30px; font-size: 2.4rem; }
}

/* -------------------------------------------------------------- moneyshot */
/* a dark screening room whatever the colour scheme, so the stills read as projected */
body.theme-shot {
  --bg: #0c0d10; --bg-fun: radial-gradient(120% 90% at 50% 0%, #1b1e26 0%, #0c0d10 60%);
  --fg: #f1eee8; --muted: #9a958c; --card: #191b21; --card-border: #2c2f38;
  --selected: #f1eee8; --selected-fg: #0c0d10; --accent: #ece8e1; --on-accent: #0c0d10;   /* the controls are a soft white */
  --shadow: 0 1px 2px rgba(0,0,0,.6);
  --ms-ok: #6fd3a0; --ms-no: #ff7a5c; --ms-pass: #ff8c00;
  --ms-hush: #8b8d93;   /* the placeholder and the hint above the box: one light grey */
  color-scheme: dark;
}
.mode-moneyshot { max-width: none; }
.ms { display: grid; gap: 10px 18px; align-items: start; }
.ms-shot { position: relative; justify-self: center; margin: 0; line-height: 0; border-radius: 4px; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .06), 0 12px 40px rgba(0, 0, 0, .6); transition: box-shadow .25s; }
/* modes.js sizes the frame to the room the page leaves; each still fits inside it */
.ms-shot { background: #000; }
.ms-shot > img { display: block; width: 100%; height: 100%; object-fit: contain; }
.ms-shot.ok { box-shadow: 0 0 0 3px var(--ms-ok), 0 12px 40px rgba(0, 0, 0, .6); }
.ms-shot.no { box-shadow: 0 0 0 3px var(--ms-no), 0 12px 40px rgba(0, 0, 0, .6); }
.ms-shot[data-act] { cursor: pointer; }
.ms-shot { touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.ms-loupe { position: fixed; z-index: 50; border-radius: 50%; pointer-events: none; background-repeat: no-repeat; background-color: #000;
  border: 3px solid #fff; box-shadow: 0 6px 24px rgba(0, 0, 0, .7), inset 0 0 0 1px rgba(0, 0, 0, .4); }
.ms-shot figcaption { position: absolute; inset: auto 0 0; display: flex; align-items: flex-end; justify-content: space-between; gap: 10px;
  padding: 28px 14px 10px; line-height: 1.3; text-align: left;
  background: linear-gradient(transparent, rgba(0, 0, 0, .85) 55%); color: #fff; animation: ms-in .3s ease-out; }
.ms-shot figcaption b { display: block; font-size: 1.15rem; font-weight: 700; }
.ms-shot figcaption b small { font-weight: 400; opacity: .75; }
.ms-shot figcaption.ok b { color: var(--ms-ok); }
.ms-shot figcaption.no b { color: var(--ms-no); }
.ms-shot figcaption div > span { font-size: .78rem; color: rgba(255, 255, 255, .7); }
@keyframes ms-in { from { opacity: 0; translate: 0 6px; } }
/* the panel is as wide as the box wants: a long title, or the hint, typed in full view */
.ms-panel { width: 100%; max-width: 560px; justify-self: center; text-align: center; }
/* the verdict once it's over, in the serif of the titles */
.ms-verdict { margin: 0 0 8px; font-size: 1.25rem; line-height: 1.25; }
.ms-verdict.won { color: var(--ms-ok); }
.ms-verdict.lost { color: var(--ms-no); }
/* one line of measures, every icon one size: the seven films to name, misses, streak, passes */
.ms-line { display: flex; justify-content: center; align-items: flex-start; gap: 14px; margin: 4px 0 8px; white-space: nowrap; }
/* each group of icons with its rule under it, grey but for the one being shown */
.ms-group { display: inline-flex; flex-direction: column; align-items: center; gap: 3px; }
/* a label takes no room of its own (all eighteen icons keep to one line): it is centred under
   its icons and may run a little into the gap either side */
.ms-group { position: relative; padding-bottom: 1.25em; }
.ms-cap { position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); white-space: nowrap;
  font-size: .66rem; line-height: 1.15; color: var(--ms-hush); transition: color .6s; }
/* the end labels keep to their icons' outer edges, so the line never runs off a phone */
.ms-group:first-child .ms-cap { left: 0; transform: none; }
.ms-group:last-child .ms-cap { left: auto; right: 0; transform: none; }
@media (max-width: 420px) { .ms-line { gap: 9px; } }   /* eighteen icons inside a phone's gutters */
.ms-cap.shots.on { color: var(--ms-ok); }
.ms-cap.miss.on { color: var(--ms-no); }
.ms-cap.streak.on { color: #ffb53b; }
.ms-cap.pass.on { color: var(--ms-pass); }
/* the icons a right answer lights blink a few times */
.ms-pips .blink { animation: ms-blink .42s ease-in-out 4; }
@keyframes ms-blink { 50% { opacity: .1; } }
.ms-pips { display: inline-flex; align-items: center; gap: 2px; }
.ms-pips i, .ms-pips button { display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; background: none; color: #3a3e48; }
.ms-pips svg { width: 16px; height: 16px; }
/* a film named lights its clapperboard green, the colour of its rule; the one looked back at is white */
.ms-pips.shots button { color: var(--ms-ok); cursor: pointer; border-radius: 3px; }
.ms-pips.shots button:hover, .ms-pips.shots button.on { color: #fff; }
.ms-pips.miss i.lit { color: var(--ms-no); }
.ms-pips.miss svg { stroke-width: 2.6; }
.ms-pips.streak i.lit { color: #ffb53b; }
.ms-pips.streak i.lit svg { fill: currentColor; }
/* a pass used fills in, solid dark orange */
.ms-pips.pass i.lit { color: var(--ms-pass); }
.ms-pips.pass i.lit svg, .ms-pips.pass .demo svg { fill: currentColor; }
.ms-pips i, .ms-pips button { transition: color .4s; }
.ms-pips.shots .demo { color: var(--ms-ok); }
.ms-pips.miss .demo { color: var(--ms-no); }
.ms-pips.streak .demo { color: #ffb53b; }
.ms-pips.streak .demo svg { fill: currentColor; }
.ms-pips.pass .demo { color: var(--ms-pass); }
/* back and forth: arrows on the frame's edges */
.ms-nav { position: absolute; top: 50%; translate: 0 -50%; z-index: 2; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
  padding: 0; border: 0; border-radius: 50%; background: rgba(0, 0, 0, .45); color: #fff; cursor: pointer; opacity: .75;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.ms-nav:hover { opacity: 1; background: rgba(0, 0, 0, .7); }
.ms-nav.prev { left: 8px; }
.ms-nav.next { right: 8px; }
.ms-nav svg { width: 20px; height: 20px; }
/* film info on TMDB: a pill at the caption's right, opening a window of its own */
.ms-film { flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border: 1.5px solid rgba(255, 255, 255, .8); border-radius: 999px;
  background: rgba(0, 0, 0, .35); color: #fff; font: inherit; font-size: .82rem; font-weight: 600; line-height: 1; cursor: pointer; white-space: nowrap; }
.ms-film span { font-size: 1.1em; }
.ms-film:hover { background: #fff; color: #000; }
.ms-shot.pass { box-shadow: 0 0 0 3px var(--muted), 0 12px 40px rgba(0, 0, 0, .6); }
.ms-shot figcaption.pass b { color: #fff; }
/* the box with its arrow inside, and the pass button beside it */
.ms-form { position: relative; display: flex; gap: 8px; align-items: center; }
/* 16px so phones don't zoom the page when the box takes focus */
.ms-input { flex: 1; min-width: 0; font: inherit; font-size: 16px; padding: 9px 46px 9px 14px; border-radius: 999px; color: var(--fg);
  background: var(--card); border: 1.5px solid var(--card-border); outline: none; }
.ms-input:focus { border-color: var(--accent); }
.ms-input::placeholder { color: var(--ms-hush); opacity: 1; }
/* on a phone the question comes down a size to fit the box (the box's own 16px keeps iOS from zooming) */
@media (max-width: 440px) { .ms-input { padding-left: 12px; padding-right: 42px; } .ms-input::placeholder { font-size: 11.5px; letter-spacing: -.01em; } }
/* a right answer: the box takes the proper title in green, and a check draws itself where the arrow was */
.ms-input.right { border-color: var(--ms-ok); color: var(--ms-ok); animation: ms-glow .7s ease-out; }
.ms-check { position: absolute; right: 4px; top: 50%; translate: 0 -50%; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%; background: var(--ms-ok); color: #062014; animation: ms-pop .4s cubic-bezier(.3, 1.6, .5, 1); }
.ms-check svg { width: 22px; height: 22px; stroke-width: 3; }
.ms-check path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: ms-draw .35s .15s ease-out forwards; }
@keyframes ms-pop { from { scale: .3; opacity: 0; } }
@keyframes ms-draw { to { stroke-dashoffset: 0; } }
@keyframes ms-glow { from { box-shadow: 0 0 0 6px rgba(111, 211, 160, .35); } to { box-shadow: 0 0 0 0 rgba(111, 211, 160, 0); } }
@media (prefers-reduced-motion: reduce) { .ms-check, .ms-input.right, .ms-pips .blink { animation: none; } .ms-check path { animation: none; stroke-dashoffset: 0; } }
/* the hint, on a line of its own above the box, starting where the box's text does; the line
   is there (empty) from the start, so the box stays put when the hint comes */
.ms-hint { min-height: 17px; margin: 0 0 4px; padding: 0 16px; font-size: 14px; line-height: 17px; text-align: left; color: var(--ms-hush); }
.ms-hint:not(:empty) { animation: ms-fade .3s ease-out; }
@keyframes ms-fade { from { opacity: 0; } }
.ms-field { position: relative; flex: 1; min-width: 0; display: flex; }
.ms-go, .ms-round { display: inline-flex; align-items: center; justify-content: center; flex: none; padding: 0; border-radius: 50%; cursor: pointer; }
.ms-go svg, .ms-round svg { width: 20px; height: 20px; }
.ms-go { position: absolute; right: 4px; top: 50%; translate: 0 -50%; width: 34px; height: 34px; border: 0; background: var(--accent); color: var(--on-accent); }
.ms-round { width: 42px; height: 42px; border: 1.5px solid var(--accent); background: none; color: var(--accent); }
.ms-round:hover:not(:disabled) { background: var(--accent); color: var(--on-accent); }
.ms-round:disabled { opacity: .35; cursor: default; }
.ms-credit { margin: 12px 0 0; font-size: .7rem; color: var(--muted); }
.ms-credit a { color: inherit; }
.ms-pre { display: none; }
/* Moneyshot ends on the still itself (the verdict, the shots to look back at): no results panel under it */
body.theme-shot #results { display: none; }
/* on a phone the game is pinned to the screen: no dragging the page about, and the keyboard
   coming up shrinks the page (modes.js sets --ms-vh to the room above it) instead of sliding it up */
@media (pointer: coarse) {
  html:has(body.theme-shot) { overflow: hidden; overscroll-behavior: none; }
  body.theme-shot { position: fixed; inset: 0; min-height: 0; height: var(--ms-vh, 100dvh); overflow: hidden; overscroll-behavior: none; }
}
/* while a game is on, the page's other controls dim; a pointer or focus brings them back */
body.theme-shot.ms-playing header.top, body.theme-shot.ms-playing .ms-credit { opacity: .35; transition: opacity .3s; }
body.theme-shot.ms-playing header.top:hover, body.theme-shot.ms-playing header.top:focus-within,
body.theme-shot.ms-playing .ms-credit:hover { opacity: 1; }
/* a phone held sideways: the still takes the height of the screen, the box sits beside it,
   and the page uses the whole width (less the safe areas) so the box's column costs the still nothing */
@media (orientation: landscape) and (max-height: 560px) {
  body.theme-shot main, body.theme-shot header.top { max-width: none; }
  .ms { grid-template-columns: minmax(0, 1fr) 350px; }
  .ms-shot { justify-self: end; }
  .ms-panel { align-self: center; }
  .ms-line { gap: 10px; }
  .ms-pips svg { width: 13px; height: 13px; }   /* all eighteen fit the panel's line */
  .ms-form { gap: 6px; }
  .ms-hint { font-size: 13px; }
  .ms-round { width: 38px; height: 38px; }
  .ms-verdict { font-size: 1.05rem; }
  body.theme-shot header.top { padding-top: 4px; }
}
/* splash: a fixed dark cover from first paint until the first puzzle is ready */
.splash { position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background: #0a0503; color: #f3c94e; transition: opacity .45s ease; }
.splash.done { opacity: 0; pointer-events: none; }
.splash-mark { width: min(50vmin, 420px); height: auto; border-radius: 4%; box-shadow: 0 10px 40px rgba(0,0,0,.6); animation: splash-pulse 1.8s ease-in-out infinite; }
.splash-bar { width: 120px; height: 2px; background: rgba(243, 201, 78, .25); overflow: hidden; position: relative; }
.splash-bar::after { content: ""; position: absolute; inset: 0; width: 40%; background: #f3c94e; animation: splash-slide 1.1s ease-in-out infinite; }
@keyframes splash-pulse { 50% { transform: scale(1.015); opacity: .92; } }
@keyframes splash-slide { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
@media (prefers-reduced-motion: reduce) { .splash-mark, .splash-bar::after { animation: none; } }

/* a tile being dragged (modes.js): the copy follows the pointer, the original fades where it was */
.mode .tile.ghost { position: fixed; z-index: 30; margin: 0; translate: none; pointer-events: none; animation: none; filter: drop-shadow(0 6px 10px rgba(0,0,0,.3)); }
.mode .tile.lifted { opacity: .25; }

/* six degrees: the chain is drawn as a figure 6 down the middle, inside a ring of smaller faces.
   Everything is cut from --T, the side of one pool cell (modes.js fit): the board is six cells across and
   eight down, and the middle is four by six. --D is a chain face; --x and --y place a face or a film, in cells. */
.mode-degrees { --D: var(--T, 57px); --ov: calc(var(--T, 57px) * .15);
  --dot: min(88%, calc(100% - 7px));   /* a pool face: most of its cell, a few px clear of the next */
  --track: color-mix(in srgb, var(--fg) 24%, transparent); }
.six { display: grid; grid-template-columns: var(--T) calc(var(--T) * 4) var(--T); grid-template-rows: var(--T) calc(var(--T) * 6) var(--T);
  gap: 4px 0; width: calc(var(--T) * 6); margin: 8px auto 0; }
.six-row { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(6, 1fr); }
.six-col { display: grid; grid-template-rows: repeat(6, 1fr); }
.six-mid { position: relative; isolation: isolate; }
/* the pool: a face and a surname; the full name shows under the board when one is tapped */
.mode-degrees .dot { position: relative; width: var(--T, 57px); height: var(--T, 57px); padding: 0; border: 0; border-radius: 0; background: none; color: inherit; overflow: visible; justify-content: center; touch-action: none; }
.mode-degrees .dot img { width: var(--dot); height: auto; aspect-ratio: 1; box-shadow: 0 0 0 2px var(--card-border); transform-origin: 50% 100%; transition: box-shadow .12s ease, scale .12s ease; }
/* a pool face is just a face: its surname shows on a label under it while the pointer is on it, or once it is picked up */
.mode-degrees .dot .name { position: absolute; z-index: 4; left: 50%; top: calc(50% + min(44%, calc(50% - 3.5px)) + 2px); translate: -50% 0; width: max-content; max-width: calc(var(--T, 57px) * 1.8);
  padding: 1px 6px; border-radius: 999px; background: var(--card); box-shadow: 0 0 0 1px var(--card-border); font-size: clamp(8.5px, calc(var(--T, 57px) * .17), 11.5px); line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0; pointer-events: none; transition: opacity .12s ease; }
.mode-degrees .dot.selected .name, .mode-degrees .dot:focus-visible .name { opacity: 1; }
@media (hover: hover) { .mode-degrees .dot:hover:not(:disabled) .name { opacity: 1; } }
.mode-degrees .dot.selected, .mode-degrees .cell.selected { background: none; color: inherit; }
.mode-degrees .dot.selected { z-index: 3; }
.mode-degrees .dot.selected img { box-shadow: 0 0 0 3px var(--selected); scale: 1.14; }
.mode-degrees .tile.match { outline: none; }
.mode-degrees .tile.match img { box-shadow: 0 0 0 3px var(--accent); }
.mode-degrees .dot:disabled { opacity: .4; cursor: default; }
.mode-degrees .dot.gone { display: flex; align-items: center; }
.mode-degrees .dot.gone::before { content: ""; display: block; width: var(--dot); aspect-ratio: 1; margin: 0 auto; border-radius: 50%; border: 1.5px dashed var(--track); }
/* the chain: six spots, the two ends in the accent colour */
.mode-degrees .cell { position: absolute; z-index: 1; left: calc(var(--x) * var(--T, 57px)); top: calc(var(--y) * var(--T, 57px) - var(--D) / 2); translate: -50% 0;
  width: var(--D); height: calc(var(--D) + var(--ov)); padding: 0; border: 0; border-radius: 0; background: none; color: inherit; overflow: visible; justify-content: flex-start; }
.mode-degrees .cell[data-id]:not([data-fixed]) { touch-action: none; }
.mode-degrees .cell[data-fixed], .mode-degrees .hole:not(.open) { cursor: default; }
.mode-degrees .cell img { width: var(--D); height: var(--D); box-shadow: 0 0 0 3px var(--card-border); transition: box-shadow .12s ease; }
.mode-degrees .cell.end img { box-shadow: 0 0 0 3px var(--accent); }
.mode-degrees .cell.given img { outline: 2px dashed var(--fg); outline-offset: 2px; }
.mode-degrees .cell.selected img { box-shadow: 0 0 0 4px var(--selected); }
.mode-degrees .cell .name { position: absolute; left: 50%; bottom: 0; translate: -50% 0; display: block; width: max-content; max-width: calc(var(--T, 57px) * 2 - 8px); margin: 0; padding: 1px 8px;
  border-radius: 999px; background: var(--card); box-shadow: 0 0 0 1px var(--card-border); font-size: clamp(9.5px, calc(var(--T, 57px) * .2), 13px); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mode-degrees .cell.end .name { background: var(--accent); color: var(--on-accent); box-shadow: none; }
.mode-degrees .cell .num { position: absolute; top: 0; left: 0; z-index: 1; min-width: 1.55em; height: 1.55em; border-radius: 999px; background: var(--fg); color: var(--bg);
  font-size: clamp(9px, calc(var(--T, 57px) * .17), 12px); font-weight: 700; line-height: 1.55em; text-align: center; }
.mode-degrees .cell.end .num { background: var(--accent); color: var(--on-accent); }
.mode-degrees .hole .ring { display: flex; align-items: center; justify-content: center; width: var(--D); height: var(--D); border-radius: 50%; background: var(--card);
  border: 2px dashed color-mix(in srgb, var(--fg) 30%, var(--card)); color: var(--muted); font: 700 calc(var(--D) * .34) / 1 var(--font); }
.mode-degrees .hole.open .ring { border-color: var(--accent); color: var(--accent); }
@media (prefers-reduced-motion: no-preference) {
  .mode-degrees .hole.open .ring { animation: beckon 1.8s ease-in-out infinite; }
}
@keyframes beckon { 50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 24%, transparent); } }
/* the track from 1 to 6 (an SVG of the middle at 100 a cell), a plain grey line; a link's film sits beside it on a light grey label */
.six-track { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.six-link { fill: none; stroke: #9a9a9a; stroke-width: 9; }
.six-film { position: absolute; z-index: 2; left: calc(var(--x) * var(--T, 57px)); top: calc(var(--y) * var(--T, 57px)); translate: -50% -50%;
  width: max-content; max-width: calc(var(--T, 57px) * 1.5); padding: 2px 6px; border-radius: 9px;
  background: #dcdcdc; color: #1d1b19; font-size: clamp(9px, calc(var(--T, 57px) * .17), 12px); font-weight: 600; line-height: 1.15; text-align: center;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.six-film.new { animation: pop .3s ease; }
.six-film.tip { background: var(--card); color: var(--fg); outline: 1.5px dashed var(--fg); outline-offset: -1.5px; }
.mode-degrees .m-bar { width: calc(var(--T, 57px) * 6); max-width: 100%; margin: 0 auto; }
.mode-degrees .m-line { min-height: 2.4rem; margin-top: 6px; font-size: .88rem; line-height: 1.2rem; }   /* two lines, whatever it says */
.mode-degrees .m-line.picking { font-size: .95rem; }
/* this game talks through the line above, so the page's own message line only takes room when it has something to say */
.mode-degrees ~ .status .message:empty { min-height: 0; margin: 0; }

/* ----------------------------------------------------------------- tablet */
/* an iPad, or any tablet, held either way (game.js's TABLET is the same query): the page takes the
   screen's width, and game.js and modes.js let the boards grow past their desktop caps to fill it */
@media (pointer: coarse) and (min-width: 700px) and (min-height: 600px) {
  :root { --max: 1180px; }
  /* a game in #mode-root is as wide as its board (modes.js sets --T), never narrower than on a desktop */
  .mode-hive { max-width: max(460px, calc(var(--T, 96px) * 4)); }
  .mode-degrees { max-width: max(460px, calc(var(--T, 57px) * 6)); }
  /* Moneyshot's still is as wide as the screen already: the still and its box sit in the middle of the
     room under the header rather than at the top of it (modes.js leaves the margin out when it sizes the still) */
  body.theme-shot main { display: flex; flex-direction: column; }
  body.theme-shot #mode-root { width: 100%; margin-block: auto; }
}
/* held sideways, Marquee's wall takes the full height at the right and the cinemas, the sign, the bonus
   round's pick and the line under them sit beside it, centred top to bottom; the find row stays under the wall */
@media (pointer: coarse) and (min-width: 700px) and (min-height: 600px) and (orientation: landscape) {
  body.theme-lights main { display: grid; grid-template-columns: minmax(0, 640px) auto; justify-content: center;
    grid-template-rows: 1fr auto auto auto auto auto 1fr auto; column-gap: 56px; align-items: start; }
  body.theme-lights .mq-theaters { grid-area: 2 / 1; }
  body.theme-lights .mq-sign { grid-area: 3 / 1; width: 100%; }
  body.theme-lights .mq-pick { grid-area: 4 / 1; justify-self: center; margin-top: 0; }
  body.theme-lights .mq-after { grid-area: 5 / 1; }
  body.theme-lights .status { grid-area: 6 / 1; }
  body.theme-lights .mq-wall { grid-area: 1 / 2 / 8 / 3; align-self: center; margin-right: 44px; }   /* room for the bonus round's right arrow */
  body.theme-lights .find-row { grid-area: 8 / 2; }
}
