/* ==========================================================================
   Weave
   --------------------------------------------------------------------------
   Loaded after styles.css and relies on its custom properties, resets, topbar,
   dialog, toast and button rules. Only what is specific to the grouping game
   lives here.

   Layout notes:
   - The grid is a hard 4x4 at every width. Reflowing it would destroy the one
     spatial skill the game asks for, which is seeing a row or a cluster.
   - Word tiles size their text down rather than wrapping, because a wrapped
     word changes tile height and makes the grid jump as groups are solved.
   - Colour is never the only carrier of meaning: each solved band states its
     category in words, and the high contrast option swaps the whole palette.
   ========================================================================== */

:root {
  /* Group colours in difficulty order: easiest to hardest. */
  --rank-0: #eab308;
  --rank-1: #4ade80;
  --rank-2: #60a5fa;
  --rank-3: #c084fc;
  --rank-ink: #10151f;
}

/* A palette that stays separable with deuteranopia and protanopia: it leans on
   lightness and on blue/orange rather than on red/green. */
[data-contrast="high"] {
  --rank-0: #f8fafc;
  --rank-1: #fb923c;
  --rank-2: #3b82f6;
  --rank-3: #1e293b;
  --rank-ink: #0b1017;
}
[data-contrast="high"] .band.is-rank-3,
[data-contrast="high"] .result-band.is-rank-3 { color: #e9edf5; }
[data-contrast="high"] .band.is-rank-3 .band-words { color: #b9c4d6; }

/* styles.css lets main run to 1320px so Verbraid's four boards can sit side by
   side. A 4x4 word grid at that width gives absurdly large tiles, so Weave
   narrows its own column. Scoped safely: this stylesheet loads on Weave only. */
main { max-width: 640px; }

/* ---------------------------------------------------------------- mistakes */

.mistakes-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 0 4px;
}

.mistakes {
  font-size: 0.76rem;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.mistake-pips { display: flex; gap: 5px; }

.mpip {
  width: 9px; height: 9px;
  border-radius: 99px;
  background: var(--accent);
}
.mpip.is-spent { background: var(--line); }

/* --------------------------------------------------------- solved groups */

/* No outer margins on any of these blocks: main is a flex column with its own
   gap, so adding margins here would double the spacing. */
.solved {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.solved:empty { display: none; }

.band {
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  text-align: center;
  color: var(--rank-ink);
  animation: band-in 240ms ease-out;
}
.band.is-rank-0 { background: var(--rank-0); }
.band.is-rank-1 { background: var(--rank-1); }
.band.is-rank-2 { background: var(--rank-2); }
.band.is-rank-3 { background: var(--rank-3); }

/* A group revealed because the day was lost, not because it was found. Outlined
   rather than filled, so the two are distinguishable without reading. */
.band.is-missed {
  background: transparent;
  color: var(--muted);
  border: 1px dashed var(--line);
}
.band.is-missed .band-label { color: var(--danger); }

.band-label {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 750;
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

.band-words {
  margin: 2px 0 0;
  font-family: var(--mono);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

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

/* -------------------------------------------------------------------- grid */

.grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--tile-gap);
}

.wtile {
  /* Tall enough for a comfortable thumb target at phone widths, and square-ish
     rather than square so a long word still fits on one line. */
  min-height: 62px;
  padding: 4px 2px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  color: var(--text);
  font-family: var(--mono);
  font-size: clamp(0.62rem, 2.5vw, 0.86rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  cursor: pointer;
  display: grid;
  place-items: center;
  user-select: none;
  transition: background var(--dur), border-color var(--dur), transform 90ms, color var(--dur);
}
.wtile:hover:not([disabled]) { background: #2a3550; }
.wtile:active:not([disabled]) { transform: translateY(1px); }

.wtile.is-picked {
  background: var(--absent);
  border-color: var(--accent);
  color: #ffffff;
}

/* The flash on a rejected submission. Colour plus motion, because the toast and
   the reading carry the actual message. */
.wtile.is-wrong { animation: tile-wrong 400ms ease; }

.wtile[disabled] { opacity: 0.5; cursor: default; }

@keyframes tile-wrong {
  0%, 100% { transform: none; }
  25% { transform: translateX(-3px); }
  75% { transform: translateX(3px); }
}

.grid.is-shaking { animation: grid-shake 340ms ease; }

@keyframes grid-shake {
  0%, 100% { transform: none; }
  20% { transform: translateX(-5px); }
  60% { transform: translateX(5px); }
}

@media (prefers-reduced-motion: reduce) {
  .band, .wtile.is-wrong, .grid.is-shaking { animation: none; }
  .wtile { transition: none; }
}

/* ------------------------------------------------------- coherence reading */

.reading { padding: 0; }

.coh {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel);
  padding: 9px 12px;
}

.coh-head {
  margin: 0 0 6px;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--text);
}

.coh-track {
  display: block;
  height: 5px;
  border-radius: 99px;
  background: var(--panel-2);
  overflow: hidden;
}

.coh-fill {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: var(--heat-unknown);
  transition: width var(--dur);
}

.coh-note {
  margin: 6px 0 0;
  font-size: 0.7rem;
  line-height: 1.5;
  color: var(--muted);
}

.coh[data-band="unrelated"] .coh-fill { background: var(--heat-freezing); }
.coh[data-band="scattered"] .coh-fill { background: var(--heat-cold); }
.coh[data-band="loose"]     .coh-fill { background: var(--heat-mild); }
.coh[data-band="plausible"] .coh-fill { background: var(--heat-warm); }
.coh[data-band="tight"]     .coh-fill { background: var(--heat-hot); }

.coh[data-band="unrelated"] .coh-head { color: var(--heat-freezing); }
.coh[data-band="scattered"] .coh-head { color: var(--heat-cold); }
.coh[data-band="loose"]     .coh-head { color: var(--heat-mild); }
.coh[data-band="plausible"] .coh-head { color: var(--heat-warm); }
.coh[data-band="tight"]     .coh-head { color: var(--heat-hot); }

/* ----------------------------------------------------------------- actions */

.wactions {
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
  padding: 0 0 24px;
}
.wactions .btn { min-width: 116px; }

/* ------------------------------------------------------------ result dialog */

.result-groups {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.result-band {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 10px;
  padding: 8px 11px;
  border-radius: var(--radius-sm);
  color: var(--rank-ink);
}
.result-band.is-rank-0 { background: var(--rank-0); }
.result-band.is-rank-1 { background: var(--rank-1); }
.result-band.is-rank-2 { background: var(--rank-2); }
.result-band.is-rank-3 { background: var(--rank-3); }
.result-band.is-missed { background: transparent; border: 1px dashed var(--line); color: var(--muted); }

.result-band-label {
  font-size: 0.7rem;
  font-weight: 750;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.result-band-words {
  grid-column: 1;
  font-family: var(--mono);
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.result-band-mark {
  grid-row: 1 / span 2;
  grid-column: 2;
  align-self: center;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.75;
}

/* ------------------------------------------------------------------ widths */

@media (min-width: 620px) {
  .wtile { min-height: 74px; font-size: 0.92rem; }
  .band-words { font-size: 0.86rem; }
}
