/* Lull Memory — palette tokens
 * ----------------------------------------------------------------------------
 * The Lull brand lives in deep night. Lull Memory is the daytime sibling —
 * same horizon, but soft and warm. These tokens are the single source of
 * truth; everything else (game.js HUD updates, SVG fills, button states)
 * reads from them.
 *
 * Visual hierarchy:
 *   --lull-night  — the lull horizon. Background base, never pure black.
 *   --lull-cream  — paper / surface. The card back face.
 *   --lull-lavender — primary brand accent (wordmark, matched state, focus).
 *   --lull-peach  — secondary, used for timer / warm CTA.
 *   --lull-sage   — tertiary, used for success / matched-pair pulse.
 *   --lull-mist   — text on dark. Lower contrast than white, easier on tired eyes.
 */

:root {
  /* Surfaces */
  --lull-night:    #1a1525;  /* horizon — never pure black */
  --lull-night-2:  #2a2140;  /* slightly lifted for cards on the night */
  --lull-cream:    #f7f0e8;  /* paper / face-down card */
  --lull-cream-2:  #ede2d2;  /* paper, slightly muted */
  --lull-mist:     rgba(247, 240, 232, 0.86);
  --lull-mist-2:   rgba(247, 240, 232, 0.62);

  /* Brand accents */
  --lull-lavender: #b8a5d9;
  --lull-lavender-deep: #5d4e7a;
  --lull-peach:    #ff8a6b;   /* saturated for HUD readability on dark */
  --lull-peach-soft: #f4c7b8; /* the brand pastel, for non-HUD use */
  --lull-peach-deep: #c98a72;
  --lull-sage:     #6cd49a;   /* saturated for HUD readability on dark */
  --lull-sage-soft: #a8c5b0;  /* the brand pastel, for non-HUD use */
  --lull-sage-deep: #5d8a6b;

  /* Motion */
  --ease-calm: cubic-bezier(0.22, 0.61, 0.36, 1);
  --t-card: 480ms;
  --t-press: 180ms;

  /* Radii */
  --r-card: 18px;
  --r-btn: 999px;
  --r-pill: 12px;

  /* Type */
  --ff-display: "DM Serif Display", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --ff-body: -apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  background-color: #0e0918; /* deepest night, used as the floor color
                                 so the gradient never reveals a lighter
                                 color underneath, even past 100dvh */
  color: var(--lull-mist);
  font-family: var(--ff-body);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}

html {
  background:
    radial-gradient(140% 100% at 50% 0%, #2e2447 0%, #1a1525 45%, #0e0918 100%) fixed;
}

body {
  min-height: 100dvh;
  /* iOS safe areas */
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
}

.app {
  min-height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 16px;
  padding: 16px;
  max-width: 720px;
  margin: 0 auto;
  /* The .app gets its own dark surface so the controls never
     paint over a transparent body — this is what was making the
     bottom of the page look light in early renders. */
  background: transparent;
}

/* HUD -----------------------------------------------------------------------*/
.hud {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 8px 4px 4px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--lull-mist);
  font-family: var(--ff-display);
  font-size: 20px;
  letter-spacing: 0.01em;
}

.wordmark__mark {
  width: 28px;
  height: 28px;
  display: block;
  /* gentle, very slow rotation — a moon doesn't move, but
     a brand mark can. 60s = matches the round timer. */
  animation: wordmark-sway 60s linear infinite;
  transform-origin: 50% 50%;
}

@keyframes wordmark-sway {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.wordmark__text { font-weight: 400; }
.wordmark__sep  { color: var(--lull-lavender); margin: 0 4px; }

.hud__meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: rgba(247, 240, 232, 0.04);
  border: 1px solid rgba(184, 165, 217, 0.18);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
}

.hud__time {
  color: var(--lull-peach);
  /* The HUD sits on a near-black pill. The pastel brand
     colour (#f4c7b8) reads as white at this contrast; we
     override with the saturated brand value so the model and
     the user can read the colour as peach. */
  font-weight: 700;
  text-shadow: 0 0 10px rgba(255, 138, 107, 0.5);
  min-width: 3.5ch;
  text-align: center;
  transition: color 200ms var(--ease-calm), text-shadow 200ms var(--ease-calm);
}

/* Last-10-seconds urgency. The class is toggled by updateHud() the moment
   timeLeft drops to URGENT_SECONDS or below (and removed when we leave
   the 'playing' phase). Slow, gentle pulse — not a flash. The Lull brand
   reads as "soft breath", not "alarm clock". The pill background also
   picks up a faint warm tint so the timer pops off the HUD chrome
   without screaming. */
.hud__time--urgent {
  color: #ffd2c1;             /* a touch warmer / brighter than the rest peach */
  text-shadow: 0 0 16px rgba(255, 138, 107, 0.95),
               0 0 4px rgba(255, 220, 200, 0.7);
  animation: hud-urgent-pulse 900ms var(--ease-calm) infinite;
}

@keyframes hud-urgent-pulse {
  0%, 100% { opacity: 1.0;  transform: scale(1.00); }
  50%      { opacity: 0.55; transform: scale(1.10); }
}

@media (prefers-reduced-motion: reduce) {
  .hud__time--urgent {
    animation: none;
    color: #ffd2c1;
    text-shadow: 0 0 16px rgba(255, 138, 107, 0.95);
  }
}

.hud__matches {
  color: var(--lull-sage);
  font-weight: 700;
  text-shadow: 0 0 10px rgba(108, 212, 154, 0.5);
  min-width: 3.5ch;
  text-align: center;
}

/* Board ---------------------------------------------------------------------*/
.board {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 10px;
  aspect-ratio: 1 / 1;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  /* board grows to fill, but the 4x4 keeps the cards square */
  align-self: center;
}

.board__placeholder {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--lull-mist-2);
  font-family: var(--ff-display);
  font-size: 18px;
  font-style: italic;
  pointer-events: none;
  transition: opacity var(--t-card) var(--ease-calm);
}

.board__placeholder[hidden] { display: none; }

.board__placeholder-text {
  margin: 0;
  padding: 16px 24px;
  border-radius: var(--r-pill);
  background: rgba(247, 240, 232, 0.06);
  border: 1px solid rgba(184, 165, 217, 0.32);
  color: var(--lull-cream);
  font-style: italic;
  font-family: var(--ff-display);
  font-size: 18px;
  letter-spacing: 0.01em;
}

/* Card cell — game.js renders <button class="cell" data-state="..."> */
.cell {
  appearance: none;
  border: 0;
  padding: 0;
  margin: 0;
  background: var(--lull-cream);
  border-radius: var(--r-card);
  cursor: pointer;
  position: relative;
  overflow: hidden;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.5) inset,
    0 8px 18px rgba(0, 0, 0, 0.35),
    0 2px 6px rgba(0, 0, 0, 0.25);
  transition: transform var(--t-press) var(--ease-calm),
              box-shadow var(--t-press) var(--ease-calm);
  -webkit-tap-highlight-color: transparent;
}

.cell:hover { transform: translateY(-1px); }
.cell:active { transform: translateY(1px) scale(0.985); }

.cell:focus-visible {
  outline: 2px solid var(--lull-lavender);
  outline-offset: 3px;
}

/* Keyboard-selected cell. Brighter, more obvious ring than the default
   focus-visible so the user can see at a glance which cell arrow-keys
   will activate. The ring uses the brand lavender, not the OS blue. */
.cell--selected,
.cell--selected:focus-visible {
  outline: 2px solid var(--lull-lavender);
  outline-offset: 4px;
  box-shadow:
    0 0 0 2px var(--lull-night) inset,
    0 0 0 4px var(--lull-lavender) inset,
    0 8px 18px rgba(0, 0, 0, 0.35),
    0 2px 6px rgba(0, 0, 0, 0.25),
    0 0 22px rgba(184, 165, 217, 0.35);
}

.cell__face {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  backface-visibility: hidden;
}

.cell__face--back {
  background:
    radial-gradient(70% 70% at 50% 35%, var(--lull-cream) 0%, var(--lull-cream-2) 100%);
}

.cell__face--back::after {
  /* Subtle Lull "moon-dot" mark on the back of every card.
     A small ring of light, evoking the brand without competing
     with the icon on the front face. */
  content: "";
  width: 38%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--lull-night);
  box-shadow:
    0 0 0 4px rgba(184, 165, 217, 0.18),
    inset -6px -4px 0 rgba(247, 240, 232, 0.12);
  position: relative;
}

/* A tiny crescent: an offset inner circle carves a "moon"
   shape out of the dark dot. */
.cell__face--back::before {
  content: "";
  position: absolute;
  width: 26%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--lull-cream);
  top: 50%;
  left: 56%;
  transform: translate(-50%, -50%);
  z-index: 1;
}

.cell__face--front {
  background: var(--lull-cream);
  transform: rotateY(180deg);
  color: var(--lull-lavender-deep);
}

.cell__icon {
  width: 56%;
  height: 56%;
  display: block;
}

.cell[data-state="flipped"] .cell__face--back,
.cell[data-state="matched"] .cell__face--back { opacity: 0; }

.cell[data-state="flipped"] .cell__face--front,
.cell[data-state="matched"] .cell__face--front { transform: rotateY(0deg); }

.cell[data-state="matched"] {
  background: var(--lull-sage);
  box-shadow:
    0 0 0 2px var(--lull-sage) inset,
    0 0 24px rgba(168, 197, 176, 0.45),
    0 8px 18px rgba(0, 0, 0, 0.25);
  animation: cell-match 600ms var(--ease-calm);
}

/* When a card is matched, the front face is rotated to face-up and would
   otherwise cover the cell's sage background with its cream paint. Override
   the front face's own background to transparent so the sage bleeds through.
   The icon inside (the SVG) is already tinted sage-deep via currentColor. */
.cell[data-state="matched"] .cell__face--front {
  background: transparent;
  color: var(--lull-sage-deep);
}

.cell[data-state="mismatch"] {
  animation: cell-shake 360ms var(--ease-calm);
}

@keyframes cell-match {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.03); }       /* softer than 1.05 — Lull, not gamified */
  100% { transform: scale(1); }
}

@keyframes cell-shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-4px); }
  75%      { transform: translateX(4px); }
}

/* Round-complete banner -----------------------------------------------------*/
/* Sits in the .app flow BELOW the board so the matched cards remain visible.
   Same surface language as the idle placeholder, but with a sage tint to
   signal success without being celebratory. */
.round-banner {
  display: grid;
  grid-template-rows: auto auto;
  place-items: center;
  gap: 10px;
  padding: 12px 0 0;
  pointer-events: none;
}

.round-banner__hero {
  display: block;
  width: min(100%, 420px);
  height: auto;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-card);
  box-shadow: 0 6px 24px rgba(20, 8, 40, 0.18);
  opacity: 0;
  animation: round-hero-in 700ms 100ms var(--ease-calm) both;
}

@keyframes round-hero-in {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .round-banner__hero { animation: none; opacity: 1; }
}

.round-banner__text {
  margin: 0;
  padding: 12px 22px;
  border-radius: var(--r-pill);
  background: rgba(108, 212, 154, 0.10);
  border: 1px solid rgba(108, 212, 154, 0.32);
  color: var(--lull-sage-soft);
  font-family: var(--ff-display);
  font-style: italic;
  font-size: 17px;
  letter-spacing: 0.01em;
  text-align: center;
  text-shadow: 0 0 12px rgba(108, 212, 154, 0.35);
  animation: round-banner-in 600ms var(--ease-calm) both;
}

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

@media (prefers-reduced-motion: reduce) {
  .round-banner__text { animation: none; }
}

/* Controls ------------------------------------------------------------------*/
.controls {
  display: flex;
  justify-content: center;
  gap: 12px;
  padding: 8px 0 4px;
}

.btn {
  appearance: none;
  border: 0;
  font-family: var(--ff-body);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 14px 28px;
  border-radius: var(--r-btn);
  cursor: pointer;
  transition: transform var(--t-press) var(--ease-calm),
              background var(--t-press) var(--ease-calm),
              box-shadow var(--t-press) var(--ease-calm);
  -webkit-tap-highlight-color: transparent;
}

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

.btn--primary {
  background: linear-gradient(180deg, var(--lull-lavender) 0%, #9d8ac7 100%);
  color: var(--lull-night);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.4) inset,
    0 6px 14px rgba(184, 165, 217, 0.35);
}
.btn--primary:hover { transform: translateY(-1px); }
.btn--primary:active { transform: translateY(1px); }

.btn--ghost {
  background: transparent;
  color: var(--lull-mist-2);
  border: 1px solid rgba(247, 240, 232, 0.18);
}
.btn--ghost:hover { color: var(--lull-mist); border-color: var(--lull-mist-2); }

/* Reduce motion */
@media (prefers-reduced-motion: reduce) {
  .wordmark__mark { animation: none; }
  .cell, .btn { transition: none; }
}

/* Small screens */
@media (max-width: 420px) {
  .app { padding: 12px; gap: 12px; }
  .wordmark { font-size: 18px; }
  .board { gap: 8px; }
  .cell__icon { width: 60%; }
}
