/* ============================================================
   game-realism-v4.css — competitive-tier UX + realism shell
   Benchmarks: Celeste (readability), Alto (atmosphere),
   Neko Atsume (pet clarity), Oregon Trail remakes (trail UI),
   Stray (lighting volume)

   Presentation only. This file must never move, resize or
   re-parent a control that a game already owns — several of the
   playables dock their own pad as a flex child of the play frame
   (fever #pad, nursery .pad action row, alleycat .pad, climb
   .padbar) and pulling those out of flow breaks their layout.
   So: existing pads get polish and bigger tap targets in place;
   only #grVirtualPad (which this pack creates) is positioned.
   ============================================================ */

:root {
  --gr-ink: #0c0a08;
  --gr-panel: #14110e;
  --gr-stock: #F2E8D5;
  --gr-sepia: #D4B483;
  --gr-fisik: #8FA366;
  --gr-soot: #5A5044;
  --gr-danger: #D48474;
  --gr-ok: #8FA366;
  --gr-tap: clamp(56px, 15vw, 72px);
  --gr-pad-gap: 0.5rem;
}

/* ---- Full-bleed play stage ----------------------------------
   The play-frame block each page already ships sets position,
   inset and overflow. Only the backdrop is added here, and
   without !important so a game that has committed to its own
   palette (fever's #17121F night) keeps it.
   ------------------------------------------------------------ */
html.play-frame body {
  background:
    radial-gradient(ellipse 100% 70% at 50% -10%, #3a2e22 0%, transparent 55%),
    radial-gradient(ellipse 80% 50% at 80% 100%, #1a1510 0%, transparent 45%),
    linear-gradient(180deg, #1a1410 0%, #0c0a08 40%, #070605 100%);
}

/* Sky wash behind the canvas (Alto-like depth) */
.gr-sky {
  pointer-events: none;
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    linear-gradient(180deg,
      #2c4a5e 0%,
      #5a6e7a 18%,
      #c4a882 42%,
      #8a6a4a 62%,
      #2a2018 100%);
  opacity: 0.22;
  mix-blend-mode: soft-light;
}
html[data-game="fever-walk"] .gr-sky { opacity: 0.28; }
html[data-game="climb"] .gr-sky {
  background: linear-gradient(180deg, #1a2030 0%, #3a4558 25%, #b08968 55%, #2a1810 100%);
  opacity: 0.26;
}
html[data-game="nursery"] .gr-sky {
  background: linear-gradient(180deg, #2a2420 0%, #4a3a30 40%, #1a1210 100%);
  opacity: 0.18;
}

.gr-vignette {
  pointer-events: none;
  position: absolute;
  inset: 0;
  z-index: 8;
  background:
    radial-gradient(ellipse at 50% 45%, transparent 35%, rgba(0,0,0,.42) 100%),
    linear-gradient(180deg, rgba(12,10,8,.25) 0%, transparent 20%, transparent 70%, rgba(6,4,3,.55) 100%);
}
.gr-grain {
  pointer-events: none;
  position: absolute;
  inset: 0;
  z-index: 9;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
html.sk-film-paused .gr-grain,
html.sk-reduce-motion .gr-grain { opacity: 0.025; }

@media (prefers-reduced-motion: reduce) {
  .gr-grain { opacity: 0.02; }
}

/* ---- Canvas grade (Stray / Celeste readability) ---- */
html.play-frame canvas {
  position: relative;
  z-index: 1;
  filter: contrast(1.08) saturate(0.9) brightness(1.04);
}
html.play-frame.gr-cat-boost canvas {
  filter: contrast(1.12) saturate(0.92) brightness(1.07);
}

/* ---- HUD — Celeste-clean ---- */
#hud, .hud, .gr-hud {
  z-index: 25;
}
#hud .chip, .hud .chip, .gr-chip, .hud-chip {
  background: rgba(10, 8, 6, 0.82);
  border: 1px solid rgba(212, 180, 131, 0.35);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-radius: 3px;
  color: var(--gr-stock);
  box-shadow: 0 4px 14px rgba(0,0,0,.4);
}
/* Blur over a canvas that repaints every frame is the single most
   expensive thing on this page on iOS. Drop it where the stage is
   full-bleed and the frame budget actually matters. */
@media (max-width: 900px), (pointer: coarse) {
  #hud .chip, .hud .chip, .gr-chip, .hud-chip {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(10, 8, 6, 0.9);
  }
}
#hud .tiny, .hud .tiny, .gr-chip .tiny {
  color: var(--gr-sepia);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
#tempread, #score, .lvlname {
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 3px rgba(0,0,0,.9);
}

/* ---- Objective strip -----------------------------------------
   Scoped to .gr-obj only. sk-phase3.css owns .sk-obj-strip for the
   Climb and Alley Cat strips and lays them inline on purpose;
   restyling that selector here would float them over the picture.
   ------------------------------------------------------------ */
.gr-obj {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: max(0.5rem, env(safe-area-inset-top, 0px));
  max-width: calc(100% - 1.5rem);
  z-index: 30;
  pointer-events: none;
  padding: 0.35rem 0.6rem;
  border-radius: 2px;
  background: rgba(10,8,6,.88);
  border: 1px solid rgba(212,180,131,.5);
  color: var(--gr-sepia);
  box-shadow: 0 6px 20px rgba(0,0,0,.45);
  font-family: "Space Mono", ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  animation: gr-obj-in 0.5s ease 0.4s forwards, gr-obj-out 0.6s ease 6s forwards;
}
@keyframes gr-obj-in  { from { opacity: 0; transform: translate(-50%, -6px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes gr-obj-out { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .gr-obj { animation: none; opacity: 1; }
}

/* ---- Touch controls ----------------------------------------
   In-place polish only. No position, no display, no width —
   each game keeps the pad layout it shipped with.
   ------------------------------------------------------------ */
#pad, .pad, .padbar, .touch-pad, .gr-pad {
  z-index: 50;
  padding-bottom: max(0.5rem, env(safe-area-inset-bottom, 0px));
  box-sizing: border-box;
}
#pad .btn, #pad button,
.pad .btn, .pad button,
.padbar button,
.touch-pad button,
.gr-pad button {
  min-height: var(--gr-tap);
  border: 1.5px solid rgba(212,180,131,.75);
  background:
    radial-gradient(circle at 35% 30%, rgba(255,236,200,.12), transparent 50%),
    rgba(18,14,10,.88);
  color: var(--gr-stock);
  font-family: "Space Mono", ui-monospace, monospace;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  box-shadow:
    0 0 0 1px rgba(0,0,0,.65),
    0 8px 18px rgba(0,0,0,.5),
    inset 0 1px 0 rgba(255,236,200,.15);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}
#pad .btn.jump, #pad .jump,
.pad #ac-jump, .padbar #pad-jump, .btn.jump {
  border-color: rgba(143,163,102,.85);
  color: #c5d4a8;
}
#pad .btn.meow, #pad .meow, .btn.meow {
  border-color: rgba(212,180,131,.9);
}
#pad .btn:active, #pad button:active,
.pad button:active, .padbar button:active {
  transform: scale(0.96);
  background: rgba(212,180,131,.28);
}

/* Fever docks its pad as a flex child and hides it with .hide
   (visibility) until play begins. Keep that contract — only make
   sure the shown state really shows. */
#pad.gr-force-on {
  visibility: visible;
  opacity: 1;
}

/* ---- Virtual pad — created by this pack, so fully owned here.
   Only ever injected when a game ships no pad of its own. ---- */
#grVirtualPad {
  display: flex;
  z-index: 50;
  position: absolute;
  left: 0; right: 0; bottom: 0;
  justify-content: space-between;
  padding: 0.65rem 0.85rem;
  padding-bottom: max(0.75rem, env(safe-area-inset-bottom, 0px));
  pointer-events: none;
  background: linear-gradient(180deg, transparent, rgba(6,4,3,.75));
}
#grVirtualPad .grp { display: flex; gap: var(--gr-pad-gap); pointer-events: auto; }
#grVirtualPad button {
  width: var(--gr-tap);
  height: var(--gr-tap);
  border-radius: 999px;
  border: 1.5px solid rgba(212,180,131,.75);
  background: rgba(18,14,10,.88);
  color: var(--gr-stock);
  font-family: "Space Mono", ui-monospace, monospace;
  font-size: 14px;
  font-weight: 700;
  pointer-events: auto;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}
#grVirtualPad button:active {
  background: rgba(212,180,131,.28);
  transform: scale(0.96);
}

/* ---- Menus / cards ------------------------------------------
   Structure only. Panel copy is injected as arbitrary HTML by
   several games and some of it carries its own colours, so the
   background and text colour are left to the game — forcing a
   dark panel is how you get dark text on dark card.
   ------------------------------------------------------------ */
#card .panel, .gr-menu {
  border-radius: 3px;
  box-shadow: 0 16px 40px rgba(0,0,0,.55);
}
#card button, .panel button, .menu button {
  min-height: 44px;
}

/* ---- Nursery — action row clarity (Neko Atsume) ---- */
html[data-game="nursery"] .pad button,
html[data-game="nursery"] .act {
  min-height: 48px;
  min-width: 48px;
  border-color: rgba(212,180,131,.4);
}
html[data-game="nursery"] .sk-need-critical {
  box-shadow: 0 0 0 1px var(--gr-danger), 0 0 14px rgba(212,132,116,.45);
}

/* ---- Trail / Long Road (already dark stock, safe to grade) ---- */
.trail-card, .mile-card, .event-card, .choice {
  border: 1px solid rgba(212,180,131,.35);
  background: linear-gradient(180deg, #1a1511, #100c0a);
  color: var(--gr-stock);
}

/* ---- Operator ---- */
html[data-game="operator"] canvas {
  filter: contrast(1.14) saturate(0.82) brightness(1.05);
}

/* ---- Intertitle loading ---- */
.gr-intertitle {
  font-family: Fraunces, Georgia, serif;
  color: var(--gr-sepia);
  text-align: center;
  letter-spacing: 0.08em;
}
