/* A grid that converges: ink for text, and whatever colours the user paints in. */
:root {
  --bg: #f7f4ee;
  --surface: #ffffff;
  --border: #ddd8cd;
  --text: #1c1b19;
  --muted: #6d6a62;
  --accent: #6a3fb0;
  --accent-soft: #ece3f9;
  --ok: #1f7a58;
  --danger: #b5462f;
  --radius: 10px;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14171a;
    --surface: #1f242a;
    --border: #333a42;
    --text: #edeff1;
    --muted: #9aa3ac;
    --accent: #b892ee;
    --accent-soft: #2a2340;
    --ok: #55c99b;
    --danger: #ff8566;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 2rem 1rem 10rem;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.55 ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif;
}

header, main, footer { max-width: 60rem; margin: 0 auto; }

h1 { font-size: 1.7rem; margin: 0 0 .2rem; }
.tagline { margin: 0 0 .9rem; font-size: .95rem; color: var(--accent); letter-spacing: .01em; }
h2 { font-size: 1.05rem; margin: 0 0 1rem; text-transform: uppercase; letter-spacing: .07em; color: var(--accent); }
.resultHead {
  font-size: .95rem;
  margin: 1.5rem 0 .6rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--accent);
  border-top: 1px solid var(--border);
  padding-top: 1.1rem;
}

.lede { color: var(--muted); margin: 0 0 1.1rem; }
header { border-bottom: 2px solid var(--accent-soft); margin-bottom: 1.5rem; padding-bottom: .3rem; }

.note {
  display: flex;
  gap: .7rem;
  align-items: flex-start;
  margin: 0 0 1.5rem;
  padding: .75rem .95rem;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.note::before {
  content: "i";
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: .12rem;
  display: grid;
  place-items: center;
  border-radius: 99px;
  background: var(--accent);
  color: #fff;
  font: italic 700 .78rem/1 Georgia, "Times New Roman", serif;
}
.note p { margin: 0; font-size: .9rem; color: var(--text); }

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}

.hint { display: block; font-weight: 400; font-size: .8rem; color: var(--muted); margin: .15rem 0 .6rem; }
.hint.inline { display: inline; margin: 0; }

.stagehead { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.stagehead label {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .85rem;
  font-weight: 600;
}
.stagehead label input[type="number"] {
  width: 3.6rem;
  font: inherit;
  padding: .3rem .4rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg);
  color: var(--text);
}
.spacer { flex: 1 1 auto; }

button {
  font: inherit;
  font-size: .9rem;
  padding: .5rem .9rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
}
button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(106, 63, 176, .35);
}
button.primary:hover { filter: brightness(1.08); }
button.ghost:hover { border-color: var(--accent); color: var(--accent); }
button.icon { padding: .3rem .5rem; font-size: .85rem; line-height: 1; }

/* ---- palette ---- */

.palette { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: .8rem; }
.swatch {
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .5rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}
.swatch input[type="color"] {
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  border: none;
  border-radius: 5px;
  background: none;
  cursor: pointer;
}
.swatch input[type="text"] {
  width: 6rem;
  font: inherit;
  font-size: .85rem;
  padding: .25rem .4rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--surface);
  color: var(--text);
}
.swatch button { padding: .2rem .4rem; font-size: .8rem; }
.swatch label.inline {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: .75rem;
  color: var(--muted);
  white-space: nowrap;
}
.swatch input.min {
  width: 3rem;
  font: inherit;
  font-size: .8rem;
  padding: .2rem .3rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--surface);
  color: var(--text);
}
.swatch .count { font-size: .72rem; color: var(--muted); }

.brush .swatch {
  cursor: pointer;
  user-select: none;
  gap: .5rem;
}
.brush .swatch .dot {
  width: 1.3rem;
  height: 1.3rem;
  border-radius: 5px;
  border: 1px solid rgba(0, 0, 0, .25);
}
.brush .swatch.active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.brush .swatch span.label { font-size: .85rem; }

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

.gridSize {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: .9rem;
}
.gridSize label {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .85rem;
  font-weight: 600;
}
.gridSize input[type="number"] {
  width: 3.6rem;
  font: inherit;
  padding: .3rem .4rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg);
  color: var(--text);
}
.gridSize .hint { margin: 0; flex: 1 1 14rem; }

.gridBoard {
  position: relative;
  display: inline-grid;
  gap: 6px;
  margin-bottom: .5rem;
}
.gridHeader {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .78rem;
  font-weight: 700;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.arrows-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
}

/* While a search runs, nothing else on the page should react -- editing a
   colour or an instruction mid-search would race the search's own writes to
   the grid it's searching over. */
main.searching > * { pointer-events: none; }
main.searching .searchStatus { pointer-events: auto; }

/* Fixed to the bottom of the viewport rather than the page, so the one
   action that ties everything else together is always in reach, however
   far you've scrolled into the grid or the instructions. */
.solvePanel {
  position: fixed;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: min(60rem, calc(100% - 2rem));
  margin: 0 0 .6rem;
  padding: .6rem .9rem;
  border-color: var(--accent);
  box-shadow: 0 -6px 20px rgba(0, 0, 0, .35);
  z-index: 30;
  max-height: 30vh;
  overflow-y: auto;
  transition: opacity .15s ease;
}
.solvePanel.offscreen { display: none; }
.solvePanel .stagehead { gap: .6rem; }
.solvePanel h2 { font-size: 1rem; margin: 0; }
.solveHint { margin: 0; font-size: .75rem; }
#solveNote:empty { display: none; margin: 0; }
#solveNote { margin: .3rem 0 0; font-size: .78rem; }
.dirtyNotice {
  margin: .4rem 0 0;
  padding: .3rem .6rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 6px;
}
.searchStatus {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .4rem .7rem;
  margin: .4rem 0 0;
  background: var(--accent-soft);
  border-radius: var(--radius);
}
/* An element's own `display` always beats the browser's default [hidden]
   rule, so the hidden attribute needs restating here explicitly. */
.searchStatus[hidden] { display: none; }
.searchStatus #searchProgress {
  flex: 1 1 auto;
  margin: 0;
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.spinner {
  flex: none;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.lockToggle {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
}
.lockToggle::before {
  content: "\1F513";   /* open padlock */
  font-size: .85rem;
}
.lockToggle.locked::before { content: "\1F512"; }   /* closed padlock */
.lockToggle.locked {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
.cell {
  position: relative;
  aspect-ratio: 1;
  border-radius: 7px;
  border: 2px solid rgba(0, 0, 0, .12);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  overflow: hidden;
}
.cell input {
  width: 92%;
  background: transparent;
  color: #1c1b19;
  border: none;
  border-radius: 4px;
  text-align: center;
  font-size: 2.2rem;
  line-height: 1;
  padding: .1rem 0;
  cursor: text;
}
/* Only worth a visible field once it can actually be typed into -- the rest
   of the time it'd just be a pale box sitting over the emoji for no reason. */
.gridBoard.editing .cell input { background: rgba(255, 255, 255, .82); }
.cell.final { outline: 3px solid var(--accent); outline-offset: 1px; }
.cell.traced { outline: 3px dashed var(--accent); outline-offset: 1px; }
.cell.target { outline: 3px solid var(--ok); outline-offset: 1px; }
.cell.frontier { outline: 3px dashed var(--accent); outline-offset: 1px; }
.cell.frontierNext { outline: 3px solid var(--accent); outline-offset: 1px; }

.stepThroughBar {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  margin-top: .8rem;
  padding: .7rem .9rem;
  background: var(--accent-soft);
  border-radius: var(--radius);
}
.stepThroughBar[hidden] { display: none; }
.stepThroughBar #stepInfo {
  flex: 1 1 16rem;
  margin: 0;
  font-size: .85rem;
  color: var(--text);
}
.stepThroughBar #stepInfo strong { color: var(--accent); }
.cell .pin {
  position: absolute;
  bottom: 2px;
  right: 3px;
  font-size: .8rem;
}
button.ghost.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.gridBoard.picking .cell { cursor: crosshair; }
.gridBoard.editing .cell { cursor: default; }
.gridBoard.editing .cell input { cursor: text; }
.cell .badge {
  position: absolute;
  top: 2px;
  right: 3px;
  font-size: .62rem;
  font-weight: 700;
  color: #fff;
  background: rgba(0, 0, 0, .55);
  border-radius: 99px;
  padding: 0 .35rem;
}
.cell .err {
  position: absolute;
  bottom: 2px;
  left: 3px;
  font-size: .7rem;
}

/* ---- steps ---- */

.step {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
  padding: .7rem .8rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  margin-bottom: .6rem;
}
.step select, .step .num {
  font: inherit;
  font-size: .85rem;
  padding: .3rem .4rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--surface);
  color: var(--text);
}
.step label.inline { display: inline-flex; align-items: center; gap: .3rem; font-size: .8rem; }
.step .sentence { flex-basis: 100%; font-size: .85rem; color: var(--muted); font-style: italic; }
.step .move { display: flex; gap: .2rem; margin-left: auto; }

/* ---- verify ---- */

.funnel {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
  font-size: .95rem;
  margin: .8rem 0;
}
.funnel .n {
  padding: .25rem .6rem;
  border-radius: 99px;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 700;
}
.funnel .arrow { color: var(--muted); }

.verdict {
  padding: .7rem .9rem;
  border-radius: var(--radius);
  font-weight: 600;
  margin: .3rem 0 .9rem;
}
.verdict.ok { background: rgba(31, 122, 88, .12); color: var(--ok); }
.verdict.bad { background: rgba(181, 70, 47, .12); color: var(--danger); }

.issues ul { margin: 0 0 .8rem; padding-left: 1.2rem; font-size: .88rem; }
.issues li { margin-bottom: .3rem; }

.trace {
  margin-top: .8rem;
  padding: .7rem .9rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  font-size: .88rem;
}
.trace ol { margin: .3rem 0 0; padding-left: 1.3rem; }
.trace li { margin-bottom: .2rem; }

footer p { color: var(--muted); font-size: .85rem; }

/* The site masthead, styled exactly as on the landing page. */
.sitebar {
  display: block;
  max-width: 60rem;
  margin: 0 auto 1.4rem;
  text-decoration: none;
  color: var(--text);
}
.sitebar-name { display: block; font-size: 1.25rem; font-weight: 700; margin: 0 0 .1rem; }
.sitebar-sub {
  display: block;
  font: italic 13px Georgia, "Times New Roman", serif;
  color: var(--muted);
  letter-spacing: 0;
}
.sitebar:hover .sitebar-name { color: var(--accent); }
.sitebar-horizon { display: block; width: 100%; height: auto; margin: .5rem 0 0; }
@media (prefers-color-scheme: dark) { .sitebar-horizon { filter: invert(1); } }
