/* ════════════════════════════════════════════════════════════════
   Schubladen — deutsches „Connections"
   ════════════════════════════════════════════════════════════════
   Spielt im Dark- UND Light-Theme: Kacheln/Chrome laufen über die
   Theme-Tokens (--color-*), die vier Gruppenfarben sind die festen
   Fynbos-Hex (gleich in beiden Themes). Architektur + Look an
   Sinnsuche + die Bento-Editorial-Sprache angelehnt.
   ════════════════════════════════════════════════════════════════ */

/* Tier colours = exact Fynbos palette. Difficulty ramp:
   apricot (leicht) → bistre → blue → pomegranate (trickreich). */
.sb-app {
  --sb-apricot: var(--fynbos-apricot, #EAA624);
  --sb-bistre: var(--fynbos-bistre, #767B39);
  --sb-blue: var(--fynbos-blue, #AADCF2);
  --sb-pomegranate: var(--fynbos-pomegranate, #C85555);
  --sb-ink-on-light: #1B1D14;
  --sb-cream: #F4EFE2;
  max-width: 560px;
  margin: 0 auto;
  font-family: 'DM Sans', system-ui, sans-serif;
}

.sb-stage { padding: var(--space-xl, 2rem) 0 var(--space-2xl, 3rem); }

.sb-intro {
  text-align: center;
  color: var(--color-text-secondary);
  font-size: 0.95rem;
  margin: 0 auto var(--space-lg, 1.5rem);
  max-width: 42ch;
}
.sb-intro strong { color: var(--color-text-primary); }

/* ── Skeleton (first paint before JS) ───────────────────────────── */
.sb-skeleton { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 12px 0; }
.sb-skeleton__cell {
  aspect-ratio: 1.35 / 1; border-radius: 9px;
  background: linear-gradient(90deg, rgba(118,123,57,0.10) 0%, rgba(118,123,57,0.22) 50%, rgba(118,123,57,0.10) 100%);
  background-size: 200% 100%; animation: sb-shimmer 1.6s linear infinite;
}
@keyframes sb-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .sb-skeleton__cell { animation: none; } }

/* ── Solved group rows ──────────────────────────────────────────── */
.sb-solved { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.sb-group {
  border-radius: 10px; padding: 12px 14px; text-align: center;
  animation: sb-pop 0.3s cubic-bezier(.2,.8,.2,1);
}
.sb-group--apricot     { background: var(--sb-apricot);     color: var(--sb-ink-on-light); }
.sb-group--bistre      { background: var(--sb-bistre);      color: var(--sb-cream); }
.sb-group--blue        { background: var(--sb-blue);        color: var(--sb-ink-on-light); }
.sb-group--pomegranate { background: var(--sb-pomegranate); color: var(--sb-cream); }
.sb-group__label {
  font-family: 'Syne', sans-serif; font-weight: 800; font-size: 12px;
  letter-spacing: 0.14em; text-transform: uppercase;
}
.sb-group__words {
  font-family: 'Fraunces', Georgia, serif; font-style: italic; font-weight: 500;
  font-size: 17px; margin-top: 2px;
}
@keyframes sb-pop { from { transform: scale(0.96); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .sb-group { animation: none; } }

/* ── The 4×4 grid ───────────────────────────────────────────────── */
.sb-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 16px; }
.sb-tile {
  aspect-ratio: 1.35 / 1;
  border: 1.5px solid var(--color-border-strong);
  border-radius: 9px;
  background: var(--color-bg-card);
  color: var(--color-text-primary);
  font-family: 'Syne', sans-serif; font-weight: 700;
  font-size: clamp(10px, 2.6vw, 14px); letter-spacing: 0.02em;
  text-transform: uppercase; cursor: pointer;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 4px; user-select: none; line-height: 1.05;
  transition: transform 80ms ease, background 120ms, color 120ms, box-shadow 120ms;
}
.sb-tile:hover:not(:disabled) { border-color: var(--color-accent); }
.sb-tile.is-selected {
  background: var(--color-text-primary);
  color: var(--color-bg-main);
  border-color: var(--color-text-primary);
  transform: translateY(-2px);
}
.sb-tile:disabled { cursor: default; }
.sb-tile.is-shake { animation: sb-shake 0.42s; }
@keyframes sb-shake {
  0%,100%{transform:translateX(0)} 20%{transform:translateX(-5px)} 40%{transform:translateX(5px)}
  60%{transform:translateX(-4px)} 80%{transform:translateX(4px)}
}
@media (prefers-reduced-motion: reduce) { .sb-tile.is-shake { animation: none; } }
.sb-tile:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 2px; }

/* ── Mistakes ───────────────────────────────────────────────────── */
.sb-mistakes {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-bottom: 16px; font-size: 13px; color: var(--color-text-secondary);
}
.sb-dots { display: inline-flex; gap: 6px; }
.sb-dot {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--fynbos-pomegranate, #C85555); transition: opacity 0.2s, transform 0.2s;
}
.sb-dot.is-used { opacity: 0.2; transform: scale(0.78); }

/* ── Controls ───────────────────────────────────────────────────── */
.sb-controls { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.sb-btn {
  font-family: 'Syne', sans-serif; font-weight: 700; font-size: 12px;
  letter-spacing: 0.08em; text-transform: uppercase;
  border: 1.5px solid var(--color-border-strong); background: transparent;
  color: var(--color-text-primary); border-radius: 999px;
  padding: 11px 20px; cursor: pointer; min-height: 44px;
  transition: background 120ms, color 120ms, border-color 120ms, opacity 120ms;
}
.sb-btn:hover:not(:disabled) { border-color: var(--color-accent); color: var(--color-accent); }
.sb-btn--primary {
  background: var(--color-text-primary); color: var(--color-bg-main); border-color: var(--color-text-primary);
}
.sb-btn--primary:hover:not(:disabled) {
  background: var(--fynbos-pomegranate, #C85555); border-color: var(--fynbos-pomegranate, #C85555); color: var(--sb-cream);
}
.sb-btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* ── Toast ──────────────────────────────────────────────────────── */
.sb-toast {
  text-align: center; min-height: 22px; margin: 14px 0 4px;
  font-family: 'Fraunces', Georgia, serif; font-style: italic; font-size: 16px;
  color: var(--color-accent); opacity: 0; transition: opacity 0.2s;
}
.sb-toast.is-show { opacity: 1; }

/* ── End screen + share ─────────────────────────────────────────── */
.sb-end { text-align: center; margin-top: 18px; }
.sb-end__title {
  font-family: 'Fraunces', Georgia, serif; font-style: italic; font-weight: 600;
  font-size: 28px; margin-bottom: 10px;
}
.sb-share {
  font-family: 'JetBrains Mono', monospace; font-size: 20px; line-height: 1.4;
  letter-spacing: 2px; margin: 0 0 14px; color: var(--color-text-primary);
}

/* ── Archive day strip ──────────────────────────────────────────── */
.sb-days { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 28px; align-items: center; }
.sb-days__label {
  font-family: 'Syne', sans-serif; font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--color-text-muted);
}
.sb-day {
  font-family: 'Syne', sans-serif; font-weight: 700; font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; border: 1px solid var(--color-border); background: var(--color-bg-card);
  color: var(--color-text-secondary); border-radius: 8px; padding: 8px 12px; cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.sb-day.is-active { border-color: var(--color-accent); color: var(--color-text-primary); }
.sb-day.is-done::after { content: ' ✓'; color: var(--fynbos-bistre, #767B39); }

/* ── Confetti ───────────────────────────────────────────────────── */
.sb-confetti { position: fixed; inset: 0; pointer-events: none; z-index: 1000; overflow: hidden; }
.sb-confetti__bit {
  position: absolute; top: -12px; width: 9px; height: 14px; border-radius: 1px;
  animation: sb-fall 2.4s cubic-bezier(.3,.7,.5,1) forwards;
}
@keyframes sb-fall {
  to { transform: translateY(105vh) rotate(540deg); opacity: 0.2; }
}

/* ── Mobile ─────────────────────────────────────────────────────── */
@media (max-width: 520px) {
  .sb-group__words { font-size: 15px; }
  .sb-share { font-size: 17px; }
}

/* ── Light Edition — ink-on-paper card chrome for the tiles ─────── */
[data-theme="light"] .sb-tile {
  border-color: var(--color-text-primary);
  box-shadow: 3px 3px 0 var(--color-border-strong);
}
[data-theme="light"] .sb-tile.is-selected { box-shadow: 3px 3px 0 var(--fynbos-pomegranate, #C85555); }
[data-theme="light"] .sb-day { border-color: var(--color-text-primary); box-shadow: 2px 2px 0 var(--color-border); }

/* ════════════════════════════════════════════════════════════════
   DELIGHT PASS — richer micro-animations (2026-05-21)
   ════════════════════════════════════════════════════════════════
   Appended last so these rules win over the base ones above. The JS
   adds the trigger classes (is-tap, is-correct, is-win) + does FLIP
   reflow. Everything is gated by prefers-reduced-motion at the end. */

/* Tap pop — fires only on the freshly-clicked tile (JS toggles in
   place, no full re-render, so existing selections don't re-pop). */
.sb-tile.is-tap { animation: sb-tap 0.2s cubic-bezier(.2,.8,.2,1); }
@keyframes sb-tap { 0% { transform: scale(1); } 45% { transform: scale(1.09); } 100% { transform: scale(1); } }
.sb-tile.is-selected { transform: translateY(-3px); }

/* Correct guess — the 4 tiles leap in unison (tiny stagger) before
   they collapse and the solved row pops in. The signature moment. */
.sb-tile.is-correct {
  animation: sb-jump 0.46s cubic-bezier(.2,.8,.2,1) both;
  z-index: 3;
  border-color: var(--color-text-primary);
}
@keyframes sb-jump {
  0%   { transform: translateY(-3px) scale(1); }
  35%  { transform: translateY(-16px) scale(1.06); }
  70%  { transform: translateY(0) scale(0.97); }
  100% { transform: translateY(0) scale(1); }
}

/* Solved row — springy entrance with a back-overshoot, words rise in. */
.sb-group { animation: sb-pop 0.42s cubic-bezier(.34, 1.56, .64, 1) both; }
.sb-group__words { animation: sb-word-rise 0.5s ease both; animation-delay: 0.1s; }
@keyframes sb-word-rise { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }

/* Win cascade — on the winning render every row does a celebratory
   bounce, staggered (delay set inline by JS). Overrides sb-pop. */
.sb-group.is-win { animation: sb-win-bounce 0.6s cubic-bezier(.2,.8,.2,1) both; }
@keyframes sb-win-bounce {
  0% { transform: scale(1); } 28% { transform: scale(1.045); }
  55% { transform: scale(0.99); } 100% { transform: scale(1); }
}

/* Mistake dot — deflates with a little squash when spent. */
.sb-dot.is-used { animation: sb-deflate 0.42s cubic-bezier(.2,.8,.2,1) both; }
@keyframes sb-deflate {
  0% { transform: scale(1.25); opacity: 1; } 50% { transform: scale(0.68); }
  100% { transform: scale(0.78); opacity: 0.2; }
}

/* Submit button — gentle "ready to go" breathing once 4 are picked. */
.sb-btn--primary:not(:disabled) { animation: sb-ready 1.8s ease-in-out infinite; }
@keyframes sb-ready { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.035); } }

@media (prefers-reduced-motion: reduce) {
  .sb-tile.is-tap, .sb-tile.is-correct, .sb-group, .sb-group.is-win,
  .sb-group__words, .sb-dot.is-used,
  .sb-btn--primary:not(:disabled) { animation: none !important; }
}

/* ════════════════════════════════════════════════════════════════
   FEEDBACK PILLS · the toast becomes a coloured pill when it carries
   a result `kind`. The plain italic line was easy to miss; the "one
   away" hint especially needs to land, so it gets the loud treatment.
   ════════════════════════════════════════════════════════════════ */
.sb-toast--found, .sb-toast--miss, .sb-toast--away {
  font-style: normal;
  font-family: 'Syne', sans-serif; font-weight: 800;
  font-size: 13px; letter-spacing: 0.07em; text-transform: uppercase;
  width: fit-content; max-width: 92%;
  margin: 14px auto 4px;
  padding: 11px 22px; border-radius: 999px; min-height: 0;
  line-height: 1.1; color: var(--sb-cream, #FBF7EF);
}

/* Correct group — calm, affirming bistre. */
.sb-toast--found {
  background: var(--fynbos-bistre, #767B39);
  box-shadow: 0 4px 14px rgba(118, 123, 57, 0.32);
}

/* Plain miss — quiet dark pill, doesn't shout. */
.sb-toast--miss {
  background: var(--color-text-primary);
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.22);
}

/* ONE AWAY — the loud one. Pomegranate pill, pops in, then keeps a
   slow throb the whole time it's up so the eye is drawn straight to
   it. Paired with the longer 2.8 s dwell in toast(). */
.sb-toast--away {
  background: var(--fynbos-pomegranate, #C85555);
  color: #FFF;
  font-size: 14px; padding: 13px 26px;
  box-shadow: 0 6px 20px rgba(200, 85, 85, 0.45);
  animation: sb-toast-pop 0.34s cubic-bezier(.2,1.3,.4,1) both,
             sb-toast-throb 1.1s ease-in-out 0.34s infinite;
}
@keyframes sb-toast-pop {
  0%   { transform: scale(0.7) translateY(6px); opacity: 0; }
  60%  { transform: scale(1.06); }
  100% { transform: scale(1) translateY(0); opacity: 1; }
}
@keyframes sb-toast-throb {
  0%, 100% { transform: scale(1); box-shadow: 0 6px 20px rgba(200, 85, 85, 0.45); }
  50%      { transform: scale(1.045); box-shadow: 0 8px 28px rgba(200, 85, 85, 0.6); }
}
[data-theme="light"] .sb-toast--away { box-shadow: 3px 3px 0 var(--color-text-primary); }
[data-theme="light"] .sb-toast--found { box-shadow: 3px 3px 0 var(--color-border-strong); }
[data-theme="light"] .sb-toast--miss  { box-shadow: 3px 3px 0 var(--color-border-strong); }

/* ════════════════════════════════════════════════════════════════
   END SCREEN · replay button + button spacing
   ════════════════════════════════════════════════════════════════ */
.sb-end .sb-btn { margin: 4px 5px 0; }

/* Replay — filled, so "play again" reads as the inviting action next
   to the outline Share/Copy button. */
.sb-btn--replay {
  background: var(--fynbos-apricot, #EAA624);
  border-color: var(--fynbos-apricot, #EAA624);
  color: #2A2410;
}
.sb-btn--replay:hover:not(:disabled) {
  background: var(--fynbos-pomegranate, #C85555);
  border-color: var(--fynbos-pomegranate, #C85555);
  color: var(--sb-cream, #FBF7EF);
}
[data-theme="light"] .sb-btn--replay {
  box-shadow: 2px 2px 0 var(--color-text-primary);
}

/* ════════════════════════════════════════════════════════════════
   ARCHIVE · mark today's puzzle with an accent ring so it stands out
   from the longer list of past days.
   ════════════════════════════════════════════════════════════════ */
.sb-day.is-today {
  border-color: var(--fynbos-pomegranate, #C85555);
  color: var(--color-text-primary);
  box-shadow: 0 0 0 1px var(--fynbos-pomegranate, #C85555);
}
[data-theme="light"] .sb-day.is-today {
  border-color: var(--fynbos-pomegranate, #C85555);
  box-shadow: 2px 2px 0 var(--fynbos-pomegranate, #C85555);
}
/* Active + today at once → accent stays the today ring, active shows
   via the filled-in text weight. */
.sb-day.is-active.is-today { color: var(--color-text-primary); }

/* ════════════════════════════════════════════════════════════════
   IMMERSIVE LAYOUT (body.is-game) · NYT-style fullscreen play
   The page is a viewport-locked app shell (critical bits inlined in
   the page head). Here: the enlarged board, the modal chrome behind
   the header's ? and 🗓 icons, and the how-to content.
   ════════════════════════════════════════════════════════════════ */

/* Bigger board — with the page chrome gone there's room to breathe,
   so tiles, gaps and group rows all scale up for a "really in it" feel. */
body.is-game .sb-grid { gap: clamp(8px, 1.4vw, 12px); margin-bottom: clamp(12px, 2vh, 18px); }
body.is-game .sb-solved { gap: clamp(8px, 1.4vw, 12px); margin-bottom: clamp(8px, 1.4vw, 12px); }
body.is-game .sb-tile { font-size: clamp(12px, 2.9vw, 17px); border-radius: 11px; }
body.is-game .sb-group { border-radius: 12px; padding: clamp(12px, 1.8vh, 16px) 14px; }
body.is-game .sb-group__words { font-size: clamp(15px, 2.4vw, 19px); }
body.is-game .sb-btn { font-size: 13px; padding: 12px 22px; }
/* The archive lives in its own modal now, never inline under the board.
   (Shell/bar/modal chrome is shared — see css/game-shell.css.) */
body.is-game .sb-app > .sb-days { display: none; }

/* Archive day-chips inside the shared modal — let them wrap freely. */
#game-archive-body .sb-days { margin-top: 4px; }
#game-archive-body .sb-days__label { width: 100%; text-align: center; margin-bottom: 4px; }

/* Short viewports — compact the board so even the end screen (4 solved
   rows + share grid + buttons) fits without the stage scrolling. */
@media (max-height: 720px) {
  body.is-game .sb-grid { gap: 7px; margin-bottom: 10px; }
  body.is-game .sb-solved { gap: 7px; margin-bottom: 7px; }
  body.is-game .sb-group { padding: 9px 14px; }
  body.is-game .sb-mistakes { margin-bottom: 10px; }
  body.is-game .sb-end { margin-top: 8px; }
  body.is-game .sb-share { font-size: 16px; margin-bottom: 8px; }
  body.is-game .sb-end__title { font-size: 24px; margin-bottom: 6px; }
}
