/* Gielionaire's blue-and-gold quiz-show stage. */
.gielionaire-body { background: #060d23; color: #f8edcd; isolation: isolate; }
/* The studio behind the question screen: the animated stage (see .gil-stage-fx below), covering the viewport
   like a backdrop and lit by the cues gielionaire.js sets on data-cue. Hidden while the intro/finale stage shows. */
.gil-game-stage { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; opacity: .9; image-rendering: pixelated; }
.gielionaire-body.in-lobby .gil-game-stage { display: none; }
.gielionaire-body [hidden] { display: none !important; }
.gil-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.gil-eyebrow { color: #d5b56f; font: 13px/1.4 'RuneScape', sans-serif; letter-spacing: 1.8px; text-transform: uppercase; }
.gil-gold-button, .gil-help-button { font: 18px 'RuneScape Bold', sans-serif; cursor: pointer; border: 1px solid #7784b0; padding: 12px 18px; border-radius: 4px; background: #162346; color: #e3e9ff; }
.gil-gold-button { border-color: #ffe1a0; background: linear-gradient(#f6d887, #c59a49); color: #271d21; box-shadow: 0 3px 0 #775123, 0 0 25px #e6b74720; }
.gil-gold-button:hover { filter: brightness(1.1); }
.gil-help-button:hover { background: #25385f; border-color: #cfb977; }
.gielionaire-body button:focus-visible { outline: 3px solid #fff0af; outline-offset: 4px; }

/* ── OSRS parchment ──
   The NPC chatbox look, shared by the intro, the in-game host bar and the rules:
   mottled tan parchment in a thin frame (dark line, bronze band, dark line) whose
   burnt edges fade into the parchment, like the in-game chatbox, Quill 8 lettering, a maroon speaker
   name and blue "Click here to continue", which turns white on hover. */
.gil-chatbox, .gil-host-bar, .gil-rules { color: #000; background: #c2b089 url('assets/textures/grain-soft.png') center / 256px; background-blend-mode: overlay; --gil-parchment-frame: inset 0 0 0 2px #8a785a, inset 0 0 0 3px #3a3024, inset 0 0 36px 6px #6f5a3570; border: 2px solid #1e1811; border-radius: 2px; box-shadow: var(--gil-parchment-frame), 0 14px 40px #000b; }
.gil-chat-name { font: 26px/1 'Quill 8', 'RuneScape Bold', serif; color: #800000; }
.gil-chatbox button:focus-visible, .gil-host-bar button:focus-visible { outline: 2px dotted #000; outline-offset: 2px; }

/* ── Intro ──
   The studio fills the screen under the nav. The backdrop covers this box, with
   nearest-neighbour scaling (sized by gielionaire.js), so the host can be pinned to
   the stage floor as a fraction of its height, clear of the chatbox. */
.gielionaire-body.in-lobby::before, .gielionaire-body.in-lobby .site-footer { display: none; }
.gil-intro { image-rendering: pixelated; --gil-chatbox-height: 180px; --gil-chatbox-base: 180px; position: relative; isolation: isolate; height: calc(100svh - 64px); min-height: 540px; overflow: hidden; display: flex; flex-direction: column; align-items: center; padding: clamp(14px, 4vh, 40px) 16px 16px; background: #0c163c; }
.gil-intro::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse 75% 70% at 50% 55%, transparent 45%, #050a20b3 100%), linear-gradient(#050a20a6, transparent 32%); }
/* Animated pieces of the stage, authored in assets/aseprite/gielionaire-stage.aseprite on its
   478x268 canvas. The layer is sized and centred exactly like the backdrop, so each sprite is
   placed in canvas fractions and scales with it. z-index -1 keeps them under the vignette. */
.gil-stage-fx { position: absolute; left: 50%; top: 50%; z-index: -1; width: var(--gil-scene-width, 1920px); height: var(--gil-scene-height, 1080px); translate: -50% -50%; pointer-events: none; background: url('assets/gielionaire/stage-backdrop-v6.png') 0 0 / 100% 100% no-repeat; }
/* Spotlights. .gil-stage-fx is a stacking context, so it paints the backdrop itself: the screen-blended beams
   need it underneath to light. One sheet (beams.cjs): rows are the beams (left outer, left inner, right inner,
   right outer); columns are 19 aims from -18deg to 54deg off vertical in 4deg steps, mirrored on the right so a
   column is the same aim on both sides. Beams sit under the crowd, so the silhouettes stand in front of the light.
   Intro cue: a dark studio, each lamp clunks on aimed at its crowd, then all four sweep in and hold on the host. */
.gil-beam { position: absolute; top: 0; width: calc(328 / 478 * 100%); height: calc(176 / 268 * 100%); background: url('assets/gielionaire/stage-beams-v1.png') 0 0 / 1900% 400% no-repeat; mix-blend-mode: screen; opacity: 0; animation: gil-beam-clunk .5s linear var(--on) both, gil-beam-sweep 1.3s steps(var(--steps)) 2.1s both, gil-beam-breathe 4.5s ease-in-out 3.4s infinite; }
/* Aims per beam: crowd, rest (the calm game pose) and host columns. A sweep between any two of a beam's aims is
   a whole multiple of its --sweep-steps columns, so stepped transitions always land exactly on a frame. */
.gil-beam-l-outer { left: calc(-32 / 478 * 100%); background-position-y: 0%; --on: .5s; --aim-crowd: calc(6 / 18 * 100%); --aim-rest: calc(12 / 18 * 100%); --aim-host: 100%; --steps: 12; --sweep-steps: 6; --aim-sway: calc(8 / 18 * 100%); }
.gil-beam-r-outer { left: calc(182 / 478 * 100%); background-position-y: 100%; --on: .8s; --aim-crowd: calc(6 / 18 * 100%); --aim-rest: calc(12 / 18 * 100%); --aim-host: 100%; --steps: 12; --sweep-steps: 6; --aim-sway: calc(8 / 18 * 100%); }
.gil-beam-l-inner { left: calc(14 / 478 * 100%); background-position-y: calc(100% / 3); --on: 1.1s; --aim-crowd: 0%; --aim-rest: calc(8 / 18 * 100%); --aim-host: calc(16 / 18 * 100%); --steps: 16; --sweep-steps: 8; --aim-sway: calc(2 / 18 * 100%); }
.gil-beam-r-inner { left: calc(136 / 478 * 100%); background-position-y: calc(200% / 3); --on: 1.4s; --aim-crowd: 0%; --aim-rest: calc(8 / 18 * 100%); --aim-host: calc(16 / 18 * 100%); --steps: 16; --sweep-steps: 8; --aim-sway: calc(2 / 18 * 100%); }
@keyframes gil-beam-clunk { 0% { opacity: 0; } 12% { opacity: 1; } 24% { opacity: .15; } 38%, 100% { opacity: 1; } }
@keyframes gil-beam-sweep { from { background-position-x: var(--aim-crowd); } to { background-position-x: var(--aim-host); } }
@keyframes gil-beam-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .8; } }
/* The intro opens with the lights off and waits for the player's first click or key (browsers only allow sound
   after one); gielionaire.js then removes .is-dark and the clunk-on cue above starts from the top. The lit crowd's
   sprite keeps running in the dark so it stays in step with the crowd underneath. */
.gil-intro.is-dark .gil-beam { animation: none; opacity: 0; }
.gil-intro.is-dark .gil-crowd-lit { animation: gil-sprite-16 3.52s steps(16) infinite; opacity: 0; }
/* Before the lights the room itself is dimmed (walls, floor, crowd) while the braziers and sconces burn at full
   brightness, and each lamp's clunk lifts it a step, back to normal on the fourth (the steps sit at 0.5s, 0.8s,
   1.1s and 1.4s, the beams' --on times, as fractions of 1.5s).
   .gil-room-dim is the first layer over the backdrop, so the screen-blended beams stay full-strength light over the
   dark room. The crowd dims with its own filter, so its silhouettes still stand in front of the beams. The host
   dims only a touch, so he doesn't look spotlit before there are spotlights. */
.gil-room-dim { position: absolute; inset: 0; background: #060b24; opacity: 0; pointer-events: none; }
.gil-intro.is-dark .gil-room-dim { opacity: .45; }
.gil-intro:not(.is-dark):not(.is-finale) .gil-room-dim { animation: gil-room-lift 1.5s step-end both; }
@keyframes gil-room-lift { 0% { opacity: .45; } 33.33% { opacity: .34; } 53.33% { opacity: .23; } 73.33% { opacity: .11; } 93.33%, 100% { opacity: 0; } }
.gil-intro.is-dark .gil-crowd:not(.gil-crowd-lit) { filter: brightness(.58) saturate(.75); }
.gil-intro:not(.is-dark):not(.is-finale) .gil-crowd:not(.gil-crowd-lit) { animation: gil-sprite-16 3.52s steps(16) infinite, gil-crowd-lift 1.5s step-end both; }
@keyframes gil-crowd-lift { 0% { filter: brightness(.58) saturate(.75); } 33.33% { filter: brightness(.68) saturate(.81); } 53.33% { filter: brightness(.79) saturate(.87); } 73.33% { filter: brightness(.89) saturate(.94); } 93.33%, 100% { filter: none; } }
/* The host lights up in two stages: a little as the last lamp clunks on (1.4s, with the room), and fully, with a brief
   catch of the light, when the beams finish sweeping onto him (3.4s, the end of gil-beam-sweep). */
.gil-intro.is-dark .gil-host-sprite { filter: brightness(.85) drop-shadow(0 0 20px #9ab8ff2e); }
.gil-intro:not(.is-dark):not(.is-finale) .gil-host-sprite { animation: gil-host-lit 3.8s linear both; }
@keyframes gil-host-lit { 0%, 36.83% { filter: brightness(.85) drop-shadow(0 0 20px #9ab8ff2e); } 36.84%, 89.47% { filter: brightness(.92) drop-shadow(0 0 20px #9ab8ff2e); } 92.5% { filter: brightness(1.08) drop-shadow(0 0 20px #9ab8ff2e); } 100% { filter: brightness(1) drop-shadow(0 0 20px #9ab8ff2e); } }
/* His spectacles only start catching the light once it's on him. */
.gil-intro:not(.is-dark) .gil-host-glint { transition-delay: 3.4s; }
/* The finale reuses this stage, without the intro's clunk-on.
   A win throws a party: the beams sweep between the crowd and the host out of step, cycling colour, and the crowd
   is lit and cheering. A loss cuts the lights one by one, leaving one cold beam on the host in a dim studio. */
.gil-intro.is-won .gil-beam { opacity: 1; animation: gil-beam-party 1.5s steps(var(--steps)) var(--party-delay, 0s) infinite alternate both, gil-beam-hue 4s linear infinite; }
.gil-intro.is-won :is(.gil-beam-r-outer, .gil-beam-l-inner) { --party-delay: -.75s; }
@keyframes gil-beam-party { from { background-position-x: var(--aim-crowd); } to { background-position-x: var(--aim-host); } }
@keyframes gil-beam-hue { to { filter: hue-rotate(360deg); } }
.gil-intro.is-won .gil-crowd-lit { animation: gil-sprite-16 3.52s steps(16) infinite, gil-crowd-cheer 1.3s ease-in-out infinite alternate; }
@keyframes gil-crowd-cheer { from { opacity: .3; } to { opacity: .8; } }
.gil-intro.is-lost .gil-stage-fx { filter: brightness(.6) saturate(.7); }
.gil-intro.is-lost .gil-beam { background-position-x: var(--aim-host); animation: gil-beam-cut .5s steps(1) var(--cut, .2s) both; }
.gil-intro.is-lost .gil-beam-r-outer { --cut: .38s; }
.gil-intro.is-lost .gil-beam-l-inner { --cut: .56s; }
.gil-intro.is-lost .gil-beam-r-inner { opacity: .55; animation: gil-beam-cold 1.2s ease-out both; }
.gil-intro.is-lost .gil-crowd-lit { animation: gil-sprite-16 3.52s steps(16) infinite; opacity: 0; }
/* Game cues (data-cue on .gil-game-stage). Aims and opacity move by stepped transitions; brightness is animated
   with filters so it never fights them.
   play    calm rest pose, lights low and slowly breathing
   locked  the studio dims, all four beams pull in to the centre and pulse while the answer hangs
   correct a flare, then a fast sweep out over both crowds (the next question sweeps them back to rest)
   wrong   the beams cut out one by one, leaving a single cold beam on the centre and a dim, desaturated studio */
.gil-game-stage .gil-stage-fx { width: var(--gil-backdrop-width, 1920px); height: var(--gil-backdrop-height, 1080px); transition: filter .6s ease; }
.gil-game-stage .gil-beam { --cue-aim: var(--aim-rest); --cue-o: .62; opacity: var(--cue-o); background-position-x: var(--cue-aim); animation: gil-beam-drift 7s ease-in-out infinite; transition: background-position-x var(--sweep-time, .9s) steps(var(--sweep-steps)), opacity .45s ease; }
@keyframes gil-beam-drift { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(.8); } }
.gil-game-stage[data-cue="locked"] .gil-stage-fx { filter: brightness(.68); }
.gil-game-stage[data-cue="locked"] .gil-beam { --cue-aim: var(--aim-host); --cue-o: .95; animation: gil-beam-tense 1.1s ease-in-out infinite; }
@keyframes gil-beam-tense { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.3); } }
.gil-game-stage[data-cue="correct"] .gil-stage-fx { animation: gil-stage-flare 1s ease-out both; }
.gil-game-stage[data-cue="correct"] .gil-beam { --cue-aim: var(--aim-crowd); --cue-o: 1; --sweep-time: .45s; animation: none; }
@keyframes gil-stage-flare { from { filter: brightness(1.8); } to { filter: brightness(1.06); } }
.gil-game-stage[data-cue="wrong"] .gil-stage-fx { filter: brightness(.55) saturate(.7); transition-duration: 1.2s; }
.gil-game-stage[data-cue="wrong"] .gil-beam { --cue-o: 0; animation: gil-beam-cut .5s steps(1) var(--cut, 0s) both; }
.gil-game-stage[data-cue="wrong"] .gil-beam-r-outer { --cut: .18s; }
.gil-game-stage[data-cue="wrong"] .gil-beam-l-inner { --cut: .36s; }
.gil-game-stage[data-cue="wrong"] .gil-beam-r-inner { --cue-aim: var(--aim-host); --cue-o: .55; animation: gil-beam-cold 1.2s ease-out both; }
@keyframes gil-beam-cut { 0% { opacity: .9; } 20% { opacity: .15; } 40% { opacity: .7; } 60%, 100% { opacity: 0; } }
@keyframes gil-beam-cold { to { filter: saturate(.35) brightness(.85); } }
/* Ask the crowd: every beam swings onto the audience and sways between two aims while they vote; the crowd lights up
   (it does on a correct answer's sweep too). */
.gil-game-stage[data-cue="audience"] .gil-beam { --cue-aim: var(--aim-crowd); --cue-o: 1; --sweep-time: .7s; animation: gil-beam-sway 1.4s steps(2) .8s infinite alternate; }
@keyframes gil-beam-sway { from { background-position-x: var(--aim-crowd); } to { background-position-x: var(--aim-sway); } }
.gil-game-stage[data-cue="audience"] .gil-crowd-lit { opacity: .8; transition-duration: .35s; }
.gil-game-stage[data-cue="correct"] .gil-crowd-lit { opacity: .7; transition-duration: .35s; }
/* 50/50: the two outer beams snap off as two answers disappear, until the next question or the lock-in. */
.gil-game-stage[data-cue="fifty"] :is(.gil-beam-l-outer, .gil-beam-r-outer) { --cue-o: 0; animation: gil-beam-cut .5s steps(1) both; }
.gil-brazier { position: absolute; top: calc(120 / 268 * 100%); width: calc(24 / 478 * 100%); height: calc(32 / 268 * 100%); background: url('assets/gielionaire/stage-brazier-v1.png') 0 0 / 800% 100%; animation: gil-sprite-8 .88s steps(8) infinite; }
.gil-brazier-l { left: 0; }
/* The right brazier is the left one mirrored, 3 frames out of phase. */
.gil-brazier-r { right: 0; scale: -1 1; animation-delay: -.33s; }
/* The redrawn crowd: 16 poses held for two 110ms ticks. Row 1 of the sheet is the left side, row 2 the right. */
.gil-crowd { position: absolute; top: calc(68 / 268 * 100%); width: calc(128 / 478 * 100%); height: calc(68 / 268 * 100%); background: url('assets/gielionaire/stage-crowd-v2.png') 0 0 / 1600% 200%; animation: gil-sprite-16 3.52s steps(16) infinite; }
.gil-crowd-l { left: 0; }
.gil-crowd-r { right: 0; background-position-y: 100%; }
/* The crowd lit by the spotlights: the same poses on the same clock, faded in over the crowd when the beams land on
   it. In the intro it catches the lamps as they clunk on at the audience, then darkens as they sweep to the host. */
.gil-crowd-lit { background-image: url('assets/gielionaire/stage-crowd-lit-v1.png'); opacity: 0; transition: opacity .6s ease; }
.gil-intro .gil-crowd-lit { animation: gil-sprite-16 3.52s steps(16) infinite, gil-crowd-intro 3.4s ease-in-out both; }
.gil-intro .gil-crowd-lit.gil-crowd-r { animation-delay: 0s, .3s; }
@keyframes gil-crowd-intro { 0%, 14% { opacity: 0; } 20%, 60% { opacity: .75; } 100% { opacity: 0; } }
/* Wall sconces: a lantern on each upper pillar and a torch above each crowd. The right-hand rows are pre-offset. */
.gil-sconce { position: absolute; background-size: 800% 200%; animation: gil-sprite-8 .88s steps(8) infinite; }
.gil-sconce-top { top: calc(28 / 268 * 100%); width: calc(8 / 478 * 100%); height: calc(8 / 268 * 100%); background-image: url('assets/gielionaire/stage-sconce-top-v1.png'); }
.gil-sconce-low { top: calc(68 / 268 * 100%); width: calc(6 / 478 * 100%); height: calc(10 / 268 * 100%); background-image: url('assets/gielionaire/stage-sconce-low-v1.png'); }
.gil-sconce-top-l { left: calc(154 / 478 * 100%); }
.gil-sconce-top-r { left: calc(316 / 478 * 100%); background-position-y: 100%; }
.gil-sconce-low-l { left: calc(48 / 478 * 100%); }
.gil-sconce-low-r { left: calc(424 / 478 * 100%); background-position-y: 100%; }
/* Every loop shares the master file's 110ms tick, so the page plays in step with the .aseprite preview. */
@keyframes gil-sprite-8 { to { background-position-x: calc(8 / 7 * 100%); } }
@keyframes gil-sprite-16 { to { background-position-x: calc(16 / 15 * 100%); } }
.gil-intro-title { position: relative; text-align: center; animation: gil-stage-arrive .7s ease-out both; }
.gil-intro-title h1 { margin: 0; }
/* The logo is smooth-scaled art, so opt out of the site-wide pixelated rendering. */
.gil-intro-logo { display: block; margin: 0 auto; width:min(88vw, 720px, calc(var(--gil-logo-room, 276px) * 2.68)); height: auto; image-rendering: pixelated; --gil-logo-shadow: drop-shadow(0 10px 22px #000b); filter: var(--gil-logo-shadow); }
/* The logo is decoration, not content to grab: stop the text-selection highlight and the
   drag ghost. -webkit-user-drag covers Chrome/Safari; Firefox needs draggable="false" on
   the elements themselves, which is set in gielionaire.html. */
:is(.gil-intro-logo, .gil-game-logo) { user-select: none; -webkit-user-select: none; -webkit-user-drag: none; }
/* The logo floats gently. A glint sweeps across GIELIONAIRE, masked to its gold letter faces
   (logo-v2-letters-mask.png, generated by build-logo.cjs), and sparkles twinkle on letter corners.
   The wrapper hugs the image, so the mask and sparkle percentages map onto the logo's own 1200x460 art. */
.gil-logo { position: relative; display: block; width: fit-content; margin: 0 auto; animation: gil-logo-bob 3.6s ease-in-out infinite; }
.gil-logo-shine { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(100deg, transparent 28%, #fff6d266 40%, #fffdf2e6 47%, #fffdf2e6 53%, #fff6d266 60%, transparent 72%) no-repeat -70% 0 / 26% 100%; -webkit-mask: url('assets/gielionaire/logo-v2-letters-mask.png') 0 0 / 100% 100% no-repeat; mask: url('assets/gielionaire/logo-v2-letters-mask.png') 0 0 / 100% 100% no-repeat; mix-blend-mode: screen; animation: gil-logo-shine 5.2s ease-in-out 1.4s infinite; }
.gil-logo-glint { position: absolute; left: var(--x); top: var(--y); width: 5%; aspect-ratio: 1; translate: -50% -50%; pointer-events: none; background: radial-gradient(circle, #fff 0 22%, #fff1b0 40%, transparent 70%); clip-path: polygon(50% 0, 56% 44%, 100% 50%, 56% 56%, 50% 100%, 44% 56%, 0 50%, 44% 44%); scale: 0; animation: gil-logo-glint var(--t, 3s) ease-in-out var(--d, 0s) infinite; }
/* Letter corners measured by logo-mask.cjs: top of the G, first E's top-right, the A's peak, last E's top-right. */
.gil-logo-glint-1 { --x: 2.7%; --y: 66.1%; --t: 3.1s; --d: .6s; }
.gil-logo-glint-2 { --x: 26.7%; --y: 66.1%; --t: 3.7s; --d: 2.1s; }
.gil-logo-glint-3 { --x: 66.7%; --y: 66.1%; --t: 3.3s; --d: 1.2s; }
.gil-logo-glint-4 { --x: 90.3%; --y: 66.1%; --t: 4.1s; --d: 2.9s; }
@keyframes gil-logo-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -1.6%; } }
@keyframes gil-logo-shine { 0% { background-position-x: -70%; } 55%, 100% { background-position-x: 170%; } }
@keyframes gil-logo-glint { 0%, 72%, 100% { scale: 0; rotate: 0deg; } 82% { scale: 1; rotate: 45deg; } 92% { scale: 0; rotate: 90deg; } }

/* ── Logo entrance ──
   The sign drops into place on load, then the studio lights bring it up: each lamp clunk
   steps it brighter on the same beats as .gil-beam's --on and gil-room-lift (0.5s / 0.8s /
   1.1s / 1.4s), with a flicker and an over-bright catch before it settles. If those lighting
   cues ever move, these percentages have to move with them.
   Every motion here is stepped rather than eased: the art is a pixel grid, and stepping keeps
   each frame on whole pixels. */
.gil-intro:not(.is-finale) .gil-intro-title { animation: gil-logo-drop .55s step-end both; }
.gil-intro.is-dark .gil-intro-logo { filter: brightness(.45) saturate(.85) var(--gil-logo-shadow); }
.gil-intro:not(.is-dark):not(.is-finale) .gil-intro-logo { animation: gil-logo-power 1.7s step-end both; }
/* The shine and sparkles hold until the lights are up, then the first sweep lands as the beams
   finish settling on the host at 3.4s (the end of gil-beam-sweep). */
.gil-intro.is-dark :is(.gil-logo-shine, .gil-logo-glint) { animation: none; }
.gil-intro:not(.is-dark):not(.is-finale) .gil-logo-shine { animation-delay: 3.3s; }
.gil-intro:not(.is-dark):not(.is-finale) .gil-logo-glint { animation-delay: calc(var(--d, 0s) + 3.4s); }
@keyframes gil-logo-drop {
  0% { opacity: 0; transform: translateY(-24px); }
  20% { opacity: 1; transform: translateY(-14px); }
  40% { transform: translateY(-7px); }
  60% { transform: translateY(-2px); }
  75% { transform: translateY(2px); }
  88% { transform: translateY(1px); }
  100% { transform: translateY(0); }
}
@keyframes gil-logo-power {
  0%, 29.3% { filter: brightness(.45) saturate(.85) var(--gil-logo-shadow); }
  29.4%, 47% { filter: brightness(.64) saturate(.9) var(--gil-logo-shadow); }
  47.1%, 64.6% { filter: brightness(.8) saturate(.95) var(--gil-logo-shadow); }
  64.7%, 70% { filter: brightness(.96) var(--gil-logo-shadow); }
  70.1%, 73.9% { filter: brightness(.58) var(--gil-logo-shadow); }
  74%, 82.3% { filter: brightness(.96) var(--gil-logo-shadow); }
  82.4%, 88% { filter: brightness(1.35) var(--gil-logo-shadow); }
  88.1%, 100% { filter: brightness(1) var(--gil-logo-shadow); }
}
/* ── Logo v1: the original smooth lockup, kept behind the dev tools' toggle ──
   v2 is the default above: a true 300x112 pixel grid from assets/gielionaire/build-logo.cjs.
   These rules put v1 back. Its aspect is 1200/460 = 2.6 against v2's 300/112 = 2.68, and since
   --gil-logo-room is vertical room, that constant has to move with the art. The shine mask and
   glint corners are measured off each logo, so they differ per version too. */
[data-logo="v1"] :is(.gil-intro-logo, .gil-game-logo) { image-rendering: auto; }
[data-logo="v1"] .gil-intro-logo { width: min(88vw, 720px, calc(var(--gil-logo-room, 276px) * 2.6)); }
[data-logo="v1"] .gil-intro.is-finale .gil-intro-logo { width: max(150px, min(80vw, 520px, calc((var(--gil-logo-room, 276px) - 96px) * 2.6))); }
[data-logo="v1"] .gil-intro.is-won .gil-intro-logo { width: max(140px, min(80vw, 440px, calc((var(--gil-logo-room, 276px) - 176px) * 2.6))); }
[data-logo="v1"] .gil-logo-shine { -webkit-mask-image: url('assets/gielionaire/logo-v1-letters-mask.png'); mask-image: url('assets/gielionaire/logo-v1-letters-mask.png'); }
[data-logo="v1"] .gil-logo-glint-1 { --x: 11.8%; --y: 50.9%; }
[data-logo="v1"] .gil-logo-glint-2 { --x: 29.3%; --y: 48.9%; }
[data-logo="v1"] .gil-logo-glint-3 { --x: 67.9%; --y: 49.1%; }
[data-logo="v1"] .gil-logo-glint-4 { --x: 91.8%; --y: 48.7%; }
[data-logo="v1"] .gielionaire-body .gielionaire-prize-ladder,
[data-logo="v1"] .gielionaire-body .gielionaire-prize-ladder:hover,
[data-logo="v1"] .gielionaire-body .gielionaire-prize-ladder.force-open { margin-top: calc(var(--gil-game-logo-w) * 460 / 1200 + 22px); }
@media (max-width: 600px) {
  [data-logo="v1"] .gil-intro.is-finale .gil-intro-logo { width: max(150px, min(80vw, calc((var(--gil-logo-room, 276px) - 76px) * 2.6))); }
  [data-logo="v1"] .gil-intro.is-won .gil-intro-logo { width: max(130px, min(80vw, calc((var(--gil-logo-room, 276px) - 136px) * 2.6))); }
}
.gil-skip { position: absolute; top: 14px; right: 16px; font: 16px 'RuneScape', sans-serif; color: #d9e2ff; background: #0a1230b3; border: 1px solid #6d7fb5; border-radius: 4px; padding: 6px 12px; cursor: pointer; }
.gil-skip:hover { border-color: #e5c574; color: #fff0bc; }
.gil-host { position: absolute; left: 50%; top: min(calc(50% + var(--gil-scene-height, 1080px) * .19), calc(100% - var(--gil-chatbox-height) - 30px)); translate: -50% -100%; animation: gil-host-arrive .8s ease-out .15s both; }
.gil-host::before { content: ''; position: absolute; left: 50%; bottom: -14px; width: 230%; height: 40px; translate: -50% 0; background: radial-gradient(closest-side, #ffe7a64d, #ffe7a614 65%, transparent); }
/* The host is rendered from the OSRS cache (assets/aseprite/stage-src/host/cache/bake-host.mjs) and played frame by
   frame by gielionaire.js (HOST_CLIPS): his in-game idle, and emotes on cue. Frames are held for their in-game lengths,
   never blended: smooth motion made the owner motion sick. .gil-host-body is his standing size; the sprite overhangs it
   so raised arms and a swung staff have room. */
.gil-host-body { position: relative; height: var(--gil-host-height, clamp(170px, calc(var(--gil-scene-height, 1080px) * .3), 330px)); }
.gil-host-sprite { position: absolute; display: block; background-repeat: no-repeat; filter: drop-shadow(0 0 20px #9ab8ff2e); }
/* Now and then the stage lights catch his spectacles: a band sweeps across, masked to the lenses of whichever frame is
   showing (the player moves the mask with the sprite). */
.gil-host-glint { position: absolute; pointer-events: none; background: linear-gradient(110deg, transparent 30%, #fffffff2 50%, transparent 70%) 0 0 no-repeat; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; animation: gil-host-glint 6.5s ease-in-out 1.5s infinite; transition: opacity .9s ease .5s; }
/* host-clips:begin */
/* Generated by assets/aseprite/stage-src/host/cache/bake-host.mjs; don't edit by hand. .gil-host-body is his standing
   box (175x440 sheet px); the sprite and the glint overhang it by the room his emotes need. */
.gil-host-body { aspect-ratio: 175 / 440; }
.gil-host-sprite, .gil-host-glint { left: -141.614%; top: -3.304%; width: 285.203%; height: 104.091%; }
.gil-host-glint { background-size: 12% 100%; }
@keyframes gil-host-glint { 0%, 78% { background-position-x: 51.424%; } 92%, 100% { background-position-x: 88.052%; } }
/* host-clips:end */
.gil-intro.is-dark .gil-host-glint { opacity: 0; }
.gil-chatbox { position: absolute; left: 50%; bottom: 16px; translate: -50% 0; width: min(720px, calc(100% - 32px)); height: var(--gil-chatbox-height); display: flex; align-items: center; gap: 14px; padding: 10px 20px; animation: gil-chat-arrive .45s ease-out .4s both; }
/* The host's chathead in the chat screens: his head models from the cache, animating the whole time the box is
   open, as a dialogue chathead does in game. .gil-chathead is the layout box, the sprite inside it overhangs. */
.gil-chathead { position: relative; flex-shrink: 0; width: auto; height: 118px; }
.gil-chathead-sprite { position: absolute; background-repeat: no-repeat; }
/* head-clips:begin */
/* Generated by assets/aseprite/stage-src/host/cache/bake-head.mjs; don't edit by hand. .gil-chathead is his resting
   head (99x200 sheet px), which is what the chatbox lays out; the sheet overhangs it by the
   room the animation needs, so he can lean out of that box without pushing the text around. */
.gil-chathead { aspect-ratio: 99 / 200; }
.gil-chathead-sprite { left: -13.166%; top: -3.851%; width: 117.135%; height: 105.5%; }
/* head-clips:end */
.gil-chat-main, .gil-chat-options { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; align-items: center; text-align: center; }
.gil-chat-main { padding-right: 40px; }
.gil-chat-main .gil-chat-name { margin-top: 4px; }
.gil-chat-say { flex: 1; display: flex; align-items: center; }
.gil-chat-text { margin: 0; font: 26px/1.15 'Quill 8', 'RuneScape', serif; overflow-wrap: break-word; }
.gil-chat-unsaid { color: transparent; }
/* A phrase the host says in OSRS public-chat effects, marked [[like this]] in HOST_SCENES: glow1 (red, yellow, green,
   cyan and back, never across grey) with wave, each letter a step behind the one before. The black shadow is the game's chat text shadow, which
   keeps the bright colours readable on parchment. Letters stay inline (not inline-block) so lines wrap as normal text.
   gielionaire.js sets negative delays from a shared clock, so the letters keep their places as the line types out. */
.gil-chat-fx { color: #f00; text-shadow: 1px 1px 0 #000; }
.gil-chat-fx span { position: relative; animation: gil-chat-glow 3.6s linear infinite, gil-chat-wave 1.2s ease-in-out infinite; }
@keyframes gil-chat-glow { 0%, 100% { color: #ff0000; } 16.67%, 83.33% { color: #ffff00; } 33.33%, 66.67% { color: #00ff00; } 50% { color: #00ffff; } }
@keyframes gil-chat-wave { 0%, 50%, 100% { top: 0; } 25% { top: -3px; } 75% { top: 3px; } }
.gil-chat-continue { font: 24px/1 'Quill 8', 'RuneScape', serif; color: #0000ff; background: none; border: 0; padding: 2px 8px 4px; cursor: pointer; }
.gil-chat-continue::after { content: ''; position: absolute; inset: 0; }
.gil-chatbox:hover:not(:has(.gil-sfx-float:hover)) .gil-chat-continue { color: #fff; }
.gil-chatbox.is-menu .gil-chathead, .gil-chatbox.is-menu .gil-chat-main { display: none; }
.gil-chat-options { justify-content: center; gap: 2px; }
/* A menu needs more room than a line of dialogue: the finale's four options ran to 192px in a box with 160px inside
   it, so the last one sat on the frame. The box grows to its options instead, never below the height a spoken line
   gets, and the variable goes up with it so the host keeps standing clear (his clamp is measured off it too). */
.gil-chatbox.is-menu { height: fit-content; min-height: var(--gil-chatbox-base); padding-block: 14px; }
.gil-intro:has(.gil-chatbox.is-menu) { --gil-chatbox-height: 232px; }
.gil-chat-options .gil-chat-name { margin-bottom: 6px; }
.gil-chat-options button { font: 26px/1.1 'Quill 8', 'RuneScape', serif; color: #000; background: none; border: 0; padding: 2px 12px; cursor: pointer; }
.gil-chat-options button:hover, .gil-chat-options button:focus-visible { color: #fff; }
.gil-intro.is-leaving { animation: gil-intro-leave .5s ease-in forwards; }
@keyframes gil-host-arrive { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes gil-chat-arrive { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes gil-intro-leave { to { opacity: 0; } }

/* ── Finale ──
   The game ends back on the stage. The winnings plaque sits under the logo,
   which shrinks to keep clear of the host. The effects layer sits between the
   host and the chatbox: spotlights and falling coins for a win, a dimmed
   studio for a loss. */
.gielionaire-container.is-leaving { animation: gil-intro-leave .5s ease-in forwards; }
.gil-intro.is-finale .gil-skip { display: none; }
.gil-intro.is-finale .gil-intro-title, .gil-intro.is-finale .gil-chatbox { z-index: 2; }
.gil-intro.is-finale .gil-intro-logo { width: max(150px, min(80vw, 520px, calc((var(--gil-logo-room, 276px) - 96px) * 2.68))); }
.gil-winnings { display: flex; align-items: center; gap: 12px; width: fit-content; margin: clamp(4px, 1.5vh, 12px) auto 0; padding: 8px 22px 8px 14px; background: linear-gradient(150deg, #1d2a53, #0d1732); border: 1px solid #c7a967; border-radius: 6px; box-shadow: inset 0 0 0 1px #0008, 0 10px 30px #000a; animation: gil-chat-arrive .45s ease-out .25s both; }
.gil-winnings img { width: 56px; height: auto; image-rendering: auto; }
.gil-winnings > div { display: flex; flex-direction: column; align-items: flex-start; text-align: left; }
.gil-winnings .gil-eyebrow { font-size: 14px; }
.gil-winnings strong { font: 32px/1.05 'RuneScape Bold', sans-serif; color: #ffe19b; text-shadow: 0 2px 0 #000; white-space: nowrap; }
.gil-intro.is-won .gil-winnings { border-color: #ffe4a0; box-shadow: inset 0 0 0 1px #0008, 0 10px 30px #000a, 0 0 42px #e6b74766; }
.gil-intro.is-lost .gil-winnings strong { color: #e3e7f5; }
/* A win also gets a headline between the logo and the plaque, in the logo's
   gold, so the screen still celebrates once the host's lines give way to the menu. */
.gil-headline { margin: clamp(2px, 1vh, 8px) 0 0; display: flex; flex-direction: column; align-items: center; gap: 2px; animation: gil-headline-arrive .6s cubic-bezier(.2, 1.4, .4, 1) .1s both; }
.gil-headline strong { font: 46px/1 'RuneScape Bold', sans-serif; letter-spacing: 1px; background: linear-gradient(#fff6cf, #f3c85e 55%, #b57c25); -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 3px 0 #4a3210) drop-shadow(0 0 18px #f3c65a66); }
.gil-headline span { font: 17px 'RuneScape', sans-serif; color: #e6ecff; text-shadow: 0 2px 0 #000; }
.gil-intro.is-won .gil-intro-logo { width: max(140px, min(80vw, 440px, calc((var(--gil-logo-room, 276px) - 176px) * 2.68))); }
@keyframes gil-headline-arrive { from { opacity: 0; transform: scale(.6); } }
.gil-finale-fx { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.gil-intro.is-lost .gil-finale-fx { background: radial-gradient(ellipse 36% 62% at 50% 60%, transparent 35%, #030817d0 100%); animation: gil-fade-in 1.2s ease-out both; }
.gil-coin { position: absolute; top: -70px; left: var(--x); width: var(--size); height: auto; image-rendering: pixelated; animation: gil-coin-fall var(--fall) cubic-bezier(.4, 0, .9, .6) var(--delay) both; }
@keyframes gil-coin-fall { to { transform: translateY(calc(100svh + 140px)) rotate(var(--spin)); } }
@keyframes gil-fade-in { from { opacity: 0; } }

/* --gil-game-logo-w sizes the in-game logo and the ladder's matching drop. */
.gielionaire-container { --gil-game-logo-w: clamp(220px, 22vw, 330px); max-width: 1180px; padding: 28px 24px 40px; display: grid; grid-template-columns: minmax(0, 1fr) 250px; gap: 32px; align-items: start; }
.gielionaire-main-stack { gap: 18px; min-width: 0; }
.gielionaire-header { padding: 0 0 4px; animation: gil-stage-arrive .7s ease-out both; }
.gielionaire-header h1 { margin: 0; }
/* A small copy of the intro logo: enough to brand the game without pushing the question down. */
.gil-game-logo { display: block; margin: 0 auto; width: var(--gil-game-logo-w); height: auto; image-rendering: pixelated; filter: drop-shadow(0 8px 16px #000a); }
/* The host keeps talking during the game, in a slim chatbox. */
.gil-host-bar { position: relative; z-index: 11; display: flex; align-items: center; gap: 14px; padding: 8px 16px; box-shadow: var(--gil-parchment-frame), 0 8px 24px #0007; }
.gil-host-bar img { flex-shrink: 0; width: auto; height: 62px; }
.gil-host-bar > div:not(.gil-host-tools) { flex: 1; min-width: 0; }
.gil-host-bar .gil-chat-name { font-size: 21px; }
/* His line always takes two lines (three on phones), so a longer line never shifts the game below. */
.gil-host-bar p { margin: 3px 0 0; font: 23px/1.15 'Quill 8', 'RuneScape', serif; color: #000; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; min-height: calc(2 * 1.15em); }
/* How to play sits with the host rather than the question. */
.gil-host-tools { flex-shrink: 0; display: flex; align-items: center; gap: 4px; }
.gil-host-bar .gil-help-button { flex-shrink: 0; font: 21px 'Quill 8', 'RuneScape', serif; color: #0000ff; background: none; border: 0; padding: 6px; }
.gil-host-bar .gil-help-button:hover { color: #fff; background: none; }
/* Sound (the shared sfx.js control): a small speaker floating just above the host's chatbox, top-left, on the
   intro/finale chatbox and the question screen's host bar alike. It is a child of each, so it moves with them.
   Hovering or focusing it slides the volume bar out to the right in a small panel; phones keep the button only
   (sfx.css hides the slider there, and touch has no hover). Styled for the stage, not the parchment. */
.gil-sfx { --sfx-bg: #0a1230d9; --sfx-bg-hover: #16224d; --sfx-border: #6d7fb5; --sfx-border-hover: #e5c574; --sfx-ink: #d9e2ff; --sfx-ink-off: #7f8bb3; --sfx-focus: #fff0bc; --sfx-accent: #e5c574; }
.gil-sfx-float { position: absolute; left: 0; bottom: calc(100% + 8px); z-index: 3; gap: 0; padding: 3px; border: 1px solid transparent; border-radius: 6px; transition: background-color .2s ease, border-color .2s ease; }
.gil-sfx-float .sfx-mute { width: 34px; height: 34px; box-shadow: none; }
.gil-sfx-float .sfx-slider { width: 0; margin: 0; opacity: 0; pointer-events: none; transition: width .22s ease, margin .22s ease, opacity .18s ease; }
.gil-sfx-float:is(:hover, :focus-within) { background: #0a1230e6; border-color: #6d7fb5; }
.gil-sfx-float:is(:hover, :focus-within) .sfx-slider { width: 96px; margin: 0 8px 0 10px; opacity: 1; pointer-events: auto; }
/* Music has its own button and slider (data-sfx-music), revealed alongside the sound slider. */
.gil-sfx-float .sfx-music { width: 0; min-width: 0; margin: 0; padding: 0; border-width: 0; opacity: 0; overflow: hidden; pointer-events: none; transition: width .22s ease, opacity .18s ease; }
.gil-sfx-float:is(:hover, :focus-within) .sfx-music { width: 34px; border-width: 1px; opacity: 1; pointer-events: auto; }
/* The lifelines sit in their own row under the logo, centred. */
.gielionaire-body .gielionaire-question-header-row { margin: 0; display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: center; align-items: center; gap: 12px; }
.gielionaire-body .gielionaire-lifelines { order: 0; width: auto; flex-wrap: nowrap; justify-content: center; }
/* The clock is a second tab on the question box, top-right, the same height as the
   question tab and flush on the box in the same way. */
.gil-question-tabs { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; margin: 0 32px; }
.gielionaire-timer { color: #e4eeff; }
.gielionaire-body .gielionaire-timer { position: relative; z-index: 11; order: 0; align-self: auto; width: auto; height: 31px; box-sizing: border-box; margin: 0; gap: 8px; padding: 0 3px 0 12px; font-size: 17px; background: #263c77; border: 2px solid #b7b0db; border-bottom: 0; border-radius: 6px 6px 0 0; box-shadow: none; }
.gielionaire-timer::after { content: ''; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px; background: #263c77; }
/* Under 10 seconds the time turns red and pulses; the old red glow would bleed onto the box. */
.gielionaire-body .gielionaire-timer.timer-warning { color: #ff8f8f; animation: none; }
.gielionaire-body .gielionaire-timer.timer-warning .gielionaire-timer-text { animation: gil-timer-urgent 1s ease-in-out infinite; }
@keyframes gil-timer-urgent { 50% { color: #fff; } }
/* Stop and resume, drawn inside the clock as a pause or play icon. */
.gielionaire-body .gielionaire-timer-toggle-btn { order: 0; position: relative; flex-shrink: 0; width: 24px; height: 24px; margin: 0; padding: 0; background: #1a2850; border: 1px solid #657aa9; border-radius: 4px; }
.gielionaire-body .gielionaire-timer-toggle-btn:hover { background: #25385f; border-color: #cfb977; }
.gielionaire-timer-toggle-btn::before, .gielionaire-timer-toggle-btn::after { content: ''; position: absolute; top: 5px; width: 4px; height: 12px; background: #e4eeff; }
.gielionaire-timer-toggle-btn::before { left: 6px; }
.gielionaire-timer-toggle-btn::after { right: 6px; }
.gielionaire-timer-toggle-btn.is-paused::before { left: 8px; width: 10px; clip-path: polygon(0 0, 100% 50%, 0 100%); }
.gielionaire-timer-toggle-btn.is-paused::after { display: none; }
.gielionaire-panel { padding: 0; }
.gielionaire-question-container { margin: 0 0 20px; }
/* A tab on the question box's top edge: which question, and what it's worth. It
   starts clear of the box's bevelled corner (a 25px clip-path in styles.css) and
   rests on the box rather than overlapping it, so its side borders end exactly on
   the box's border at any zoom. A strip in the tab's colour covers that border
   under the opening, so the two read as one piece. */
.gielionaire-body .gielionaire-question-container { gap: 0; }
.gil-question-tab { position: relative; z-index: 11; display: flex; align-items: baseline; gap: 8px; margin: 0; padding: 7px 14px 6px; font: 16px/1 'RuneScape Bold', sans-serif; color: #bccbeb; background: #263c77; border: 2px solid #b7b0db; border-bottom: 0; border-radius: 6px 6px 0 0; }
.gil-question-tab::after { content: ''; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px; background: #263c77; }
.gil-question-tab-prize { color: #f3d189; }
.gil-question-tab-sep { color: #7d8cb0; }
/* Always room for a two-line question (three on phones), so the next question doesn't shift the answers.
   The gradient runs straight down so the top edge is one flat colour, matching the tabs on it. */
.gielionaire-question-text { color: #f4f2ff; padding: 30px 36px; font-size: clamp(22px, 3vw, 28px); background: linear-gradient(180deg, #263c77, #15234e); border-block: 2px solid #b7b0db; min-height: max(126px, calc(2 * 1.4em + 64px)); display: grid; place-items: center; }
.gielionaire-question-text::before, .gielionaire-question-text::after { display: none; }
.gielionaire-answers { gap: 14px; margin-bottom: 22px; }
.gielionaire-answer-btn { background: linear-gradient(135deg, #1d305f, #101c3c); border: 1px solid #8194c5; border-radius: 4px 16px; box-shadow: inset 0 1px #ffffff10, 0 5px 12px #0003; min-height: 72px; padding: 16px 18px; color: #edf1ff; }
.gielionaire-answer-btn:hover:not(:disabled):not(.selected) { background: #293e73; border-color: #ebce87; transform: translateY(-2px); box-shadow: 0 0 18px #86a1ff20; }
.gielionaire-answer-btn.selected { background: linear-gradient(135deg, #bd8737, #e5bb65) !important; border-color: #ffe8ac !important; color: #1d1930; transform: none; box-shadow: 0 0 24px #eec56425; }
.gielionaire-answer-btn.selected:hover:not(:disabled) { transform: translateY(-2px); color: #1d1930; }
/* Hovering lifts the answers, Final Answer and the lifelines a few pixels, and the lift
   carries the hit area with it: a pointer resting on a bottom edge would fall off, drop
   the hover, sink back under the pointer and flicker. While hovered, an invisible strip
   fills the gap left underneath (6px covers the largest lift). */
.gielionaire-body :is(.gielionaire-answer-btn, .gielionaire-final-answer-btn, .gielionaire-lifeline-btn) { position: relative; }
.gielionaire-body :is(.gielionaire-answer-btn, .gielionaire-final-answer-btn, .gielionaire-lifeline-btn):hover:not(:disabled)::after { content: ''; position: absolute; left: 0; right: 0; bottom: -6px; height: 6px; }
/* Final answer locked in: the choice glows and the rest dim while the host holds the reveal. */
.gielionaire-answers.is-locked .gielionaire-answer-btn:not(.locked) { opacity: .45; }
.gielionaire-answer-btn.locked { animation: gil-lock-pulse 1.1s ease-in-out infinite; }
@keyframes gil-lock-pulse { 50% { box-shadow: 0 0 34px #ffd77a80, inset 0 0 14px #fff5; } }
.gielionaire-answer-label { color: #f3d189; border: 0; background: transparent; width: auto; height: auto; min-width: 18px; }
.gielionaire-answer-btn.selected .gielionaire-answer-label { color: #342548; }
.gielionaire-answer-btn.correct { background: #204d3a; border-color: #89dba2; color: #e6ffe7; }
.gielionaire-answer-btn.incorrect { background: #612c43; border-color: #e68494; }
.gielionaire-answer-btn.hidden-5050 { opacity: .3; background: #121a30; border-color: #495879; }
/* The change-over between questions (see swapBoard). The question, its tab and the answers fade down together,
   still carrying the verdict; the next question is put in while they are invisible; then the answers arrive one
   after another, A to D. The board is never seen changing, so nothing has to line up frame by frame. */
.gil-swap-out :is(.gil-question-tab, .gielionaire-question-text, .gielionaire-answer-btn) { opacity: 0; transform: translateY(6px); transition: opacity .2s ease, transform .2s ease; }
.gil-swap-in :is(.gil-question-tab, .gielionaire-question-text) { animation: gil-board-in .28s ease both; }
.gil-swap-in .gielionaire-answer-btn { animation: gil-board-in .34s ease both; }
.gil-swap-in .gielionaire-answer-btn:nth-child(2) { animation-delay: .07s; }
.gil-swap-in .gielionaire-answer-btn:nth-child(3) { animation-delay: .14s; }
.gil-swap-in .gielionaire-answer-btn:nth-child(4) { animation-delay: .21s; }
@keyframes gil-board-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* The crowd's vote, left on each answer after Ask the crowd closes. */
.gil-crowd-pct { position: absolute; top: 50%; right: 12px; translate: 0 -50%; padding: 1px 8px 2px; font: 14px/1.2 'RuneScape Bold', sans-serif; color: #ffe19b; background: #0d1732; border: 1px solid #c7a967; border-radius: 999px; box-shadow: 0 2px 6px #0007; pointer-events: none; animation: gil-crowd-pct-in .35s ease-out both; }
.gielionaire-answer-btn:has(.gil-crowd-pct) { padding-right: 68px; }
@keyframes gil-crowd-pct-in { from { opacity: 0; scale: .85; } }
/* Ask the crowd mirrors the answer grid: A B over C D. */
.gielionaire-body .gielionaire-audience-results { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 16px; align-items: start; margin: 20px 0; }
.gielionaire-body .gielionaire-audience-bar { align-items: stretch; gap: 6px; }
.gielionaire-body .gielionaire-audience-label-text { text-align: left; font-size: 15px; }
.gielionaire-body .gielionaire-audience-bar-fill { width: 100%; height: 48px; }
.gielionaire-body .gielionaire-audience-bar.is-removed { opacity: .35; }
/* Ask the crowd's clock, on the results: "paused" during the free read, red at 10 seconds or fewer like the board's. */
.gil-crowd-clock { display: inline-flex; align-items: center; gap: 8px; margin: 12px auto 0; padding: 5px 14px; font: 17px/1 'RuneScape Bold', sans-serif; color: #e4eeff; background: #263c77; border: 2px solid #b7b0db; border-radius: 999px; }
.gil-crowd-clock[hidden] { display: none; }
.gil-crowd-clock.is-warning { color: #ff8f8f; }
.gil-crowd-clock-held { font: 12px/1 'RuneScape', sans-serif; letter-spacing: .05em; text-transform: uppercase; color: #cad5ee; }
.gil-crowd-clock:not(.is-held) .gil-crowd-clock-held { display: none; }
.gielionaire-final-answer-btn { background: linear-gradient(#f5d993, #c89e50); color: #231c28; border: 1px solid #ffe4a8; border-radius: 4px; box-shadow: 0 3px 0 #735324; font-size: 20px; padding: 12px 36px; }
.gielionaire-final-answer-btn:disabled { opacity: .4; }
/* The shared styles.css hover swaps the gradient for a flat dark fill, and its "transition: all" fades that fill in
   from transparent, so the button went see-through for a moment. Keep the gold, and never transition the background. */
.gielionaire-body .gielionaire-final-answer-btn { transition: opacity .2s ease, transform .15s ease, box-shadow .15s ease; }
.gielionaire-body .gielionaire-final-answer-btn:hover:not(:disabled) { background: linear-gradient(#ffe4a8, #d6ab5c); border-color: #fff1c9; color: #231c28; transform: translateY(-2px); box-shadow: 0 5px 0 #735324, 0 0 20px #eec56433; }
.gielionaire-body .gielionaire-final-answer-btn:active:not(:disabled) { transform: translateY(0); box-shadow: 0 2px 0 #735324; }
/* Lifelines are OSRS rune stones again, keeping the coloured glows from styles.css
   (green 50/50, purple Ask the crowd, blue Extra Time, brighter on hover). A little
   smaller than the old 80px so the question stays near the top; the labels get a
   dark shadow to stay legible on the grey stone. */
.gielionaire-lifelines { gap: 14px; margin: 0; }
.gielionaire-body :is(#gielionaire-lifeline-5050, #gielionaire-lifeline-audience, #gielionaire-lifeline-extra) { width: 76px; height: 76px; min-width: 0; min-height: 0; padding: 8px; gap: 3px; background: url('assets/icons/rune.png') center / contain no-repeat; border: 0; border-radius: 50%; color: #fff; font-size: 13px; text-shadow: 0 1px 2px #000, 0 0 5px #000; }
.gielionaire-body .gielionaire-lifeline-icon { font-size: 21px; line-height: 1; color: #f4d58b; }
.gielionaire-lifeline-icon-img { width: 26px; height: 26px; object-fit: contain; filter: drop-shadow(0 1px 1px #000); }
.gielionaire-body .gielionaire-lifeline-label { display: block; font-size: 10px; line-height: 1; white-space: nowrap; margin: 0; }
.gielionaire-body .gielionaire-lifeline-btn:disabled { opacity: .4; filter: grayscale(1); }
/* The ladder starts level with the lifelines: the logo (width x 460/1200 tall), the header's
   4px padding and the stack's 18px gap. Keep in step with .gil-game-logo and .gielionaire-header. */
.gielionaire-body .gielionaire-prize-ladder, .gielionaire-body .gielionaire-prize-ladder:hover, .gielionaire-body .gielionaire-prize-ladder.force-open { position: sticky; top: 24px; right: auto; transform: none; width: 100%; max-height: none; pointer-events: auto; z-index: 1; margin-top: calc(var(--gil-game-logo-w) * 112 / 300 + 22px); }
.gielionaire-prize-ladder::before { display: none; }
/* ── Prize ladder ──
   One plain row per question: its number on the left, the prize on the right.
   Every row keeps the same 1px frame so nothing shifts. Questions still ahead are
   pale blue, the checkpoints (5, 10) and the billion are white like the show's
   safe havens, banked rows turn gold, and the current question is a gold bar.
   The old site styles (stone texture, green rows, thick milestone borders) are
   switched off here. */
.gielionaire-prize-ladder-inner { background: linear-gradient(150deg, #1d2a53, #0d1732); border: 1px solid #a38b57; border-radius: 8px; padding: 14px 10px; max-height: none; overflow: visible; gap: 2px; box-shadow: 0 12px 30px #0004; }
.gielionaire-prize-ladder-title { color: #ffe19b; font-size: 18px; }
.gielionaire-prize-ladder-header { border-bottom: 1px solid #827247; margin-bottom: 6px; }
.gielionaire-body .gielionaire-prize-item { flex-direction: row-reverse; justify-content: space-between; gap: 10px; min-height: 0; margin: 0; padding: 6px 10px; background: transparent; border: 1px solid transparent; border-radius: 4px; box-shadow: none; opacity: 1; transition: background-color .25s ease; }
.gielionaire-body .gielionaire-prize-item::before { display: none; }
.gielionaire-body .gielionaire-prize-amount { flex: none; font-size: 17px; color: #c2ceea; text-shadow: none; }
.gielionaire-body .gielionaire-prize-label { min-width: 22px; font-size: 16px; text-align: left; color: #6f80ab; }
/* Checkpoints and the top prize read brighter, like the show's safe havens. */
.gielionaire-body .gielionaire-prize-item.gielionaire-prize-milestone, .gielionaire-body .gielionaire-prize-item.gielionaire-prize-top { background: transparent; border: 1px solid transparent; box-shadow: none; }
.gielionaire-body :is(.gielionaire-prize-milestone, .gielionaire-prize-top) .gielionaire-prize-amount { color: #fff; }
.gielionaire-body :is(.gielionaire-prize-milestone, .gielionaire-prize-top) .gielionaire-prize-label { font-size: 16px; color: #d6b56a; }
.gielionaire-body .gielionaire-prize-item.gielionaire-prize-top .gielionaire-prize-amount { font-size: 18px; color: #ffe19b; text-shadow: 0 0 12px #f3c65a55; }
/* Tier dividers above 5 and 10: an equal gap with a 1px line centred in it, as wide as the rows. */
.gielionaire-body .gielionaire-prize-item.gielionaire-prize-milestone { margin-top: 9px; }
.gielionaire-body .gielionaire-prize-item.gielionaire-prize-milestone::after { content: ''; position: absolute; left: -1px; right: -1px; top: -6px; height: 1px; background: #827247; opacity: 1; }
/* Banked: every question below the current one. */
.gielionaire-body .gielionaire-prize-item.answered .gielionaire-prize-amount { color: #d9bd7a; }
.gielionaire-body .gielionaire-prize-item.answered .gielionaire-prize-label { color: #8a7a52; }
/* The current question: a gold bar, on every row including the billion. */
.gielionaire-body .gielionaire-prize-item.current { background: linear-gradient(90deg, #f6d887, #c59a49); border-color: #ffe4a0; box-shadow: 0 0 16px #dfb75533; }
.gielionaire-body .gielionaire-prize-item.current :is(.gielionaire-prize-amount, .gielionaire-prize-label) { color: #1d1930; text-shadow: none; }
.gielionaire-body .gielionaire-prize-item.current.flash { animation: gil-prize-flash .8s ease-in-out; }
@keyframes gil-prize-flash { 50% { filter: brightness(1.2); box-shadow: 0 0 28px #f3c65aaa; } }
/* ── Player line ──
   Who's playing and the Discord link, as one quiet line under the ladder: small
   muted text and plain links rather than a panel, so it doesn't compete with the game. */
/* A slim panel in the ladder's colours: the lit stage behind made bare text hard to read. */
.gil-player-card { margin-top: 10px; padding: 7px 10px; display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 12px; font: 14px/1.3 'RuneScape', sans-serif; color: #c3cde8; text-shadow: 0 1px 1px #000c; background: #0d1732eb; border: 1px solid #a38b5766; border-radius: 6px; box-shadow: 0 6px 16px #0005; }
.gil-player-name { margin: 0; display: flex; align-items: baseline; gap: 5px; min-width: 0; }
.gil-player-name .gil-eyebrow { font: inherit; letter-spacing: 0; text-transform: none; color: inherit; }
.gil-player-name strong { font: 14px/1.3 'RuneScape Bold', sans-serif; color: #ffe19b; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gil-player-actions { display: flex; align-items: baseline; gap: 12px; }
.gil-card-button { display: inline-flex; align-items: center; gap: 5px; padding: 0; font: inherit; color: #dbe3fb; text-decoration: none; background: none; border: 0; cursor: pointer; }
.gil-card-button:hover { color: #fff0bc; text-decoration: underline; }
.gil-card-button[hidden] { display: none; }
/* Discord gets its brand purple instead of a logo, lightened enough to read as small text on the navy. */
.gil-discord-button { color: #b3b9ff; }
.gil-discord-button:hover { color: #dde0ff; }
.gil-rules { padding: 26px 30px; width: min(600px, calc(100% - 32px)); max-height: 85dvh; box-sizing: border-box; box-shadow: var(--gil-parchment-frame), 0 25px 100px #000b; }
.gil-rules::backdrop { background: #020715cc; backdrop-filter: blur(5px); }
.gil-rules-close { position: absolute; right: 12px; top: 8px; background: transparent; border: 0; color: #2b241b; font-size: 28px; cursor: pointer; }
.gil-rule-host { display: flex; gap: 18px; align-items: center; }
.gil-rule-host img { width: auto; height: 84px; }
.gil-rules .gil-eyebrow { color: #5a4a33; }
.gil-rule-host h2 { font: 32px 'Quill 8', 'RuneScape Bold', serif; color: #800000; margin: 4px 0; }
.gil-rules .gil-gold-button { width: 100%; }
/* The flag form reuses the rules parchment, with its fields inked onto it. */
.gil-flag-intro { font: 17px/1.4 'RuneScape', sans-serif; color: #2b241b; margin: 16px 0 6px; }
.gil-field { display: block; margin: 12px 0 5px; font: 21px/1.1 'Quill 8', 'RuneScape Bold', serif; color: #000; }
.gil-field span { font: 15px 'RuneScape', sans-serif; color: #5a4a33; }
.gil-input { display: block; width: 100%; box-sizing: border-box; padding: 9px 11px; font: 17px/1.35 'RuneScape', sans-serif; color: #1e1811; background: #efe4c8a6; border: 1px solid #8a785a; border-radius: 2px; box-shadow: inset 0 1px 3px #3a302440; }
.gil-input::placeholder { color: #7a6a4f; }
.gil-input:focus-visible { outline: 2px dotted #000; outline-offset: 2px; background: #f5ecd6; }
textarea.gil-input { resize: vertical; min-height: 96px; }
.gil-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.gil-flag-note { margin: 12px 0 0; font: 16px/1.35 'RuneScape', sans-serif; color: #2f5a1e; }
.gil-flag-note.is-error { color: #800000; }
.gil-flag-actions { display: flex; gap: 10px; margin-top: 18px; }
.gil-flag-actions .gil-gold-button { flex: 1; }
.gil-flag .gil-gold-button:disabled { opacity: .55; cursor: wait; }
.gil-plain-button { font: 18px 'RuneScape Bold', sans-serif; cursor: pointer; padding: 12px 18px; border-radius: 4px; background: transparent; color: #2b241b; border: 1px solid #8a785a; }
.gil-plain-button:hover { background: #0000000f; border-color: #3a3024; }
/* The question being flagged, quoted in an inset, and the reasons as ink-stamp chips. */
.gil-flag-question { margin: 12px 0 2px; padding: 10px 12px; background: #e9dcb999; border-left: 3px solid #800000; font: 16px/1.35 'RuneScape', sans-serif; color: #5a4a33; }
.gil-flag-question q { display: block; margin-bottom: 4px; font-family: 'RuneScape Bold', sans-serif; color: #1e1811; }
.gil-flag-question strong { color: #1e1811; font-weight: normal; }
.gil-flag-reasons { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; border: 0; min-width: 0; }
.gil-flag-reasons legend { padding: 0; }
.gil-flag-reasons label { position: relative; cursor: pointer; }
.gil-flag-reasons input { position: absolute; opacity: 0; pointer-events: none; }
.gil-flag-reasons label span { display: inline-block; padding: 6px 12px; font: 15px/1.2 'RuneScape', sans-serif; color: #2b241b; background: #efe4c866; border: 1px solid #8a785a; border-radius: 999px; }
.gil-flag-reasons label:hover span { border-color: #3a3024; }
.gil-flag-reasons input:checked + span { color: #fff3d6; background: #800000; border-color: #800000; }
.gil-flag-reasons input:focus-visible + span { outline: 2px dotted #000; outline-offset: 2px; }
.gil-flag-count { margin-top: 4px; text-align: right; font: 13px 'RuneScape', sans-serif; color: #7a6a4f; }
.gil-flag-count.is-near { color: #800000; }
.gielionaire-body .site-footer { background: transparent; color: #8e9bb9; }
.gielionaire-overlay { background: #020715cc; backdrop-filter: blur(5px); }
.gielionaire-modal { background: linear-gradient(145deg, #24355f, #101a36); border: 1px solid #c7a967; border-radius: 10px; padding: 30px 24px; overflow-y: auto; }
.gielionaire-modal::before, .gielionaire-modal::after { display: none; }
.gielionaire-modal .gielionaire-modal-title { color: #ffe19b; text-shadow: none; }
.gielionaire-modal-subtitle, .gielionaire-modal-question-info, .gielionaire-community-subtitle, .gielionaire-audience-label-text, .gielionaire-flag-link { color: #cad5ee; }
.gil-rules, .gielionaire-modal { scrollbar-color: #69799d #172446; }
.gielionaire-modal .gielionaire-community-title { color: #ffe19b !important; }
.gielionaire-modal-actions .btn { font-size: 18px; }
@keyframes gil-stage-arrive { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
/* Wide screens: an empty column mirrors the ladder, so the game sits dead centre under the
   stage lights and the Wise Old Man. The game column gives up width before the ladder moves. */
@media (min-width: 1240px) {
  .gielionaire-container { max-width: 1600px; grid-template-columns: minmax(250px, 1fr) minmax(0, 850px) minmax(250px, 1fr); }
  .gielionaire-main-stack { grid-column: 2; }
  .gielionaire-body .gielionaire-prize-ladder, .gielionaire-body .gielionaire-prize-ladder:hover, .gielionaire-body .gielionaire-prize-ladder.force-open { grid-column: 3; justify-self: end; width: 250px; }
}
@media (max-width: 900px) {
  .gielionaire-container { grid-template-columns: minmax(0, 1fr); max-width: 800px; }
  /* Match the desktop selectors, or the correct-answer flash (.force-open) adds 25px above the ladder for 3s. */
  .gielionaire-body .gielionaire-prize-ladder, .gielionaire-body .gielionaire-prize-ladder:hover, .gielionaire-body .gielionaire-prize-ladder.force-open { position: static; max-width: 480px; margin: 0 auto; }
}
@media (max-width: 600px) {
  .gil-intro { image-rendering: pixelated; --gil-chatbox-height: 206px; --gil-chatbox-base: 206px; }
  /* The smaller type already fits four options here, so a menu keeps the same box. */
  .gil-intro:has(.gil-chatbox.is-menu) { --gil-chatbox-height: 206px; }
  .gil-intro-title { margin-top: 34px; }
  .gil-skip { top: 10px; right: 12px; font-size: 14px; padding: 5px 10px; }
  .gil-chatbox { width: calc(100% - 24px); bottom: 12px; gap: 8px; padding: 8px 12px; }
  .gil-chathead { height: 78px; }
  .gil-chat-main { padding-right: 0; }
  .gil-chat-name, .gil-chat-text, .gil-chat-options button { font-size: 22px; }
  .gil-chat-continue { font-size: 21px; }
  .gil-intro.is-finale .gil-intro-logo { width: max(150px, min(80vw, calc((var(--gil-logo-room, 276px) - 76px) * 2.68))); }
  .gil-winnings { gap: 8px; padding: 6px 16px 6px 10px; }
  .gil-winnings img { width: 40px; }
  .gil-winnings strong { font-size: 24px; }
  .gil-intro.is-won .gil-intro-logo { width: max(130px, min(80vw, calc((var(--gil-logo-room, 276px) - 136px) * 2.68))); }
  /* The 170px in-game logo is BELOW the 300px native, and nearest-neighbour shreds a grid on the
     way down, so let the browser resample smoothly there. */
  .gil-game-logo { image-rendering: auto; }
  .gil-headline strong { font-size: 32px; }
  .gil-headline span { font-size: 14px; }
  .gil-field-row { grid-template-columns: 1fr; gap: 0; }
  .gil-flag-actions { flex-direction: column-reverse; }
  .gielionaire-body .gielionaire-question-header-row { gap: 8px; }
  .gielionaire-body .gielionaire-lifelines { gap: 10px; }
  .gielionaire-body :is(#gielionaire-lifeline-5050, #gielionaire-lifeline-audience, #gielionaire-lifeline-extra) { width: 66px; height: 66px; }
  .gil-question-tabs { margin: 0 14px; gap: 8px; }
  .gil-question-tab { padding-inline: 10px; font-size: 14px; }
  /* Match the phone question tab, whose smaller text makes it 29px tall. */
  .gielionaire-body .gielionaire-timer { height: 29px; padding-left: 10px; }
  .gielionaire-timer-icon { display: none; }
  .gielionaire-container { padding: 12px 14px 24px; gap: 16px; }
  .gielionaire-main-stack { gap: 12px; }
  .gielionaire-container { --gil-game-logo-w: 170px; }
  .gil-host-bar { position: relative; padding: 8px 10px; gap: 8px; }
  .gil-host-bar img { height: 48px; }
  .gil-host-bar p { font-size: 18px; -webkit-line-clamp: 3; min-height: calc(3 * 1.15em); }
  /* On phones "How to play" sits beside his name, giving his words the full width. */
  .gil-host-tools { position: absolute; top: 4px; right: 6px; }
  .gil-host-bar .gil-help-button { font-size: 18px; padding: 2px 4px; }
  .gil-sfx-float { bottom: calc(100% + 6px); }
  .gil-sfx-float .sfx-mute { width: 30px; height: 30px; }
  .gil-sfx-float .sfx-music { width: 0; }
  .gil-sfx-float:is(:hover, :focus-within) .sfx-music { width: 30px; }
  .gielionaire-question-text { padding: 16px 18px; font-size: 21px; min-height: calc(3 * 1.4em + 36px); }
  .gielionaire-question-container { margin-bottom: 12px; }
  /* Phones: answers in a 2x2 grid, so the question, all four answers and Final Answer
     fit on one screen. Each answer keeps room for two lines so rows stay put between
     questions; the rare longer answer (about 1 in 50) grows its row. */
  .gielionaire-answers { grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 14px; }
  .gielionaire-answer-btn { min-height: 58px; padding: 10px 12px; gap: 8px; font-size: 16px; line-height: 1.2; }
  .gil-crowd-pct { right: 6px; padding: 0 6px 1px; font-size: 12px; }
  .gielionaire-answer-btn:has(.gil-crowd-pct) { padding-right: 46px; }
  .gielionaire-body .gielionaire-audience-results { gap: 12px 10px; }
  .gielionaire-body .gielionaire-audience-label-text { font-size: 13px; }
  .gielionaire-body .gielionaire-audience-bar-fill { height: 40px; }
  .gielionaire-final-answer-container { margin: 14px 0; }
  .gil-rules { padding: 24px 20px; }
  .gil-rule-host { gap: 10px; }
  .gil-rule-host img { height: 64px; }
  .gil-rule-host h2 { font-size: 26px; }
}

/* ── Local dev tools (gielionaire-dev.js, localhost only) ──
   Deliberately plain and unbranded so it never reads as part of the game. */
.gil-dev-launcher {
  position: fixed; right: 12px; bottom: 12px; z-index: 10050;
  padding: 8px 12px; border: 1px solid #6b6a8a; border-radius: 6px;
  background: #16161f; color: #d9d7ee; font: 13px system-ui, sans-serif; cursor: pointer;
}
.gil-dev-panel {
  position: fixed; right: 12px; bottom: 12px; z-index: 10050; width: 300px;
  display: flex; flex-direction: column; gap: 9px;
  padding: 12px; border: 1px solid #55546e; border-radius: 8px;
  background: #121219; color: #e4e2f3; font: 13px system-ui, sans-serif;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
}
/* The site styles give text elements the game font; keep the panel plain. */
.gil-dev-panel * { font-family: system-ui, sans-serif; }
.gil-dev-head { display: flex; align-items: center; justify-content: space-between; }
.gil-dev-x { border: 0; background: none; color: #b9b7d0; font-size: 18px; line-height: 1; padding: 0 4px; cursor: pointer; }
.gil-dev-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.gil-dev-row select { flex: 1; min-width: 0; }
.gil-dev-panel :is(button:not(.gil-dev-x), select) {
  padding: 6px 9px; border: 1px solid #55546e; border-radius: 4px;
  background: #22222e; color: #e4e2f3; font: inherit; cursor: pointer;
}
.gil-dev-panel button:not(.gil-dev-x):hover { background: #2e2e3d; }
.gil-dev-state { margin: 0; color: #fff; }
.gil-dev-label { display: inline-flex; align-items: center; gap: 5px; color: #b9b7d0; font-size: 12px; }
.gil-dev-foot { justify-content: space-between; border-top: 1px solid #2e2e3d; padding-top: 9px; }
.gil-dev-note { color: #8886a0; font-size: 11px; line-height: 1.35; }
@media (max-width: 640px) {
  .gil-dev-panel { right: 8px; left: 8px; width: auto; max-height: 50vh; overflow-y: auto; }
}
