/* Game Integration Styles 🎮 - CLEAN VERSION */

/* ===== FULLSCREEN GAME BACKGROUND ===== */
.game-background {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: -1;
  pointer-events: none;
  opacity: 0; /* Start hidden to prevent FOUC */

  /* grass, like the page */
  background-color: #384535; /* Fallback colour */
  background-image: url('/game-assets/grass-tile-bg.png'); /* matches the game's grass texture */
  background-repeat: repeat;
  background-size: 32px 32px; /* Game displays at 32x32 (scaled from 16x16) */
  image-rendering: pixelated; /* Crisp pixel art rendering */
  image-rendering: -moz-crisp-edges;
  image-rendering: crisp-edges;

  transition: opacity 0.6s ease-in; /* Smooth fade-in when loaded */
}

/* Game loaded state - fade in smoothly */
.game-background.game-loaded {
  opacity: 1;
}

/* Clean canvas styling - no important overrides */
.game-background canvas {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* Game disabled state - use visibility instead of display to maintain layout */
.game-background.game-disabled {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

/* Ensure game is visible when not disabled */
.game-background:not(.game-disabled) {
  visibility: visible;
  opacity: 1;
}

/* Game active state (when Konami mode is enabled) */
.game-background.game-active {
  z-index: 1000;
  pointer-events: auto;
}

/* ===== KONAMI GAME MODE ===== */
/* Hide main site content when in game mode */
.site-container {
  opacity: 1;
  transition: opacity 0.75s ease;
}

/* In play the page behind the game does not scroll: its scrollbar drew over the right edge of the game, and a
   mouse wheel scrolled the hidden page (600 px a turn), so leaving play put the visitor somewhere else. The page keeps
   its place underneath and is exactly where it was on the way back. */
html:has(body.konami-mode) {
  overflow: hidden;
}

body.konami-mode .site-container {
  opacity: 0;
  pointer-events: none;
}

body.konami-mode .theme-toggle,
body.konami-mode .accessibility-toggle {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.75s ease;
}

/* Show game UI when in Konami mode */
body.konami-mode .game-ui {
  display: block;
}

/* Game UI container (hidden by default) */
.game-ui {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 2000;
  pointer-events: none;
}

/* Character stats in top-left during game mode */
.game-ui .character-stats {
  position: absolute;
  top: 20px;
  left: 20px;
  background: var(--colour-bg-secondary);
  border: var(--border-main);
  border-radius: 8px;
  padding: var(--spacing-md);
  box-shadow: var(--shadow-main);
  pointer-events: auto;
}

.game-ui .character-portrait {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  margin-bottom: var(--spacing-sm);
}

.game-ui .character-portrait img {
  width: 48px;
  height: 48px;
  border: 1px solid var(--colour-border-light);
  background-color: var(--colour-highlight-bg);
}

.game-ui .character-info {
  color: var(--colour-text-primary);
  font-family: var(--font-family-serif);
}

.game-ui .character-name {
  font-weight: bold;
  font-size: 1.1rem;
  margin-bottom: 4px;
}

.game-ui .character-level {
  font-size: 0.9rem;
  color: var(--colour-text-secondary);
  margin-bottom: 8px;
}

/* Exit hint */
.game-ui .exit-hint {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  /* With left: 50% the shrink-to-fit width is capped at half the container, which wrapped the
     hint below ~1200px; size it to its content instead. */
  width: max-content;
  max-width: calc(100vw - 40px);
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: var(--spacing-sm) var(--spacing-md);
  border-radius: 4px;
  font-family: var(--font-family-mono);
  font-size: 0.9rem;
  /* Own keyframe name: a global `pulse` elsewhere animates transform (scale), and an animation
     overrides the transform property, which threw away the translateX(-50%) centring. */
  animation: exit-hint-pulse 2s infinite;
}

/* a gentle pulse that never dims the words below 0.85 (5.1:1): at 0.7 its trough was 3.7:1 */
@keyframes exit-hint-pulse {
  0%, 100% { opacity: 0.85; }
  50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .game-ui .exit-hint { animation: none; }
}

/* while a piece is being set down, Escape cancels it (the prompt says so): the hint that says Escape leaves the game steps
   aside rather than contradict it beside the prompt */
body[data-placing] .game-ui .exit-hint { visibility: hidden; }


/* The game's canvas and toggle are hidden on mobile and for reduced motion in the critical CSS (sass/terraboops.scss) */


/* ===== KONAMI CODE HINT MESSAGES =====
   The code's progress, its flash and its "not here" notes wear the game's own toast: the pack's pixel frame on its
   parchment, the pixel font, the palette's brown (not a web toast's neon, glow and rounded glass). Opaque, so there
   is nothing for reduced transparency to take away. */
.konami-hint {
  position: fixed;
  top: 20px;
  left: 20px;
  width: max-content;
  max-width: calc(100vw - 40px);
  padding: 0.35rem 0.9rem;
  border: 20px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-small.png') 8 fill / 20px stretch;
  background: #e4a672 padding-box;
  image-rendering: pixelated;
  color: #3b2415;
  font-family: 'Wayfarer\'s Toy Box', monospace;
  font-size: 1rem;
  filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.25));
  z-index: 10000;
  opacity: 0;
  transform: translateY(-20px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  pointer-events: none;
}

.konami-hint.show {
  opacity: 1;
  transform: translateY(0);
}

/* the flash when the code is entered: the same frame, larger, in the middle of the screen */
.konami-hint.activation {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.8);
  padding: 0.75rem 1.75rem;
  border-width: 28px;
  border-image-width: 28px;
  font-size: 2rem;
  text-align: center;
}

.konami-hint.activation.show {
  transform: translate(-50%, -50%) scale(1);
  animation: konamiFlash 3.5s ease-out forwards;
}

@keyframes konamiFlash {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.8);
  }
  10% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.1);
  }
  15% {
    transform: translate(-50%, -50%) scale(1);
  }
  85% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.95);
  }
}

/* ===== LOAD TIMING OVERLAY (DEBUG - DEV ONLY) ===== */
#load-timing-overlay {
  position: fixed;
  bottom: 20px;
  right: 20px;
  background: rgba(0, 0, 0, 0.9);
  color: #00ff00;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  padding: 12px;
  border-radius: 4px;
  border: 1px solid #00ff00;
  z-index: 9999;
  max-width: 450px;
  pointer-events: auto;
  line-height: 1.6;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
}

#load-timing-overlay .timing-header {
  font-weight: bold;
  color: #ffff00;
  margin-bottom: 8px;
  border-bottom: 1px solid #00ff00;
  padding-bottom: 4px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

#load-timing-overlay .timing-header-buttons {
  display: flex;
  gap: 4px;
  align-items: center;
}

#load-timing-overlay .copy-button {
  background: #00ff00;
  color: #000;
  border: none;
  padding: 4px 8px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 11px;
  font-weight: bold;
  font-family: 'Courier New', monospace;
  transition: background 0.2s;
  margin: 2px;
}

#load-timing-overlay .copy-button:hover {
  background: #00ffff;
}

#load-timing-overlay .copy-button:active {
  background: #ffff00;
}

#load-timing-overlay .copy-button.copied {
  background: #ffff00;
  color: #000;
}

#load-timing-overlay .timing-entry {
  display: flex;
  justify-content: space-between;
  padding: 2px 0;
}

#load-timing-overlay .timing-label {
  color: #00ffff;
}

#load-timing-overlay .timing-value {
  color: #00ff00;
  font-weight: bold;
  margin-left: 12px;
}

#load-timing-overlay .timing-phase {
  color: #ff00ff;
  font-style: italic;
  margin-top: 4px;
}

#load-timing-overlay.hidden {
  display: none;
}

/* ===== FEATURE FLAGS SECTION (DEBUG - DEV ONLY) ===== */
#feature-flags-section {
  border-bottom: 1px solid #00ff00;
  margin-bottom: 12px;
  padding-bottom: 8px;
}

.feature-flags-header {
  font-weight: bold;
  color: #ffff00;
  margin-bottom: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  user-select: none;
}

.feature-flags-header:hover {
  color: #ffff77;
}

.collapse-toggle {
  background: transparent;
  border: 1px solid #00ff00;
  color: #00ff00;
  padding: 2px 8px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 14px;
  font-weight: bold;
  font-family: 'Courier New', monospace;
  transition: all 0.2s;
  line-height: 1;
  min-width: 24px;
  margin: 0 0 0 5px;
}

.collapse-toggle:hover {
  background: #00ff00;
  color: #000;
}

.feature-flags-content {
  margin-top: 8px;
}

.feature-flag-empty {
  color: #999;
  font-size: 11px;
  font-style: italic;
  padding: 4px 0;
}

.feature-flag-select-wrapper {
  margin: 8px 0;
}

.feature-flag-select-label {
  display: block;
  color: #00ffff;
  font-size: 11px;
  margin-bottom: 4px;
}

.feature-flag-select {
  width: 100%;
  background: #1a1a1a;
  border: 1px solid #00ff00;
  color: #00ff00;
  padding: 6px;
  border-radius: 3px;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  cursor: pointer;
}

.feature-flag-select:hover {
  border-color: #00ffff;
}

.feature-flag-select:focus {
  outline: none;
  border-color: #ffff00;
}

.feature-flag-select optgroup {
  color: #ff00ff;
  font-weight: bold;
}

.feature-flag-select option {
  color: #00ff00;
  background: #1a1a1a;
  padding: 4px;
}

.feature-flag-checkbox-area {
  margin-top: 12px;
  padding: 8px;
  background: rgba(0, 255, 0, 0.05);
  border: 1px solid #00ff00;
  border-radius: 3px;
}

.feature-flag-checkbox-label {
  display: flex;
  align-items: center;
  cursor: pointer;
  margin-bottom: 6px;
}

.feature-flag-checkbox {
  cursor: pointer;
  margin-right: 8px;
  accent-color: #00ff00;
  width: 18px;
  height: 18px;
}

.feature-flag-checkbox-text {
  color: #00ffff;
  font-size: 13px;
  font-weight: bold;
  user-select: none;
}

.feature-flag-description {
  color: #999;
  font-size: 10px;
  line-height: 1.4;
  margin-top: 4px;
}

.reset-flags-button {
  background: #333;
  border: 1px solid #ff00ff;
  color: #ff00ff;
  padding: 4px 8px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 10px;
  font-weight: bold;
  font-family: 'Courier New', monospace;
  transition: all 0.2s;
  margin-top: 8px;
  width: 100%;
}

.reset-flags-button:hover {
  background: #ff00ff;
  color: #000;
}

.reset-flags-button:active {
  transform: scale(0.98);
}
/* Cute Fantasy UI pack click sparkle (Pointer_Click_Anim.png, 4 frames of 16px). Spawned by
   frontend/src/game/main.ts on pointerdown while the game has the pointer (Konami mode). */
.ui-click {
  position: fixed;
  width: 32px;
  height: 32px;
  margin: -16px 0 0 -16px;
  pointer-events: none;
  z-index: 3000;
  background: url('/game-assets/ui/parts/click.png') 0 0 / 128px 32px no-repeat;
  image-rendering: pixelated;
  animation: ui-click 0.32s steps(4, end) forwards;
}

@keyframes ui-click {
  from { background-position: 0 0; }
  to { background-position: -128px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ui-click { display: none; }
}

/* ---- Selkirk Valley map credit (ODbL) -------------------------------------------------------------
   A small folded map in a wooden frame, in the corner of the map it credits. It shows only while the game is
   on and the level is drawn from OpenStreetMap (main.ts toggles [hidden] per level). When a level arrives it
   spells out "(c) OpenStreetMap" for a few seconds (main.ts sets .map-credit--telling), then folds back to the
   icon; hover and keyboard focus spell it out again, and a click opens the full credit in #map-credit-dialog.
   Stepped 16px in from the corner so the 9px focus halo is always drawn whole. Reading the site (not in play)
   the credit sits in the margin beside the 960 px column, which has room for the words only from 1500 px wide;
   narrower, it stays the icon there and spells itself out on hover or focus. */
.map-credit {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 1000;
  display: none;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 0;
  border: 7px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-small.png') 8 fill / 7px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  color: #3b2415;
  font: 0.75rem/1 'Wayfarer\'s Toy Box', monospace;
  white-space: nowrap;
  cursor: pointer;
  filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.25));
  transition: transform 0.15s ease;
}
/* only where the map itself shows (.game-background is hidden below 769 px and for reduced motion): a game started
   in a big window and then made small leaves no credit floating over the page */
@media (min-width: 769px) and (prefers-reduced-motion: no-preference) {
  body[data-game="on"] .map-credit:not([hidden]) { display: flex; }
}
@media (max-width: 1499px) {
  body:not(.konami-mode) .map-credit--telling:not(:hover):not(:focus-visible) .map-credit__source { display: none; }
}
.map-credit:hover, .map-credit:focus-visible { transform: translateY(-2px); }
.map-credit:focus-visible { outline: 3px solid #3b2415; outline-offset: 3px; box-shadow: 0 0 0 9px #F5EFE3; }
.map-credit__icon { display: block; width: 32px; height: 32px; image-rendering: pixelated; }
.map-credit__source { display: none; padding-right: 4px; }
.map-credit--telling .map-credit__source,
.map-credit:hover .map-credit__source,
.map-credit:focus-visible .map-credit__source { display: inline; }

.map-credit-dialog {
  /* a modal dialog centres itself with margin: auto; the site's reset zeroes margins, so say it again */
  margin: auto;
  max-width: min(420px, calc(100vw - 32px));
  padding: 4px 8px;
  border: solid transparent;
  border-width: 24px 24px 36px;
  border-image: url('/game-assets/ui/parts/frame-panel.png') 12 12 18 12 fill / 24px 24px 36px 24px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  color: #3b2415;
  font: 1rem/1.5 system-ui, sans-serif;
}
.map-credit-dialog::backdrop { background: rgba(20, 12, 8, 0.55); }
.map-credit-dialog h2 { margin: 0 0 8px; font: 1.25rem/1.2 'Wayfarer\'s Toy Box', monospace; color: #3b2415; } /* the panel's ink, not the site's salmon heading accent */
.map-credit-dialog p { margin: 0 0 12px; }
.map-credit-dialog a { color: #6e2914; } /* 5.02:1 on the parchment (#7a2e17 was 4.48:1) */
.map-credit-dialog form { display: flex; justify-content: flex-end; margin: 0; }
.map-credit-dialog__close {
  padding: 6px 14px;
  border: 2px solid #3b2415;
  border-radius: 6px;
  background: #F5EFE3;
  color: #3b2415;
  font: 0.9rem/1 'Wayfarer\'s Toy Box', monospace;
  cursor: pointer;
}
.map-credit-dialog__close:focus-visible { outline: 3px solid #3b2415; outline-offset: 2px; }

/* ===== Touch pad (frontend/src/game/touch-pad.ts) =====
   A touch screen has no keys: in play, the arrows (held) and E, F, R, I, C, Shift, Space and Esc (tapped) send the keys' own events. It
   shows only for a coarse pointer: the arrows at the left between the character panel and the bag button, the keys at
   the bottom right beside the toolbar. It sits under the HUD layer, so an open panel covers it rather than the pad
   covering its rows (the HUD layer lets touches through wherever it draws nothing); the walk cross also steps away
   while the bag is open, and the prompt keeps to the room between the two groups. */
.touch-pad { display: none; }
@media (pointer: coarse) {
  body.konami-mode .touch-pad {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 1990; /* over the game (1000), under the HUD layer (2000) and so under every panel */
    pointer-events: none;
  }
  .touch-pad__walk,
  .touch-pad__act {
    position: absolute;
    display: grid;
    gap: 8px;
    pointer-events: auto;
  }
  .touch-pad__walk {
    left: 16px;
    /* between the bag tab (20 px up, 66 px tall) and the character panel (to 494 px): 176 px fits there on a 768 px
       screen with 6 px to spare each side */
    bottom: 92px;
    gap: 4px;
    grid-template-columns: repeat(3, 56px);
    grid-template-areas: ". up ." "left . right" ". down .";
  }
  /* bottom-right, where a thumb rests, just left of the toolbar (right 20 px, 60 px wide) and level with its foot; not
     above it, where the level banner that opens on every level would cover the keys on a 768 px screen */
  .touch-pad__act { right: 88px; bottom: 88px; grid-template-columns: repeat(2, 92px); }
  /* the act keys are 92 px wide: "Shift" in the pack's font is 72 px, inside the key's 4 px padding and 6 px frame; Space across its row, as on a keyboard, and Esc a row
     of its own, apart from the play keys */
  .touch-pad__key[data-key="Space"],
  .touch-pad__key[data-key="Escape"] { grid-column: 1 / -1; }
  /* scoped to the pad: its keys wear the HUD's .key look (character-portrait.css, which loads after this sheet and sets
     44 px tall), and the pad's own size is the pad's to say */
  /* each key fills its grid cell: the columns say the width (56 px in the walk cross, 92 at the right), the pad the height */
  .touch-pad .touch-pad__key { width: 100%; height: 56px; touch-action: none; user-select: none; -webkit-user-select: none; }
  .touch-pad__key[data-key="ArrowUp"] { grid-area: up; }
  .touch-pad__key[data-key="ArrowLeft"] { grid-area: left; }
  .touch-pad__key[data-key="ArrowRight"] { grid-area: right; }
  .touch-pad__key[data-key="ArrowDown"] { grid-area: down; }
  /* the open bag reaches over the walk cross's corner but not all of it (a sliver of the up key stood above its top
     edge, still tappable): the bag is its own moment, its rows are what is tapped, so the cross steps away while it
     is open */
  body:has(#inventory[data-open="true"]) .touch-pad__walk { visibility: hidden; }
  /* the prompt names E and Esc, so the keys stay while it shows; it keeps to the room between them instead: the
     action keys take 280 px from the right edge (the walk cross 192 from the left), so a box centred with 288 px
     clear each side, wrapping a long line upwards (it is anchored at the bottom) */
  body.konami-mode .game-prompt { max-width: calc(100vw - 576px); }
  /* with the bag open too, between the bag and the action keys (280 px from the right edge); in play, so it outranks
     the bag-open rule in character-portrait.css, which loads after this sheet */
  body.konami-mode:has(#inventory[data-open="true"]) .game-prompt { right: 288px; max-width: calc(100vw - var(--bag-right, 336px) - 304px); }
}
