/* Base layout (Phase 3 Agent LAYOUT owns css/*).
   The two chrome bars (#hud, #ability-bar) are fixed to the viewport edges.
   The canvas renders behind the bottom chrome so the scene reads as continuous;
   gameplay placement still reserves the bar height in js/config.js. */
* { box-sizing: border-box; }

:root {
  /* Phase 4 (Agent LAYOUT): FLUID bar heights (content only; safe-area insets are
     ADDED below so the bars grow to clear notches / the home indicator, and the
     canvas inset matches). Sized from BOTH viewport width and height via
     min(vw, vh): tall phones get roomy bars, while short / landscape viewports
     compress instead of eating the whole play area. Combined bars stay ~<=25% of
     viewport height on phones and <=20% on desktop (see the matrix in the handoff).
     The Phaser canvas auto-follows any change here via SCALE's ResizeObserver. */
  --hud-h: clamp(66px, min(23vw, 11.5vh), 100px);
  --ability-h: clamp(130px, min(34vw, 24vh), 244px);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --bar-top: calc(var(--hud-h) + var(--safe-top));           /* total top-bar height */
  --bar-bottom: calc(var(--ability-h) + var(--safe-bottom)); /* total bottom-bar height */
}

/* Short viewports (landscape phones, split-screen, ~<=520px tall): shrink the
   bars hard so the canvas keeps a usable band. SCALE drops to its compact sprite
   mode below a 320px canvas; smaller bars help stay above that threshold. */
@media (max-height: 520px) {
  :root {
    --hud-h: clamp(42px, 11vh, 66px);
    --ability-h: clamp(92px, min(29vw, 22vh), 138px);
  }
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background:
    radial-gradient(circle at 50% -10%, rgba(43, 220, 255, 0.2), transparent 34%),
    radial-gradient(circle at 18% 18%, rgba(168, 93, 255, 0.16), transparent 28%),
    linear-gradient(180deg, #030711 0%, #071027 42%, #05040e 100%);
  font-family: 'Baloo 2', 'Nunito', 'Trebuchet MS', system-ui, sans-serif;
  color: #eef0ff;
  overflow: hidden;
  /* Mobile: kill page scroll/bounce, pinch/double-tap zoom, and the tap flash. */
  overscroll-behavior: none;
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  /* Fill the visual viewport including behind notches; svh handles mobile URL bars. */
  width: 100%;
  width: 100vw;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(115deg, transparent 0 23px, rgba(255, 255, 255, 0.025) 24px 25px),
    radial-gradient(circle at 50% 112%, rgba(30, 212, 255, 0.16), transparent 34%);
  opacity: 0.7;
}

body {
  /* Prefer the small viewport height so the layout doesn't jump when the mobile
     browser chrome shows/hides; fall back to 100% for older engines. */
  height: 100svh;
  height: 100dvh;
}

html.high-contrast-mode {
  --ssm-ink: #ffffff;
}
html.high-contrast-mode .hud-bar,
html.high-contrast-mode .ability-row { filter: contrast(1.16) saturate(1.12); }
html.high-contrast-mode .trivia-question,
html.high-contrast-mode .trivia-answer-text,
html.high-contrast-mode .result-sub { text-shadow: 0 2px 6px #000, 0 0 2px #000; }
html.large-text-mode { font-size: 112.5%; }
html.large-text-mode .trivia-question { font-size: clamp(21px, 5.4vw, 33px); }
html.large-text-mode .trivia-answer-text { font-size: clamp(16px, 4vw, 22px); }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: .01ms !important; }
}
html.prefers-reduced-motion *, html.prefers-reduced-motion *::before, html.prefers-reduced-motion *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }

/* Phase 4 (Agent SCALE): the game is RESPONSIVE — no aspect-ratio lock and no
   letterboxing. #game-root is the full visual viewport; the top chrome reserves
   space, while the Phaser canvas extends behind the bottom chrome so the art
   continues to the ability controls. */
#game-root {
  position: fixed;
  inset: 0;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  /* No long-press callout / text selection / image drag anywhere in the game
     shell (both are inherited, so this cascades to the HUD, bars and canvas). */
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
}

/* The play surface starts below the HUD and extends behind the bottom ability
   rail. Gameplay anchors subtract the live rail height, but the backdrop keeps
   painting behind the controls so there is no dead band. */
#phaser-container {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--bar-top);
  bottom: 0;
}
/* Kill ALL native touch gestures on the play surface (double-tap zoom, pinch,
   pull-to-refresh / rubber-band) so every touch is a clean game input. Explicit
   on the canvas itself (not just the #game-root ancestor) for engines that only
   honour touch-action on the direct touch target. GameScene toggles the cursor
   to `pointer` over tappable cats; default the rest of the time. */
#phaser-container,
#phaser-container canvas {
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
}
#phaser-container canvas {
  width: 100% !important;
  height: 100% !important;
  display: block;
  cursor: default;
}

/* The two chrome bars only ever receive taps (never scroll): `manipulation`
   removes the legacy 300ms tap delay and double-tap zoom while keeping taps
   instant, and nothing in them is selectable or long-press-callout-able. */
#hud,
#ability-bar {
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.overlay {
  pointer-events: none; /* interactive children must set pointer-events: auto */
}

/* Modal/announcement layers cover the WHOLE viewport (over the bars too) so a
   trivia modal or a title/game-over screen fully occludes the fixed chrome. */
#toast-layer,
#trivia-layer,
#screen-layer {
  position: fixed;
  inset: 0;
}

/* #hud spans the full reserved top band (var(--bar-top), incl. safe-area). The
   actual raster frame (.hud-bar) is width-capped + centered inside it by
   screens.css, and carries the container context so its % children track the
   frame — not the whole viewport — at every size. */
#hud {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--bar-top);
}

/* #ability-bar is ABSOLUTE inside the aspect-locked #game-root container. */
#ability-bar {
  position: absolute;
  left: 0;
  right: 0;
  top: auto;
  bottom: 0;
  height: var(--bar-bottom);
}

/* Layer stacking: hud/ability under toast, trivia above, full screens on top */
#hud          { z-index: 10; }
#ability-bar  { z-index: 11; }
#toast-layer  { z-index: 20; }
#trivia-layer { z-index: 30; }
#screen-layer { z-index: 40; }

/* ---- Rotate-to-portrait prompt ------------------------------------------
   Portrait is the only designed orientation. On a phone held sideways the
   trivia panel is taller than the viewport and clips its first line off the
   top, so the question cannot be read. Rather than covering the broken layout
   with a second layout, cover it with a request to turn the device back.

   EVERYTHING except the visibility switch is declared here, unconditionally.
   The media query below carries exactly one declaration — `display: flex` —
   which makes the gate auditable on its own and keeps the geometry, colour and
   motion rules measurable at any viewport.

   The gate has three clauses and all three are load-bearing:

     orientation: landscape  Height alone is not enough. A portrait phone with
                             the software keyboard raised can fall under 520px
                             tall, and telling a player who is already upright
                             to turn upright is worse than saying nothing.
     max-height: 520px       The repo's existing short-viewport breakpoint
                             (see :root above, css/trivia.css, css/screens.css)
                             — the same threshold at which the bars, the trivia
                             modal and the title screen already switch to their
                             compact treatment. Reused rather than reinvented so
                             there is one definition of "short" to keep in sync.
                             It also excludes tablets: an iPad is 768px tall in
                             landscape and 1024px on the larger models.
     pointer: coarse         The desktop guard, and the only clause that can do
                             that job. Desktop is landscape by definition, so a
                             size-only query would cover the game for every
                             desktop player who narrows their window; no
                             width/height/aspect combination separates a phone
                             held sideways from a short desktop window. Primary
                             input does. `pointer` (not `any-pointer`) is
                             deliberate: `any-pointer: coarse` is true on a
                             touchscreen laptop, and this must fail towards
                             staying hidden.

   There is no dismiss control, and that is a choice, not an omission:

     - Being script-free is what guarantees criterion 3. A dismiss needs state,
       state needs to be cleared on rotation, and a stale dismissed flag is the
       one way this overlay could show or hide at the wrong moment.
     - Dismissing would land the player on the layout the owner confirmed is
       unreadable, so it is not an escape to anywhere.
     - iOS rotation lock locks to portrait, which is the good state, so the
       obvious "cannot rotate" case does not produce a trap.

   The residual — a player whose device is physically fixed in landscape has no
   way past this — is real and recorded in MASTER_HANDOFF.md section 8 for the
   landscape design pass that will resolve it properly. */
#rotate-prompt {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 100; /* above #help-layer (70), the highest layer in the app */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Covers under the notch and the home indicator: fixed/inset-0 already spans
     the whole viewport because index.html sets viewport-fit=cover, and the
     insets keep the copy out from under the hardware. */
  padding:
    calc(14px + env(safe-area-inset-top, 0px))
    calc(18px + env(safe-area-inset-right, 0px))
    calc(14px + env(safe-area-inset-bottom, 0px))
    calc(18px + env(safe-area-inset-left, 0px));
  /* Opaque: the linear gradient underneath the tint has no alpha, so no part of
     the clipped layout shows through at any edge. */
  background:
    radial-gradient(circle at 50% 24%, rgba(43, 220, 255, 0.18), transparent 62%),
    linear-gradient(180deg, #030711 0%, #071027 46%, #05040e 100%);
  color: #eef0ff;
  text-align: center;
  overscroll-behavior: none;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* The one visibility gate. Nothing else belongs in this block. */
@media (orientation: landscape) and (max-height: 520px) and (pointer: coarse) {
  #rotate-prompt { display: flex; }
}

.rotate-prompt-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(6px, 2.2vh, 14px);
  max-width: min(30em, 92vw);
  animation: rotate-prompt-rise 320ms ease-out both;
}

.rotate-prompt-icon {
  width: clamp(40px, 13vh, 62px);
  height: clamp(40px, 13vh, 62px);
  color: var(--kuriosi-cyan, #35dfff);
  animation: rotate-prompt-turn 2.6s ease-in-out infinite;
}

.rotate-prompt-title {
  margin: 0;
  font-family: var(--kuriosi-ui-font, 'Trebuchet MS', system-ui, sans-serif);
  font-size: clamp(19px, 5.6vh, 26px);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--kuriosi-gold-hot, #ffe08a);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7);
}

.rotate-prompt-body {
  margin: 0;
  font-size: clamp(14px, 3.8vh, 17px);
  line-height: 1.42;
  color: #cfd6ff;
}

@keyframes rotate-prompt-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes rotate-prompt-turn {
  0%, 62%, 100% { transform: rotate(0deg); }
  30%           { transform: rotate(-88deg); }
}

/* Reduced motion: no animated entrance and no looping turn. The icon is parked
   at the sideways angle it would otherwise animate through, so it still reads
   as "this is the wrong way round" without moving. base.css already clamps
   every animation globally, but that leaves a one-frame entrance; these rules
   remove the animations outright, for both the OS preference and the in-app
   html.prefers-reduced-motion setting. */
@media (prefers-reduced-motion: reduce) {
  .rotate-prompt-card { animation: none; }
  .rotate-prompt-icon { animation: none; transform: rotate(-88deg); }
}
html.prefers-reduced-motion .rotate-prompt-card { animation: none; }
html.prefers-reduced-motion .rotate-prompt-icon { animation: none; transform: rotate(-88deg); }

/* Large-text mode raises the root font size, which the viewport-relative clamps
   above cannot see, so restate the copy in em. */
html.large-text-mode .rotate-prompt-title { font-size: 1.5em; }
html.large-text-mode .rotate-prompt-body { font-size: 1.05em; }

/* High contrast: flat background instead of the gradient, and ink over tint. */
html.high-contrast-mode #rotate-prompt {
  background: #000208;
}
html.high-contrast-mode .rotate-prompt-title { color: #ffffff; }
html.high-contrast-mode .rotate-prompt-body { color: #ffffff; }
html.high-contrast-mode .rotate-prompt-icon { color: #ffffff; }

/* Shared premium screen chrome. Launch, game screens, and meta panels use one
   material language without changing their runtime contracts.
   Phase 1 polish: design tokens — spacing, radii, type, interaction. Screens,
   trivia, and meta should prefer these over one-off literals. */
:root {
  --kuriosi-lacquer: #030812;
  --kuriosi-lacquer-raised: #081426;
  --kuriosi-gold: #d9a23d;
  --kuriosi-gold-hot: #ffe08a;
  --kuriosi-cyan: #35dfff;
  --kuriosi-cyan-soft: #bff8ff;
  --kuriosi-danger: #ff4d36;
  --kuriosi-screen-shadow: 0 28px 80px rgba(0, 0, 0, 0.82);
  --kuriosi-ui-font: 'Trebuchet MS', 'Arial Narrow', system-ui, sans-serif;

  /* Spacing scale (8pt) */
  --k-space-1: 4px;
  --k-space-2: 8px;
  --k-space-3: 12px;
  --k-space-4: 16px;
  --k-space-5: 24px;
  --k-space-6: 32px;

  /* Radii family — prefer these four over ad-hoc corners */
  --k-radius-sm: 6px;
  --k-radius-md: 12px;
  --k-radius-lg: 18px;
  --k-radius-pill: 999px;

  /* Type scale */
  --k-type-xs: clamp(10px, 2.4vw, 12px);
  --k-type-sm: clamp(12px, 3vw, 14px);
  --k-type-md: clamp(14px, 3.4vw, 17px);
  --k-type-lg: clamp(18px, 4.2vw, 24px);
  --k-type-xl: clamp(24px, 6vw, 36px);
  --k-type-display: clamp(32px, 8vw, 54px);

  /* Interaction */
  --k-press-ms: 90ms;
  --k-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --k-ease-spring: cubic-bezier(0.2, 1.45, 0.35, 1);
  --k-touch-min: 48px;
  --k-touch-floor: 44px;
  --k-btn-min-height: 56px;
  --k-btn-radius: var(--k-radius-sm);
  --k-btn-pad-y: 13px;
  --k-btn-pad-x: 34px;

  /* Elevation — multi-layer emboss: outer drop, edge glow, dark rail, top specular, bottom shelf */
  --k-shadow-btn:
    0 10px 24px rgba(0, 0, 0, 0.62),
    0 2px 0 rgba(255, 232, 170, 0.14),
    0 0 20px rgba(255, 78, 48, 0.22),
    inset 0 0 0 2px rgba(22, 3, 6, 0.88),
    inset 0 1px 0 rgba(255, 248, 214, 0.52),
    inset 0 2px 6px rgba(255, 210, 120, 0.12),
    inset 0 -5px 0 rgba(12, 1, 4, 0.48);
  --k-shadow-btn-primary:
    0 12px 30px rgba(0, 0, 0, 0.68),
    0 2px 0 rgba(255, 236, 180, 0.18),
    0 0 28px rgba(255, 70, 43, 0.42),
    0 0 14px rgba(255, 204, 74, 0.28),
    inset 0 0 0 2px rgba(36, 5, 8, 0.88),
    inset 0 1px 0 rgba(255, 248, 214, 0.58),
    inset 0 2px 8px rgba(255, 200, 90, 0.16),
    inset 0 -5px 0 rgba(16, 2, 4, 0.55);
  --k-shadow-btn-secondary:
    0 9px 24px rgba(0, 0, 0, 0.6),
    0 1px 0 rgba(180, 245, 255, 0.14),
    0 0 20px rgba(53, 223, 255, 0.2),
    inset 0 0 0 2px rgba(0, 3, 10, 0.9),
    inset 0 1px 0 rgba(200, 250, 255, 0.32),
    inset 0 2px 6px rgba(53, 223, 255, 0.08),
    inset 0 -4px 0 rgba(0, 2, 8, 0.45);
  --k-shadow-panel: 0 22px 66px rgba(0, 0, 0, 0.74);

  /* Screen / panel vertical rhythm (Phase 2) */
  --k-screen-pad-y: var(--k-space-5);
  --k-screen-pad-x: var(--k-space-4);
  --k-screen-gap: var(--k-space-3);
  --k-screen-gap-tight: var(--k-space-2);
  --k-screen-radius: var(--k-radius-lg);

  /* Phase 3 press + overlay motion */
  --k-press-scale: 0.98;
  --k-overlay-exit-ms: 180ms;

  /* Phase 4 — glow budget (one dominant glow per HUD region) */
  --k-glow-soft: 0 0 10px rgba(53, 223, 255, 0.22);
  --k-glow-strong: 0 0 18px rgba(53, 223, 255, 0.48);
  --k-glow-gold: 0 0 14px rgba(255, 200, 87, 0.42);
  --k-type-kicker: clamp(9px, 2.2vw, 11px);
  --k-type-kicker-track: 0.14em;
}

/* Reward chips fly from trivia / playfield toward the HUD score plate. */
.k-reward-fly {
  position: fixed;
  z-index: 90;
  margin: 0;
  padding: 0;
  pointer-events: none;
  font-family: var(--kuriosi-ui-font, 'Trebuchet MS', system-ui, sans-serif);
  font-weight: 900;
  font-size: clamp(18px, 4.6vw, 28px);
  letter-spacing: 0.02em;
  color: #ffe28a;
  text-shadow:
    0 2px 0 rgba(58, 18, 8, 0.92),
    0 0 18px rgba(255, 200, 80, 0.72);
  will-change: transform, opacity;
  transition:
    transform 420ms var(--k-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    opacity 420ms var(--k-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}
@media (prefers-reduced-motion: reduce) {
  .k-reward-fly { display: none !important; }
}
html.prefers-reduced-motion .k-reward-fly { display: none !important; }
