/* ============================================================================
   lc-practice.css — Practice hub (Task 2) + Flashcards (Task 3)
   ----------------------------------------------------------------------------
   Requires lc-tokens.css. Append to wwwroot/css/site.css.

   These rules REPLACE the inline <style> blocks currently in
   Pages/Games/Index.cshtml and Pages/Games/Flashcards.cshtml. Delete those
   blocks — the three Games views each carry private styles today, which is
   why they drifted apart.

   Requires Bootstrap Icons. It is referenced in the Razor (bi bi-lock-fill,
   bi bi-exclamation-triangle) but NEVER LINKED in _Layout.cshtml, so those
   glyphs render as nothing in production today. Self-host to wwwroot/lib/
   to match how Bootstrap and jQuery are already vendored.
   ========================================================================== */


/* ==========================================================================
   PRACTICE HUB — /games
   ========================================================================== */

/* Content column: keeps the hub a short menu, not a dashboard. Wrap the
   Razor `else` body in <div class="cg-games-page"> so the heading, intro
   line and groups all share one measure. */
.cg-games-page { max-width: 960px; }

/* ── Grouped hub (Task 2b) ─────────────────────────────────────────────────
   The catalogue is SEVEN activities and still growing — GameCatalog.cs says
   Phase 2/3 activities "register here as they ship". A single grid orphans a
   card at 7 (3+3+1) and again at 9; tuning the column count is a losing game.
   Three groups of 2 / 3 / 2 solve it structurally, and the grouping is the
   more useful thing to tell a learner: three different KINDS of practice,
   ordered recognition -> production -> play. Groups are taken from
   GameCatalog.cs's own phase comments:
     Review  flashcards, matching
     Drills  mcq, typing, audio
     Games   hangman, memory
   Costs three localised strings (games.group_review / _drills / _games).
   If refused, drop .cg-games-group and let .cg-games-grid hold all seven at
   four columns — 4+3 today, revisit at eight. */
.cg-games-groups {
  display: flex;
  flex-direction: column;
  gap: var(--lc-space-6);
  margin-top: var(--lc-space-6);
}
.cg-games-group {
  display: flex;
  flex-direction: column;
  gap: var(--lc-space-3);
}
.cg-games-group-label {
  font-size: var(--lc-text-sm);
  font-weight: var(--lc-weight-semi);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--lc-text-muted);
}

.cg-games-grid {
  display: grid;
  /* 272px floor + the 960px cap = 3 columns desktop, 2 tablet, 1 phone.
     At 960px, 3-up yields (960 - 64 padding - 32 gaps) / 3 = 288px per card,
     which is ~90px more width for German and Greek than the shipped
     minmax(240px, 1fr). */
  grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
  gap: var(--lc-space-4);
}

.cg-game-card {
  position: relative;                /* .stretched-link containing block */
  display: flex;
  flex-direction: column;
  gap: var(--lc-space-2);
  padding: var(--lc-space-5);
  background: var(--lc-base);
  border: 1px solid var(--lc-border);
  border-radius: var(--lc-radius-md);
  transition: background-color var(--lc-duration-fast) var(--lc-ease),
              border-color     var(--lc-duration-fast) var(--lc-ease);
}

.cg-game-icon {
  font-size: 20px;
  line-height: 1;
  color: var(--lc-text-muted);
}
.cg-game-title {
  font-size: var(--lc-text-md);
  font-weight: var(--lc-weight-semi);
  line-height: var(--lc-leading-snug);
  color: var(--lc-text);
  margin-top: 2px;
}
.cg-game-desc {
  font-size: var(--lc-text-sm);
  color: var(--lc-text-muted);
  line-height: var(--lc-leading-normal);
}

.cg-game-card .btn { align-self: flex-start; margin-top: auto; }
.cg-game-card > .cg-game-action { margin-top: auto; padding-top: var(--lc-space-3); }

/* Hover — available cards only. Two properties. No transform, no lift,
   no shadow bloom: the card must not move under the cursor. */
.cg-game-card:not(.cg-unavailable):hover {
  background: var(--lc-surface-2);
  border-color: var(--lc-border-strong);
}

/* The focus ring belongs to the CARD, not the stretched anchor inside it. */
.cg-game-card:focus-within {
  outline: var(--lc-focus-width) solid var(--lc-focus-ring);
  outline-offset: var(--lc-focus-offset);
}
.cg-game-card .stretched-link:focus-visible { outline: none; }

/* ── Unavailable ───────────────────────────────────────────────────────────
   `opacity: .55` is REMOVED, not tuned. It composited #212529 down to
   ~#858789 (3.61:1) and the .text-muted description to ~2.1:1 — both below
   WCAG 1.4.3 AA. The card recedes via its GROUND; the text stays legible. */
.cg-game-card.cg-unavailable {
  background: var(--lc-surface-2);
  border-color: var(--lc-border);
}
.cg-unavailable .cg-game-title {
  color: var(--lc-text-muted);          /* 7.76:1 on surface-2 */
  font-weight: var(--lc-weight-medium); /* weight drops, contrast does not */
}

/* Requirement chip. Replaces <span class="text-muted"><small>…, which on a
   14px root computes to 11.2px — below the --lc-text-xs floor for a
   sentence. */
.cg-game-req {
  display: flex;
  align-items: flex-start;
  gap: var(--lc-space-2);
  margin-top: auto;
  padding: var(--lc-space-2) var(--lc-space-3);
  background: var(--lc-surface-3);
  border-radius: var(--lc-radius-sm);
  font-size: var(--lc-text-sm);
  line-height: var(--lc-leading-normal);
  color: var(--lc-text-muted);          /* 6.90:1 on surface-3 */
}
.cg-game-req .bi { flex: none; line-height: var(--lc-leading-normal); }

/* ── Informational notice (quiz-blocked, D-G22) ───────────────────────────
   Same left-rule vocabulary as .feedback-section, so "blocked",
   "incorrect" and "informational" read as one family. Replaces
   `alert alert-warning`; keep role="alert" on the element.
   NOTE: Bootstrap's warning pair (#664d03 on #fff3cd) measures 7.21:1, so
   this change is about TONE, not contrast. Amber says "something has gone
   wrong"; nothing has. .alert-danger on the error branch is untouched. */
.cg-notice {
  display: flex;
  gap: var(--lc-space-3);
  align-items: flex-start;
  padding: var(--lc-space-4) var(--lc-space-5);
  background: var(--lc-info-surface);
  border: 0;
  border-left: 3px solid var(--lc-info);
  border-radius: 0 var(--lc-radius-md) var(--lc-radius-md) 0;
  color: var(--lc-text);
}
.cg-notice .bi {
  font-size: 19px;
  color: var(--lc-info);
  flex: none;
  line-height: var(--lc-leading-snug);
}
.cg-notice-title  { font-size: var(--lc-text-base); font-weight: var(--lc-weight-semi); }
.cg-notice-detail { font-size: var(--lc-text-sm); color: var(--lc-text-muted);
                    line-height: var(--lc-leading-normal); }

.cg-games-empty {
  padding: var(--lc-space-6);
  background: var(--lc-surface-2);
  border: 1px solid var(--lc-border);
  border-radius: var(--lc-radius-md);
  color: var(--lc-text-muted);
  font-size: var(--lc-text-base);
  line-height: var(--lc-leading-normal);
}

@media (prefers-reduced-motion: reduce) {
  .cg-game-card { transition: none; }
}


/* ==========================================================================
   FLASHCARDS — /games/flashcards
   ========================================================================== */

/* ── Fallback grid (no JS). Every card is a native <details>. ────────────── */
.cg-fc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--lc-space-3);
  margin-top: var(--lc-space-4);
}
.cg-fc-card {
  background: var(--lc-base);
  border: 1px solid var(--lc-border);
  border-radius: var(--lc-radius-md);
  padding: var(--lc-space-4);
}
.cg-fc-card summary { cursor: pointer; font-weight: var(--lc-weight-semi); }
.cg-fc-card summary:focus-visible {
  outline: var(--lc-focus-width) solid var(--lc-focus-ring);
  outline-offset: var(--lc-focus-offset);
}
.cg-fc-term  { font-size: var(--lc-text-md); }
.cg-fc-ipa   { color: var(--lc-text-muted); font-weight: var(--lc-weight-normal);
               font-size: var(--lc-text-sm); }
.cg-fc-back  { margin-top: var(--lc-space-2); }
.cg-fc-gloss { font-size: var(--lc-text-base); line-height: var(--lc-leading-normal); }
.cg-fc-def   { color: var(--lc-text-muted); font-size: var(--lc-text-sm);
               line-height: var(--lc-leading-normal); margin-top: var(--lc-space-1); }
.cg-fc-forms { color: var(--lc-text-muted); font-size: var(--lc-text-sm);
               margin-top: var(--lc-space-1); }
.cg-fc-img   { max-height: 90px; display: block; margin-top: var(--lc-space-2);
               border-radius: var(--lc-radius-sm); }

/* The native disclosure marker STAYS in the grid — it is the only affordance
   on the no-JS path, and a styled chevron is not worth the risk there. */

/* ── Deck mode (JS added .cg-fc-deck) ───────────────────────────────────── */
.cg-fc-deck .cg-fc-grid { display: block; }
.cg-fc-deck .cg-fc-card { display: none; }

.cg-fc-deck .cg-fc-card.cg-fc-current {
  display: grid;
  grid-template-rows: auto 1fr auto;   /* term / meaning / hint */
  gap: var(--lc-space-4);
  max-width: 480px;
  min-height: 300px;                   /* the anti-layout-shift guarantee */
  margin: var(--lc-space-4) auto 0;
  padding: var(--lc-space-6);
  border-radius: var(--lc-radius-lg);
}

/* Marker belongs to the fallback grid, not the deck: in deck mode the Flip
   button is the affordance, and two competing affordances for one action is
   what ships today. */
.cg-fc-deck .cg-fc-card summary { list-style: none; cursor: pointer; }
.cg-fc-deck .cg-fc-card summary::-webkit-details-marker { display: none; }
.cg-fc-deck .cg-fc-card summary::marker { content: ""; }

.cg-fc-deck .cg-fc-current summary {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--lc-space-2);
  text-align: center;
}
.cg-fc-deck .cg-fc-current .cg-fc-term {
  font-size: var(--lc-text-2xl);
  font-weight: var(--lc-weight-medium);
  line-height: var(--lc-leading-tight);
  letter-spacing: -0.02em;
}
.cg-fc-deck .cg-fc-current .cg-fc-ipa { font-size: var(--lc-text-sm); }

/* Row 2. Fades in; NEVER animates height — the row is already reserved by
   grid-template-rows, so revealing the meaning cannot move the term.
   There is no 3D flip: <details> has one face and a slot, and the browser
   does not render the slot while closed. Two absolutely-positioned faces
   would destroy the <details> semantics and the no-JS story with them. */
.cg-fc-deck .cg-fc-current .cg-fc-back {
  grid-row: 2;
  margin: 0;
  padding-top: var(--lc-space-5);
  border-top: 1px solid var(--lc-border);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--lc-space-3);
  text-align: center;
  opacity: 0;
  transition: opacity var(--lc-duration-base) var(--lc-ease);
}
.cg-fc-deck .cg-fc-current[open] .cg-fc-back { opacity: 1; }

.cg-fc-deck .cg-fc-current .cg-fc-gloss { font-size: var(--lc-text-md); max-width: 38ch; }
.cg-fc-deck .cg-fc-current .cg-fc-img   { max-height: 132px; margin: 0; }

/* Row 3 — reveal hint. OPTIONAL: needs two new localised strings. If those
   are not affordable, omit the element entirely; row 3 collapses cleanly and
   the Flip button plus the pointer cursor still carry the affordance. */
.cg-fc-hint {
  grid-row: 3;
  text-align: center;
  font-size: var(--lc-text-sm);
  color: var(--lc-text-muted);
  border-top: 1px solid var(--lc-border);
  padding-top: var(--lc-space-3);
}

/* ── Audio control — flashcards only ───────────────────────────────────────
   Scoped to .cg-fc-card so the inline usages elsewhere ("Come si dice…? 🔊"
   inside sentences and table cells) keep their compact inline rendering. */
.cg-fc-card .cg-audio-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--lc-border-control);
  border-radius: var(--lc-radius-pill);
  background: var(--lc-base);
  transition: background-color var(--lc-duration-fast) var(--lc-ease),
              border-color     var(--lc-duration-fast) var(--lc-ease);
}
/* Kill the inherited scale() — a control that grows is a moving target. */
.cg-fc-card .cg-audio-link:hover,
.cg-fc-card .cg-audio-link:focus-visible { transform: none; }
.cg-fc-card .cg-audio-link:hover { background: var(--lc-surface-2); }

/* The shipped --playing state runs `cg-audio-pulse 1.2s ease-in-out infinite`
   plus scale(1.2), with NO prefers-reduced-motion guard (unlike its sibling
   --error shake, which has one). An infinitely pulsing element is on the
   brief's forbidden list. Static state that ends with playback instead.
   Also delete @keyframes cg-audio-pulse from site.css. audio-link.js is
   untouched — only the rendering of the class changes. */
.cg-fc-card .cg-audio-link--playing {
  transform: none;
  opacity: 1;
  animation: none;
  background: var(--lc-primary-subtle);
  border-color: var(--lc-primary);
}

/* ── Controls ──────────────────────────────────────────────────────────── */
.cg-fc-controls { display: none; }
.cg-fc-deck .cg-fc-controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--lc-space-3);
  margin-top: var(--lc-space-5);
  padding-top: var(--lc-space-5);
  border-top: 1px solid var(--lc-border);
}
.cg-fc-nav {
  display: flex;
  gap: var(--lc-space-3);
  justify-content: center;
  flex-wrap: wrap;
}
#cg-fc-flip { min-width: 140px; }

/* Shuffle is the only control that discards your position, and it currently
   sits in the same row as Next at the same weight. Demoted to a quiet text
   button on its own line: still one tap, no longer one tap away from Next. */
#cg-fc-shuffle {
  border: 0;
  background: none;
  color: var(--lc-primary);
  font-size: var(--lc-text-sm);
  padding: var(--lc-space-2) var(--lc-space-3);
}

/* Plain text, not a progress bar. A filling bar turns a study loop into a
   completion loop. Keep the existing aria-live="polite". */
#cg-fc-progress {
  font-size: var(--lc-text-sm);
  color: var(--lc-text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .cg-fc-deck .cg-fc-current .cg-fc-back,
  .cg-fc-card .cg-audio-link { transition: none; }
}
