/* Games with You - Design Tokens
   Dark theme. All games consume these variables.
   Games never hardcode colors - always reference vars. */

:root {
  /* Background tiers */
  --bg: #0f172a;
  --bg-surface: #1e293b;
  --bg-elevated: #334155;

  /* Text tiers */
  --text-primary: #f1f5f9;
  --text-secondary: #94a3b8;
  --text-tertiary: #64748b;

  /* Accent */
  --accent: #eab308;
  --game-accent: #eab308;

  /* ========================================================================
   * Seasonal palette tokens (per docs/visual-dna.md > "Seasonal palette")
   *
   * The painted scenes shift palette by season: summer -> autumn -> winter ->
   * spring. Per-game accents (--game-accent) stay constant across seasons;
   * only these scene tones rotate. CSS chrome that wants to "breathe" the
   * current season should reference these tokens, not hardcode hex values.
   *
   * Currently committed: summer 2026 (cool sky blues, fresh greens, warm
   * sand cream). Autumn commits at the 2026-07-27 review.
   *
   * Architecture: each season fills its own block; --season-* tokens (no
   * suffix) alias the current season. To rotate, swap the alias block.
   * Future seasons (autumn/winter/spring) are placeholders — values get
   * filled in at each seasonal review.
   * ====================================================================== */

  /* Summer 2026 */
  --summer-sky: #4ba6d6;
  --summer-meadow: #6db86d;
  --summer-sand: #f0d896;
  --summer-shadow: #2c6a3f;
  --summer-water: #2d7a8c;
  --summer-ink: #2a1810;

  /* Current-season aliases. Chrome should reference these so a seasonal
   * swap is a one-block edit, not a per-call-site rewrite. */
  --season-sky: var(--summer-sky);
  --season-meadow: var(--summer-meadow);
  --season-sand: var(--summer-sand);
  --season-shadow: var(--summer-shadow);
  --season-water: var(--summer-water);
  --season-ink: var(--summer-ink);

  /* Future seasons (placeholders — filled in at each seasonal review).
   * --autumn-*: 2026-07-27 review
   * --winter-*: 2026-10-27 review
   * --spring-*: 2027-01-27 review */

  /* Borders */
  --border: #334155;

  /* Radius */
  --radius: 12px;
  --radius-sm: 6px;

  /* Typography (aligned with BRAND.md, with --font-display purged of Syne
   * per v0.4.40 - Syne's chunky display character clashed with the studio's
   * clean dark-mode aesthetic. Display tier now uses DM Sans 600 - same
   * family as body text, slightly bolder, no faux-bold issues, unified feel.) */
  --font-display: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-sans: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', monospace;
  /* Voice / handwritten moments: score popups, taglines, eyebrow lines, "+15! sweet move"
   * toasts, modal eyebrows. The studio's painted-2D voice font per docs/visual-dna.md
   * Tier 1. Used on the wordmark top line ("Games") and reserved for future track 6
   * animation work (score popups, watercolor wash bloom moments). */
  --font-handwritten: 'Shadows Into Light', cursive;
  --font-wordmark-top: 'Shadows Into Light', cursive;
  /* Permanent Marker is preserved as a wordmark-only exception (the chunky "with You"
   * second line). It is not used anywhere else in the app per the type stack lock. */
  --font-wordmark-bottom: 'Permanent Marker', cursive;

  --text-scale: 1;
  --text-xs: clamp(11px, calc(11px * var(--text-scale)), 14px);
  --text-sm: clamp(13px, calc(13px * var(--text-scale)), 16px);
  --text-base: clamp(15px, calc(15px * var(--text-scale)), 19px);
  --text-lg: clamp(18px, calc(18px * var(--text-scale)), 22px);
  --text-xl: clamp(22px, calc(22px * var(--text-scale)), 28px);
  --text-2xl: clamp(28px, calc(28px * var(--text-scale)), 36px);
  /* v0.4.33 display tier: hero copy on launcher cards + ready screens. */
  --text-3xl: clamp(34px, calc(34px * var(--text-scale)), 44px);
  --text-4xl: clamp(44px, calc(44px * var(--text-scale)), 56px);
  --text-display: clamp(56px, calc(56px * var(--text-scale)), 80px);

  /* Tracking + line-height per text tier (v0.4.33). */
  --tracking-tight: -0.02em;
  --tracking-snug: -0.01em;
  --tracking-normal: 0;
  --tracking-wide: 0.04em;
  --tracking-eyebrow: 0.08em;

  --line-height-tight: 1.2;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.7;

  --font-weight-normal: 400;
  /* DM Sans ships at 400/500/600 only per BRAND.md - asking for 700 triggers
   * browser faux-bold synthesis (ugly stretched letters). All weight tokens
   * cap at 600. v0.4.40 purged Syne entirely, so --font-weight-display is
   * also 600 (just an alias for callers that conceptually want "the
   * heaviest weight available"). */
  --font-weight-semibold: 500;
  --font-weight-bold: 600;
  --font-weight-display: 600;

  /* Spacing (8pt baseline, fluid). v0.4.33 added 2xl/3xl for hero gaps. */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 48px;
  --space-3xl: 72px;

  /* Measurements */
  --header-height: 48px;
  --safe-area-top: env(safe-area-inset-top, 0px);
  --safe-area-bottom: env(safe-area-inset-bottom, 0px);

  --card-min-width: 140px;
  --card-gap: 12px;
  --card-padding: 16px;
  --card-icon-size: 48px;

  --button-height: 48px;
  --button-height-lg: 56px;
  --button-radius: var(--radius);
  --touch-target-min: 44px;

  --modal-width: min(360px, calc(100vw - 32px));
  --modal-padding: 24px;
  --modal-radius: 16px;
  --overlay-bg: rgba(0, 0, 0, 0.6);

  --toast-height: 44px;
  --toast-radius: 22px;

  --banner-ad-height: 56px;

  /* Motion */
  --motion-duration: 200ms;
  --motion-duration-slow: 400ms;
  --motion-duration-fast: 100ms;
  --motion-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --motion-ease-in: cubic-bezier(0.4, 0, 1, 1);
  --motion-ease-out: cubic-bezier(0, 0, 0.2, 1);
  --motion-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Elevation (v0.4.33 expanded). Layered shadows for proper depth on the
   * dark theme. Each tier combines a tight + diffuse shadow for material feel.
   * Use --shadow-card on launcher tiles, --shadow-card-hover on hover.
   * --shadow-glow is per-game-accent, used for primary CTAs + active states.
   */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 8px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 12px 28px rgba(0, 0, 0, 0.5), 0 4px 8px rgba(0, 0, 0, 0.3);
  --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.55), 0 8px 16px rgba(0, 0, 0, 0.35);
  --shadow-card: 0 6px 16px rgba(0, 0, 0, 0.45), 0 1px 3px rgba(0, 0, 0, 0.35);
  --shadow-card-hover: 0 16px 36px rgba(0, 0, 0, 0.55), 0 4px 12px rgba(0, 0, 0, 0.4);
  --shadow-glow: 0 0 16px color-mix(in srgb, var(--game-accent, var(--accent)) 60%, transparent);
  --shadow-glow-strong: 0 0 28px color-mix(in srgb, var(--game-accent, var(--accent)) 70%, transparent),
                        0 0 6px color-mix(in srgb, var(--game-accent, var(--accent)) 90%, transparent);

  /* Atmosphere (v0.4.33). Per-game soft halo + tint that pull the eye to
   * the active card / screen. Used on launcher tiles, ready screens, and
   * primary CTAs. The accent itself is the source; these are derived. */
  --atmosphere-tint: color-mix(in srgb, var(--game-accent, var(--accent)) 8%, var(--bg));
  --atmosphere-tint-strong: color-mix(in srgb, var(--game-accent, var(--accent)) 18%, var(--bg));
  --atmosphere-halo: radial-gradient(circle at 50% 0%,
    color-mix(in srgb, var(--game-accent, var(--accent)) 22%, transparent) 0%,
    transparent 60%);

  /* Card surfaces (v0.4.33). Distinct from --bg-surface so cards can have
   * their own treatment without affecting other surfaces. */
  --bg-card: #182236;
  --bg-card-hover: #1d2840;

  /* Semantic colors (for feedback states) */
  --color-success: #22c55e;
  --color-error: #ef4444;
  --color-warning: #f97316;

  /* Simon Says pad colors */
  --simon-red: #ef4444;
  --simon-blue: #3b82f6;
  --simon-green: #22c55e;
  --simon-yellow: #eab308;

  /* 2048 tile colors */
  --tile-2-bg: #eee4da;    --tile-2-text: #776e65;
  --tile-4-bg: #ede0c8;    --tile-4-text: #776e65;
  --tile-8-bg: #f2b179;    --tile-8-text: #f9f6f2;
  --tile-16-bg: #f59563;   --tile-16-text: #f9f6f2;
  --tile-32-bg: #f67c5f;   --tile-32-text: #f9f6f2;
  --tile-64-bg: #f65e3b;   --tile-64-text: #f9f6f2;
  --tile-128-bg: #edcf72;  --tile-128-text: #f9f6f2;
  --tile-256-bg: #edcc61;  --tile-256-text: #f9f6f2;
  --tile-512-bg: #edc850;  --tile-512-text: #f9f6f2;
  --tile-1024-bg: #edc53f; --tile-1024-text: #f9f6f2;
}

/* High contrast override (toggled via .high-contrast on <html>) */
.high-contrast {
  --bg: #000000;
  --bg-surface: #1a1a1a;
  --bg-elevated: #2a2a2a;
  --text-primary: #ffffff;
  --text-secondary: #cccccc;
  --text-tertiary: #999999;
  --border: #555555;
  --accent: #ffd700;
}

/* Reduce motion (respects OS preference or manual toggle) */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-duration: 0s;
    --motion-duration-slow: 0s;
    --motion-duration-fast: 0s;
  }
}

.reduce-motion {
  --motion-duration: 0s;
  --motion-duration-slow: 0s;
  --motion-duration-fast: 0s;
}

/* ============================================================================
   A11y + presentation classes (Phase C Wave 3; 2026-04-19)
   Added per the kit's theme.css to give the studio a shared class vocabulary
   for accessibility and premium presentation. Toggle on <html> from settings
   UI or the premium entitlement check.

   These are additive: existing behavior (inline --text-scale via settings)
   continues to work; the classes give games an alternative composable path.

   Kit source of truth: .studio/kit/theme.css
   ============================================================================ */

/* Text-scale classes: alternative to inline --text-scale style. */
/* Collection's current settings UI sets --text-scale inline; either approach works. */
.text-scale-sm { --text-scale: 0.85; }
.text-scale-md { --text-scale: 1; }
.text-scale-lg { --text-scale: 1.15; }

/* Colorblind-safe palette: swaps semantic colors to a colorblind-safe set. */
/* Toggle when the player opts into colorblind mode. Distinct from high-contrast. */
.colorblind-safe {
  --color-success: #2563eb;
  --color-error: #f97316;
  --color-warning: #eab308;
}

/* Premium-clean view: hides any element with data-placement when a premium */
/* purchase removes passive placements. Per C.3 premium-entitlement contract. */
.premium-clean [data-placement] {
  display: none !important;
}

/* Stronger border variant for high-contrast overlays. */
/* High-contrast override already sets --border-strong; this declaration */
/* exposes it as a first-class token so games can reference border-strong */
/* on elements that need extra definition in high-contrast mode. */
:root {
  --border-strong: #475569;
}
.high-contrast {
  --border-strong: #888888;
}

/* Base reset */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--line-height-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
  user-select: none;
  touch-action: manipulation;
}

/* Font loading */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../assets/fonts/dm-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/ibm-plex-mono-400.woff2') format('woff2');
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/ibm-plex-mono-700.woff2') format('woff2');
}

@font-face {
  font-family: 'Shadows Into Light';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/shadows-into-light-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Permanent Marker';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/permanent-marker-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Shared animations */
@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

@keyframes shake {
  0%, 100% { transform: rotate(0deg); }
  25% { transform: rotate(-8deg) scale(1.1); }
  75% { transform: rotate(8deg) scale(1.1); }
}

@keyframes spin {
  0% { transform: rotateY(0deg); }
  100% { transform: rotateY(720deg); }
}

@keyframes pop {
  0% { transform: scale(0.9); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}

/* Animation utility classes */
.anim-pulse { animation: pulse 1s infinite; }
.anim-shake { animation: shake 0.6s ease-out; }
.anim-spin { animation: spin 0.8s ease-out; }
.anim-pop { animation: pop var(--motion-duration) var(--motion-spring); }

/* ============================================================================
 * Track 6 (v0.5.9): painted-2D motion specimens.
 *
 * Four canonical motion specimens per docs/visual-dna.md > Animation language.
 * Ported from docs/visual-system.html. Tender, hand-touched, never aggressive
 * - the studio voice in motion matches the studio voice in copy.
 *
 * Usage:
 *   .anim-score-toast    one-shot toast on score events ("+15! sweet move")
 *   .anim-sun-glow       radial gold-warmth bloom behind a success element
 *   .anim-brush-mark     horizontal stroke sweep for level/screen transition
 *   .anim-watercolor-wash big-moment three-color bloom (level cleared, streak)
 * ========================================================================== */

/* Score popup: Shadows Into Light pill scales 1.0 -> 1.04 + lifts 5px.
 * Use for "+15! sweet move" style toasts on score events. */
@keyframes score-toast {
  0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.9; }
  50%      { transform: translate(-50%, -55%) scale(1.04); opacity: 1; }
}
.anim-score-toast {
  font-family: var(--font-handwritten);
  font-size: var(--text-xl);
  color: var(--game-accent, var(--accent));
  background: rgba(15, 23, 42, 0.7);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  padding: var(--space-sm) var(--space-md);
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--game-accent, var(--accent)) 30%, transparent);
  white-space: nowrap;
  animation: score-toast 2.5s var(--motion-ease) infinite;
}

/* Sun-glow bloom: radial gold-warmth pulse behind a subject.
 * Use as a ::before/::after on a success element, or as a positioned div. */
@keyframes sun-glow {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    opacity: 0.7; }
  50%      { transform: translate(-50%, -50%) scale(1.15); opacity: 1.0; }
}
.anim-sun-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--season-sand, #f0d896) 70%, transparent) 0%,
    color-mix(in srgb, var(--season-sand, #f0d896) 25%, transparent) 40%,
    transparent 70%);
  filter: blur(4px);
  animation: sun-glow 2.5s var(--motion-ease) infinite;
  pointer-events: none;
}

/* Brush-mark transition: horizontal accent stroke sweeps L->R then fades R->L.
 * Use for level/screen transition seams. 2s loop in spec; one-shot version
 * also valid - drop the `infinite` to play once. */
@keyframes brush-mark {
  0%   { transform: translateY(-50%) scaleX(0); transform-origin: left;  opacity: 0.9; }
  50%  { transform: translateY(-50%) scaleX(1); transform-origin: left;  }
  100% { transform: translateY(-50%) scaleX(1); transform-origin: right; opacity: 0; }
}
.anim-brush-mark {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 14px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--game-accent, var(--accent)) 30%,
    var(--game-accent, var(--accent)) 70%,
    transparent 100%);
  filter: blur(1px);
  transform: translateY(-50%) scaleX(0);
  transform-origin: left;
  animation: brush-mark 2s var(--motion-ease) infinite;
  pointer-events: none;
}

/* Watercolor wash bloom: three soft watercolor washes (snake green, studio
 * gold, summer sky) bloom outward from center, scaling and fading. 3.6s loop.
 * Painterly and quiet, not aggressive. Big moments (level cleared, streak hit,
 * end of round). Use the wrapper + 3 layers per the spec. */
@keyframes watercolor-wash {
  0%   { transform: translate(-50%, -50%) scale(0.25) rotate(0deg);  opacity: 0; }
  18%  { transform: translate(-50%, -50%) scale(0.85) rotate(4deg);  opacity: 1; }
  55%  { transform: translate(-50%, -50%) scale(1.6)  rotate(-2deg); opacity: 0.6; }
  100% { transform: translate(-50%, -50%) scale(2.4)  rotate(2deg);  opacity: 0; }
}
.anim-watercolor-wash {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.anim-watercolor-wash > .wash-layer {
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: 60% 40% 55% 45% / 50% 60% 40% 50%;
  filter: blur(3px);
  opacity: 0;
}
.anim-watercolor-wash > .wash-layer.l1 {
  width: 90px;
  height: 90px;
  background: radial-gradient(circle at 40% 35%,
    color-mix(in srgb, var(--season-meadow, #6db86d) 65%, transparent) 0%,
    color-mix(in srgb, var(--season-meadow, #6db86d) 30%, transparent) 40%,
    transparent 70%);
  animation: watercolor-wash 3.6s ease-out infinite;
}
.anim-watercolor-wash > .wash-layer.l2 {
  width: 70px;
  height: 70px;
  background: radial-gradient(circle at 45% 40%,
    color-mix(in srgb, var(--season-sand, #f0d896) 60%, transparent) 0%,
    color-mix(in srgb, var(--season-sand, #f0d896) 25%, transparent) 40%,
    transparent 70%);
  animation: watercolor-wash 3.6s ease-out 0.5s infinite;
}
.anim-watercolor-wash > .wash-layer.l3 {
  width: 110px;
  height: 110px;
  background: radial-gradient(circle at 35% 30%,
    color-mix(in srgb, var(--season-sky, #4ba6d6) 55%, transparent) 0%,
    color-mix(in srgb, var(--season-sky, #4ba6d6) 20%, transparent) 45%,
    transparent 75%);
  animation: watercolor-wash 3.6s ease-out 1.1s infinite;
}

/* Reduced-motion: kill the painted-2D motion specimens. */
@media (prefers-reduced-motion: reduce) {
  .anim-score-toast,
  .anim-sun-glow,
  .anim-brush-mark,
  .anim-watercolor-wash > .wash-layer {
    animation: none;
  }
}

/* Respect reduced motion for all shared animations */
@media (prefers-reduced-motion: reduce) {
  .anim-pulse, .anim-shake, .anim-spin, .anim-pop {
    animation: none;
  }
}

/* --- kit-dpad: directional control primitive (kit/dpad.js) --- */
.kit-dpad {
  position: fixed;
  bottom: calc(var(--space-md) + var(--safe-area-bottom));
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  grid-template-rows: auto auto auto;
  gap: var(--space-xs);
  z-index: 50;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  pointer-events: auto;
}

.kit-dpad[hidden] {
  display: none;
}

.kit-dpad__row {
  display: flex;
  justify-content: center;
  gap: var(--space-xs);
}

.kit-dpad__btn {
  width: 64px;
  height: 64px;
  font-size: 22px;
  color: var(--text-primary);
  background: rgba(51, 65, 85, 0.75);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--motion-duration) var(--motion-ease), transform var(--motion-duration) var(--motion-ease);
}

.kit-dpad__btn:active {
  background: var(--game-accent);
  color: var(--bg);
  transform: scale(0.95);
}

.kit-dpad__btn--spacer {
  width: 64px;
  height: 64px;
  visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .kit-dpad__btn {
    transition: none;
  }
  .kit-dpad__btn:active {
    transform: none;
  }
}

/* Landscape-phone carve-out: centered-bottom D-pad is ~200px tall which eats
   over half the viewport height on landscape phones. Anchor to bottom-right
   and shrink buttons so the play area stays visible. */
@media (orientation: landscape) and (max-height: 500px) {
  .kit-dpad {
    left: auto;
    right: calc(var(--space-md) + env(safe-area-inset-right, 0px));
    bottom: calc(var(--space-sm) + var(--safe-area-bottom));
    transform: none;
  }
  .kit-dpad__btn,
  .kit-dpad__btn--spacer {
    width: 48px;
    height: 48px;
    font-size: 18px;
  }
}

/* --- UI scale: user-configurable board sizing (applied by a11y prefs) ---
   Games that have a fixed-size board element reference var(--ui-scale, 1)
   in max-width / width / grid-template-columns, etc. Default is 1 (Medium). */
:root {
  --ui-scale: 1;
}
