/**
 * MOYAKO GAMES - UNIFIED CSS DESIGN SYSTEM
 *
 * This file establishes design tokens and shared component styles
 * used across ALL pages (landing, games hub, assessment, profiles, etc.)
 *
 * Import this file in all HTML pages:
 * <link rel="stylesheet" href="./shared/styles.css">
 */

/* v5_5 design tokens — chart + dashboard variables */
@import './styles/_tokens.css';

/* ===== FONT FACES (self-hosted — no Google CDN, GDPR per LG München 2022) ===== */
@font-face {
  font-family: 'Plus Jakarta Sans';
  src: url('./fonts/plus-jakarta-sans.woff2') format('woff2');
  font-weight: 500 800;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('./fonts/inter.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}

/* ==========================================================================
   ROOT DESIGN TOKENS — Global Standards (WCAG 2.2 AA/AAA, Apple HIG, Material 3)
   --------------------------------------------------------------------------
   DESIGN-RULES.md §10 mandates every game use these tokens instead of
   hardcoded px / rgba values. Contrast ratios are labeled inline; do NOT
   substitute less-accessible values in game CSS.
   Light theme values live here; dark-theme overrides follow in
   [data-theme="dark"] below — same token names, different values.
   ========================================================================== */
:root {
  /* ------- Brand colors ------- */
  --moyako-primary: #4CAF50;
  --moyako-primary-dark: #388E3C;
  --moyako-primary-light: #81C784;
  --moyako-accent: #FF9800;
  --moyako-accent-dark: #F57C00;

  /* ------- Background + surface ------- */
  --moyako-bg: #F0F0F0;
  --moyako-bg-light: #F5F5F5;
  --moyako-card: #FFFFFF;
  --moyako-surface-raised: #FFFFFF;        /* elevated above --moyako-card */
  --moyako-surface-sunken: #E8EAED;        /* recessed below --moyako-bg */

  /* ------- Text (WCAG 2.2 AA/AAA tested on --moyako-bg / --moyako-card) ------- */
  --moyako-text: #1F2937;                  /* 13.6:1 on #FFF — body text, AAA */
  --moyako-text-strong: #0F172A;           /* 17.7:1 — headings, AAA */
  --moyako-text-muted: #4B5563;            /* 7.6:1 — secondary labels, AAA */
  --moyako-text-subtle: #6B7280;           /* 4.8:1 — tertiary hints, AA */
  --moyako-text-on-primary: #FFFFFF;       /* 4.6:1 on #4CAF50 — AA (large/UI) */
  --moyako-text-on-accent:  #FFFFFF;       /* 4.5:1 on #FF9800 when bold — AA */

  /* ------- Borders + dividers ------- */
  --moyako-border: #D1D5DB;                /* 3.0:1 non-text (AA UI) */
  --moyako-border-light: #E5E7EB;
  --moyako-border-strong: #9CA3AF;         /* focus / emphasis */

  /* ------- Semantic ------- */
  --moyako-error: #D32F2F;                 /* 5.0:1 on #FFF — AA */
  --moyako-success: #2E7D32;               /* 5.6:1 on #FFF — AA */
  --moyako-warning: #E65100;               /* 5.2:1 on #FFF — AA */
  --moyako-info: #1565C0;                  /* 6.3:1 on #FFF — AAA */

  /* ------- Shadows ------- */
  --moyako-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.1);
  --moyako-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
  --moyako-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2);

  /* ------- Gradients ------- */
  --moyako-metallic: linear-gradient(135deg, #E8E8E8 0%, #F5F5F5 25%, #E0E0E0 50%, #F0F0F0 75%, #E8E8E8 100%);
  --moyako-card-grad: linear-gradient(145deg, #FFFFFF 0%, #F8F8F8 50%, #F0F0F0 100%);
  --moyako-primary-grad: linear-gradient(135deg, var(--moyako-primary), var(--moyako-primary-light));

  /* ------- Typography families (self-hosted, GDPR-compliant) ------- */
  --font-display: 'Plus Jakarta Sans', system-ui, -apple-system, Arial, sans-serif;
  --font-body: 'Inter', system-ui, -apple-system, Arial, sans-serif;

  /* ------- Fluid font scale (Apple HIG / Material 3 / NN/g readability) ------
     Uses clamp(min, preferred-vw, max) so small phones and large desktops
     both stay in the readable band.
     Rule of thumb (DESIGN-RULES.md §10):
       body ≥ 16px, secondary labels ≥ 13px, stat values 20–24 → 24–32 desktop */
  --font-size-caption: clamp(11px, 0.8vw, 12px);  /* only microcopy */
  --font-size-label:   clamp(13px, 1vw,   14px);  /* secondary labels */
  --font-size-body:    clamp(15px, 1.1vw, 16px);  /* paragraphs, inputs */
  --font-size-body-lg: clamp(16px, 1.2vw, 18px);  /* prominent body */
  --font-size-value:   clamp(18px, 1.6vw, 22px);  /* stat numbers */
  --font-size-value-lg: clamp(22px, 2.2vw, 30px); /* hero stats */
  --font-size-h3:      clamp(18px, 1.5vw, 22px);
  --font-size-h2:      clamp(22px, 2vw,   28px);
  --font-size-h1:      clamp(28px, 3vw,   40px);
  --line-height-ui:    1.3;
  --line-height-text:  1.5;
  --letter-spacing-uppercase: 0.4px;

  /* ------- Spacing (8-pt baseline grid) ------- */
  --space-0: 0;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  /* Legacy rem aliases (kept for pages that still use them) */
  --spacing-xs: 0.5rem;
  --spacing-sm: 1rem;
  --spacing-md: 1.5rem;
  --spacing-lg: 2rem;
  --spacing-xl: 3rem;

  /* ------- Icon sizes (Material 3 + Apple HIG) -------
     Standalone icon-only buttons MUST be ≥ 44×44 (Apple HIG) or
     ≥ 48×48 (Material MD3). Inline icons follow 1em flow. */
  --icon-size-xs: 16px;   /* inline, right next to 14–16px text */
  --icon-size-sm: 20px;   /* inline badges, chips */
  --icon-size-md: 24px;   /* default standalone icon */
  --icon-size-lg: 32px;   /* feature icon */
  --icon-size-xl: 48px;   /* hero icon */
  --tap-target-min: 44px; /* Apple HIG minimum */
  --tap-target-md:  48px; /* Material 3 default */
  --tap-target-lg:  56px; /* primary CTA on desktop */

  /* ------- Border radius ------- */
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-full: 50%;

  /* ------- Surfaces for shell panels (game-shell / cards on the gradient) ------ */
  --surface-panel:     rgba(255, 255, 255, 0.85);
  --surface-panel-alt: rgba(255, 255, 255, 0.70);

  /* ------- Z-indexes ------- */
  --z-sticky: 100;
  --z-header: 150;
  --z-modal:  200;
  --z-toast:  300;

  /* ------- Motion ------- */
  --motion-fast: 0.15s ease;
  --motion-med:  0.25s ease;
  --motion-slow: 0.4s  ease;
}

/* ==========================================================================
   DARK METALLIC THEME
   Dark-theme text contrast is the session's #1 accessibility bug.
   Values below are tested against the dominant dark bg #1a1a2e
   (WebAIM contrast checker):
     #ECEFF4 on #1a1a2e = 13.4:1  (AAA) — strong body / headings
     #CBD5E1 on #1a1a2e =  9.5:1  (AAA) — default body
     #B7C0D4 on #1a1a2e =  8.5:1  (AAA) — secondary labels
     #9AA3B7 on #1a1a2e =  5.5:1  (AA)  — tertiary hints (min allowed)
   DO NOT lower `--moyako-text-subtle` below #9AA3B7 — it fails AA.
   ========================================================================== */
[data-theme="dark"] {
  /* ------- Background + surface ------- */
  --moyako-bg: #1a1a2e;
  --moyako-bg-gradient: linear-gradient(135deg, #1a1a2e 0%, #16213e 25%, #0f3460 50%, #1a1a2e 75%, #16213e 100%);
  --moyako-card: rgba(255, 255, 255, 0.08);
  --moyako-card-hover: rgba(255, 255, 255, 0.12);
  --moyako-surface-raised: rgba(255, 255, 255, 0.10);
  --moyako-surface-sunken: rgba(0, 0, 0, 0.20);

  /* ------- Text (WCAG contrast vs #1a1a2e — see table above) ------- */
  --moyako-text: #CBD5E1;                  /* 9.5:1 — AAA */
  --moyako-text-strong: #ECEFF4;           /* 13.4:1 — AAA */
  --moyako-text-muted: #B7C0D4;            /* 8.5:1 — AAA */
  --moyako-text-subtle: #9AA3B7;           /* 5.5:1 — AA min */
  --moyako-text-on-primary: #FFFFFF;
  --moyako-text-on-accent:  #1a1a2e;       /* dark on accent in dark mode */

  /* ------- Borders ------- */
  --moyako-border: rgba(255, 255, 255, 0.12);       /* 3.1:1 UI contrast */
  --moyako-border-light: rgba(255, 255, 255, 0.06);
  --moyako-border-strong: rgba(255, 255, 255, 0.22);

  /* ------- Semantic (re-tuned for dark bg) ------- */
  --moyako-error:   #F87171;               /* 5.9:1 on #1a1a2e — AA */
  --moyako-success: #86EFAC;               /* 10.8:1 — AAA */
  --moyako-warning: #FCD34D;               /* 11.4:1 — AAA */
  --moyako-info:    #93C5FD;               /* 8.9:1 — AAA */

  /* ------- Surfaces for shell panels (override light values) ------- */
  --surface-panel:     rgba(255, 255, 255, 0.06);
  --surface-panel-alt: rgba(255, 255, 255, 0.04);

  /* ------- Shadows ------- */
  --moyako-header-bg: rgba(26, 26, 46, 0.95);
  --moyako-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
  --moyako-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4);
  --moyako-shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5);
}

[data-theme="dark"] body {
  background: var(--moyako-bg-gradient);
  color: var(--moyako-text);
}

[data-theme="dark"] .moyako-card {
  background: var(--moyako-card);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--moyako-border);
}

[data-theme="dark"] .moyako-header {
  background: var(--moyako-header-bg);
  backdrop-filter: blur(12px);
  border-bottom-color: var(--moyako-primary);
}

/* ===== RESET ===== */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* ===== BASE TYPOGRAPHY =====
 * NOTE: height must be `min-height: 100%` not `height: 100%` — on iOS
 * Safari, capping body to 100% of viewport clips content taller than the
 * window and can make the page feel "not scrollable" when the address
 * bar shows/hides (viewport shrinks). min-height keeps the fill-the-
 * screen behaviour for short pages while letting tall content grow.
 */
html, body {
  width: 100%;
  min-height: 100%;
  background: var(--moyako-metallic);
  color: var(--moyako-text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Title Case rule (DESIGN-RULES §3.16, 2026-05-08): titles use
 * sentence case / Title Case — only initial letters capital, never
 * shouting UPPERCASE. text-transform: uppercase removed from h1/h2/h3
 * globals. Per-element uppercase (badges, labels, micro-copy where
 * uppercase reads as a design treatment, not a title) is still OK. */
h1 {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 900;
  line-height: 1.2;
  color: var(--moyako-primary);
  letter-spacing: 0.5px;
  margin-bottom: 1rem;
}

h2 {
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 900;
  line-height: 1.3;
  color: var(--moyako-primary);
  letter-spacing: 0.5px;
  margin-bottom: 1rem;
}

h3 {
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 900;
  color: var(--moyako-primary);
  letter-spacing: 0.25px;
  margin-bottom: 0.75rem;
}

p {
  font-size: 1rem;
  line-height: 1.5;
  color: var(--moyako-text);
  margin-bottom: 1rem;
}

/* ===== HEADER / NAVIGATION ===== */
.moyako-header {
  background: linear-gradient(180deg, var(--moyako-card) 0%, var(--moyako-bg-light) 100%);
  border-bottom: 2px solid var(--moyako-primary);
  padding: var(--spacing-md) var(--spacing-lg);
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  box-shadow: var(--moyako-shadow-sm);
}

.moyako-header .moyako-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.moyako-logo {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 900;
  color: var(--moyako-primary);
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 2px;
}

.moyako-logo-icon {
  width: 50px;
  height: 50px;
  background: var(--moyako-primary-grad);
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3);
}

/* ===== BUTTONS ===== */
.moyako-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3) var(--space-6);
  min-height: var(--tap-target-md);  /* 48px — Material 3 */
  border: none;
  border-radius: var(--radius-md);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--font-size-label);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: all var(--motion-med);
  text-decoration: none;
  gap: var(--space-2);
  touch-action: manipulation;
}

.moyako-btn:focus-visible {
  outline: 3px solid var(--moyako-primary);
  outline-offset: 2px;
}

.moyako-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Primary Button */
.moyako-btn-primary {
  background: var(--moyako-primary-grad);
  color: white;
  box-shadow: var(--moyako-shadow-md);
}

.moyako-btn-primary:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: var(--moyako-shadow-lg);
}

.moyako-btn-primary:active:not(:disabled) {
  transform: translateY(0);
}

/* Secondary Button */
.moyako-btn-secondary {
  background: transparent;
  color: var(--moyako-primary);
  border: 2px solid var(--moyako-primary);
}

.moyako-btn-secondary:hover:not(:disabled) {
  background: rgba(76, 175, 80, 0.08);
}

/* Play / Accent Button */
.moyako-btn-play {
  background: linear-gradient(135deg, var(--moyako-accent), var(--moyako-accent-dark));
  color: white;
  box-shadow: var(--moyako-shadow-md);
}

.moyako-btn-play:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: var(--moyako-shadow-lg);
}

.moyako-btn-play:active:not(:disabled) {
  transform: translateY(0);
}

/* Large Button */
.moyako-btn-large {
  padding: var(--space-4) var(--space-10);
  font-size: var(--font-size-body);
  min-height: var(--tap-target-lg);  /* 56px — primary CTA */
}

/* ===== CARDS ===== */
.moyako-card {
  background: var(--moyako-card);
  border: 1px solid var(--moyako-border-light);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  box-shadow: var(--moyako-shadow-sm);
  transition: all 0.3s ease;
}

.moyako-card:hover {
  box-shadow: var(--moyako-shadow-md);
  transform: translateY(-2px);
}

/* ===== BADGES ===== */
.moyako-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.375rem 0.75rem;
  background: var(--moyako-primary);
  color: white;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  white-space: nowrap;
}

.moyako-badge-accent {
  background: var(--moyako-accent);
}

.moyako-badge-success {
  background: var(--moyako-success);
}

.moyako-badge-error {
  background: var(--moyako-error);
}

/* ===== CONTAINERS & LAYOUT ===== */
.moyako-container {
  max-width: 480px;
  width: 100%;
  margin: 0 auto;
  padding: 0 var(--spacing-md);
}

.moyako-container-lg {
  max-width: 1200px;
}

/* ===== UTILITY CLASSES ===== */
.moyako-text-center {
  text-align: center;
}

.moyako-text-muted {
  color: var(--moyako-text-muted);
}

.moyako-text-error {
  color: var(--moyako-error);
}

.moyako-text-success {
  color: var(--moyako-success);
}

.moyako-mt-sm { margin-top: var(--spacing-sm); }
.moyako-mt-md { margin-top: var(--spacing-md); }
.moyako-mt-lg { margin-top: var(--spacing-lg); }

.moyako-mb-sm { margin-bottom: var(--spacing-sm); }
.moyako-mb-md { margin-bottom: var(--spacing-md); }
.moyako-mb-lg { margin-bottom: var(--spacing-lg); }

.moyako-gap-sm { gap: var(--spacing-sm); }
.moyako-gap-md { gap: var(--spacing-md); }
.moyako-gap-lg { gap: var(--spacing-lg); }

/* ===== ANIMATIONS ===== */
@keyframes moyako-fade-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.moyako-fade-in {
  animation: moyako-fade-in 0.3s ease forwards;
}

@keyframes moyako-pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

.moyako-pulse {
  animation: moyako-pulse 2s ease-in-out infinite;
}

/* ===== ACCESSIBILITY ===== */
/* Minimum 44x44px tap targets for mobile */
button, a[role="button"], input[type="button"], input[type="submit"] {
  min-width: 44px;
  min-height: 44px;
}

/* Focus visible for keyboard navigation */
:focus-visible {
  outline: 3px solid var(--moyako-primary);
  outline-offset: 2px;
}

/* Respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ===== RESPONSIVE BREAKPOINTS ===== */
/* Mobile-first approach: styles default to mobile */
/* Tablet: min-width 640px */
@media (min-width: 640px) {
  :root {
    font-size: 16px;
  }

  .moyako-container {
    max-width: 620px;
  }

  h1 {
    font-size: 2rem;
  }

  h2 {
    font-size: 1.5rem;
  }
}

/* Desktop: min-width 1024px */
@media (min-width: 1024px) {
  .moyako-container {
    max-width: 960px;
  }

  .moyako-container-lg {
    max-width: 1200px;
  }

  h1 {
    font-size: 2.25rem;
  }

  h2 {
    font-size: 1.75rem;
  }
}

/* Large Desktop: min-width 1280px */
@media (min-width: 1280px) {
  .moyako-container-lg {
    max-width: 1280px;
  }
}

/* ===== PRINT STYLES ===== */
@media print {
  .moyako-header,
  .moyako-btn,
  [role="navigation"] {
    display: none;
  }
}

/* ===== THEME SWITCHER UTILITY ===== */
.moyako-theme-toggle {
  position: fixed;
  bottom: 80px;
  right: 16px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: var(--moyako-primary);
  color: white;
  font-size: 20px;
  cursor: pointer;
  z-index: 1000;
  box-shadow: var(--moyako-shadow-md);
  transition: transform 0.2s;
}

.moyako-theme-toggle:hover {
  transform: scale(1.1);
}

/* ============================================================
   Moyako Shared Difficulty Picker (used by chess, sudoku, etc.)
   Color-coded tiles with emoji + technique/tier label. Works in
   light and dark themes because the white text is always on a
   gradient background — no CSS-variable inheritance required.
   First shipped for Sudoku 2026-04-12; align all games to this.
   ============================================================ */

/* Single-column stack — 5 tier tiles reading top-to-bottom. Previously
   2-col with an orphaned 5th tile at the bottom. Single-column keeps the
   visual hierarchy (Beginner → Expert) obvious and scrolls cleanly on
   short screens. Gap tightened 10→8 px to match the compact single-line
   tile (name-only, no descriptions). */
.moyako-difficulty-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  margin-bottom: 20px;
}

.moyako-difficulty-btn {
  padding: 10px 14px;
  min-height: 44px;
  border: 0;
  border-radius: 10px;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.2s ease;
  text-align: center;
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  box-shadow: 0 3px 10px rgba(0,0,0,0.22);
  -webkit-tap-highlight-color: rgba(255,255,255,0.3);
  touch-action: manipulation;
  position: relative;
  overflow: hidden;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
}
.moyako-difficulty-btn:active { transform: scale(0.97); }
.moyako-difficulty-btn:hover  { box-shadow: 0 6px 18px rgba(0,0,0,0.35); }

.moyako-difficulty-btn[data-tier="beginner"] { background: linear-gradient(135deg, #4DD0E1 0%, #0097A7 100%); }
.moyako-difficulty-btn[data-tier="easy"]     { background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%); }
.moyako-difficulty-btn[data-tier="medium"]   { background: linear-gradient(135deg, #FF9800 0%, #E65100 100%); }
.moyako-difficulty-btn[data-tier="hard"]     { background: linear-gradient(135deg, #E53935 0%, #B71C1C 100%); }
.moyako-difficulty-btn[data-tier="expert"]   { background: linear-gradient(135deg, #9C27B0 0%, #4A148C 100%); }

/* Single-select state — frame-only so the gradient + white text stay
   visible. The previous pattern washed the tile white on click, which
   hid the emoji, tier name, and description. */
.moyako-difficulty-btn.active {
  outline: 3px solid #fff;
  outline-offset: -5px;
  box-shadow:
    0 0 0 3px rgba(255,255,255,0.75),
    0 6px 18px rgba(0,0,0,0.45);
  transform: scale(1.02);
}
.moyako-difficulty-btn.active::after {
  content: '✓';
  position: absolute;
  top: 6px;
  right: 8px;
  font-size: 14px;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}

/* Two-section difficulty modal — two symmetric containers stacked:
     .moyako-intro-section   (top    ≈ 50 %)  — icon · title · skills · tier pill
     .moyako-actions-section (bottom ≈ 50 %)  — pills (col 1) · actions (col 2)
   Both sections share visual treatment (background, border, padding)
   so they read as equal siblings rather than "chrome + loose buttons".

   Legacy structure (icon, title, subtitle, grid, button as flat direct
   children — pre-.moyako-intro-section) still works: first three spans
   both cols, grid takes row 2 col 1, trailing button takes row 2 col 2. */
.moyako-difficulty-modal {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 10px;
  max-width: 440px;
  width: min(440px, calc(100vw - 24px));
  height: min(560px, calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 24px));
  max-height: calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 24px);
  overflow: hidden;
  box-sizing: border-box;
}
/* Legacy fallback — modal without explicit sections switches back to
   2-col / 2-row (icon/title/subtitle in row 1, pills+buttons in row 2). */
.moyako-difficulty-modal:not(:has(.moyako-intro-section)):not(:has(.moyako-actions-section)) {
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  grid-template-rows: minmax(auto, 1fr) minmax(auto, 1fr);
  gap: 8px 12px;
  height: auto;
}
.moyako-difficulty-modal > .moyako-intro-section,
.moyako-difficulty-modal > .moyako-actions-section {
  min-height: 0;
  overflow: hidden;
}
/* Intro section spans both cols on row 1 and stacks its own children
   (icon, title, skills, tier) vertically centered. */
.moyako-difficulty-modal > .moyako-intro-section {
  grid-row: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 8px;
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 12px;
}
/* Actions section sits in row 2 (below intro). Width spans the full
   modal. Internal 2-col grid is handled by .moyako-actions-section rules. */
.moyako-difficulty-modal > .moyako-actions-section {
  grid-row: 2;
}
.moyako-intro-icon { font-size: 44px; line-height: 1; }
.moyako-intro-title {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 1px;
  color: #ECEFF4;
  text-align: center;
}
.moyako-intro-skills { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.moyako-intro-skill {
  font-size: 11px;
  font-weight: 600;
  color: #ECEFF4;
  background: rgba(0,0,0,0.25);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 999px;
  padding: 4px 10px;
  white-space: nowrap;
}
.moyako-intro-tier {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 1px;
  color: #fff;
  background: linear-gradient(135deg, #FF9800 0%, #E65100 100%);
  border-radius: 999px;
  padding: 6px 16px;
  text-transform: uppercase;
}
.moyako-intro-tier[data-tier="beginner"] { background: linear-gradient(135deg, #4DD0E1 0%, #0097A7 100%); }
.moyako-intro-tier[data-tier="easy"]     { background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%); }
.moyako-intro-tier[data-tier="medium"]   { background: linear-gradient(135deg, #FF9800 0%, #E65100 100%); }
.moyako-intro-tier[data-tier="hard"]     { background: linear-gradient(135deg, #E53935 0%, #B71C1C 100%); }
.moyako-intro-tier[data-tier="expert"]   { background: linear-gradient(135deg, #9C27B0 0%, #4A148C 100%); }
/* Actions section — mirrors the intro section visually (same bg, border,
   padding). Internally a 2-col grid: pills left, action buttons right.
   Both columns share the SAME total height (stretch to row), and the
   items inside each column share that height evenly via grid-auto-rows
   so 5 pills and 2–3 action buttons end up with equal-height tiles. */
.moyako-actions-section {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  grid-template-rows: 1fr;
  gap: 8px 10px;
  padding: 10px 12px;
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 12px;
  align-items: stretch;
  overflow: hidden;
}
.moyako-actions-section > .moyako-difficulty-grid {
  grid-column: 1;
  grid-row: 1;
  margin-bottom: 0;
  align-self: stretch;
  height: 100%;
  display: grid;
  grid-auto-rows: 1fr;   /* 5 pills split the column height evenly */
  gap: 8px;
  min-height: 0;
}
.moyako-actions-section > button,
.moyako-actions-section > .overlay-buttons {
  grid-column: 2;
  grid-row: 1;
  align-self: stretch;
  margin-top: 0 !important;
  height: 100%;
  min-height: 0;
}
.moyako-actions-section > .overlay-buttons {
  display: grid;
  grid-auto-rows: 1fr;   /* 1-3 action buttons split the column evenly */
  gap: 8px;
  height: 100%;
}
/* Pills + action buttons inside actions-section share a tight preset
   (min-height:0, padding trimmed, uppercase labels) so they scale down
   cleanly as the grid-auto-rows:1fr redistributes vertical space. */
.moyako-actions-section .moyako-difficulty-btn {
  min-height: 0 !important;
  padding: 4px 10px !important;
  font-size: 13px !important;
  line-height: 1.15;
}
[data-theme="light"] .moyako-actions-section {
  background: rgba(0,0,0,0.03);
  border-color: rgba(0,0,0,0.08);
}

[data-theme="light"] .moyako-difficulty-modal > .moyako-intro-section {
  background: rgba(0,0,0,0.03);
  border-color: rgba(0,0,0,0.08);
}
[data-theme="light"] .moyako-intro-title { color: #2D2D2D; }
[data-theme="light"] .moyako-intro-skill {
  color: #2D2D2D;
  background: rgba(255,255,255,0.6);
  border-color: rgba(0,0,0,0.1);
}

/* Legacy pre-grid children (icon/title/subtitle before a modal adopts
   .moyako-intro-section) still span both cols in row 1. Exclude
   .overlay-buttons / bare <button> so they don't steal row 1 when
   the modal has <3 pre-grid children. */
.moyako-difficulty-modal > :nth-child(1):not(.moyako-intro-section):not(.moyako-actions-section):not(.moyako-difficulty-grid):not(.overlay-buttons):not(button),
.moyako-difficulty-modal > :nth-child(2):not(.moyako-intro-section):not(.moyako-actions-section):not(.moyako-difficulty-grid):not(.overlay-buttons):not(button),
.moyako-difficulty-modal > :nth-child(3):not(.moyako-intro-section):not(.moyako-actions-section):not(.moyako-difficulty-grid):not(.overlay-buttons):not(button) {
  grid-column: 1 / -1;
  grid-row: 1;
  align-self: center;
  justify-self: center;
  text-align: center;
}
.moyako-difficulty-modal > .moyako-difficulty-grid {
  grid-column: 1;
  grid-row: 2;
  margin-bottom: 0;
  align-self: stretch;
}
.moyako-difficulty-modal > .moyako-difficulty-grid ~ button,
.moyako-difficulty-modal > .moyako-difficulty-grid ~ .overlay-buttons {
  grid-column: 2;
  grid-row: 2;
  align-self: stretch;
  margin-top: 0 !important;
  height: 100%;
  min-height: 0;
}
.moyako-difficulty-modal > .overlay-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 100%;
}
/* Col-2 action buttons split the 5-pill column height evenly and wrap
   labels cleanly rather than breaking mid-word in a narrow column. */
.moyako-difficulty-modal > .moyako-difficulty-grid ~ button,
.moyako-difficulty-modal > .overlay-buttons > button {
  margin-top: 0 !important;
  width: 100%;
  flex: 1 1 0 !important;
  height: auto !important;
  min-height: 44px;
  font-size: 12px !important;
  line-height: 1.15 !important;
  padding: 8px 4px !important;
  white-space: normal;
  word-break: keep-all;
  overflow-wrap: break-word;
}
/* Very narrow screens — fall back to single-column stack so pills
   don't get squeezed below readable width. */
@media (max-width: 339px) {
  .moyako-difficulty-modal {
    grid-template-columns: 1fr;
  }
  .moyako-difficulty-modal > .moyako-difficulty-grid,
  .moyako-difficulty-modal > .moyako-difficulty-grid ~ button,
  .moyako-difficulty-modal > .moyako-difficulty-grid ~ .overlay-buttons {
    grid-column: 1;
  }
}

/* ============================================================
   Shared game-page mobile conventions (2026-04-23)
   Every body[data-no-bottom-nav][data-page-brand-label] except Sudoku
   (which runs its own bespoke mobile layout) inherits these:
     • no right-edge swipe drawer chevron — stats panel flows inline
     • stats panel static under the board
     • ad banner pinned to the bottom of the viewport
   Sudoku is explicitly excluded via :not([data-page-brand-label="Sudoku"]).
   ============================================================ */
@media (max-width: 1024px) {
  body[data-no-bottom-nav][data-page-brand-label]:not([data-page-brand-label="Sudoku"]) #moyako-drawer-toggle,
  body[data-no-bottom-nav][data-page-brand-label]:not([data-page-brand-label="Sudoku"]) #moyako-drawer-backdrop {
    display: none !important;
  }
  body[data-no-bottom-nav][data-page-brand-label]:not([data-page-brand-label="Sudoku"]) .moyako-stats-panel {
    position: static !important;
    transform: none !important;
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    max-height: none !important;
    box-shadow: none !important;
    border-left: 0 !important;
    padding: 8px !important;
    margin: 0 auto !important;
  }
  body[data-no-bottom-nav][data-page-brand-label]:not([data-page-brand-label="Sudoku"]) .moyako-game-shell {
    grid-template-columns: 1fr !important;
    grid-template-rows: auto auto !important;
  }
  body[data-no-bottom-nav][data-page-brand-label]:not([data-page-brand-label="Sudoku"]) #moyako-ad-bottom {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    height: clamp(50px, 10dvh, 81px) !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 8px !important;
    background: var(--moyako-bg, #1A1E2A) !important;
    z-index: 90 !important;
    box-sizing: border-box !important;
  }
  body[data-no-bottom-nav][data-page-brand-label]:not([data-page-brand-label="Sudoku"]) #moyako-ad-bottom > * {
    max-width: 100%;
    max-height: 100%;
  }
}

/* ============================================================
   Shared "landing overlay" template (2026-04-23)
   Any game's start overlay can opt in by adding .moyako-landing-screen
   to the outer overlay element (alongside .overlay / .moyako-overlay /
   whatever the game already uses for backdrop toggling).

   Effect: the overlay stops being a centred-modal-on-a-dim-backdrop
   and becomes a full-band landing screen between the brand bar (top
   50 px) and the ad banner (bottom ~10dvh). The .moyako-difficulty-
   modal inside it is forced to fill the band at 100 % height so the
   intro + actions sections split 50/50 based on the viewport.
   ============================================================ */
.moyako-landing-screen,
.overlay.moyako-landing-screen,
.moyako-overlay.moyako-landing-screen {
  position: fixed !important;
  top: 50px !important;
  left: 0 !important;
  right: 0 !important;
  bottom: 56px !important;                /* reserve the ad banner height */
  background: var(--moyako-bg, #1A1E2A) !important;
  z-index: 500 !important;
  padding: 12px !important;
  align-items: stretch !important;
  overflow: hidden !important;
}
/* ============================================================
   Clean landing template — one set of rules, no conflicts.
   Mobile portrait : intro stacked above actions (2 rows).
   Desktop/landscape: intro | actions side-by-side (2 cols).
   Modal sizes to its content, centred inside the landing band.
   ============================================================ */
.moyako-landing-screen {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 16px !important;
}
/* Sprint 5c — respect the [hidden] attribute so state-machine toggles
   (e.g. chess hidePicker() sets pickerState.hidden = true) can actually
   hide the overlay despite the display:flex !important above. */
.moyako-landing-screen[hidden] {
  display: none !important;
}
.moyako-landing-screen .overlay-content,
.moyako-landing-screen .moyako-overlay-content {
  max-width: none !important;
  width: 100% !important;
  max-width: 500px !important;
  height: auto !important;
  max-height: calc(100% - 16px) !important;
  margin: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  padding: 0 !important;
}
.moyako-landing-screen .moyako-difficulty-modal {
  display: grid !important;
  grid-template-columns: 1fr !important;
  grid-template-rows: auto auto !important;
  width: 100% !important;
  max-width: 100% !important;
  height: auto !important;
  max-height: 100% !important;
  gap: 12px !important;
  overflow: hidden !important;
}
/* Mobile portrait: intro row 1, actions row 2. */
.moyako-landing-screen .moyako-difficulty-modal > .moyako-intro-section {
  grid-column: 1 !important;
  grid-row: 1 !important;
}
.moyako-landing-screen .moyako-difficulty-modal > .moyako-actions-section {
  grid-column: 1 !important;
  grid-row: 2 !important;
}

@media (min-width: 769px), (orientation: landscape) and (min-width: 600px) {
  .moyako-landing-screen .overlay-content,
  .moyako-landing-screen .moyako-overlay-content {
    max-width: min(760px, 80vw) !important;
  }
  .moyako-landing-screen .moyako-difficulty-modal {
    grid-template-columns: 1fr 1fr !important;
    grid-template-rows: 1fr !important;
    gap: 14px !important;
  }
  .moyako-landing-screen .moyako-difficulty-modal > .moyako-intro-section {
    grid-column: 1 !important;
    grid-row: 1 !important;
  }
  .moyako-landing-screen .moyako-difficulty-modal > .moyako-actions-section {
    grid-column: 2 !important;
    grid-row: 1 !important;
  }
}

/* Desktop polish (≥1024) — modal grows to 1100px so the 2-col landing
   actually fills the viewport instead of sitting as a 760px island at
   1440+. Intro typography upsized so the intro column reads as a hero
   card, not a phone card centred in empty space. PR-6b.7 polish. */
@media (min-width: 1024px) {
  .moyako-landing-screen .overlay-content,
  .moyako-landing-screen .moyako-overlay-content {
    max-width: min(1100px, 90vw) !important;
  }
  .moyako-landing-screen .moyako-difficulty-modal > .moyako-intro-section {
    padding: 36px 28px !important;
    gap: 18px !important;
  }
  .moyako-landing-screen .moyako-intro-icon {
    font-size: 72px !important;
  }
  .moyako-landing-screen .moyako-intro-title {
    font-size: 36px !important;
    letter-spacing: 2px !important;
  }
  .moyako-landing-screen .moyako-intro-skill {
    font-size: 13px !important;
    padding: 6px 14px !important;
  }
  .moyako-landing-screen .moyako-intro-tier {
    font-size: 16px !important;
    padding: 8px 22px !important;
  }
  .moyako-landing-screen .moyako-difficulty-modal > .moyako-actions-section {
    padding: 20px 22px !important;
    gap: 14px 18px !important;
  }
  .moyako-landing-screen .moyako-actions-section .moyako-difficulty-btn {
    padding: 10px 16px !important;
    font-size: 15px !important;
  }
}

/* Hide the game shell when a landing overlay is visible. Each game's
   JS toggles the overlay differently; using per-game narrow selectors
   avoids false matches when an overlay is present but closed. */
body[data-page-brand-label="Chess"]:has(#startOverlay.active) .moyako-game-shell,
body[data-page-brand-label="Memory Game"]:has(#startOverlay.active) .moyako-game-shell,
body[data-page-brand-label="Maze"]:has(#startOverlay.active) .moyako-game-shell,
body[data-page-brand-label="Word Puzzle"]:has(#startOverlay:not(.hidden)) .moyako-game-shell,
body[data-page-brand-label="Backgammon"]:has(#bg-difficulty-overlay:not(.hidden)) .moyako-game-shell,
body[data-page-brand-label="Block Puzzle"]:has(#blockPuzzleStartOverlay:not(.hidden)) .moyako-game-shell {
  visibility: hidden !important;
}

/* Single-line tile at 44 px — Apple HIG tap-target minimum. */
.moyako-difficulty-btn {
  min-height: 44px;
}

.moyako-difficulty-name {
  font-weight: 700;
  font-size: var(--font-size-body);
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.3);
  line-height: 1.2;
}

@media (max-width: 480px) {
  .moyako-difficulty-grid { gap: 6px; }
  .moyako-difficulty-btn { padding: 8px 10px; font-size: 13px; }
}

/* ============================================================
   Moyako Shared Game Shell (TASK-010)
   Canonical 3-panel layout used by every game page:
     Header (brand bar + back row) — from shared/components.js
     [ left-panel ] [ board-center ] [ right-panel ]
     Footer (bottom nav) — from shared/components.js

   Left panel: 🐼 panda coach reserved top 70% (future video/story),
               skills training compact 2-col grid bottom 30%.
   Right panel: game stats grid, difficulty row, controls, history,
                captured/end-state preview.

   Mobile ≤1024px collapses to single column with priority order:
   coach → board → stats → controls → history.
   ============================================================ */

.moyako-game-shell {
  display: grid;
  /* `auto` columns hug their content, so the side panels sit flush
     next to the board instead of stretching to fill leftover space
     (which left empty gaps between panels and the centered board).
     `justify-content: center` centers the whole trio in the viewport.
     `align-items: stretch` makes side panels grow to match the tallest
     column (the board), so their bottom edges align with the board's
     bottom — previously panels were shorter and left an uneven gap. */
  grid-template-columns: 240px auto 240px;
  justify-content: center;
  gap: var(--space-5);
  max-width: 1600px;
  margin: 0 auto;
  padding: var(--space-4);
  box-sizing: border-box;
  align-items: stretch;
  /* Explicit min-height so the shell isn't squeezed to whichever
     panel / board is currently the shortest. Caps at 820 px on huge
     monitors; floor uses (100dvh - 120 px) reserving just the brand
     bar + ad banner (bottom nav is opt-out via data-no-bottom-nav). */
  min-height: min(820px, calc(100dvh - 120px));
}

/* Game title at the top of the coach panel — replaces the old
   standalone page-header bar. User feedback 2026-04-12:
   "game name could be a bit colorful or dominant with frame" —
   gave it a brand-green gradient tile so it reads as the prominent
   name-plate for the current game (parallel to the tier-gradient
   difficulty pill on the opposite panel). */
.moyako-game-title {
  display: block;
  font-family: var(--font-display);
  font-size: var(--font-size-h3);
  color: #fff;
  text-align: center;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  background: linear-gradient(135deg, var(--moyako-primary) 0%, var(--moyako-primary-dark) 100%);
  padding: 10px 16px;
  border-radius: var(--radius-md);
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
  text-shadow: 0 1px 2px rgba(0,0,0,0.35);
  margin: 0;
  line-height: 1.15;
}

/* Friendly greeting line below the game title. Rendered by
   MoyakoComponents.renderGreeting() — personalized when the user is
   logged in (reads moyako_user from localStorage) and time-of-day
   based otherwise. Visually lighter than the title so the hierarchy
   reads Title > Greeting > Coach message. */
.moyako-game-greeting {
  font-size: var(--font-size-label);
  color: var(--moyako-text-muted);
  text-align: center;
  margin: 0 0 var(--space-2) 0;
  line-height: 1.3;
}

.moyako-coach-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--surface-panel);
  border: 1px solid var(--moyako-border-light);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--moyako-shadow-sm);
  color: var(--moyako-text);
  /* No forced min-height — the panel stretches to match the tallest
     grid row (usually the board) via align-items: stretch. If it has
     more content than the board height, the panel drives the row
     height and the board is vertically centered in its column.
     No overflow-y: auto — an earlier version hid Skills / Move History
     under a scroll fold on shorter viewports. */
}
/* Panda slot: ~70 % of panel height, reserved for future video/story
   interactions (TASK-010 Phase 2). For v1 just shows the panda asset
   + coach message. `flex: 7 1 0` gives it the first 70% slice;
   `.moyako-coach-skills` takes the rest via `margin-top: auto` so the
   skills block sticks to the bottom edge of the panel — when the panel
   stretches to match a tall board, the extra space lands inside
   coach-top (making room for future video/story content) rather than
   leaving a dead gap between coach-top and skills. */
.moyako-coach-top {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  padding: 8px;
  background: rgba(76,175,80,0.05);
  border-radius: 10px;
  min-height: 220px;
}
.moyako-coach-top img,
.moyako-coach-top .panda-avatar {
  width: 120px;
  height: auto;
  max-width: 100%;
}
.moyako-coach-message {
  font-size: var(--font-size-body);
  line-height: var(--line-height-text);
  color: var(--moyako-text);
  padding: var(--space-2) var(--space-1) 0;
}
/* Skills training block — stuck to the bottom of the coach panel via
   `margin-top: auto` so the panel's bottom edge visually aligns with
   the board's bottom edge (user feedback 2026-04-12). */
.moyako-coach-skills {
  margin-top: auto;
  flex: 0 0 auto;
  border-top: 1px solid var(--moyako-border-light);
  padding-top: var(--space-3);
}
.moyako-coach-skills h4 {
  font-size: var(--font-size-label);
  font-weight: 700;
  letter-spacing: var(--letter-spacing-uppercase);
  text-transform: uppercase;
  color: var(--moyako-text-muted);
  margin: 0 0 var(--space-3) 0;
}
.moyako-coach-skills ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2) var(--space-3);
}
.moyako-coach-skills li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-label);
  line-height: var(--line-height-ui);
  color: var(--moyako-text);
}

.moyako-stats-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--surface-panel);
  border: 1px solid var(--moyako-border-light);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--moyako-shadow-sm);
  color: var(--moyako-text);
  /* If the panel has more content than the board height, it drives
     the grid row height — board centers in its column. We deliberately
     DO NOT clip with overflow-y: auto, which was hiding Move History +
     Captured below a scroll fold on shorter viewports. */
}
.moyako-stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}
.moyako-stat-box {
  background: var(--surface-panel-alt);
  border: 1px solid var(--moyako-border-light);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-3);
  text-align: center;
  color: var(--moyako-text);
}
/* Secondary label — --moyako-text-muted hits AAA contrast on both themes
   (7.6:1 light, 8.5:1 dark), replacing the previous opacity-0.75 hack. */
.moyako-stat-box > div:first-child {
  font-size: var(--font-size-label);
  color: var(--moyako-text-muted);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-uppercase);
  line-height: var(--line-height-ui);
}
.moyako-stat-box > div:last-child {
  font-size: var(--font-size-value);
  font-weight: 700;
  color: var(--moyako-text-strong);
  margin-top: var(--space-1);
  line-height: 1.2;
}

.moyako-board-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Center the board vertically inside its grid column. When the side
     panels are taller than the board (common when the stats panel is
     scrolled to its content height), the board was pinned to the top
     leaving a visible gap underneath; center keeps it optically
     balanced. */
  justify-content: center;
  gap: 10px;
}

/* Bounded-scroll region inside a stats/coach panel — use this to wrap
   secondary content (move history, captured pieces, log, etc.) so the
   panel's overall height stays equal to the board's height while the
   secondary content scrolls internally when there's more of it than
   fits. Relies on the panel being a flex column. */
.moyako-panel-scroll {
  flex: 1 1 auto;
  /* Guaranteed minimum visible area so users always see at least a
     row or two of move history / captured pieces even when the parent
     row is short. Without this, flex: 1 1 0 + short panel collapses
     the region to 0 height and the content becomes invisible. */
  min-height: 140px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  scrollbar-width: thin;
}

/* ===================================================================
   OVERLAYS — shared game overlay pattern (difficulty picker, game-over)
   Nearly-opaque dark backdrop so the game board doesn't distract.
   All games inherit these; game-specific overrides go in the game's
   own <style> block.
   =================================================================== */
.moyako-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(10, 12, 18, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 16px;
}
.moyako-overlay.hidden { display: none; }
.moyako-overlay-content {
  background: var(--card-bg, #232838);
  color: var(--moyako-text-strong, #ECEFF4);
  border-radius: 16px;
  padding: 24px 22px;
  text-align: center;
  max-width: 340px;
  width: calc(100% - 48px);
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
  animation: moyako-slideUp 0.3s ease-out;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.moyako-overlay-title {
  font-size: var(--font-size-h3, 20px);
  font-weight: 700;
  margin-bottom: 6px;
  color: var(--moyako-text-strong, #ECEFF4);
}
.moyako-overlay-subtitle {
  font-size: var(--font-size-label, 13px);
  color: var(--moyako-text-muted, #888);
  margin-bottom: 16px;
}
@keyframes moyako-slideUp {
  from { transform: translateY(20px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
@media (max-width: 768px) {
  .moyako-overlay-content { padding: 20px 16px; max-width: 340px; width: calc(100% - 32px); }
}

/* ===================================================================
   PLAYER CARDS v2 — 3-section stats panel (wireframe v11 approved).
   Section 1: You (hero avatar + name + scores + captures/pip)
   Section 2: Opponent (same layout)
   Section 3: Game (turn banner + clock/dice + move history)
   Buttons pinned to bottom.
   =================================================================== */

/* Player section — dominant background for player cards */
.moyako-player-section {
  border-radius: var(--radius-md, 10px);
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.12);
  padding: 10px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.moyako-player-section.active-turn {
  background: rgba(76,175,80,0.12);
  border-color: rgba(76,175,80,0.4);
  box-shadow: 0 0 12px rgba(76,175,80,0.08);
}

/* Hero row — avatar + name + subtitle */
.moyako-hero-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  margin: -4px -4px 4px -4px;
}
.moyako-hero-row.white-header { background: rgba(240,240,240,0.10); border-bottom: 2px solid rgba(240,240,240,0.25); }
.moyako-hero-row.black-header { background: rgba(80,80,100,0.12); border-bottom: 2px solid rgba(100,100,120,0.25); }

/* Hero avatar — black fill, game-color border */
.moyako-hero-avatar {
  width: 56px; height: 56px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 32px; flex-shrink: 0;
  background: #1a1a2e;
  box-shadow: 0 3px 12px rgba(0,0,0,0.4);
}
.moyako-hero-avatar.white-side { border: 4px solid #f0f0f0; }
.moyako-hero-avatar.black-side { border: 4px solid #555; }
.moyako-hero-avatar.light-side { border: 4px solid #f0f0f0; }
.moyako-hero-avatar.dark-side  { border: 4px solid #555; }

.moyako-hero-info { flex: 1; }
.moyako-hero-name { font-weight: 700; font-size: 15px; margin-bottom: 2px; }
.moyako-hero-sub { font-size: 11px; color: var(--moyako-text-muted, #888); }

/* Score badges */
.moyako-scores-row { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.moyako-score-badge {
  font-size: 11px; color: #ccc;
  padding: 3px 8px;
  background: rgba(255,255,255,0.06);
  border-radius: 6px;
  display: flex; align-items: center; gap: 3px;
}
.moyako-score-badge strong { color: #fff; font-size: 13px; }

/* Captures — visible but secondary */
.moyako-captures-row { margin-top: 6px; font-size: 20px; letter-spacing: 3px; min-height: 26px; opacity: 0.75; }
.moyako-captures-adv { font-size: 13px; color: #81C784; font-weight: 700; vertical-align: middle; margin-left: 6px; letter-spacing: 0; opacity: 1; }

/* Pip + home progress (backgammon) */
.moyako-pip-row { display: flex; justify-content: space-between; align-items: center; margin-top: 6px; }
.moyako-pip-val { font-size: 13px; color: #ccc; }
.moyako-pip-val strong { color: #fff; font-size: 16px; }
.moyako-home-bar { height: 8px; border-radius: 4px; background: rgba(255,255,255,0.08); margin-top: 4px; overflow: hidden; }
.moyako-home-fill { height: 100%; border-radius: 4px; background: #4CAF50; transition: width 0.3s; }

/* Turn dot */
.moyako-turn-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: #4CAF50;
  display: inline-block; vertical-align: middle; margin-right: 4px;
  animation: moyako-pulse 1.5s ease-in-out infinite;
}
@keyframes moyako-pulse { 0%,100%{opacity:1} 50%{opacity:0.3} }

/* Turn banner */
.moyako-turn-banner { text-align: center; padding: 6px; border-radius: 8px; font-weight: 700; font-size: 14px; margin-bottom: 6px; }
.moyako-turn-banner.yours { background: rgba(76,175,80,0.15); color: #81C784; }
.moyako-turn-banner.theirs { background: rgba(255,152,0,0.12); color: #FFB74D; }

/* Big clock */
.moyako-big-clock { text-align: center; font-size: 32px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--moyako-text-strong, #ECEFF4); letter-spacing: 2px; margin: 4px 0; }
.moyako-big-clock.low { color: #EF5350; animation: moyako-clockPulse 1s ease-in-out infinite; }
@keyframes moyako-clockPulse { 0%,100%{opacity:1} 50%{opacity:0.6} }

/* Big dice (backgammon) */
.moyako-dice-area { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 6px 0; }
.moyako-big-dice {
  width: 56px; height: 56px;
  border-radius: 12px;
  background: linear-gradient(180deg, #f5f5f5, #ddd);
  color: #1a1a2e;
  display: flex; align-items: center; justify-content: center;
  font-size: 28px; font-weight: 800;
  box-shadow: 0 4px 12px rgba(0,0,0,0.4), inset 0 2px 0 rgba(255,255,255,0.8);
}
.moyako-roll-btn {
  flex: 1; padding: 14px;
  border-radius: 12px; font-size: 16px; font-weight: 800; text-align: center;
  background: linear-gradient(180deg, #2A3040, #1A1E2A);
  color: #81C784; border: 1px solid rgba(76,175,80,0.3); cursor: pointer;
}

/* Move counter row below dice */
.moyako-move-row { text-align: center; font-size: 11px; color: #666; margin-top: 4px; letter-spacing: 0.5px; }
.moyako-move-row strong { color: #aaa; font-size: 14px; }

/* Challenge tile (replaces difficulty pill in MP) */
.moyako-challenge-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: 10px 14px; border-radius: 10px;
  background: linear-gradient(135deg, rgba(107,142,250,0.2), rgba(74,111,232,0.12));
  border: 1px solid rgba(107,142,250,0.35);
  color: #90AAFF; font-weight: 700; font-size: 13px;
  margin-bottom: 8px; flex-shrink: 0;
}
.moyako-challenge-vs { font-size: 18px; font-weight: 800; color: #FFB74D; }

/* Match tracker — series dots */
.moyako-match-tracker { display: flex; align-items: center; justify-content: center; gap: 6px; }
.moyako-match-label { font-size: 10px; color: #888; text-transform: uppercase; letter-spacing: 0.5px; }
.moyako-match-dots { display: flex; gap: 4px; }
.moyako-match-dot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.15); background: transparent; }
.moyako-match-dot.won { background: #4CAF50; border-color: #4CAF50; }
.moyako-match-dot.lost { background: #EF5350; border-color: #EF5350; }
.moyako-match-dot.current { border-color: #FFB74D; animation: moyako-pulse 1.5s ease-in-out infinite; }
.moyako-match-score { font-size: 16px; font-weight: 800; }
.moyako-match-score.green { color: #81C784; }
.moyako-match-score.red { color: #EF5350; }

/* Challenge banner (inline within opponent card) */
.moyako-challenge-banner { margin-top: 6px; padding: 6px 10px; border-radius: 8px; background: linear-gradient(135deg, rgba(255,152,0,0.15), rgba(255,87,34,0.10)); border: 1px solid rgba(255,152,0,0.3); font-size: 12px; color: #FFB74D; display: flex; align-items: center; gap: 6px; }

/* Game section — less dominant than player sections */
.moyako-game-section {
  border-radius: var(--radius-md, 10px);
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.06);
  padding: 10px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

/* Move history */
.moyako-move-list { flex: 1; overflow-y: auto; font-size: 11px; min-height: 0; margin-top: 4px; }
.moyako-move-entry { display: flex; gap: 8px; padding: 1px 0; color: #8890a0; }
.moyako-move-num { color: #555; width: 16px; }

/* Game stats row */
.moyako-game-stats {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px; border-radius: var(--radius-md, 10px);
  background: var(--surface-panel-alt, rgba(255,255,255,0.04));
  border: 1px solid var(--moyako-border-light, rgba(255,255,255,0.08));
  font-size: 13px;
}
.moyako-game-stats-item { text-align: center; }
.moyako-game-stats-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--moyako-text-muted, #888); margin-bottom: 2px; }
.moyako-game-stats-value {
  font-size: 15px;
  font-weight: 700;
  color: var(--moyako-text-strong, #ECEFF4);
}

/* ===================================================================
   SHARED BUTTONS — consistent across all games.
   =================================================================== */
.btn {
  padding: 10px 18px;
  min-height: var(--tap-target-min, 44px);
  border: none;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: all 0.2s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  touch-action: manipulation;
  width: 100%;
  box-sizing: border-box;
}
.btn-primary {
  background: linear-gradient(135deg, #4CAF50, #388E3C);
  color: #fff;
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(76,175,80,0.3); }
.btn-secondary {
  background: var(--surface-panel-alt, rgba(255,255,255,0.05));
  color: var(--moyako-text, #e0e0e0);
  border: 1px solid var(--moyako-border-light, rgba(255,255,255,0.1));
}
.btn-secondary:hover { background: rgba(76,175,80,0.12); }

/* Compact "current difficulty" bar — a full-width pill that sits at the
   top of a game's stats panel, showing the selected tier with its
   tier-colored gradient. Click to open the difficulty modal and change
   tier. Replaces the old in-panel difficulty picker (5 emoji buttons)
   with a single prominent bar — industry pattern used by most puzzle
   games ("Current: Medium · change"). */
.moyako-difficulty-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: var(--tap-target-md);
  padding: 8px 14px;
  border: 0;
  border-radius: 12px;
  color: #fff;
  font-weight: 700;
  font-size: var(--font-size-body);
  text-shadow: 0 1px 2px rgba(0,0,0,0.3);
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
  transition: transform 0.15s ease, box-shadow 0.2s ease;
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(255,255,255,0.3);
  position: relative;
}
.moyako-difficulty-pill:hover  { box-shadow: 0 6px 18px rgba(0,0,0,0.35); }
.moyako-difficulty-pill:active { transform: scale(0.98); }

/* Tier gradients — match .moyako-difficulty-btn so the pill visually
   inherits the tile the user picked. */
.moyako-difficulty-pill[data-tier="beginner"] { background: linear-gradient(135deg, #4DD0E1 0%, #0097A7 100%); }
.moyako-difficulty-pill[data-tier="easy"]     { background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%); }
.moyako-difficulty-pill[data-tier="medium"]   { background: linear-gradient(135deg, #FF9800 0%, #E65100 100%); }
.moyako-difficulty-pill[data-tier="hard"]     { background: linear-gradient(135deg, #E53935 0%, #B71C1C 100%); }
.moyako-difficulty-pill[data-tier="expert"]   { background: linear-gradient(135deg, #9C27B0 0%, #4A148C 100%); }

.moyako-difficulty-pill-emoji { font-size: 18px; line-height: 1; }
.moyako-difficulty-pill-edit  {
  margin-left: auto;
  opacity: 0.8;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

@media (max-width: 1024px) {
  .moyako-game-shell {
    grid-template-columns: 1fr;
    gap: 14px;
    padding: 10px;
    /* Stop forcing a tall shell on mobile — let content flow. */
    min-height: 0;
  }
  /* Tablet order (769–1024px): board first, then coach, then stats —
     all still in-flow (single column stack). Phones (≤768px) get the
     board-first drawer layout below. */
  .moyako-board-center { order: 1; }
  .moyako-coach-panel  { order: 2; min-height: 0; }
  .moyako-stats-panel  { order: 3; min-height: 0; }

  .moyako-coach-top { min-height: 0; flex: none; padding: 4px; }
  .moyako-coach-top img,
  .moyako-coach-top .panda-avatar { width: 64px; }
  .moyako-coach-skills { flex: none; }
  .moyako-coach-skills ul { grid-template-columns: repeat(4, 1fr); }

  /* The prominent game-title gradient plate looks chunky at full
     width on a phone. Trim a bit so it doesn't dominate. */
  .moyako-game-title {
    font-size: var(--font-size-body-lg);
    padding: 8px 12px;
    letter-spacing: 1px;
  }
}

/* ============================================================
   PHONE OPTIMIZATION (≤768px) — see KNOW-HOW A26, DESIGN-RULES §2b
   Board-first layout. Coach panel hidden (marketing, not gameplay).
   Stats panel becomes an off-canvas right drawer toggled by a
   floating edge button. Brand bar collapses to logo + streak + ☰
   burger; sound/back/settings fold into the settings popup.
   Applies only to game pages (body[data-no-bottom-nav]).
   ============================================================ */

/* Drawer toggle + backdrop default: hidden everywhere; shown only
   on phone game pages via the @media block below. */
#moyako-drawer-toggle,
#moyako-drawer-backdrop { display: none; }

/* Centred panda mascot — shared 3-zone brand bar shows the mascot
   on every viewport size. Absolute-centred between brand-left (logo
   + title) and brand-right (streak chip + menu). */
#moyako-brand-bar .moyako-brand-panda-center {
  display: block;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(255,255,255,0.08);
  padding: 2px;
  box-sizing: border-box;
  box-shadow: 0 2px 6px rgba(0,0,0,0.35);
  object-fit: contain;
  pointer-events: none;
  z-index: 1;
}
#moyako-brand-bar {
  position: relative;
  /* Push brand bar below the device status bar / camera cutout. iPhones
     and Android phones with punch-hole or notch overlap the page top by
     ~24-44px; without this padding the system clock/signal icons paint
     over the "Moyako Sudoku" title. Capacitor WebView reports the inset
     correctly when viewport-fit=cover is set (already in place). */
  padding-top: env(safe-area-inset-top, 0px);
}
[data-theme="light"] #moyako-brand-bar .moyako-brand-panda-center {
  background: rgba(0,0,0,0.06);
}

/* The two icon spans inside the settings button — desktop shows ⚙️,
   phone swaps to ☰. Span classes set in components.js injectBrandBar. */
.moyako-icon-mobile { display: none; }

/* Quick-actions section default: hidden on tablet+desktop (sound + back
   live in the brand bar). The @media ≤768px block below overrides this. */
.moyako-quick-actions { display: none; }

@media (max-width: 768px) {
  /* --- Shell: board takes the whole viewport --- */
  .moyako-game-shell {
    grid-template-columns: 1fr;
    gap: 0;
    padding: 6px;
    min-height: 0;
  }
  .moyako-board-center { order: 1; width: 100%; }

  /* ============================================================
     OPT-IN: quadrant shell — body[data-shell^="quadrant"]
     4-band vertical stack on phones:
       Brand bar  : fixed-top, 48-81 px (≈10dvh cap)
       Board area : 1fr (≈40% of viewport)
       Controls   : 1fr (≈40% of viewport)
       Ad banner  : fixed-bottom, 50-81 px (≈10dvh cap)
     All 4 bands span full width with a consistent 8 px side padding.
     Board + controls split the remaining 80 % 50/50.
     Board is centered (aspect-ratio 1), never trimmed — shrinks to
     fit its band instead.
     Games opt in with <body data-shell="quadrant" ...>.
     ============================================================ */
  body[data-shell^="quadrant"] {
    height: 100dvh;
    overflow: hidden;
    padding-top: clamp(48px, 10dvh, 81px) !important;
    padding-bottom: clamp(50px, 10dvh, 81px) !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  body[data-shell^="quadrant"] .moyako-game-shell,
  body[data-shell="quadrant-board"] .moyako-game-shell {
    display: grid !important;
    grid-template-columns: 1fr !important;
    gap: 8px !important;
    padding: 8px 8px !important;
    height: calc(100dvh - clamp(48px, 10dvh, 81px) - clamp(50px, 10dvh, 81px)) !important;
    width: 100% !important;
    min-height: 0 !important;
    box-sizing: border-box !important;
    overflow: hidden !important;
  }
  /* "quadrant": 40/40 equal split (board + controls same height). */
  body[data-shell="quadrant"] .moyako-game-shell {
    grid-template-rows: 1fr 1fr !important;
  }
  /* "quadrant-board": 45/35 board-priority split — board gets 9/16 of
     the middle 80 %, controls get 7/16. Same 10/10 header/ad bands. */
  body[data-shell="quadrant-board"] .moyako-game-shell {
    grid-template-rows: 9fr 7fr !important;
  }
  /* Row 1: board area — full width, centered square board */
  body[data-shell^="quadrant"] .moyako-board-center {
    grid-row: 1 !important;
    order: unset !important;
    width: 100% !important;
    min-width: 0;
    min-height: 0;
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    padding: 0 !important;
    box-sizing: border-box;
  }
  body[data-shell^="quadrant"] .moyako-board-center > *,
  body[data-shell^="quadrant"] .board-wrapper {
    width: auto;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    aspect-ratio: 1;
    margin: 0 auto;
  }
  /* Row 2: stats panel — full width, docked in row */
  body[data-shell^="quadrant"] .moyako-stats-panel {
    grid-row: 2 !important;
    position: static !important;
    transform: none !important;
    box-shadow: none !important;
    border-radius: 8px !important;
    width: 100% !important;
    max-width: 100% !important;
    max-height: 100% !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 6px !important;
    overflow-y: auto !important;
    background: var(--moyako-bg) !important;
    z-index: auto !important;
  }
  /* Ad banner: fixed at the very bottom, inside the 10dvh body
     padding-bottom reservation. */
  body[data-shell^="quadrant"] #moyako-ad-bottom {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    height: clamp(50px, 10dvh, 81px) !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 8px !important;
    box-sizing: border-box !important;
    z-index: 90 !important;
    background: var(--moyako-bg) !important;
  }
  body[data-shell^="quadrant"] #moyako-ad-bottom > * {
    max-width: 100%;
    max-height: 100%;
  }
  /* Drawer toggle + coach panel are irrelevant for quadrant shells. */
  body[data-shell^="quadrant"] #moyako-drawer-toggle,
  body[data-shell^="quadrant"] #moyako-drawer-backdrop,
  body[data-shell^="quadrant"] .moyako-coach-panel {
    display: none !important;
  }
  /* End of quadrant shell — everything below stays as legacy drawer pattern. */

  /* --- Hide the coach panel entirely on phones.
         The skills-training copy is marketing context, not gameplay.
         It still appears on tablet (769–1024px) and desktop. --- */
  .moyako-coach-panel { display: none; }

  /* --- Hide the game-title plate on phones; the brand bar + context
         already identify the page. Saves a full row above the board. --- */
  .moyako-game-title,
  .moyako-game-greeting { display: none; }

  /* --- Stats panel → right-edge off-canvas drawer ---
     Opaque background via var(--moyako-bg) — the default
     --surface-panel is rgba(255,255,255,0.06) in dark theme, which
     works inside a page-bg card but lets the chess board bleed through
     when the panel is floating as a drawer. Theme-aware solid color
     matches the page body so nothing ghosts through. */
  .moyako-stats-panel {
    position: fixed;
    top: 56px;
    right: 0;
    bottom: calc(70px + env(safe-area-inset-bottom, 0px));
    width: min(360px, 88vw);
    max-height: none;
    margin: 0;
    border-radius: 0;
    box-shadow: -12px 0 24px rgba(0,0,0,0.4);
    transform: translateX(100%);
    transition: transform 0.25s ease-out;
    z-index: 1100;
    overflow-y: auto;
    background: var(--moyako-bg);
  }
  body.moyako-drawer-open .moyako-stats-panel {
    transform: translateX(0);
  }

  /* --- Brand bar: logo + name + streak + burger only ---
     Compact across ALL game pages (body[data-no-bottom-nav]) at mobile
     widths. Individual games can fine-tune via a page-scoped override
     (e.g. body[data-page-brand-label="Sudoku"]).
     !important because components.js injects a later <style> with the
     desktop default padding (0.75rem 1rem = 12px 16px) which would
     otherwise inflate the bar to 75px on phones. */
  #moyako-brand-bar {
    flex-direction: row;
    /* padding-top includes status-bar inset so the bar clears the system
       clock + cutout on phones (env() falls back to 2px when the inset
       is 0 — desktop browsers + landscape phones with no top inset). */
    padding: calc(2px + env(safe-area-inset-top, 0px)) 10px 2px 10px !important;
    gap: 8px;
    min-height: 48px !important;
    position: relative;
  }
  #moyako-brand-bar .moyako-brand-icon {
    width: 40px !important;
    height: 40px !important;
    border-radius: 50% !important;
    background: rgba(255,255,255,0.08);
    padding: 2px;
    box-sizing: border-box;
    box-shadow: 0 2px 6px rgba(0,0,0,0.35);
  }
  [data-theme="light"] #moyako-brand-bar .moyako-brand-icon {
    background: rgba(0,0,0,0.06);
  }
  /* Centred panda mascot — absolute-centred between brand-left and
     brand-right so every game page shows the shared mascot emblem. */
  #moyako-brand-bar .moyako-brand-panda-center {
    display: block;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(255,255,255,0.08);
    padding: 2px;
    box-sizing: border-box;
    box-shadow: 0 2px 6px rgba(0,0,0,0.35);
    object-fit: contain;
    pointer-events: none;
    z-index: 1;
  }
  [data-theme="light"] #moyako-brand-bar .moyako-brand-panda-center {
    background: rgba(0,0,0,0.06);
  }
  .moyako-brand-motto { display: none; }
  .moyako-brand-name { font-size: 0.95rem; }
  .moyako-brand-back,
  #moyako-sound-btn { display: none !important; }

  /* Swap ⚙️ gear → ☰ burger inside the settings button */
  .moyako-icon-desktop { display: none; }
  .moyako-icon-mobile  { display: inline; }

  /* Body padding-top matches the compact 48 px bar + a 2 px breathing
     gap. !important because components.js injects a later <style> with
     the desktop default; on phones we want the tighter value. */
  body { padding-top: 50px !important; }

  /* --- Floating drawer toggle (right edge, mid-viewport) --- */
  body[data-no-bottom-nav] #moyako-drawer-toggle {
    display: flex;
    position: fixed;
    top: 50%;
    right: 0;
    transform: translateY(-50%);
    width: 36px;
    height: 72px;
    border: 0;
    border-radius: 10px 0 0 10px;
    background: var(--moyako-primary, #4CAF50);
    color: #fff;
    font-size: 18px;
    font-weight: 700;
    align-items: center;
    justify-content: center;
    box-shadow: -6px 0 14px rgba(0,0,0,0.35);
    cursor: pointer;
    z-index: 1200;
    transition: right 0.25s ease-out;
    touch-action: manipulation;
    -webkit-tap-highlight-color: rgba(255,255,255,0.2);
  }
  body[data-no-bottom-nav].moyako-drawer-open #moyako-drawer-toggle {
    right: min(360px, 88vw);
  }

  /* --- Backdrop behind the open drawer (tap to close) --- */
  body[data-no-bottom-nav].moyako-drawer-open #moyako-drawer-backdrop {
    display: block;
    position: fixed;
    top: 56px;
    left: 0;
    right: 0;
    bottom: calc(70px + env(safe-area-inset-bottom, 0px));
    background: rgba(0,0,0,0.5);
    z-index: 1080;
    animation: moyako-fade-in 0.2s ease-out;
  }
  @keyframes moyako-fade-in { from { opacity: 0; } to { opacity: 1; } }

  /* --- Quick-actions section in the settings popup (phone only).
         Desktop shows sound + back directly in the brand bar, so
         this section is hidden there via the default rule above. --- */
  .moyako-quick-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    margin-bottom: 10px;
  }
}

/* ==========================================================================
   SHARED GAME CARD — TASK-011 golden-base alignment
   --------------------------------------------------------------------------
   Single source of truth for the game-tile card used on games.html,
   index.html (Featured Games) and anywhere else we showcase a game.
   Previously the two pages drifted (games.html used `.game-card`,
   index.html used `.step`). Consolidating here keeps hover, radius,
   padding and the 4-colour cycling top-border identical everywhere.

   Tokens intentionally fall back to hardcoded brand values so this class
   works even on pages that don't define --primary-green / --shadow-soft.
   ========================================================================== */
.moyako-game-card {
  background: rgba(255, 255, 255, 0.10);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 12px;
  padding: 24px;
  position: relative;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-soft, 0 2px 12px rgba(0, 0, 0, 0.3));
  transition: all 0.3s ease;
}

.moyako-game-card:hover {
  border-left-color: var(--primary-green, #4CAF50);
  border-right-color: var(--primary-green, #4CAF50);
  border-bottom-color: var(--primary-green, #4CAF50);
  background: rgba(255, 255, 255, 0.14);
  box-shadow: 0 8px 32px rgba(76, 175, 80, 0.20);
  transform: translateY(-4px);
}

/* Default child typography so bare h3/p on the card render consistently.
   Pages that wrap headings in more-specific classes (e.g. .game-title
   on games.html) still win via specificity. */
.moyako-game-card h3 {
  font-family: var(--font-display, 'Plus Jakarta Sans', system-ui, sans-serif);
  font-size: 1.15rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
  color: #F5F7FA;
}
.moyako-game-card p {
  color: #C5CAD5;
  line-height: 1.6;
  margin: 0 0 0.5rem;
}
[data-theme="light"] .moyako-game-card h3 { color: #0F172A; }
[data-theme="light"] .moyako-game-card p  { color: #475569; }

/* Cycling accent top-border — matches the brand tile pattern */
.moyako-game-card:nth-child(4n+1) { border-top: 3px solid #66BB6A; }  /* green */
.moyako-game-card:nth-child(4n+2) { border-top: 3px solid #4DD0E1; }  /* cyan  */
.moyako-game-card:nth-child(4n+3) { border-top: 3px solid #FFD54F; }  /* yellow*/
.moyako-game-card:nth-child(4n)   { border-top: 3px solid #FF6B9D; }  /* pink  */

/* Coming-soon state */
.moyako-game-card[data-status="coming-soon"] { opacity: 0.65; }
.moyako-game-card[data-status="coming-soon"] .game-button,
.moyako-game-card[data-status="coming-soon"] .btn {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Honour prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
  .moyako-game-card { transition: none; }
  .moyako-game-card:hover { transform: none; }
}

/* Light-theme override — silver/gray metallic tile (per user "may be
   silver/gray metallic background at tiles at light mode") with the
   4-colour cycling top border restated so the colored line stays
   visible after the side/bottom border-color override. */
[data-theme="light"] .moyako-game-card {
  background: linear-gradient(180deg, #F2F5FB 0%, #D8DFEC 100%);
  border: 1px solid rgba(15, 23, 42, 0.10);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -1px 0 rgba(15, 23, 42, 0.04),
    0 2px 6px rgba(15, 23, 42, 0.08),
    0 8px 18px rgba(15, 23, 42, 0.06);
  color: #0F172A;
}
[data-theme="light"] .moyako-game-card:nth-child(4n+1) { border-top: 3px solid #66BB6A; }
[data-theme="light"] .moyako-game-card:nth-child(4n+2) { border-top: 3px solid #4DD0E1; }
[data-theme="light"] .moyako-game-card:nth-child(4n+3) { border-top: 3px solid #FFD54F; }
[data-theme="light"] .moyako-game-card:nth-child(4n)   { border-top: 3px solid #FF6B9D; }
[data-theme="light"] .moyako-game-card:hover {
  transform: translateY(-6px) scale(1.02);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 -1px 0 rgba(15, 23, 42, 0.05),
    0 6px 14px rgba(15, 23, 42, 0.10),
    0 16px 36px rgba(15, 23, 42, 0.14);
}

/* ==========================================================================
   SCORE BREAKDOWN — TASK-008 P2
   --------------------------------------------------------------------------
   Shows "Base 82 × Hard 1.2× = 98" on the game-over overlay so the user
   understands how the tier multiplier shaped their final score. Games
   opt-in by adding <div id="scoreBreakdown" class="score-breakdown-row">
   inside their overlay. Empty until renderStats() populates it.
   ========================================================================== */
.score-breakdown-row {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: 6px;
  background: rgba(76, 175, 80, 0.10);
  border: 1px solid rgba(76, 175, 80, 0.22);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  letter-spacing: 0.01em;
  color: inherit;
  font-variant-numeric: tabular-nums;
}
.score-breakdown-row:empty {
  display: none;
}
.score-breakdown-row .sb-base,
.score-breakdown-row .sb-mult,
.score-breakdown-row .sb-final {
  display: inline-block;
  padding: 0 4px;
}
.score-breakdown-row .sb-mult {
  color: #FF9800;
  font-weight: 700;
}
.score-breakdown-row .sb-final {
  color: #4CAF50;
  font-weight: 800;
  font-size: 15px;
}
.score-breakdown-row .sb-op {
  opacity: 0.55;
  margin: 0 2px;
  font-weight: 400;
}
[data-theme="light"] .score-breakdown-row {
  background: rgba(37, 99, 235, 0.08);
  border-color: rgba(37, 99, 235, 0.18);
}
[data-theme="light"] .score-breakdown-row .sb-mult { color: #EA580C; }
[data-theme="light"] .score-breakdown-row .sb-final { color: #2563EB; }

/* ============================================================
   Rotate-to-portrait nudge — phone landscape only.
   Shows on viewports < 600 px wide AND in landscape orientation.
   Tablets (≥ 600 px wide) skip the nudge entirely; their landscape
   layouts are designed to work. Only applies to game pages
   (data-no-bottom-nav) — main site + landing pages are free to
   render however the user prefers.
   ============================================================ */
@media (max-width: 599px) and (orientation: landscape) {
  body[data-no-bottom-nav]::before {
    content: "📱  Rotate to portrait\A for the best experience";
    white-space: pre;
    position: fixed;
    inset: 0;
    z-index: 99999;
    background: rgba(10, 12, 18, 0.96);
    color: #ECEFF4;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 24px;
    font-size: 18px;
    font-weight: 700;
    line-height: 1.5;
    letter-spacing: 0.5px;
    pointer-events: auto;
  }
}
