/* Keys. The board is near-white and the tiles near-black, because that is the
   highest-contrast pairing available and this genre is entirely about seeing
   the next tile. The chrome stays dark so it never competes with the board. */

:root {
  --ink: #e9eefc;
  --dim: #8d97b5;
  --accent: #2DE1FF;
  --panel: rgba(10, 14, 26, 0.86);
}

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

html, body {
  height: 100%;
  overflow: hidden;
  background: #07090f;
  color: var(--ink);
  font-family: ui-rounded, "SF Pro Rounded", system-ui, -apple-system, sans-serif;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}

#app { position: fixed; inset: 0; }
#game { display: block; width: 100%; height: 100%; }
.hidden { display: none !important; }

/* ---------------------------------------------------------------------- HUD */

.hud {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top));
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  pointer-events: none;
}

.hud-score {
  font-size: clamp(2rem, 8vw, 3rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  /* The score sits over the white board, so it needs to be dark there. */
  color: #e9eefc;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.8);
}

.hud-tune {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #5d7a6b;
}

/* ------------------------------------------------------------------ screens */

.screen {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 1.25rem;
  background: rgba(5, 7, 14, 0.66);
  backdrop-filter: blur(3px);
}

.panel {
  width: min(23rem, 100%);
  padding: 1.7rem 1.4rem;
  border-radius: 18px;
  background: var(--panel);
  border: 1px solid rgba(217, 164, 65, 0.22);
  text-align: center;
}

.logo {
  font-size: clamp(1.9rem, 9vw, 2.6rem);
  font-weight: 900;
  letter-spacing: 0.04em;
  line-height: 1;
  color: var(--accent);
}
.logo { font-size: clamp(2.8rem, 14vw, 3.8rem); letter-spacing: 0.08em; }

/* The four colours, shown once on the menu so the rule is understood before
   the first ring rather than learned by dying at it. */
.swatches { display: flex; justify-content: center; gap: 0.5rem; margin-top: 1.1rem; }
.swatches i {
  width: 1.5rem; height: 1.5rem; border-radius: 50%;
  background: var(--c); box-shadow: 0 0 14px color-mix(in srgb, var(--c) 60%, transparent);
}

/* The duff switch sits with the tune list, because choosing to hear the
   nasheed unaccompanied is part of choosing the nasheed. */
.duff {
  margin-top: 0.55rem;
  padding: 0.5rem 0.9rem;
  border: 1px solid rgba(238, 244, 238, 0.16);
  border-radius: 999px;
  background: transparent;
  color: var(--dim);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
}
.duff.is-on { border-color: var(--accent); color: var(--accent); }

.lede { margin-top: 0.6rem; color: var(--dim); font-size: 0.95rem; line-height: 1.5; }

.tunes { display: grid; gap: 0.4rem; margin-top: 1.2rem; }

.tune {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid rgba(232, 241, 255, 0.14);
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tune b { font-size: 0.95rem; }
.tune span { font-size: 0.75rem; color: var(--dim); }

.tune.is-on {
  border-color: var(--accent);
  background: rgba(217, 164, 65, 0.12);
}

.best { margin-top: 1.1rem; color: var(--dim); font-size: 0.95rem; }
.best b { color: var(--ink); font-size: 1.15rem; }

.tap {
  margin-top: 1rem;
  color: var(--accent);
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  animation: pulse 1.6s ease-in-out infinite;
}

@keyframes pulse { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .tap { animation: none; opacity: 0.85; } }

.new-best {
  color: #ffd24a;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.8rem;
}

.score { font-size: clamp(3rem, 16vw, 4.4rem); font-weight: 900; letter-spacing: -0.03em; }
.sub { margin-top: 0.2rem; color: var(--dim); font-size: 0.95rem; }
.sub b { color: var(--ink); }

.btn {
  display: block;
  width: 100%;
  margin-top: 0.7rem;
  padding: 0.85rem 1rem;
  border: 1px solid rgba(232, 241, 255, 0.18);
  border-radius: 12px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  font-size: 1rem;
  cursor: pointer;
}

/* The revive button. Gold, because it is the one optional thing on the screen,
   and it counts itself down so the choice stays quick. */
.btn--revive {
  margin-top: 1.4rem;
  border-color: var(--accent);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
.btn--revive .ad-dot { font-size: 0.75em; opacity: 0.85; }
.btn--revive i { font-style: normal; opacity: 0.7; font-variant-numeric: tabular-nums; }

.btn--primary {
  margin-top: 1.4rem;
  border-color: transparent;
  background: var(--accent);
  color: #06211a;
}

.btn:focus-visible, .tune:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --------------------------------------------------------------------- store */
/* Built by src/store.js, and only in the self-hosted build - on the portals the
   module returns nothing and none of this is ever on screen. Styled against the
   game's own tokens so the storefront reads as part of the game rather than as
   a panel bolted onto it. */

.store {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin-top: 1rem;
  padding: 0.85rem;
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.25);
  text-align: left;
}

.store.is-busy { opacity: 0.7; }

.store-copy { font-size: 0.8rem; line-height: 1.4; color: var(--ink); }
.store-label { font-size: 0.72rem; color: var(--dim); }

.store-field {
  width: 100%;
  padding: 0.5rem 0.65rem;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.4);
  color: var(--ink);
  font: inherit;
  font-size: 0.85rem;
  /* The one field in the game a player must be able to select and edit. */
  user-select: text;
  -webkit-user-select: text;
}

.store-field:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.store-row { display: flex; flex-wrap: wrap; gap: 0.45rem; }

.store-btn {
  /* Two-up on a phone, and never so narrow that a price wraps off the label. */
  flex: 1 1 7.5rem;
  padding: 0.6rem 0.5rem;
  border: 1px solid transparent;
  border-radius: 10px;
  background: var(--accent);
  color: #06111a;
  font: inherit;
  font-weight: 700;
  font-size: 0.82rem;
  white-space: nowrap;
  cursor: pointer;
}

.store-btn--ghost {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.22);
  color: var(--dim);
  font-weight: 600;
}

.store-btn:disabled { opacity: 0.5; cursor: default; }
.store-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.store-msg { font-size: 0.75rem; color: var(--ink); min-height: 1em; }

/* The licence key is the one string a player must be able to copy exactly. */
.store-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8rem;
  color: var(--accent);
  word-break: break-all;
  user-select: all;
  -webkit-user-select: all;
}

.store-fine { font-size: 0.68rem; color: var(--dim); line-height: 1.5; }
.store-fine a { color: var(--dim); }

/* Stripe mounts its own iframe here; this only has to be a legible, scrollable
   box with a way out. Stripe's form is light-themed, so a white card reads as
   intentional rather than as something failing to load. */
.checkout-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: grid;
  place-items: center;
  padding: max(16px, env(safe-area-inset-top)) 16px;
  background: rgba(3, 6, 12, 0.86);
  backdrop-filter: blur(4px);
  overflow: auto;
}

.checkout-mount {
  width: min(460px, 100%);
  max-height: 86vh;
  overflow: auto;
  padding: 14px;
  border-radius: 12px;
  background: #fff;
}

.checkout-close {
  position: absolute;
  top: calc(10px + env(safe-area-inset-top));
  right: 12px;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(220, 235, 250, 0.35);
  border-radius: 50%;
  background: rgba(8, 12, 22, 0.85);
  color: #eaf6ff;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

.checkout-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------------ backdrops */

.panel-title { font-size: 1.3rem; font-weight: 800; letter-spacing: 0.02em; }

.theme-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
  margin-top: 1rem;
}

.theme {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.6rem 0.4rem;
  border: 1px solid rgba(233, 238, 252, 0.14);
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.25);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}

.theme b { font-size: 0.85rem; }
.theme span { font-size: 0.68rem; color: var(--dim); }

/* The swatch is the actual gradient the game paints, so the button shows the
   product rather than a label for it. */
.theme-swatch {
  width: 100%;
  height: 2.4rem;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: linear-gradient(to bottom, var(--top), var(--bottom));
}

.theme.is-on { border-color: var(--accent); }
.theme.is-locked { opacity: 0.55; cursor: default; }
.theme:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* A screen carrying a store can be taller than the phone it is on. The menus
   were centred with `place-items: center`, which clips the top of anything that
   overflows rather than letting it scroll - so the buy buttons would sit off the
   bottom of the screen with no way to reach them. Flex plus `margin: auto` keeps
   a short panel centred and lets a tall one scroll from its true top. */
.screen {
  display: flex;
  place-items: initial;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.screen > .panel { margin: auto; }
