/* ============================================================================
   PRACTICE MODE (Phase 2)
   ----------------------------------------------------------------------------
   Spotlight overlay + instruction card. Practice runs on its OWN isolated
   local sandbox board (not the user's real team), so this file deliberately
   only styles the overlay chrome — no mock-board styles. The full traffic-light
   palette, scanner, team-bar, etc. come from their production CSS files because
   the live board (the sandbox) is what the user sees during practice.

   z-index: 9500 (above coach-marks at 9400, below system-critical dialogs).
   ============================================================================ */

.practice-spotlight-root {
  font-family: inherit;
}

.practice-spotlight-backdrop {
  /* Inline positioning set by JS; this rule provides paint-only defaults.
     NO backdrop blur: the steps ask the user to READ the board (which rows
     line up, where the readout lands), and a blur defeats that. The dim alone
     carries the "look here" framing. */
  background: rgba(15, 23, 42, 0.55);
}

body.dark-mode .practice-spotlight-backdrop {
  background: rgba(0, 0, 0, 0.65);
}

.practice-spotlight-ring {
  /* Soft teal halo around the target. Animates as the target moves. */
  border-radius: 12px;
  pointer-events: none;
}

/* ---------- Instruction Card ---------- */
.practice-spotlight-card {
  position: fixed;
  width: 340px;
  max-width: calc(100vw - 32px);
  background: white;
  border-radius: var(--radius-lg, 16px);
  padding: 16px 18px 14px;
  box-shadow:
    0 18px 48px rgba(15, 23, 42, 0.28),
    0 4px 12px rgba(15, 23, 42, 0.10);
  pointer-events: auto;
  z-index: 1;
  animation: practice-card-in 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}

body.dark-mode .practice-spotlight-card {
  background: var(--slate-900, #0f172a);
  color: var(--slate-100, #f1f5f9);
  box-shadow:
    0 18px 48px rgba(0, 0, 0, 0.6),
    0 4px 12px rgba(0, 0, 0, 0.4);
}

@keyframes practice-card-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.practice-card-step {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--primary-600, #0d9488);
  margin-bottom: 6px;
}

body.dark-mode .practice-card-step {
  color: #2dd4bf;
}

.practice-card-title {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--slate-900, #0f172a);
  margin: 0 0 8px;
}

body.dark-mode .practice-card-title {
  color: var(--slate-100, #f1f5f9);
}

.practice-card-body {
  font-size: 13px;
  line-height: 1.5;
  color: var(--slate-600, #475569);
  margin-bottom: 10px;
  /* Bodies are written as numbered, step-by-step instructions with real
     newlines (escapeHTML keeps them safe, so we can't use <br>); pre-line
     renders those \n as line breaks while still wrapping long lines. */
  white-space: pre-line;
}

body.dark-mode .practice-card-body {
  color: var(--slate-300, #cbd5e1);
}

/* ---------- Feedback Line ---------- */
.practice-card-feedback {
  font-size: 12px;
  line-height: 1.45;
  margin-bottom: 10px;
  padding: 0;
  min-height: 0;
  transition: all 0.2s ease;
}

.practice-card-feedback:empty {
  display: none;
}

.practice-card-feedback.success {
  color: #15803d;
  background: rgba(34, 197, 94, 0.10);
  border-left: 3px solid var(--status-working, #16a34a);
  padding: 6px 10px;
  border-radius: 4px;
}

.practice-card-feedback.error {
  color: #b45309;
  background: rgba(251, 191, 36, 0.15);
  border-left: 3px solid #d97706;
  padding: 6px 10px;
  border-radius: 4px;
}

/* Neutral notice — neither praise nor correction (2026-08-26). Used for the
   two-stage Esc confirm ("Press Esc again to leave"), which is a statement of
   fact: styling it as `.error` amber would tell the user they had done
   something wrong just for pressing a key. Slate keeps it informational. */
.practice-card-feedback.notice {
  color: #334155;
  background: rgba(100, 116, 139, 0.12);
  border-left: 3px solid #64748b;
  padding: 6px 10px;
  border-radius: 4px;
}

body.dark-mode .practice-card-feedback.success {
  color: #86efac;
  background: rgba(34, 197, 94, 0.16);
}

body.dark-mode .practice-card-feedback.error {
  color: #fde68a;
  background: rgba(251, 191, 36, 0.18);
}

body.dark-mode .practice-card-feedback.notice {
  color: #cbd5e1;
  background: rgba(148, 163, 184, 0.18);
}

/* ---------- Footer Buttons ---------- */
.practice-card-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  border-top: 1px solid var(--slate-200, #e2e8f0);
  padding-top: 10px;
  margin-top: 4px;
}

body.dark-mode .practice-card-footer {
  border-top-color: var(--slate-700, #334155);
}

.practice-card-back,
.practice-card-skip,
.practice-card-close {
  appearance: none;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  border-radius: 6px;
  padding: 6px 12px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

/* Footer layout (DOM order Exit · Back · Next):
   Exit sits on the far LEFT — margin-right:auto pushes Back + Next to the right
   edge (the footer is justify-content:flex-end). Exit is the quiet escape hatch,
   Back is a quiet step-back, and Next is the primary GREEN forward action on the
   right — the shape people expect from a guided walkthrough. */

/* Exit — quiet, far left. Was the teal primary (backwards); demoted to a low-
   emphasis ghost so it reads as "leave", not "the button to press". */
.practice-card-close {
  background: transparent;
  border: 1px solid transparent;
  color: var(--slate-500, #64748b);
  margin-right: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.practice-card-close:hover {
  background: var(--slate-100, #f1f5f9);
  color: var(--slate-800, #1e293b);
}

body.dark-mode .practice-card-close {
  background: transparent;
  border-color: transparent;
  color: var(--slate-400, #94a3b8);
}

body.dark-mode .practice-card-close:hover {
  background: var(--slate-800, #1e293b);
  color: white;
}

/* Back — quiet outline, middle (sits just left of Next on the right cluster). */
.practice-card-back {
  background: transparent;
  border: 1px solid var(--slate-200, #e2e8f0);
  color: var(--slate-600, #475569);
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.practice-card-back:hover {
  background: var(--slate-100, #f1f5f9);
  color: var(--slate-800, #1e293b);
}

body.dark-mode .practice-card-back {
  border-color: var(--slate-700, #334155);
  color: var(--slate-300, #cbd5e1);
}

body.dark-mode .practice-card-back:hover {
  background: var(--slate-800, #1e293b);
  color: white;
}

/* Next — primary GREEN forward action, far right. Was a quiet outline (read as
   secondary); promoted to the emphasised button so the eye lands on it. */
.practice-card-skip {
  background: #16a34a;
  border: 1px solid #16a34a;
  color: white;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.practice-card-skip:hover {
  background: #15803d;
  border-color: #15803d;
  color: white;
}

body.dark-mode .practice-card-skip {
  background: #16a34a;
  border-color: #16a34a;
  color: white;
}

body.dark-mode .practice-card-skip:hover {
  background: #15803d;
  border-color: #15803d;
}

/* ---------- Mobile ---------- */
@media (max-width: 640px) {
  .practice-spotlight-card {
    width: calc(100vw - 24px);
    left: 12px !important;
  }
  /* JS can't beat a fixed-position pin here, so it instead stamps
     data-mobile-edge based on where the spotlight hole sits, and we pin the
     card to the edge AWAY from the target. (Stamped in positionCard().)

     Retuned 2026-07-31 (user: "the text would be better being at the top as the
     highlight highlights the lower and mid sections typically"). The card now
     defaults to the TOP and only drops to a bottom sheet when the hole sits
     entirely in the top ~30% band — because the steps mostly spotlight mid and
     lower board content, and because scrollTargetIntoClearZone() parks the
     target near the top of the screen on a narrow viewport. The unstamped
     fallback moved to `top` with it, so the first paint (before positionCard()
     runs) doesn't flash the sheet at the bottom and then jump up. */
  .practice-spotlight-card[data-mobile-edge="top"],
  .practice-spotlight-card:not([data-mobile-edge]) {
    top: 16px !important;
    bottom: auto;
  }
  .practice-spotlight-card[data-mobile-edge="bottom"] {
    bottom: 16px;
    top: auto !important;
  }

  /* 2026-08-08 — the sheet is pinned to an edge but had NO height limit, so a
     long step body simply grew across the highlight it was describing. On a
     727px-tall phone the first step rendered a 321px card at top:16px (ending
     at y=337) while its hole started at y=324: a 13px overlap, reported as
     "the highlight is under the text box".

     positionCard() cannot fix this — the !important pins above deliberately
     discard its computed top/left on mobile — so the ceiling has to live here,
     in the same rule that does the pinning. --practice-hole-edge is stamped by
     positionCard() with the px distance from the card's edge to the nearest
     edge of the hole; the fallback keeps the card inside a sane band if the
     variable is ever missing. Body scrolls inside the card rather than the card
     growing over the target. */
  .practice-spotlight-card {
    display: flex;
    flex-direction: column;
    max-height: var(--practice-hole-edge, 46vh);
  }
  .practice-spotlight-card .practice-card-body {
    overflow-y: auto;
    min-height: 0;
  }
}

/* ---------- Body marker ----------
   Other code can opt out of itself during practice (e.g. sync listeners can
   skip demo rows, autosave can be deferred) by checking body.practice-mode-active
   or window.__practiceModeActive. */
body.practice-mode-active {
  /* No visual change — marker only. */
}

/* ---------- Board-swap veil (2026-08-26) ----------
   start() adds the body marker SYNCHRONOUSLY, then awaits
   applyPracticeSandboxBoard() — an async create + seed + setActiveBoard. For
   that whole gap the user's PREVIOUS board is still fully painted, so the
   timezone rows of whatever they were just looking at (typically the demo /
   sample board) sat on screen and then visibly swapped to the sandbox roster:
   the "clicking practice flashes the previous demo's timezones" report.

   Cover the board for exactly that gap. This is a plain opaque veil, not a
   spinner: the wait is short (two RAFs after the seed resolves) and a spinner
   for ~a frame reads as jank of its own. It is removed in the same RAF block
   that mounts the first spotlight, and on EVERY abort path, so it can never
   outlive the swap it hides.

   Painted above the board but BELOW the spotlight (z 9500) and the completion
   card, so the first step's ring is never veiled. */
.practice-board-veil {
  position: fixed;
  inset: 0;
  z-index: 9400;
  background: var(--bg-primary, #0f172a);
  pointer-events: all;
  opacity: 1;
}
/* Fade OUT only. Appearing instantly is correct (it must hide the old board on
   the very first frame); dissolving away lets the seeded board arrive gently. */
.practice-board-veil.is-clearing {
  opacity: 0;
  transition: opacity 0.22s ease;
}
@media (prefers-reduced-motion: reduce) {
  .practice-board-veil.is-clearing { transition: none; }
}

/* ============================================================================
   COMPLETION CARD
   ----------------------------------------------------------------------------
   Modal-light card shown when practice completes. Offers three next steps —
   "Create your own group" (the culmination, → Onboarding.startManual),
   "Back to my team" (clean return + sandbox teardown), and "Keep exploring the
   sandbox" (dismiss, stay on the sandbox board). No auto-dismiss: backdrop
   click / Esc / "Keep exploring" all leave the user on the sandbox.
   ============================================================================ */

.practice-completion-root {
  position: fixed;
  inset: 0;
  z-index: 9550;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  pointer-events: none;
  animation: practice-completion-in 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes practice-completion-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.practice-completion-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  pointer-events: auto;
}

.practice-completion-card {
  position: relative;
  width: 100%;
  max-width: 440px;
  background: white;
  border-radius: var(--radius-2xl, 24px);
  padding: 22px 24px 18px;
  box-shadow:
    0 24px 64px rgba(15, 23, 42, 0.32),
    0 6px 16px rgba(15, 23, 42, 0.14);
  pointer-events: auto;
  text-align: center;
  animation: practice-completion-card-in 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes practice-completion-card-in {
  from { opacity: 0; transform: translateY(12px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

body.dark-mode .practice-completion-card {
  background: var(--slate-900, #0f172a);
  color: var(--slate-100, #f1f5f9);
}

.practice-completion-icon {
  font-size: 36px;
  color: var(--status-working, #16a34a);
  margin-bottom: 10px;
  animation: practice-completion-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.1s both;
}

@keyframes practice-completion-pop {
  from { opacity: 0; transform: scale(0.4); }
  to   { opacity: 1; transform: scale(1); }
}

.practice-completion-title {
  font-size: 18px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--slate-900, #0f172a);
  margin-bottom: 8px;
}

body.dark-mode .practice-completion-title {
  color: var(--slate-100, #f1f5f9);
}

.practice-completion-body {
  font-size: 13px;
  line-height: 1.55;
  color: var(--slate-600, #475569);
  margin-bottom: 16px;
}

.practice-completion-body strong {
  color: var(--slate-800, #1e293b);
  font-weight: 600;
}

body.dark-mode .practice-completion-body {
  color: var(--slate-300, #cbd5e1);
}

body.dark-mode .practice-completion-body strong {
  color: var(--slate-100, #f1f5f9);
}

.practice-completion-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}

.practice-completion-secondary,
.practice-completion-cta {
  appearance: none;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  border-radius: 8px;
  padding: 9px 16px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.practice-completion-secondary {
  background: transparent;
  border: 1px solid var(--slate-200, #e2e8f0);
  color: var(--slate-600, #475569);
}

.practice-completion-secondary:hover {
  background: var(--slate-100, #f1f5f9);
  color: var(--slate-800, #1e293b);
}

body.dark-mode .practice-completion-secondary {
  border-color: var(--slate-700, #334155);
  color: var(--slate-300, #cbd5e1);
}

body.dark-mode .practice-completion-secondary:hover {
  background: var(--slate-800, #1e293b);
  color: white;
}

/* "Keep exploring the sandbox" — quiet text link below the two buttons. */
.practice-completion-explore {
  appearance: none;
  margin: 12px auto 0;
  display: block;
  background: transparent;
  border: none;
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  color: var(--slate-500, #64748b);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 0.15s ease;
}

.practice-completion-explore:hover {
  color: var(--slate-700, #334155);
}

body.dark-mode .practice-completion-explore {
  color: var(--slate-400, #94a3b8);
}

body.dark-mode .practice-completion-explore:hover {
  color: var(--slate-200, #e2e8f0);
}

.practice-completion-cta {
  background: linear-gradient(135deg, var(--primary-500, #14b8a6) 0%, var(--primary-600, #0d9488) 100%);
  border: 1px solid transparent;
  color: white;
}

.practice-completion-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(20, 184, 166, 0.35);
}

.practice-completion-cta:active {
  transform: translateY(0);
}

@media (max-width: 640px) {
  .practice-completion-actions {
    flex-direction: column;
  }
  .practice-completion-secondary,
  .practice-completion-cta {
    width: 100%;
    justify-content: center;
  }
}
