/* ==========================================================
   ELEMENT SNAKE — namespaced "snk-" per EC per-app CSS convention.
   All colors/spacing/radii pull from base.css tokens so the game
   tracks theme + scheme changes automatically. Font sizes use the
   canonical 8-step rem scale (EC_Design_System.md §3.2).
   ========================================================== */

/* ── Canonical button classes ──────────────────────────────
   .btn-primary and .btn-outline-sm are NOT defined in base.css or
   layout.css — per EC convention each app duplicates them in its own
   stylesheet. Verbatim from EC_Design_System.md §6.1; without these the
   game's buttons fall back to raw browser chrome.
   ------------------------------------------------------------------ */
.btn-primary {
  background: var(--primary);
  color: white;
  border: none;
  border-radius: var(--radius-sm);
  padding: 0.5rem 1.1rem;
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 600;
  font-family: var(--font);
  transition: all var(--transition);
  white-space: nowrap;
  box-shadow: var(--shadow-primary);
}
.btn-primary:hover { background: var(--primary-hover); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.btn-outline-sm {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.8rem;
  cursor: pointer;
  font-size: 0.80rem;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  transition: all var(--transition);
  font-family: var(--font);
}
.btn-outline-sm:hover { color: var(--primary); border-color: var(--primary); }
.btn-outline-sm:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.snk-wrap {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
}

/* ── Page head ── */
.snk-head {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem;
}
.snk-head-copy { flex: 1; min-width: 240px; }
.snk-subtitle { margin: 0; font-size: 0.85rem; color: var(--text-muted); line-height: 1.5; }

/* The app name already lives in the CoreUI header, so the visible <h1>
   is redundant. Keep a screen-reader-only one so the page still has a
   proper top-level heading for assistive tech and search indexing. */
.snk-sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.snk-best {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.8rem;
  color: var(--text-muted);
}
.snk-best strong { color: var(--text); font-size: 0.95rem; }

/* ── Shared panel ── */
.snk-panel {
  width: 100%;
  max-width: 660px;
  padding: 1.35rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  animation: fadeInUp .3s ease-out forwards;
}

.snk-section-label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.55rem;
}

/* ── Option grid (mode / edges / category) ── */
.snk-opt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0.6rem; }
.snk-opt-grid.snk-opt-grid-cat { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 0.5rem; }

.snk-opt {
  text-align: left;
  padding: 0.75rem 0.8rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font);
  transition: all var(--transition);
}
.snk-opt:hover { border-color: var(--primary); }
.snk-opt[data-selected="true"] { border-color: var(--primary); background: var(--primary-light); }
.snk-opt-title { font-size: 0.85rem; font-weight: 700; margin-bottom: 0.2rem; }
.snk-opt-desc { font-size: 0.72rem; color: var(--text-muted); line-height: 1.4; }

.snk-opt-cat {
  display: flex; align-items: center; gap: 0.55rem;
  padding: 0.6rem 0.7rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font);
  font-size: 0.8rem;
  font-weight: 500;
  transition: all var(--transition);
}
.snk-opt-cat:hover { border-color: var(--primary); }
.snk-opt-cat[data-selected="true"] { border-color: var(--primary); background: var(--primary-light); }
.snk-opt-dot { width: 0.7rem; height: 0.7rem; border-radius: 0.2rem; flex: none; }
.snk-opt-cat-label { flex: 1; text-align: left; }
.snk-opt-cat-count { font-size: 0.72rem; color: var(--text-muted); }

/* ── Contaminant toggle row ── */
.snk-toggle-row {
  display: flex; align-items: center; gap: 0.8rem;
  padding: 0.75rem 0.8rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  text-align: left;
  color: var(--text);
  font-family: var(--font);
  width: 100%;
  transition: all var(--transition);
}
.snk-toggle-row[data-on="true"] { border-color: var(--primary); background: var(--primary-light); }
.snk-switch {
  position: relative; flex: none;
  width: 2.6rem; height: 1.5rem;
  border-radius: 999px;
  background: var(--border);
  transition: background var(--transition);
}
.snk-switch[data-on="true"] { background: var(--primary); }
.snk-switch-knob {
  position: absolute; top: 0.18rem; left: 0.18rem;
  width: 1.1rem; height: 1.1rem;
  border-radius: 999px;
  background: #fff;
  box-shadow: var(--shadow-sm);
  transition: left var(--transition);
}
.snk-switch[data-on="true"] .snk-switch-knob { left: 1.3rem; }
.snk-toggle-copy { flex: 1; }
/* These are <span>s, so they MUST be blockified — as inline elements they
   run together on one line ("Contaminants · onHatched off-family tiles…")
   and margin-top is silently ignored. */
.snk-toggle-title { display: block; font-size: 0.85rem; font-weight: 700; }
.snk-toggle-hint { display: block; font-size: 0.72rem; color: var(--text-muted); line-height: 1.4; margin-top: 0.25rem; }

/* ── Start row ── */
.snk-start-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.snk-start-row .btn-primary { flex: 1; min-width: 190px; padding: 0.8rem 1.1rem; font-size: 0.95rem; }
.snk-start-hint { font-size: 0.72rem; color: var(--text-muted); }

/* ── Play screen ── */
.snk-play { width: 100%; max-width: 660px; display: flex; flex-direction: column; gap: 0.85rem; }

.snk-stats { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.snk-stat {
  flex: 1; min-width: 6.5rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.snk-stat-label { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.snk-stat-value { font-size: 1.15rem; font-weight: 700; color: var(--text); line-height: 1.3; }

/* The board is a SQUARE, so constraining its width also constrains its
   height. --snk-chrome is the vertical space the rest of the play screen
   needs (sticky header + stats row + controls row + gaps + padding); it's
   set in rem so it tracks the CoreUI font-scale control, and measured at
   runtime by snkFit() which overwrites it with the real number.
   100dvh (not 100vh) so mobile browser toolbars don't push the board
   under the fold. */
.snk-play {
  --snk-chrome: 13rem;
}
.snk-board {
  position: relative;
  width: min(100%, calc(100vh - var(--snk-chrome)));
  width: min(100%, calc(100dvh - var(--snk-chrome)));
  margin: 0 auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
  touch-action: none;
}
.snk-board canvas { display: block; width: 100%; aspect-ratio: 1 / 1; touch-action: none; }

/* ── Mobile immersive play ─────────────────────────────────
   While a run is active on a small screen, hide the site header and
   footer and lock page scroll. Two things fall out of this:
     1. The board gets the full viewport height (snkMeasureChrome reads
        offsetHeight 0 for the hidden header, so it resizes automatically).
     2. Swipe gestures can no longer drag the page, because there is
        nothing left to scroll — this is the real fix for "swiping moved
        the whole screen", since touch-action alone doesn't stop a scroll
        gesture that begins just outside the canvas.
   The header returns on the menu and after "Change mode".
   Also fires on short landscape viewports, where a phone's height is the
   binding constraint even though its width isn't.
   ------------------------------------------------------------------ */
@media (max-width: 700px), (max-height: 520px) {
  body.snk-playing #core-header,
  body.snk-playing #core-footer { display: none; }
  body.snk-playing {
    overflow: hidden;
    overscroll-behavior: none;   /* kills pull-to-refresh and rubber-banding */
  }
  body.snk-playing .main-content { padding-top: 0.5rem; padding-bottom: 0.5rem; }
  body.snk-playing .snk-board { touch-action: none; }
}

.snk-flash {
  position: absolute; top: 14%; left: 0; right: 0;
  text-align: center; pointer-events: none;
  font-size: 1.4rem; font-weight: 700; letter-spacing: -0.01em;
  color: var(--primary);
  text-shadow: 0 2px 14px rgba(0,0,0,.18);
  /* MUST stay 0. The rise animation ends at opacity 0 with fill-mode
     forwards, but the moment the .snk-flash-show class is removed the
     element reverts to THIS rule — without opacity:0 the message stays
     painted over the board permanently. */
  opacity: 0;
}
.snk-flash.snk-flash-show { animation: snkRise 1.1s ease forwards; }

.snk-overlay {
  position: absolute; inset: 0;
  display: none;
  place-items: center;
  background: var(--overlay);
  backdrop-filter: blur(3px);
  padding: 1rem;
}
.snk-overlay.snk-overlay-show { display: grid; }

.snk-pause-card, .snk-over-card {
  padding: 1.35rem 1.5rem;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  text-align: center;
  animation: scaleIn .25s ease-out forwards;
}
.snk-pause-title { font-size: 1.05rem; font-weight: 700; margin-bottom: 0.25rem; color: var(--text); }
.snk-pause-hint { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 1rem; }

.snk-over-card { width: 100%; max-width: 320px; }
.snk-over-reason { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.snk-over-score { font-size: 2.4rem; font-weight: 700; letter-spacing: -0.03em; margin: 0.3rem 0 0.1rem; color: var(--text); }
.snk-over-note { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 1rem; }
.snk-over-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; margin-bottom: 1.1rem; }
.snk-over-stat { padding: 0.5rem; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.snk-over-stat-label { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.snk-over-stat-value { font-size: 1.05rem; font-weight: 700; color: var(--text); }
.snk-over-actions { display: flex; gap: 0.5rem; }
.snk-over-actions .btn-primary { flex: 1; }

.snk-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.55rem; }
.snk-controls .btn-outline-sm { font-weight: 500; }
.snk-hint { flex: 1; min-width: 160px; text-align: right; font-size: 0.72rem; color: var(--text-muted); }

@keyframes snkRise {
  0%   { transform: translateY(6px); opacity: 0; }
  20%  { opacity: 1; }
  100% { transform: translateY(-26px); opacity: 0; }
}

@media (max-width: 480px) {
  .snk-hint { text-align: left; width: 100%; }
}
