﻿/* ==========================================================================
   Word Unscramblers - solver widget
   The same markup and stylesheet drive every tool page. What changes between
   the unscrambler, the anagram solver, the Wordle helper and the rest is which
   controls are rendered and which engine call runs, never the layout.
   ========================================================================== */

.tool {
  position: relative;
  z-index: 1;
}

/* ---------------------------------------------------------------- the rack */

.tool-panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
  padding: clamp(1.1rem, 3vw, 1.9rem);
}

.rack-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.55rem;
}
.rack-label label {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.rack-hint {
  font-size: 0.8rem;
  color: var(--ink-3);
}
.rack-hint kbd {
  font-family: var(--font-body);
  font-weight: 700;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 0.3rem;
  font-size: 0.78rem;
  color: var(--ink-2);
}

.rack-row {
  display: flex;
  gap: 0.6rem;
  align-items: stretch;
}
@media (max-width: 560px) {
  .rack-row {
    flex-wrap: wrap;
  }
  .rack-row .btn {
    width: 100%;
  }
}

.rack-input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.85rem);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.6rem 0.9rem;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--line-2);
  border-radius: var(--r-md);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.rack-input::placeholder {
  color: var(--ink-3);
  opacity: 0.55;
  letter-spacing: 0.08em;
}
.rack-input:focus {
  outline: none;
  border-color: var(--pine);
  background: var(--surface);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--pine) 14%, transparent);
}
.rack-input[aria-invalid='true'] {
  border-color: var(--clay);
}

/* The scramble maker holds a whole word list, so it needs normal text sizing
   rather than the wide-tracked single-rack treatment. */
.rack-input-list {
  font-family: var(--font-body);
  font-size: 1.02rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
}

.rack-clear {
  position: absolute;
}

/* Live preview of the rack as physical tiles. Purely reassurance: it shows the
   player exactly what the solver thinks they typed, including blanks. */
.tile-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.85rem;
  min-height: 2.6rem;
  align-items: center;
}
.tile-strip:empty {
  display: none;
}
.tile-strip .tile {
  animation: tile-in 0.16s ease-out;
}
@keyframes tile-in {
  from {
    opacity: 0;
    transform: translateY(-4px) scale(0.94);
  }
}
.tile-strip .rack-total {
  margin-left: auto;
  font-size: 0.8rem;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.tile-strip .rack-total b {
  color: var(--ochre);
}

/* ---------------------------------------------------------------- controls */

.tool-advanced {
  margin-top: 1rem;
  border-top: 1px solid var(--line);
  padding-top: 0.35rem;
}
.tool-advanced > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.6rem 0;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--pine);
}
.tool-advanced > summary::-webkit-details-marker {
  display: none;
}
.tool-advanced > summary::before {
  content: '';
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.18s ease;
}
.tool-advanced[open] > summary::before {
  transform: rotate(-135deg);
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: 0.85rem 1rem;
  padding: 0.4rem 0 1rem;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}
.field > span {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.field input,
.field select {
  font-family: inherit;
  font-size: 0.94rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 0.5rem 0.6rem;
  min-width: 0;
  width: 100%;
}
.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--pine);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--pine) 12%, transparent);
}
.field input[type='text'] {
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.field-note {
  font-size: 0.76rem;
  color: var(--ink-3);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}
.chip {
  border: 1px solid var(--line-2);
  background: var(--surface);
  color: var(--ink-2);
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  font: inherit;
  font-size: 0.83rem;
  font-weight: 550;
  cursor: pointer;
  white-space: nowrap;
}
.chip:hover {
  border-color: var(--pine);
  color: var(--pine);
}
.chip[aria-pressed='true'] {
  background: var(--pine);
  border-color: var(--pine);
  color: #f6f0e4;
}
[data-theme='dark'] .chip[aria-pressed='true'] {
  color: #17140d;
}

.example-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--ink-3);
}
.example-row button {
  border: 1px dashed var(--line-2);
  background: transparent;
  color: var(--ink-2);
  border-radius: var(--r-sm);
  padding: 0.22rem 0.55rem;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
}
.example-row button:hover {
  border-style: solid;
  border-color: var(--ochre);
  color: var(--ochre);
}

/* ---------------------------------------------------------------- results */

.results {
  margin-top: 1.5rem;
}

.results-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  padding: 0.9rem 1.1rem;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  margin-bottom: 1.25rem;
}
.results-count {
  font-family: var(--font-display);
  font-size: 1.12rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
}
.results-count b {
  color: var(--pine);
  font-variant-numeric: tabular-nums;
}
.results-meta {
  font-size: 0.8rem;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.results-sort {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.83rem;
  color: var(--ink-3);
}
.results-sort select {
  font-family: inherit;
  font-size: 0.86rem;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
}

.group + .group {
  margin-top: 1.9rem;
}
.group-head {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-bottom: 0.85rem;
}
.group-head h3 {
  margin: 0;
  font-size: 1.06rem;
}
.group-head .rule {
  flex: 1;
  height: 1px;
  background: var(--line);
}
.group-head .count {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.word-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(215px, 100%), 1fr));
  gap: 0.6rem;
}

.word {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  text-align: left;
  font: inherit;
  cursor: pointer;
  width: 100%;
  transition: border-color 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;
}
.word:hover {
  border-color: var(--line-2);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
.word[aria-expanded='true'] {
  border-color: var(--pine);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--pine) 11%, transparent);
}

.word-text {
  font-family: var(--font-display);
  font-size: 1.06rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.15;
  overflow-wrap: anywhere;
}

/* The top scoring word in the whole result set gets the ochre tile treatment.
   One highlight only, otherwise it stops meaning anything. */
.word[data-best='true'] {
  background: var(--ochre-soft);
  border-color: color-mix(in oklab, var(--ochre) 40%, transparent);
}
.word[data-best='true'] .word-text {
  color: var(--ochre-hi);
}

.word-scores {
  margin-left: auto;
  display: flex;
  gap: 0.3rem;
  flex: none;
}
.score {
  min-width: 1.85rem;
  padding: 0.1rem 0.32rem;
  border-radius: 4px;
  text-align: center;
  font-size: 0.76rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  border: 1px solid transparent;
}
.score-scrabble {
  background: var(--pine-soft);
  color: var(--pine);
  border-color: color-mix(in oklab, var(--pine) 22%, transparent);
}
.score-wwf {
  background: var(--ochre-soft);
  color: var(--ochre);
  border-color: color-mix(in oklab, var(--ochre) 24%, transparent);
}
.score-ochre {
  background: var(--ochre-soft);
  color: var(--ochre);
  border-color: color-mix(in oklab, var(--ochre) 24%, transparent);
}
.score-feud {
  background: var(--teal-soft);
  color: var(--teal);
  border-color: color-mix(in oklab, var(--teal) 24%, transparent);
}

/* ---------------------------------------------------- spelling bee board */

/* The centre letter is required in every answer, so it gets the visual weight
   of the honeycomb centre rather than being one field among seven. */
.bee-board {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  align-items: flex-end;
}
.bee-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.bee-field > span {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.bee-centre {
  width: 3.4rem;
  height: 3.4rem;
  text-align: center;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  text-transform: uppercase;
  color: #2a1f08;
  background: var(--ochre);
  border: 2px solid var(--ochre-hi);
  border-radius: 10px;
  padding: 0;
}
.bee-centre::placeholder {
  color: rgba(42, 31, 8, 0.5);
}
.bee-centre:focus {
  outline: none;
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--ochre) 30%, transparent);
}
.bee-outer {
  flex: 1 1 15rem;
  min-width: 0;
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 0.55rem 0.85rem;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--line-2);
  border-radius: 10px;
  height: 3.4rem;
}
.bee-outer:focus {
  outline: none;
  border-color: var(--ochre);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--ochre) 16%, transparent);
}

/* ---------------------------------------------------- boggle board */

.boggle-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
  max-width: 19rem;
  margin-top: 0.5rem;
}
.boggle-cell {
  aspect-ratio: 1;
  width: 100%;
  text-align: center;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 0.9rem + 1.2vw, 1.5rem);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--tile-ink);
  background: var(--tile-face);
  border: 1px solid var(--tile-edge);
  border-radius: 8px;
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.12);
  padding: 0;
  min-width: 0;
}
.boggle-cell:focus {
  outline: none;
  border-color: var(--pine);
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.12), 0 0 0 3px color-mix(in oklab, var(--pine) 20%, transparent);
}
.boggle-cell::placeholder {
  color: transparent;
}

/* ---------------------------------------------------- quordle boards */

.quordle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 1.25rem;
}
.quordle-board {
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 4px solid var(--card-accent, var(--pine));
  border-radius: var(--r-lg);
  padding: 1.1rem 1.2rem;
}
.quordle-board > h3 {
  font-size: 0.95rem;
  color: var(--card-accent, var(--pine));
  margin-bottom: 0.9rem;
}
.quordle-board .wordle-slot {
  width: 2.4rem;
  height: 2.4rem;
  font-size: 1rem;
}
.quordle-board .wordle-row > span {
  min-width: 5.5rem;
  font-size: 0.68rem;
}
.quordle-board .results {
  margin-top: 1rem;
}
.quordle-board .word-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(110px, 100%), 1fr));
}
.quordle-board .results-bar {
  padding: 0.6rem 0.8rem;
  margin-bottom: 0.8rem;
}
.quordle-board .results-count {
  font-size: 0.95rem;
}

.word-common {
  position: absolute;
  top: -5px;
  left: 0.6rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--surface);
  color: var(--ink-3);
  padding: 0 0.28rem;
  border-radius: 3px;
}

.word-def {
  grid-column: 1 / -1;
  margin: -0.15rem 0 0.35rem;
  padding: 0.85rem 1rem;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-left: 3px solid var(--pine);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  font-size: 0.9rem;
  color: var(--ink-2);
  line-height: 1.6;
}
.word-def strong {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink);
  margin-right: 0.4rem;
}
.word-def .def-scores {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.8rem;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------- pre-rendered results */

/*
 * The /unscramble/<letters>/ pages ship their word list in the HTML so they work
 * with JavaScript off. Those words are links to each word's own page rather than
 * buttons that expand a definition, which is what builds the internal linking
 * between them, so they get their own lighter treatment.
 */
/*
 * A word page can carry several hundred of these. content-visibility lets the
 * browser skip layout and paint for the groups still below the fold, which on a
 * long list is the difference between a slow first render and an instant one.
 * contain-intrinsic-size gives it a height to reserve so the scrollbar does not
 * jump around as you scroll, which would otherwise cost us on layout shift.
 */
.rgroup {
  content-visibility: auto;
  contain-intrinsic-size: auto 320px;
}
.rgroup + .rgroup {
  margin-top: 1.75rem;
}

.rw-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr));
  gap: 0.45rem;
}

.rw {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.6rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  text-decoration: none;
  transition: border-color 0.14s ease, background 0.14s ease;
}
.rw:hover {
  border-color: var(--pine);
  background: var(--pine-soft);
}
.rw-word {
  font-family: var(--font-display);
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.rw:hover .rw-word {
  color: var(--pine);
}
.rw-score {
  margin-left: auto;
  flex: none;
  min-width: 1.6rem;
  text-align: center;
  padding: 0.05rem 0.28rem;
  border-radius: 4px;
  background: var(--sunk);
  border: 1px solid var(--line);
  font-size: 0.72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}
.rw-best {
  background: var(--ochre-soft);
  border-color: color-mix(in oklab, var(--ochre) 40%, transparent);
}
.rw-best .rw-word {
  color: var(--ochre-hi);
}
.rw-best .rw-score {
  background: var(--ochre);
  border-color: var(--ochre);
  color: #fff8ec;
}
[data-theme='dark'] .rw-best .rw-score {
  color: #1a140a;
}

/* ---------------------------------------------------------------- states */

.tool-state {
  padding: 2.5rem 1.25rem;
  text-align: center;
  color: var(--ink-3);
  border: 1px dashed var(--line-2);
  border-radius: var(--r-lg);
  background: color-mix(in oklab, var(--sunk) 55%, transparent);
}
.tool-state h2,
.tool-state h3 {
  color: var(--ink);
  margin-bottom: 0.35rem;
}
.tool-state p {
  margin: 0 auto;
  max-width: 46ch;
  font-size: 0.94rem;
}
.tool-state.is-error {
  border-color: color-mix(in oklab, var(--clay) 45%, transparent);
  background: var(--clay-soft);
  color: var(--clay);
}
.tool-state.is-error h3 {
  color: var(--clay);
}

.loader {
  display: inline-flex;
  gap: 0.3rem;
  margin-bottom: 0.9rem;
}
.loader i {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 3px;
  background: var(--ochre);
  animation: loader 0.9s ease-in-out infinite;
}
.loader i:nth-child(2) {
  animation-delay: 0.12s;
}
.loader i:nth-child(3) {
  animation-delay: 0.24s;
}
.loader i:nth-child(4) {
  animation-delay: 0.36s;
}
@keyframes loader {
  0%,
  70%,
  100% {
    opacity: 0.28;
    transform: translateY(0);
  }
  35% {
    opacity: 1;
    transform: translateY(-4px);
  }
}

.show-more {
  margin-top: 1.5rem;
  text-align: center;
}

/* ---------------------------------------------------------------- wordle */

.wordle-board {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.wordle-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.wordle-row > span {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
  min-width: 6.5rem;
}
.wordle-slots {
  display: flex;
  gap: 0.35rem;
}
.wordle-slot {
  width: 2.9rem;
  height: 2.9rem;
  text-align: center;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--line-2);
  border-radius: 6px;
  padding: 0;
}
.wordle-slot:focus {
  outline: none;
  border-color: var(--pine);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--pine) 13%, transparent);
}
.wordle-slot[data-state='green'] {
  background: var(--pine);
  border-color: var(--pine);
  color: #f6f0e4;
}
[data-theme='dark'] .wordle-slot[data-state='green'] {
  color: #14120c;
}
.wordle-free {
  flex: 1 1 12rem;
  min-width: 0;
}

/* ---------------------------------------------------------------- scramble */

.scramble-out {
  margin-top: 1.4rem;
  display: grid;
  gap: 0.6rem;
}
.scramble-line {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.75rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  flex-wrap: wrap;
}
.scramble-line .orig {
  font-size: 0.8rem;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  min-width: 7rem;
}
.scramble-line .scrambled {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ochre-hi);
}
