/*
 * Ivar's Filter Frenzy -- the game (.vg-*) and page (.ff-*) styles, ported from
 * the designer's artifact (qa-artifacts/game-landing/stripped.html L18-652).
 *
 * Served as a static file and linked ONLY by the `game` template view
 * (templates/views/game.tsx, <link precedence>), so no other page downloads it.
 * Unlayered on purpose, exactly as in the artifact: the site stylesheet lives in
 * @layer components, and these rules have to win over it.
 *
 * Changes from the artifact: the two document-wide rules (:focus-visible and the
 * reduced-motion `*`) are scoped to the game; the dead launcher / coupon /
 * footnote / design-notes rules are dropped; the lead form's tel input joins
 * the text/email input rules; the prize by-line takes rich text; `.ff-rules`
 * (the optional CMS fine print) is new.
 *
 * Cached for a year (next.config `/game/:path*`) -- the folder is versioned
 * (`v1`), so a change ships under a new folder rather than an edited file.
 */
.vg-app, .vg-modal {
  --navy: #002147;
  --navy-2: #001629;
  --blue: #0056b4;
  --red: #bb133d;
  --red-hover: #94112f;
  --silver: #cfd1d3;
  --gold: #fbbc04;
  --ink: #ffffff;
  --plate: rgba(2, 14, 33, 0.9);
  --focus: #ffd24d;
  --font: "Sora", system-ui, -apple-system, "Segoe UI", sans-serif;
}

.vg-app *, .vg-modal * { box-sizing: border-box; }

/* ---------------- Modal (landscape lightbox) ---------------- */
.vg-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(12px, 3vw, 28px);
  overscroll-behavior: none;
}
/* A tap has to be a jump the instant the finger lands. Without touch-action the
   browser holds the touch back while it decides whether the gesture is a scroll,
   a pinch or a double-tap zoom, which is felt as a missed or late jump. */
.vg-modal__panel, .viking-game__stage, .viking-game__canvas, .vg-hud {
  touch-action: none;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
.vg-modal[hidden] { display: none; }
.vg-modal__scrim {
  position: absolute; inset: 0; background: rgba(0, 8, 20, 0.82);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  animation: vg-fade 200ms ease both;
}
.vg-modal__panel {
  position: relative; z-index: 1;
  width: min(1400px, 96vw, 140vh);   /* the lightbox is the BIG view: on the page it has to beat the inline window */
  aspect-ratio: 3 / 2;
  background: var(--navy); color: var(--ink);
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 40px 120px rgba(0, 6, 20, 0.75);
  overflow: hidden;
  animation: vg-pop 200ms cubic-bezier(.2,.8,.2,1) both;
}
.vg-modal__panel .viking-game__stage { position: absolute; inset: 0; }
.vg-modal__close {
  position: absolute; top: 8px; right: 8px; z-index: 30;
  width: 44px; height: 44px; display: grid; place-items: center;
  background: var(--plate); color: #fff; border: 1px solid rgba(255, 255, 255, 0.3);
  font-size: 24px; line-height: 1; cursor: pointer;
}
.vg-modal__close:hover { background: var(--red); }
@keyframes vg-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes vg-pop { from { opacity: 0; transform: scale(0.965); } to { opacity: 1; transform: none; } }

.viking-game__stage {
  position: relative;
  display: grid;
  place-items: center;
  background: var(--navy-2);
  overflow: hidden;
}
.viking-game__canvas {
  display: block;
  touch-action: none;
  overscroll-behavior: none;
  user-select: none;
  -webkit-user-select: none;
  background: var(--navy-2);
}

/* scoped: the artifact set this on the whole document */
.vg-app :focus-visible, .vg-modal :focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

/* ---------------- Buttons ---------------- */
.vg-btn {
  appearance: none; border: 0; cursor: pointer;
  font-family: var(--font); font-weight: 700; font-size: 17px; line-height: 1.1;
  padding: 14px 22px; min-height: 48px; color: #fff; background: var(--red);
  border-radius: 0; transition: background-color 160ms cubic-bezier(.2,.8,.2,1), transform 160ms;
  text-align: center; text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
.vg-btn:hover { background: var(--red-hover); }
.vg-btn:active { transform: translateY(1px); }
.vg-btn:disabled { opacity: .55; cursor: not-allowed; }
.vg-btn--lg { font-size: 20px; padding: 18px 26px; min-height: 56px; width: 100%; }
.vg-btn--ghost { background: transparent; border: 1px solid rgba(255,255,255,.55); color: #fff; }
.vg-btn--ghost:hover { background: rgba(255,255,255,.12); }
.vg-link {
  color: #fff; text-decoration: underline; font-weight: 700; background: none; border: 0;
  cursor: pointer; font-size: 15px; font-family: inherit; padding: 8px; min-height: 44px;
}
.vg-link:hover { color: var(--gold); }

/* ---------------- Screen overlays ---------------- */
.vg-screen {
  position: absolute; inset: 0; z-index: 20;
  display: flex; flex-direction: column; justify-content: center; gap: 16px;
  padding: 28px 24px; text-align: center;
  background: linear-gradient(180deg, rgba(0,20,45,.92), rgba(0,12,30,.96));
  overflow-y: auto;
}
.vg-screen[hidden] { display: none; }
.vg-screen h2 { color: #fff; font-size: 30px; margin: 0; line-height: 1.1; text-wrap: balance; }
.vg-screen p { color: #eaf1fb; font-size: 16px; margin: 0 auto; max-width: 34ch; line-height: 1.5; }
.vg-eyebrow { color: var(--gold); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; font-size: 13px; }
.vg-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }

/* ---------------- HUD ---------------- */
.vg-hud { position: absolute; inset: 0; z-index: 15; pointer-events: none; padding: 10px; }
.vg-hud[hidden] { display: none; }
.vg-hud__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.vg-hud__plate { background: var(--plate); color: #fff; padding: 6px 12px; border: 1px solid rgba(255,255,255,.22); }
/* The Viking page colours every bare div and p itself, so the plate's white never
   reached these four and they rendered black on navy (the score, its label and the
   level row). Spans inherit normally; these are divs, so say it outright. */
.vg-hud__label, .vg-hud__time, .vg-hud__score, .vg-prog__row { color: #fff; }
/* Same page, same story for size: every span without its own size is set to 17px,
   so the level row (meant to be 10px) wrapped onto two lines and the clock ran large. */
.vg-hud__sub span, .vg-prog__row span { font-size: inherit; line-height: inherit; }
.vg-hud__time { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.vg-hud__sub { font-size: 12px; font-weight: 700; color: #cfe0f5; font-variant-numeric: tabular-nums; display: flex; gap: 8px; align-items: baseline; }
.vg-hud__speed { color: var(--gold); }
.vg-hud__speed--slow { color: #ff8b9d; }
.vg-hud__score { font-size: 24px; font-weight: 700; font-variant-numeric: tabular-nums; }
.vg-hud__label { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; opacity: .85; }
.vg-prog { margin-top: 7px; width: 168px; }
.vg-prog__row { display: flex; justify-content: space-between; gap: 8px; font-size: 10px;
  letter-spacing: .08em; text-transform: uppercase; opacity: .9; margin-bottom: 3px; }
.vg-prog__rail { position: relative; height: 8px; background: rgba(2, 14, 33, .8);
  border: 1px solid rgba(255, 255, 255, .28); }
.vg-prog__fill { position: absolute; top: 0; bottom: 0; left: 0; width: 0%;
  background: linear-gradient(90deg, var(--blue), var(--gold)); transition: width 120ms linear; }
.vg-prog__flag { position: absolute; top: -5px; right: -1px; width: 3px; height: 18px; background: var(--red); }
.vg-hud__combo { font-size: 18px; font-weight: 700; color: var(--gold); transition: transform 140ms cubic-bezier(.2,.8,.2,1); }
.vg-lives { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.vg-lives__cap { font-size: 8px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: #9fb6d0; }
.vg-lives__pips { display: flex; gap: 3px; }
.vg-lives__pip { width: 7px; height: 7px; border-radius: 2px; background: var(--gold);
  box-shadow: 0 0 0 1px rgba(0,0,0,.35); transition: background 160ms linear; }
.vg-lives__pip--spent { background: rgba(255,255,255,.17); box-shadow: none; }
.vg-lives__pips--low .vg-lives__pip:not(.vg-lives__pip--spent) { background: var(--red); }
.vg-hud__combo--pulse { transform: scale(1.25); }
.vg-hud__buttons { display: flex; gap: 6px; pointer-events: auto; }
.vg-hud__btn {
  width: 44px; height: 44px; display: grid; place-items: center;
  background: var(--plate); color: #fff; border: 1px solid rgba(255,255,255,.3);
  cursor: pointer; font-size: 16px;
}
.vg-hud__btn[aria-pressed="true"] { background: var(--blue); }
/* "Sound on!" pointer under the speaker. Its right edge sits 22px right of the
   speaker's centre and the caret sits 22px in from that edge, so the caret lands
   on the speaker at any button size. Same navy pill and gold edge as the jump hint. */
.vg-sound-wrap { position: relative; display: grid; }
.vg-sound-hint {
  position: absolute; top: calc(100% + 11px); right: 50%; transform: translateX(22px);
  white-space: nowrap; margin: 0; padding: 8px 14px; border-radius: 999px; cursor: pointer;
  background: rgb(2, 14, 33); border: 2px solid rgba(242, 184, 75, .9); color: #ffe9b5;
  font: 800 13px/1 Sora, sans-serif; letter-spacing: .05em; text-transform: uppercase;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .4);
  animation: vg-sound-in .28s ease-out both, vg-sound-bob 1.3s ease-in-out .28s infinite;
}
.vg-sound-hint::before {
  content: ''; position: absolute; top: -7px; right: 16px; width: 10px; height: 10px;
  background: rgb(2, 14, 33); border-top: 2px solid rgba(242, 184, 75, .9);
  border-left: 2px solid rgba(242, 184, 75, .9); transform: rotate(45deg);
}
.vg-sound-hint--out { animation: vg-sound-out .3s ease-in forwards; pointer-events: none; }
@keyframes vg-sound-in { from { opacity: 0; transform: translateX(22px) translateY(6px); } to { opacity: 1; transform: translateX(22px) translateY(0); } }
@keyframes vg-sound-bob { 0%, 100% { transform: translateX(22px) translateY(0); } 50% { transform: translateX(22px) translateY(-4px); } }
@keyframes vg-sound-out { to { opacity: 0; transform: translateX(22px) translateY(-6px); } }
@media (max-width: 620px), (max-height: 560px) and (orientation: landscape) {
  .vg-sound-hint { top: calc(100% + 9px); padding: 6px 11px; font-size: 11px; }
}
/* the game-wide reduced-motion rule shortens every animation to 0.001ms, which on an
   infinite bob would jitter, so this one simply holds still */
@media (prefers-reduced-motion: reduce) {
  .vg-sound-hint { animation: none; }
  .vg-sound-hint--out { animation: none; opacity: 0; }
}
/* In full screen on a desktop the pop-up's close button sits in the panel's top
   right corner, which is exactly where the HUD's pause button is: a click on pause
   landed on close. Step the HUD buttons clear of it (44px button + 8px). On a phone
   the close button sits outside the play field, so nothing moves there. */
.vg-modal__panel .vg-hud__buttons { margin-right: 52px; }
@media (max-width: 620px), (max-height: 560px) and (orientation: landscape) {
  .vg-modal__panel .vg-hud__buttons { margin-right: 0; }
}

.vg-thermo {
  position: absolute; left: 12px; bottom: 14px; width: 26px; height: 190px;
  background: var(--plate); border: 1px solid rgba(255,255,255,.28); padding: 4px;
}
.vg-thermo__fill {
  position: absolute; left: 4px; right: 4px; bottom: 4px;
  background: linear-gradient(180deg, var(--blue), #17b26a); transition: height 120ms linear;
}
.vg-thermo__fill--low { background: linear-gradient(180deg, var(--red), #ff6b6b); }
.vg-thermo__cap { position: absolute; top: -10px; left: 0; font-size: 10px; color: #fff; }
/* Both labels hang off the LEFT EDGE of the meter, not its middle. Centred on a
   26px column sitting 12px in, anything wider than 50px runs off the canvas, and
   both of these are wider than that: the C of Comfort and the H of Half points
   were being cut off, worse on a phone where the meter is narrower still.
   Half points sits BESIDE the foot of the meter because it cannot go under it:
   the gap down there is 13px and the badge is 13px tall.
   This rule was moved up from further down the sheet, where it sat AFTER the
   phone media block. A media query carries no extra specificity, so the base
   rule won and this badge's phone overrides had never once applied. */
.vg-thermo__half { position: absolute; bottom: 0; left: calc(100% + 6px);
  font-size: 10px; font-weight: 700; letter-spacing: .06em; color: var(--red); white-space: nowrap; }
.vg-thermo--empty { box-shadow: 0 0 0 2px var(--red); }

/* Phones get the whole screen. The lightbox padding and the panel's 3:2 lock were
   costing about a quarter of the play field, and worse, they left the start and
   finish cards taller than the panel, so on a phone the title and the buttons were
   cropped behind a scrollbar. The panel is now the viewport and the canvas is
   centred inside it, with the HUD pinned to the canvas by resize(). */
@media (max-width: 620px), (max-height: 560px) and (orientation: landscape) {
  .vg-modal { padding: 0; }
  .vg-modal__panel {
    width: 100vw; max-width: 100vw; height: 100vh; height: 100dvh;
    aspect-ratio: auto; border: 0;
  }
}

/* Phone. The HUD is sized in CSS pixels while the play field scales with the
   screen, so on a small canvas the score plate and the Comfort meter swallow the
   game. Everything in the HUD steps down together here. */
@media (max-width: 620px), (max-height: 560px) {
  .vg-hud { padding: 6px; }
  .vg-hud__plate { padding: 4px 8px; }
  .vg-hud__score { font-size: 17px; }
  .vg-hud__time { font-size: 18px; }
  .vg-hud__sub { font-size: 10px; gap: 6px; }
  .vg-hud__label { font-size: 9px; }
  .vg-prog { width: 104px; margin-top: 5px; }
  .vg-prog__row { font-size: 8px; margin-bottom: 2px; }
  .vg-prog__rail { height: 6px; }
  .vg-prog__flag { height: 14px; top: -4px; }
  .vg-hud__combo { font-size: 13px; }
  .vg-lives { gap: 5px; margin-top: 5px; }
  .vg-lives__cap { font-size: 7px; }
  .vg-lives__pips { gap: 2px; }
  .vg-lives__pip { width: 5px; height: 5px; border-radius: 1.5px; }
  .vg-hud__btn { width: 40px; height: 40px; font-size: 15px; }
  .vg-thermo { width: 16px; height: 86px; left: 8px; bottom: 26px; padding: 3px; }
  .vg-thermo__fill { left: 3px; right: 3px; bottom: 3px; }
  .vg-thermo__cap { font-size: 8px; top: -9px; }
  .vg-thermo__half { font-size: 8px; }
}
.vg-fight { position: absolute; left: 0; right: 0; bottom: 12px; display: flex;
  justify-content: space-between; padding: 0 16px; pointer-events: none; z-index: 24; }
.vg-fight[hidden] { display: none; }
.vg-fight__btn { pointer-events: auto; font-family: var(--font); font-weight: 800; font-size: 15px;
  letter-spacing: .1em; color: #fff; background: var(--red); border: 2px solid rgba(255,255,255,.5);
  padding: 12px 26px; cursor: pointer; touch-action: manipulation; box-shadow: 0 6px 18px rgba(0,10,30,.5); }
.vg-fight__btn:active { transform: translateY(2px); }
.vg-fight__btn--magic { background: var(--blue); }
.vg-fight__btn--magic[disabled] { opacity: .4; cursor: default; }
@media (prefers-reduced-motion: no-preference) {
  .vg-thermo--empty .vg-thermo__half { animation: vg-blink 1.1s steps(1, end) infinite; }
}
@keyframes vg-blink { 0%, 60% { opacity: 1; } 61%, 100% { opacity: .25; } }

/* ---------------- Stats / forms / board ---------------- */
.vg-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 4px 0; }
.vg-stat { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.14); padding: 12px; }
.vg-stat__num { font-size: 26px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.vg-stat__label { font-size: 12px; letter-spacing: .05em; text-transform: uppercase; color: #cfe0f5; }
.vg-pb { color: var(--gold); font-weight: 700; font-size: 15px; }
.vg-time { font-size: 44px; font-weight: 800; color: #fff; font-variant-numeric: tabular-nums; line-height: 1; }
.vg-time__label { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: #cfe0f5; margin-top: 4px; }
.vg-prize {
  border: 1px solid rgba(242,184,75,.55); background: rgba(242,184,75,.10);
  padding: 8px 12px; display: flex; flex-direction: column; gap: 1px;
}
.vg-prize__kicker { font-size: 11px !important; letter-spacing: .08em; text-transform: uppercase; color: var(--gold) !important; font-weight: 700; }
.vg-prize__headline { font-size: 17px !important; font-weight: 800; color: #fff !important; line-height: 1.15; }
.vg-prize__by { font-size: 12px !important; color: #e6eefa !important; }
.vg-prize__by a { color: var(--gold); }
/* PORT: the by-line is CMS rich text (Contest -> Prize details), so it arrives as
   <div class="vg-prize__by"><p>...</p></div>; the inner paragraph takes the band's
   size and colour instead of the card/page paragraph rules. */
.vg-prize__by p { margin: 0 !important; max-width: none !important; font-size: inherit !important;
  color: inherit !important; line-height: inherit !important; }

.vg-form { display: flex; flex-direction: column; gap: 12px; text-align: left; }
.vg-field label { display: block; font-size: 13px; font-weight: 700; color: #eaf1fb; margin-bottom: 4px; }
.vg-field input[type="text"], .vg-field input[type="email"], .vg-field input[type="tel"] {
  width: 100%; font-family: var(--font); font-size: 16px; padding: 12px; min-height: 48px;
  background: #fff; color: #141414; border: 1px solid #6b6f6e; border-radius: 0;
}
.vg-consent { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; color: #eaf1fb; line-height: 1.4; }
.vg-consent input { width: 22px; height: 22px; margin-top: 2px; flex: 0 0 auto; }
.vg-error { color: #ffd0d8; background: rgba(187,19,61,.35); border: 1px solid var(--red); padding: 8px 10px; font-size: 14px; }
.vg-note { font-size: 13px; color: #b9cbe4; }

.vg-tabs { display: flex; gap: 6px; justify-content: center; }
.vg-tab { flex: 1; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.2); color: #fff; font-family: inherit; font-weight: 700; font-size: 14px; padding: 10px; min-height: 44px; cursor: pointer; }
.vg-tab[aria-selected="true"] { background: var(--blue); }
.vg-board { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; overflow-y: auto; }
.vg-board li { display: grid; grid-template-columns: 34px 1fr auto; gap: 10px; align-items: center; background: rgba(255,255,255,.05); padding: 10px 12px; color: #fff; font-size: 15px; }
.vg-board li.vg-board__me { background: rgba(0,86,180,.4); border: 1px solid var(--blue); }
.vg-board__rank { font-weight: 700; color: var(--gold); font-variant-numeric: tabular-nums; }
.vg-board__score { font-weight: 700; font-variant-numeric: tabular-nums; }

.vg-note--rotate { color: var(--gold); font-weight: 700; }
.vg-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

@media (prefers-reduced-motion: reduce) {
  .vg-app *, .vg-modal * { transition-duration: .001ms !important; animation-duration: .001ms !important; }
}

/* Narrow screens: the cards carry a lot of words for a 335px column, so the type
   and the spacing come in. Kept beside the short-screen rules for the same reason:
   these have to win over the base card rules declared above them. */
@media (max-width: 620px) {
  .vg-screen { gap: 10px; padding: 18px 16px; }
  .vg-screen h2 { font-size: 24px; }
  .vg-screen p { font-size: 14px; line-height: 1.45; }
  .vg-eyebrow { font-size: 12px; }
  .vg-btn--lg { font-size: 17px; min-height: 50px; padding: 14px 20px; }
  .vg-link { font-size: 14px; min-height: 40px; }
  .vg-prize { padding: 7px 10px; }
  .vg-prize__headline { font-size: 15px !important; }
}
/* Short screens. Last in the sheet on purpose: these have to win over the
   card rules further up, which are declared later than the phone block. */
/* A phone on its side has about 390px of height for a finish card that wants 520,
   so the cards tighten up rather than scroll. */
@media (max-height: 560px) {
  .vg-screen { padding: 10px 14px; gap: 6px; }
  .vg-screen h2 { font-size: 21px; }
  .vg-screen p { font-size: 13px; max-width: 46ch; }
  .vg-eyebrow { font-size: 11px; }
  .vg-stats { gap: 6px; }
  .vg-stat { padding: 6px 8px; }
  .vg-stat__num { font-size: 18px; }
  .vg-stat__label { font-size: 10px; }
  .vg-pb { font-size: 12px; }
  .vg-time { font-size: 25px; }
  .vg-time__label { font-size: 9px; margin-top: 2px; }
  .vg-prize { padding: 4px 8px; }
  .vg-stat { padding: 4px 7px; }
  .vg-prize__headline { font-size: 14px !important; }
  .vg-prize__by, .vg-prize__kicker { font-size: 10px !important; }
  .vg-actions { gap: 6px; margin-top: 2px; }
  .vg-btn { font-size: 15px; padding: 8px 14px; min-height: 40px; }
  .vg-btn--lg { font-size: 16px; padding: 11px 18px; min-height: 44px; }
  .vg-link { font-size: 13px; min-height: 34px; padding: 5px; }
  /* the leaderboard form is the one card with inputs, and on a phone held
     sideways the keyboard takes half of what is left */
  .vg-field { margin-bottom: 2px; }
  .vg-field label { font-size: 11px; margin-bottom: 2px; }
  .vg-field input[type="text"], .vg-field input[type="email"], .vg-field input[type="tel"] { padding: 8px 10px; min-height: 38px; }
  .vg-consent { font-size: 12px; gap: 8px; }
  .vg-consent input { width: 18px; height: 18px; }
  .vg-note { font-size: 11px; }
}
/* the shortest case there is: a phone on its side with a keyboard open */
@media (max-height: 440px) {
  .vg-screen { padding: 7px 12px; gap: 4px; }
  .vg-screen h2 { font-size: 18px; }
  .vg-screen p { font-size: 12px; }
  .vg-time { font-size: 21px; }
  .vg-stat { padding: 3px 6px; }
  .vg-stat__num { font-size: 15px; }
  .vg-prize { padding: 3px 8px; }
  .vg-btn { min-height: 36px; padding: 7px 12px; }
  /* on the shortest screen the card keeps the four things that matter: the time,
     whether it beat your best, the prize, and the buttons */
  .vg-stats { display: none; }
  .vg-btn--lg { font-size: 15px; padding: 8px 14px; min-height: 38px; }
  .vg-field input[type="text"], .vg-field input[type="email"], .vg-field input[type="tel"] { min-height: 34px; padding: 6px 9px; font-size: 15px; }
}

/* ---- Filter Frenzy page ------------------------------------------- */
/* The hero is deliberately NOT the site's hero. Every other Viking page ends its
   hero on the big red V, and that V is what made this page slow to get to: the
   ornament hangs a long way below its own section, so the game window was pushed
   most of a screen down. This one ends on a STRAIGHT red divider and is about a
   third of the height, so the game is the first thing you see. */
.ff-hero { position: relative; overflow: hidden; background: #001437; isolation: isolate; }
.ff-hero__media { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; object-fit: cover; }
.ff-hero__scrim {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, rgba(0,20,55,.58) 0%, rgba(0,20,55,.80) 100%);
}
.ff-hero__inner {
  position: relative; z-index: 2; max-width: 900px; margin: 0 auto;
  padding: 150px 20px 26px;          /* clears the fixed 139px header */
  text-align: center;
}
.ff-hero__title {
  margin: 0; color: #fff; font-weight: 700; line-height: 1.02; letter-spacing: -.01em;
  font-size: clamp(28px, 4vw, 44px);
}
.ff-hero__sub { margin: 10px auto 0; max-width: 560px; color: #dce8f8; font-size: 17px; line-height: 1.5; }
.ff-hero__ctas { display: flex; gap: 14px; justify-content: center; align-items: center; flex-wrap: wrap; margin-top: 16px; }
/* the straight divider: the brand red, flat, no chevron */
.ff-hero__rule {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; height: 7px;
  background: linear-gradient(90deg, var(--color-v-red-deep, #8f0f2c), var(--color-v-red-bright, #e01933) 50%, var(--color-v-red-deep, #8f0f2c));
}
@media (max-width: 900px) { .ff-hero__inner { padding: 138px 20px 24px; } }
@media (max-width: 620px) {
  .ff-hero__inner { padding: 104px 18px 20px; }
  .ff-hero__sub { font-size: 15px; }
  .ff-hero__ctas { gap: 10px; margin-top: 18px; }
}

.ff-section { max-width: 1100px; margin: 0 auto; padding: 0 20px; }
/* straight divider, nothing hanging below it, so this is ordinary band padding */
.ff-play { padding-top: 32px; padding-bottom: 56px; }
@media (max-width: 620px) { .ff-play { padding-top: 34px; padding-bottom: 40px; } }
.ff-head { text-align: center; margin: 0 auto 16px; max-width: 720px; }
/* `.ff-head p` below is (0,1,1) and would otherwise outrank a bare class, which
   is why this eyebrow rendered slate instead of brand red from the first build */
.ff-head p.ff-head__eyebrow { color: #bb133d; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; font-size: 13px; margin: 0 0 6px; }
.ff-head h2 { font-size: clamp(24px, 3.2vw, 32px); margin: 0 0 6px; color: #0b2545; line-height: 1.1; }
.ff-head p { margin: 0; color: #46586f; font-size: 15px; line-height: 1.5; }

.ff-window {
  /* The point of the page is the game, so the whole play field has to be on
     screen when you land. Width is what drives height at a locked 3:2, so the
     window is capped by whatever vertical room is left under the hero and the
     heading, with a floor so it never shrinks to a postage stamp. */
  /* The game and the high-score panel sit side by side and have to finish on
     screen together, so the window is capped by the vertical room left under the
     hero and the heading. Width drives height at a locked 3:2. */
  /* v2 (Austin 2026-11-06): ONE fixed desktop size. The height-driven cap
     (100svh - 500px) shrank the game whenever the viewport got short — a
     docked DevTools panel, a short laptop — so it is gone; 620px wide (413
     tall) sits level with the 394px high-score panel. */
  position: relative; width: 100%; max-width: 620px;
  margin-inline: auto; aspect-ratio: 3 / 2; background: #001629;
  border: 1px solid rgba(0,33,71,.25); box-shadow: 0 30px 80px rgba(0,16,40,.28);
  overflow: hidden;
}
.ff-window .viking-game__stage { position: absolute; inset: 0; }
.ff-window--empty::after {
  content: 'Playing full screen'; position: absolute; inset: 0; display: grid; place-items: center;
  color: #9fb6d4; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; font-size: 13px;
}
.ff-bar { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 12px; flex-wrap: wrap; }
.ff-bar__hint { color: #46586f; font-size: 14px; margin: 0; }
.ff-mini {
  appearance: none; background: #002147; color: #fff; border: 0; cursor: pointer;
  font-family: inherit; font-weight: 700; font-size: 14px; padding: 10px 16px; min-height: 42px;
}
.ff-mini:hover { background: #0056b4; }
.ff-mini--ghost { background: transparent; color: #002147; border: 1px solid rgba(0,33,71,.35); text-decoration: none; display: inline-flex; align-items: center; }
.ff-mini--ghost:hover { background: rgba(0,33,71,.06); color: #002147; }
.ff-bar__actions { display: flex; gap: 10px; flex-wrap: wrap; }
/* v2: "Play full screen" sits centred under the game window, in its column */
.ff-stage-col { min-width: 0; }
.ff-stage-actions { display: flex; justify-content: center; margin-top: 12px; }

/* ---- the stage: game on the left, high scores on the right -------- */
.ff-stage-row { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 20px; align-items: start; justify-content: center; }

/* An arcade high-score board: black glass, fixed-width type, a colour per rank
   counting down the table the way a cabinet does. It is the one place on the page
   allowed to look like a game rather than like the rest of the site. */
.ff-arcade { display: flex; flex-direction: column; gap: 10px; }
.ff-arcade__screen {
  position: relative; background: #05060b; border: 2px solid #1b2740;
  box-shadow: 0 0 0 4px rgba(5,6,11,.9), 0 24px 60px rgba(0,16,40,.4), inset 0 0 60px rgba(0,60,120,.16);
  padding: 16px 14px 14px; overflow: hidden;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;
}
/* CRT scanlines. Static, so reduced motion needs no special case. */
.ff-arcade__screen::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(255,255,255,.045) 0 1px, transparent 1px 3px);
}
.ff-arcade__title {
  margin: 0 0 14px; text-align: center; color: #63e2c6; font-size: 15px; font-weight: 700;
  letter-spacing: .26em; text-transform: uppercase; text-shadow: 0 0 10px rgba(99,226,198,.5);
}
/* fixed px, not em: the header sits at 11px and the rows at 13px, so em columns
   would be two different widths and the header would not line up with the table */
.ff-arcade__cols, .ff-arcade__list li {
  display: grid; grid-template-columns: 56px 62px minmax(0, 1fr); gap: 12px; align-items: baseline;
}
.ff-arcade__cols {
  /* tracking on a 4-letter word in a 56px column pushes its trailing space into
     the next column, which made RANK and TIME read as one word */
  color: #f2c94c; font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  padding-bottom: 8px; margin-bottom: 6px; border-bottom: 1px solid rgba(242,201,76,.28);
}
.ff-arcade__list { list-style: none; margin: 0; padding: 0; }
.ff-arcade__list li {
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase; padding: 4px 0;
  color: var(--row); text-shadow: 0 0 8px color-mix(in oklab, var(--row) 45%, transparent);
}
/* the cabinet ramp: white at the top, down through red, amber, gold, green, cyan */
.ff-arcade__list li:nth-child(1)  { --row: #f4f7ff; }
.ff-arcade__list li:nth-child(2)  { --row: #ff4d4d; }
.ff-arcade__list li:nth-child(3)  { --row: #ff8a3d; }
.ff-arcade__list li:nth-child(4)  { --row: #ffa94d; }
.ff-arcade__list li:nth-child(5)  { --row: #f2c94c; }
.ff-arcade__list li:nth-child(6)  { --row: #e6e14c; }
.ff-arcade__list li:nth-child(7)  { --row: #8fe04c; }
.ff-arcade__list li:nth-child(8)  { --row: #4cd97b; }
.ff-arcade__list li:nth-child(9)  { --row: #46d6c0; }
.ff-arcade__list li:nth-child(10) { --row: #56c8f0; }
.ff-arcade__list li.is-me { background: rgba(86,200,240,.14); outline: 1px solid rgba(86,200,240,.5); }
.ff-arcade__rank, .ff-arcade__time { font-variant-numeric: tabular-nums; }
.ff-arcade__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ff-arcade__empty {
  margin: 0; padding: 26px 8px; text-align: center; color: #6f86a8;
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase; line-height: 1.9;
}
.ff-arcade__empty b { display: block; color: #f2c94c; font-size: 13px; }
#ff-prize { margin-top: 18px; }

/* ---- the cabinet opening itself ----------------------------------- */
/* These come after the game's own modal rules in the same stylesheet, so they
   win on order without needing !important. The flat scrim becomes a lit gradient
   so the pop-up reads as a machine powering up rather than a dialog appearing. */
.vg-modal__scrim {
  background:
    radial-gradient(1100px 680px at 50% 8%, rgba(0, 92, 190, .50), rgba(0, 92, 190, 0) 60%),
    radial-gradient(900px 600px at 50% 104%, rgba(187, 19, 61, .32), rgba(187, 19, 61, 0) 62%),
    linear-gradient(180deg, rgba(0, 14, 36, .93) 0%, rgba(2, 6, 18, .97) 100%);
}
.vg-modal__panel {
  animation: ff-cabinet 440ms cubic-bezier(.16, 1, .3, 1) both;
  box-shadow: 0 40px 120px rgba(0, 6, 20, .75), 0 0 0 1px rgba(120, 180, 255, .16),
              0 0 90px rgba(0, 92, 190, .28);
}
@keyframes ff-cabinet {
  from { opacity: 0; transform: translateY(22px) scale(.90); }
  to   { opacity: 1; transform: none; }
}

/* The inline window is deliberately small so the game and the board finish on
   screen together, and the start and finish cards were written for the full
   screen view, so inside the window they get a tighter setting. Without this the
   card scrolls inside the frame, which is the one thing this layout is for. */
.ff-window .vg-screen { padding: 14px 16px; gap: 7px; }
.ff-window .vg-screen h2 { font-size: 20px; }
.ff-window .vg-screen p { font-size: 12.5px; line-height: 1.4; max-width: 40ch; }
.ff-window .vg-eyebrow { font-size: 10px; }
.ff-window .vg-prize { padding: 5px 9px; }
.ff-window .vg-prize__headline { font-size: 13px !important; }
.ff-window .vg-prize__kicker, .ff-window .vg-prize__by { font-size: 9.5px !important; }
.ff-window .vg-time { font-size: 26px; }
.ff-window .vg-stats { display: none; }
.ff-window .vg-actions { gap: 6px; margin-top: 2px; }
.ff-window .vg-btn--lg { font-size: 15px; min-height: 40px; padding: 9px 14px; }
.ff-window .vg-link { font-size: 12px; min-height: 30px; padding: 4px; }
/* the board is right beside the window now, so the card does not need a link to
   it, and the closing note repeats what the page already says above the game */
.ff-window #s-board { display: none; }
.ff-window .vg-screen .vg-note:not(.vg-note--rotate) { display: none; }

/* v2: the max-height:800px block that shrank the window and its card copy on
   short screens is removed — the window is one fixed size (see .ff-window). */
#ff-prize .vg-prize { background: rgba(242,184,75,.16); border-color: rgba(187,19,61,.35); }
#ff-prize .vg-prize__kicker { color: #bb133d !important; }
#ff-prize .vg-prize__headline { color: #0b2545 !important; }
#ff-prize .vg-prize__by { color: #46586f !important; }
#ff-prize .vg-prize__by a { color: #0056b4; }

@media (max-width: 900px) {
  .ff-stage-row { grid-template-columns: minmax(0, 1fr); }
  .ff-window { max-width: 100%; }
  .ff-arcade { max-width: 520px; width: 100%; margin-inline: auto; }
}
@media (max-width: 620px) {
  .ff-hero__ctas .btn { width: 100%; }
  /* a 3:2 window is only 260px tall on a phone, which is not enough for the start
     and finish cards, so the box grows and the play field centres inside it */
  .ff-window { aspect-ratio: auto; height: min(720px, 84vh); }
  .ff-window.is-playing { height: auto; aspect-ratio: 3 / 2; }
}

/* PORT (new): optional Contest -> Rules / fine print, under the prize band. */
.ff-rules { margin-top: 14px; color: #46586f; font-size: 12px; line-height: 1.55; }
.ff-rules p { margin: 0 0 6px; font-size: inherit; color: inherit; line-height: inherit; }
.ff-rules a { color: #0056b4; }

/* Port fixes (QA #14, #3) */
/* The artifact's host page hid [hidden] globally; .vg-btn's display:flex overrode it here. */
[class*="vg-"][hidden], [class*="ff-"][hidden] { display: none !important; }
/* By-line is rich text (div > p) here, not the artifact's bare <p>: restore its spacing + measure. */
.vg-prize__headline:has(+ .vg-prize__by) { margin-bottom: 16px; }
.vg-prize__by { margin-top: 12px; }
.vg-prize__by > p { margin: 0; max-width: none; color: inherit; font-size: inherit; line-height: inherit; }
.vg-screen .vg-prize__by { max-width: 34ch; margin: 0 auto; line-height: 1.5; }
.vg-screen .vg-prize__headline:has(+ .vg-prize__by) { margin-bottom: 0; }
