/* ── Queens ───────────────────────────────────────────────────────────────
   The board is a riso print, and the one board that follows the theme: fluoro
   spot inks on charcoal stock in the dark, the same inks knocked back on
   newsprint in the light. Near-black ink sits on top of either. Everything
   around it is the app's ordinary chrome. Values come from tokens.css only.

   The grain below is a deliberate exception to the "no textures" rule in
   tokens.css — a riso print without the press is just flat colour. It is
   scoped to the board face and appears nowhere else in the app.             */

/* ── play: layout ─────────────────────────────────────────────────────── */

.queens-play {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.q-chrome {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  padding-top: calc(var(--space-4) + var(--sat));   /* clear the status bar / notch */
  border-bottom: var(--hairline) solid var(--line);
}
/* the play bar wears the same ghost buttons as the app bar */
.q-chrome .icon-btn, .lits-chrome .icon-btn { border-color: transparent; background: none; }
.q-chrome .icon-btn:hover:not(:disabled), .lits-chrome .icon-btn:hover:not(:disabled) {
  background: var(--surface); border-color: transparent;
}
.q-chrome .spacer { flex: 1; }
.q-tag {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--accent);
}

.q-stage {
  flex: 1;
  min-height: 0;
  display: grid;
  place-items: center;
  padding: var(--space-6);
}

.q-loading {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-label);
  color: var(--mute);
  text-align: center;
}

.q-foot {
  display: flex;
  align-items: center;
  justify-content: center;   /* the options bar centres its content — one convention, all games */
  gap: var(--space-4);
  padding: var(--space-5);
  /* gesture-nav / notched devices: keep Hint-Restart and the palettes clear of
     the home indicator. Every grid game wears this foot; circuits pays its own. */
  padding-bottom: calc(var(--space-5) + var(--sab));
  border-top: var(--hairline) solid var(--line);
}
.q-foot:empty { display: none; }
/* a foot whose children are all empty (snap's idle message span) is as good as
   empty — no options, no divider */
.q-foot:not(:has(> :not(:empty))) { display: none; }
.q-foot .pill { display: inline-flex; align-items: center; gap: var(--space-3); }
.q-foot .pill svg { width: var(--icon-sm); height: var(--icon-sm); flex: none; }
.q-foot .q-hint.busy { opacity: 0.5; pointer-events: none; }
.q-chrome .q-title { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text); letter-spacing: var(--tracking-label); }
/* the secondary action reads quieter than Hint */
.q-foot .q-restart { color: var(--dim); }
.q-foot .q-restart:hover { color: var(--text); }
.q-auto.active { color: var(--accent); border-color: var(--accent-line); background: var(--accent-dim); }

/* ── the board ────────────────────────────────────────────────────────── */

.q-board {
  --n: 8;
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--n), 1fr);
  grid-template-rows: repeat(var(--n), 1fr);
  width: min(92vw, 66vh, 520px);
  aspect-ratio: 1;
  /* a hair of dark ink around the whole slab, so the stock sits on the theme */
  outline: 2px solid var(--q-edge);
  border-radius: 2px;
  /* none, not manipulation: a press-drag paints dots, it must not scroll/select */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

/* The press: ink mottle over the whole slab. Static and pointer-transparent, so
   it costs one composited layer and never intercepts a tap.

   soft-light over *grayscale* noise, not multiply over colour noise. Multiply
   only ever darkens: at a legible grain size it averaged out to a flat ~11%
   dimming of every tint — the palette above would not have been the palette
   that shipped, and the texture still read as nothing. Soft-light lightens and
   darkens in equal measure, so the tints survive and the grain is what you see.
   baseFrequency is deliberately coarse: finer speckle disappears at the size a
   phone actually draws a cell. */
.q-board::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  opacity: 0.55;
  mix-blend-mode: soft-light;
  border-radius: inherit;
  background-size: 120px 120px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.6' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}

.q-cell {
  position: relative;
  box-sizing: border-box;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: filter var(--duration-1) var(--ease);
}
.q-cell:hover { filter: brightness(1.05); }
.q-cell:active { filter: brightness(0.94); }

.q-mark {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}

/* the crown — a filled coronet, so it still reads at thumbnail size */
.q-crown { display: none; }
.q-crown svg {
  width: 62%;
  height: 62%;
  fill: var(--q-ink);
  stroke: none;
  transition: fill 340ms var(--ease);   /* the bad-queen reddening eases in/out */
}
.q-cell.has-queen .q-crown { display: block; animation: q-pop var(--duration-2) var(--ease) both; }

/* the player's dot, and the fainter one auto-mark leaves */
.q-dotmark { display: none; }
.q-cell.has-dot .q-dotmark,
.q-cell.has-autodot .q-dotmark {
  display: block;
  width: 16.5%;
  height: 16.5%;
  border-radius: var(--radius-full);
  background: var(--q-ink);
}
.q-cell.has-autodot .q-dotmark {
  width: 12.1%;
  height: 12.1%;
  background: var(--q-ink-soft);
}

/* auto-marks that a fresh crown just ruled out ripple outward from it — each
   cell waits by its distance (--qd), so the dots land nearest-first, ~200ms end
   to end. `both` holds them invisible until their turn. */
@keyframes q-dotwave { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.q-cell.q-wave .q-dotmark { animation: q-dotwave 100ms var(--ease) var(--qd, 0ms) both; }

/* the red cross over a clash or a boxed-in region. It is held back a beat before
   it fades in — so a mistake you correct within a second never flashes — then
   fades straight back out the moment the cell is fixed. Always in the layout,
   its visibility carried by opacity so the fade can run in both directions. */
.q-cross {
  display: block;
  position: absolute;
  inset: 18%;
  opacity: 0;
  pointer-events: none;
  transition: opacity 340ms var(--ease);   /* fade OUT immediately when fixed */
}
.q-cell.bad .q-cross { opacity: 1; transition-delay: 1s; }   /* … but wait 1s to fade IN */
.q-cross::before,
.q-cross::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--q-cross);
  border-radius: 2px;
}
.q-cross::before { transform: rotate(45deg); }
.q-cross::after { transform: rotate(-45deg); }
/* a bad queen keeps its crown but reddens — held the same beat, then eased */
.q-cell.bad.has-queen .q-crown svg { fill: var(--q-cross); transition-delay: 1s; }
.q-cell.bad.has-queen .q-cross { opacity: 0; }   /* show the red crown, not a cross */

/* the hint pulse */
.q-cell.hinted { animation: q-hint 1.6s var(--ease) 2; z-index: 1; }

@keyframes q-pop { from { transform: scale(0.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes q-hint {
  0%, 100% { box-shadow: inset 0 0 0 0 var(--accent); }
  50% { box-shadow: inset 0 0 0 3px var(--accent); }
}

/* ── landscape phone: board left, controls stacked right ──────────────── */
@media (orientation: landscape) and (max-height: 700px) {
  /* rails come from the shared block in puzzle.css — only the board is queens' */
  .queens-play .q-board { width: min(88vh, 78vw); }
}

/* ── journey: the chapter lesson ─────────────────────────────────────────── */

.q-teach {
  max-width: 52ch;
  margin: 0 auto var(--space-7);
  padding: var(--space-5) var(--space-6);
  border-left: 2px solid var(--accent-line);
  background: var(--accent-dim);
  border-radius: var(--radius);
  color: var(--dim);
  font-size: var(--text-base);
  line-height: var(--leading-prose);
}

/* the region-grid thumbnail on a level card */
.q-mini {
  display: grid;
  grid-template-columns: repeat(var(--n), 1fr);
  aspect-ratio: 1;
  width: 100%;
  outline: 1.5px solid var(--q-edge);
}
.q-mini i { display: grid; place-items: center; }
.q-mini-crown { display: block; width: 74%; height: 74%; }
.q-mini-crown svg {
  width: 100%; height: 100%;
  fill: var(--q-ink); stroke: none;
}

/* ── daily: the day's three challenges ───────────────────────────────────── */

.q-day {
  max-width: 460px;
  margin: 0 auto var(--space-8);
  width: 100%;
}
.q-day-head {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: var(--space-4);
}
.q-challenges { display: grid; gap: var(--space-3); }
.q-chal {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-5) var(--space-6);
  background: var(--surface);
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color var(--t), background var(--t);
}
.q-chal:hover { border-color: var(--accent-line); background: var(--surface-2); }
.q-chal.done { border-color: var(--success-line); }
.q-chal-name { font-size: var(--text-lg); color: var(--text); }
.q-chal-time { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--dim); letter-spacing: var(--tracking-label); }
.q-chal-go { display: inline-flex; color: var(--mute); }
.q-chal-go svg {
  width: var(--icon); height: var(--icon);
  fill: none; stroke: currentColor; stroke-width: var(--stroke);
  stroke-linecap: round; stroke-linejoin: round;
}
.q-chal.done .q-chal-go { color: var(--green); }

/* calendar states unique to Queens: a partly-done day, and the selected day */
.cal-cell.part .dot { background: var(--accent); opacity: 0.5; }
.cal-cell.sel { outline: 1.5px solid var(--accent); outline-offset: -1.5px; border-radius: var(--radius-sm); }

/* the input chips (auto | dots | queens) — contents only, the chip itself is
   the shared .po-chip. The "A" is auto mode's glyph; the dot is the same swatch
   the board draws; the crown must stay FILLED (the shared chip rule strokes
   svgs, and a hairline coronet dissolves at chip size). */
.qm-auto { font-family: var(--font-mono); font-size: 16px; line-height: 1; }
.qm-dot { width: 10px; height: 10px; border-radius: 50%; background: currentColor; opacity: 0.75; }
.qm-crown { display: inline-flex; }
.po-chip .qm-crown svg,
.ng-ghost.po-ghost .qm-crown svg { fill: currentColor; stroke: none; }

/* a pinned (hint-revealed) queen: quietly marked, and it never moves again */
.q-cell.revealed::after { content: ''; position: absolute; right: 3px; top: 3px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--accent); opacity: 0.85; pointer-events: none; }
