/* Nibbles theme - the shared cuteness: palette, cards, chips, buttons,
   floaties, toasts. Every game page loads this before its own stylesheet.
   Kit rule: nothing game-specific lives here. */

/* ============================================================== Word Nibbles
   A soft, candy-coloured theme. Mobile first; everything scales off the board
   width so the same layout works on a phone and on a desktop browser.
   ========================================================================= */

:root {
  --pink:        #ff8fbe;
  --pink-deep:   #f0619a;
  --pink-soft:   #ffdcec;
  --mint:        #8fe3cc;
  --mint-deep:   #3fbfa2;
  --lemon:       #ffe27a;
  --lavender:    #c3b1ff;
  --sky:         #a5d8ff;
  --cream:       #fffaf6;
  --ink:         #5c4657;
  --ink-soft:    #786675;
  --danger:      #ff7a7a;

  /* Surfaces and edges. Everything below paints through these, so a theme
     is a palette swap and never a second copy of the rules. */
  --page-1:      #fff1f8;
  --page-2:      #f4f0ff;
  --page-3:      #eafaf6;
  --surface:     rgba(255, 255, 255, .78);   /* a card, over the page */
  --surface-2:   rgba(255, 255, 255, .5);    /* the quieter card */
  --surface-3:   #ffffff;                    /* solid: chips, inputs, pills */
  --edge:         #ffffff;                   /* the card's own rim */
  --edge-soft:   #ddc7d6;                    /* hairlines and placeholder ink */
  /* White on a pastel is a deliberate choice, not an oversight: it reads
     1.50 on mint and 2.12 on pink, well under WCAG's 4.5. The alternatives
     were mocked up and measured, and the candy look won. */
  --on-accent:   #ffffff;                    /* ink on a pink or mint fill */
  --on-bright:   #402e3d;                    /* ink on gold and lavender, which
                                                stay light in both themes */
  --on-dark:     #ffffff;                    /* ink on the toast, always dark */
  --emboss:      #ffffff;                    /* the little raised text shadow */
  --card-shadow: rgba(190, 140, 170, .14);
  --tint-lemon:  #fffaeb;                    /* a lemon wash: best words, leaders */
  --veil:        rgba(255, 245, 250, .88);   /* pause and countdown, over the board */
  --tint-pink:   #fff5fa;                    /* the sudoku grid's quiet washes */
  --tint-pink-2: #ffeaf4;
  --tint-lavender: #ece3ff;
  --tint-mint:   #eafff7;

  --tile-face:   #ffffff;
  --tile-edge:   #f3d9e6;
  --radius:      22px;
  --shadow:      0 8px 0 rgba(206, 160, 186, .28), 0 14px 28px rgba(190, 130, 165, .18);

  --board-w: min(100vw - 32px, 440px);   /* viewport minus the app's side padding */
  --size: 4;
  --tile: calc(var(--board-w) / var(--size));

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* ------------------------------------------------------------------- dark
   Only the tokens move, so every rule above keeps working untouched. The
   page head resolves "auto" against the phone before the first frame and
   stamps data-theme, so there is exactly one dark block to keep in step
   and nothing ever flashes the wrong palette. */

:root[data-theme="dark"] {
  color-scheme: dark;

  --pink-soft:   #4b2f41;
  --lemon:       #f5d06a;
  --lavender:    #a892f0;
  --cream:       #2c2431;
  --ink:         #f3e9f0;
  --ink-soft:    #b7a5b4;

  --tile-face:   #3b3040;
  --tile-edge:   #56414f;
  --shadow:      0 8px 0 rgba(0, 0, 0, .34), 0 14px 28px rgba(0, 0, 0, .42);

  --page-1:      #251b28;
  --page-2:      #1f1b2e;
  --page-3:      #16242a;
  --surface:     rgba(58, 47, 63, .82);
  --surface-2:   rgba(58, 47, 63, .52);
  --surface-3:   #382e3d;
  --edge:        rgba(255, 255, 255, .09);
  --edge-soft:   #6a5566;
  --emboss:      rgba(0, 0, 0, .35);
  --on-bright:   #2b1f2a;
  --card-shadow: rgba(0, 0, 0, .45);
  --tint-lemon:  #3e3524;
  --veil:        rgba(28, 22, 32, .9);
  --tint-pink:   #322530;
  --tint-pink-2: #402c3a;
  --tint-lavender: #2f2747;
  --tint-mint:   #1f342f;
}

/* The drifting snacks are decoration, and the cog can switch them off. */
:root.no-sky .sky { display: none; }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Several elements below set `display`, which would otherwise beat the browser
   default for [hidden] and leave them stuck on screen. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  overscroll-behavior: none;
  overflow-x: clip;   /* decorative bleed must never cause sideways scroll */
}

body {
  font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Quicksand", "Segoe UI",
               system-ui, -apple-system, sans-serif;
  color: var(--ink);
  background: linear-gradient(170deg, var(--page-1) 0%, var(--page-2) 45%, var(--page-3) 100%);
  background-attachment: fixed;
  -webkit-user-select: none;
  user-select: none;
}

/* --------------------------------------------------------- background fluff */

/* The snacks drift behind the app, but the cards above them are
   translucent, so near the top and bottom they read as sitting on the HUD
   and the button row. Fading them out of those bands keeps them off the
   clock a player is racing without taking the charm away. */
.sky {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 15%, #000 85%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 15%, #000 85%, transparent 100%);
}

.floaty {
  position: absolute;
  left: var(--x);
  top: 100%;
  font-size: calc(26px * var(--s, 1));
  opacity: .5;
  animation: drift 22s linear infinite;
  animation-delay: var(--d, 0s);
}

@keyframes drift {
  from { transform: translateY(0) rotate(0deg); }
  to   { transform: translateY(-118vh) rotate(340deg); }
}

/* ------------------------------------------------------------------ layout */

#app {
  position: relative;
  z-index: 1;
  max-width: 520px;
  margin: 0 auto;
  padding: calc(14px + var(--safe-top)) 16px calc(20px + var(--safe-bottom));
}

.screen { display: none; }
.screen.is-active { display: flex; flex-direction: column; gap: 14px; animation: screen-in .35s ease both; }
.screen.is-active.no-anim { animation: none; }

@keyframes screen-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* -------------------------------------------------------------------- hero */

.hero { text-align: center; padding: 6px 0 0; }
.hero-tight { padding-top: 0; }

.mascot {
  font-size: 58px;
  line-height: 1;
  animation: bob 2.6s ease-in-out infinite;
  filter: drop-shadow(0 6px 10px rgba(190, 130, 165, .3));
}

@keyframes bob {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50%      { transform: translateY(-8px) rotate(3deg); }
}

.title {
  margin: 6px 0 2px;
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -.5px;
  background: linear-gradient(100deg, var(--pink-deep), var(--lavender) 55%, var(--mint-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.tagline { margin: 0; font-size: 14px; color: var(--ink-soft); }

/* ------------------------------------------------------------------- cards */

.card {
  background: var(--surface);
  backdrop-filter: blur(6px);
  border: 2px solid var(--edge);
  border-radius: var(--radius);
  padding: 16px;
  box-shadow: 0 10px 24px var(--card-shadow);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.card-quiet { background: var(--surface-2); gap: 8px; }

.field { display: flex; flex-direction: column; gap: 8px; }

.field-label {
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--ink-soft);
}

.hint-text { margin: 0; font-size: 12.5px; color: var(--ink-soft); line-height: 1.45; }
.hint-text.error { color: var(--danger); font-weight: 700; }

/* ------------------------------------------------------------------- chips */

.chips { display: flex; flex-wrap: wrap; gap: 8px; }

.chip {
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  background: var(--surface-3);
  border: 2px solid var(--pink-soft);
  border-radius: 16px;
  padding: 9px 14px;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, box-shadow .18s ease;
}

/* Grow to fill the row so a wrapped last option looks deliberate, not stranded. */
.chips .chip:not(.chip-tall) { flex: 1 1 auto; }

.chip:active { transform: scale(.94); }

.chip.is-on {
  background: linear-gradient(160deg, var(--pink), var(--pink-deep));
  border-color: var(--pink-deep);
  color: var(--on-accent);
  box-shadow: 0 4px 0 rgba(210, 90, 140, .35);
}

.chip-tall {
  flex: 1 1 0;
  min-width: 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 10px 6px;
}

.chip-tall b { font-size: 22px; line-height: 1.1; }
.chip-tall span { font-size: 13px; }
.chip-tall em { font-style: normal; font-size: 11px; opacity: .65; }

/* ----------------------------------------------------------------- toggles */

.toggles { display: flex; gap: 8px; }

.toggle {
  flex: 1;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px;
  border-radius: 16px;
  border: 2px solid var(--pink-soft);
  background: var(--surface-3);
  color: var(--ink-soft);
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}

.toggle[aria-pressed="true"] {
  background: linear-gradient(160deg, var(--surface-3), var(--pink-soft));
  border-color: var(--pink);
  color: var(--ink);
}

.toggle[aria-pressed="false"] .toggle-emoji { filter: grayscale(1); opacity: .5; }
.toggle:active { transform: scale(.96); }

/* ------------------------------------------------------------------ <more> */

.more { border-top: 2px dashed var(--pink-soft); padding-top: 12px; }

.more summary {
  font-size: 14px;
  font-weight: 800;
  color: var(--pink-deep);
  cursor: pointer;
  list-style: none;
  text-align: center;
  padding: 4px;
}

.more summary::-webkit-details-marker { display: none; }
.more[open] summary { margin-bottom: 12px; }
.more > .field { margin-bottom: 14px; }

/* ----------------------------------------------------------------- buttons */

.big-button {
  font: inherit;
  font-size: 20px;
  font-weight: 800;
  color: var(--on-accent);
  background: linear-gradient(160deg, var(--pink), var(--pink-deep));
  border: none;
  border-radius: 24px;
  padding: 17px;
  cursor: pointer;
  box-shadow: 0 6px 0 #d9548c, 0 14px 24px rgba(230, 120, 170, .35);
  transition: box-shadow .1s ease;
}

.big-button:active {
  transform: translateY(4px);
  box-shadow: 0 2px 0 #d9548c, 0 8px 14px rgba(230, 120, 170, .3);
}

.mini-button {
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  color: var(--on-accent);
  background: linear-gradient(160deg, var(--mint), var(--mint-deep));
  border: none;
  border-radius: 16px;
  padding: 11px 18px;
  cursor: pointer;
  box-shadow: 0 4px 0 rgba(45, 160, 135, .55);
  transition: box-shadow .1s ease;
}

.mini-button:active { transform: translateY(3px); box-shadow: 0 1px 0 rgba(45, 160, 135, .55); }

.mini-button.ghost {
  background: var(--surface-3);
  color: var(--ink-soft);
  box-shadow: 0 4px 0 var(--pink-soft);
}

.text-button {
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-soft);
  background: none;
  border: none;
  padding: 8px;
  cursor: pointer;
  text-decoration: underline dotted;
}

.join-row { display: flex; gap: 8px; }

.code-input {
  flex: 1;
  font: inherit;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 3px;
  text-align: center;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--surface-3);
  border: 2px solid var(--pink-soft);
  border-radius: 16px;
  padding: 10px;
  min-width: 0;
}

.code-input:focus { outline: none; border-color: var(--pink); }
.code-input::placeholder { color: var(--edge-soft); letter-spacing: 2px; }

/* ------------------------------------------------------------------ toast */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + var(--safe-bottom));
  transform: translate(-50%, 20px);
  background: rgba(92, 70, 87, .94);
  color: var(--on-dark);
  font-size: 14.5px;
  font-weight: 700;
  padding: 11px 18px;
  border-radius: 18px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease, transform .25s ease;
  z-index: 50;
  max-width: 86vw;
  text-align: center;
}

.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.happy { background: linear-gradient(160deg, var(--mint-deep), #2fa88c); }
.toast.sad { background: linear-gradient(160deg, #ff8f8f, #e05a5a); }

/* ----------------------------------------------------------- settings cog
   Per-device preferences, built by src/kit/settings.ts. It opens from a
   real button rather than a floating cog: none of this is something a
   player changes often, so it does not need to follow them around. */

.set-veil {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(48, 34, 45, .55);
  backdrop-filter: blur(3px);
  animation: screen-in .2s ease both;
}

.set-panel { width: min(340px, 100%); max-height: 88vh; overflow-y: auto; }

.set-title {
  margin: 0;
  font-size: 19px;
  font-weight: 800;
  text-align: center;
}

.set-done { margin-top: 2px; }

/* The hub gives it a proper button; a game's setup screen a quiet link. */
.set-open { align-self: center; }

/* ------------------------------------------------------------ preferences */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .floaty { display: none; }
}

/* ------------------------------------------------------- foot buttons
   The side padding and the row gap ride --foot-fit, which src/kit/foot.ts
   sets to 1 whenever the row fits and lowers only as far as a narrow
   phone demands. */

.foot-button {
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  background: var(--surface-3);
  border: 2px solid var(--pink-soft);
  border-radius: 18px;
  padding: 10px calc(14px * var(--foot-fit, 1));
  color: var(--ink);
  cursor: pointer;
  box-shadow: 0 4px 0 var(--pink-soft);
  transition: box-shadow .1s ease, opacity .2s ease;
}

.foot-button:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--pink-soft); }
.foot-button:disabled { opacity: .4; cursor: default; }
.foot-emoji { font-size: 19px; }

/* ------------------------------------------------------------ party look
   The identity, lobby and invite widgets every Nibbles game shares -
   each game's stylesheet only adds its own flavour on top. */

@keyframes pop-word {
  0% { transform: scale(1); }
  35% { transform: scale(1.18) rotate(-2deg); }
  100% { transform: scale(1); }
}

.name-input {
  text-transform: none;
  letter-spacing: .5px;
  font-size: 16px;
}
.name-input::placeholder { text-transform: none; letter-spacing: .5px; }

.emoji-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
}

.emoji-btn {
  font-size: 22px;
  line-height: 1;
  background: var(--surface-3);
  border: 2px solid var(--pink-soft);
  border-radius: 12px;
  padding: 6px 8px;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.emoji-btn:active { transform: scale(.9); }
.emoji-btn.sel {
  border-color: var(--pink-deep);
  background: var(--pink-soft);
  transform: scale(1.12);
}

.lobby-code-card { text-align: center; }

.party-code-big {
  font-size: 44px;
  font-weight: 800;
  letter-spacing: 10px;
  padding-left: 10px;   /* optically recentre the tracked text */
  color: var(--pink-deep);
  text-shadow: 0 3px 0 var(--emboss);
  cursor: pointer;
  animation: pop-word .5s ease;
}

.lobby-players { display: flex; flex-direction: column; gap: 8px; }

.lobby-player {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-3);
  border: 2px solid var(--pink-soft);
  border-radius: 16px;
  padding: 9px 12px;
  font-size: 15px;
  font-weight: 700;
}
.lobby-player .p-emoji {
  font-size: 22px;
  animation: bob 2.6s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}
.lobby-player .p-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lobby-player .p-tag {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .5px;
  background: var(--lemon);
  border-radius: 8px;
  padding: 2px 7px;
}
.lobby-player .p-total { font-size: 12px; color: var(--ink-soft); }
.lobby-player.away { opacity: .45; }
.lobby-player.away .p-emoji { filter: grayscale(1); }

.kick-btn {
  font: inherit;
  font-size: 13px;
  font-weight: 800;
  color: var(--ink-soft);
  background: var(--surface-3);
  border: 2px solid var(--pink-soft);
  border-radius: 10px;
  width: 26px;
  height: 26px;
  line-height: 1;
  cursor: pointer;
  flex: none;
}
.kick-btn:active { color: var(--danger); border-color: var(--danger); }

.lobby-wait { text-align: center; font-size: 14px; }

.invite-card { text-align: center; align-items: center; }
.invite-emoji { font-size: 46px; line-height: 1.1; }
.invite-heading { font-size: 21px; margin: 0; }

/* A muted sound or music foot button dims until tapped back on. */
.foot-button.is-off { opacity: .55; }

/* ------------------------------------------------------------- game HUD
   The score pill, round clock ring and stat pill both games wear, plus
   the footer button row. */

.hud { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

.hud-pill {
  flex: 1;
  background: var(--surface);
  border: 2px solid var(--edge);
  border-radius: 18px;
  padding: 8px 10px;
  text-align: center;
  box-shadow: 0 6px 14px var(--card-shadow);
}

.hud-label {
  display: block;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.hud-pill strong { font-size: 22px; font-weight: 800; }

@keyframes bump {
  0% { transform: scale(1); }
  40% { transform: scale(1.35); color: var(--pink-deep); }
  100% { transform: scale(1); }
}

/* ----------------------------------------------------------------- timer */

.timer { position: relative; width: 84px; height: 84px; flex: none; }
.timer svg { width: 100%; height: 100%; transform: rotate(-90deg); }

.ring-bg { fill: var(--surface-3); stroke: var(--pink-soft); stroke-width: 8; }

.ring-fg {
  fill: none;
  stroke: var(--mint-deep);
  stroke-width: 8;
  stroke-linecap: round;
  stroke-dasharray: 276.5;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset .3s linear, stroke .6s ease;
}

.timer.warn .ring-fg { stroke: var(--lemon); }
.timer.danger .ring-fg { stroke: var(--danger); }
.timer.danger { animation: heartbeat 1s ease-in-out infinite; }

@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  15% { transform: scale(1.09); }
  30% { transform: scale(1); }
}

.timer-text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -.5px;
}

.game-foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(10px * var(--foot-fit, 1));
}

@media (max-height: 700px) {
  .timer { width: 72px; height: 72px; }
}

/* A settings card a lobby guest may read but never edit. */
.is-locked { pointer-events: none; opacity: .8; }

/* ------------------------------------------------------------ game screen
   The one layout template both games play on, phone or desktop: HUD at
   the top, the game area floating in the screen's slack, the button row
   docked at the bottom. A game's area holds whatever it plays with - a
   letter grid, or a number grid with its pad. */
.game-screen.is-active { min-height: calc(100dvh - 34px - var(--safe-top) - var(--safe-bottom)); }
.game-area { margin-block: auto; }

/* Scaffold chrome (src/kit/screens.ts): the more-games foot link and
   the lobby settings region, shared by both games. */
.foot-link { text-align: center; }
.lobby-settings { display: flex; flex-direction: column; gap: 8px; }

/* Folded away for a guest: one line of what the host picked, and a tap to
   see the rest. Nobody needs 640px of chips they are not allowed to touch. */
.lobby-settings.is-folded > div,
.lobby-settings.is-folded > .lobby-wait { display: none; }
.lobby-peek { align-self: center; }
