:root {
  --bg: #0c0c0e; --panel: #131317; --line: rgba(255,255,255,.09);
  --ink: #e8e6e3; --dim: #8d8a86; --hot: #e9a13b; --warm: #2e8f8c;
  --pad: 20px;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--bg); color: var(--ink);
  font: 14px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  display: grid; grid-template-columns: 300px 1fr;
  grid-template-areas: "side stage";
  height: 100dvh; overflow: hidden;
}

/* ── panel ─────────────────────────────────────────────────────────────────── */
#side {
  grid-area: side; background: var(--panel); border-right: 1px solid var(--line);
  padding: 0 var(--pad) var(--pad); overflow-y: auto;
}
.head {
  position: sticky; top: 0; z-index: 3; background: var(--panel);
  padding: var(--pad) 0 10px; display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
h1 {
  /* min-width: 0, or the gradient heading takes the whole row and squashes the
     buttons into a pile that overflows the panel */
  margin: 0; flex: 1 1 auto; min-width: 0; font-size: 22px; font-weight: 650;
  letter-spacing: .1em; text-transform: lowercase;
  background: linear-gradient(96deg, var(--hot), var(--warm));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* The four things you DO, as opposed to the options you set, which live in
   their own list at the bottom of the panel. */
.acts { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 14px; }
.acts button { flex: none; white-space: nowrap; }
button:disabled { opacity: .38; cursor: default; }
h2 {
  margin: 18px 0 8px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--dim);
}
button {
  font: inherit; color: var(--ink); background: #1c1c22;
  border: 1px solid var(--line); border-radius: 9px; padding: 6px 11px; cursor: pointer;
}
button:hover { background: #24242c; }
button.ghost { font-size: 12px; padding: 5px 10px; }

.row { display: flex; justify-content: space-between; padding: 3px 0; font-size: 13px; }
.row span { color: var(--dim); }
.row b { font-weight: 650; }
.row b.stars { color: var(--hot); font-weight: 400; letter-spacing: 1.5px; }

.verdict {
  margin: 12px 0 4px; padding: 10px 12px; border-radius: 10px; font-size: 12.5px;
  background: rgba(46,143,140,.13); border: 1px solid rgba(46,143,140,.3);
}

.clue {
  margin: 8px 0 4px; padding: 10px 12px; border-radius: 10px; font-size: 12.5px;
  background: rgba(233,161,59,.10); border: 1px solid rgba(233,161,59,.28);
}
.clabel {
  display: block; font-size: 9.5px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--hot); margin-bottom: 3px;
}
.clue.broken {
  background: rgba(255,59,107,.10); border-color: rgba(255,59,107,.42);
}
.clue.broken .clabel { color: #ff3b6b; }
.clue.broken .clabel::after { content: '— broken'; margin-left: 4px; letter-spacing: .04em; }

.snag {
  margin: 8px 0 4px; padding: 10px 12px; border-radius: 10px; font-size: 12.5px;
  background: rgba(255,59,107,.10); border: 1px solid rgba(255,59,107,.42);
}
.snag .clabel { color: #ff3b6b; }
.snag button { margin-top: 9px; }

.course { display: flex; align-items: center; gap: 7px; padding: 4px 0; font-size: 12px; }
.cdot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.cname { color: var(--dim); width: 46px; flex: none; }
.chips { display: flex; gap: 3px; flex: 1; }
.chip {
  width: 13px; height: 13px; border-radius: 4px; opacity: .18;
  border: 1px solid rgba(0,0,0,.5);
}
.chip.on { opacity: 1; }
.chip.held { outline: 2px solid var(--ink); outline-offset: 1px; }
.cnote { color: var(--dim); font-size: 11px; width: 40px; text-align: right; flex: none; }

/* ── stage ─────────────────────────────────────────────────────────────────── */
#stage { grid-area: stage; position: relative; overflow: hidden; }
/* isolate, or the leaded design's multiply blends with the page behind the
   board instead of only with the glass it is clipped to. */
#board {
  position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none;
  isolation: isolate;
}
#banner {
  position: absolute; left: 50%; top: 14px; transform: translateX(-50%);
  background: #1c1c22ee; border: 1px solid var(--line); border-radius: 10px;
  padding: 8px 14px; font-size: 12.5px; max-width: 70%; text-align: center;
  opacity: 0; transition: opacity .18s; pointer-events: none;
}
#banner.on { opacity: 1; }

/* ── the glass round the window ─────────────────────────────────────────────── */
/* The unused tiles are drawn in the board's own SVG, laid out in a ring around
   it, so it reads like glass set out around a bench rather than a drawer. */
#whose { margin-top: 16px; }
#whose b { display: block; font-size: 15px; }
#whose span { display: block; font-size: 11.5px; color: var(--dim); line-height: 1.4; }

/* The teaching box. Deliberately unlike the other two — .verdict is teal and
   .clue is amber, and a third box in either of those colours would read as more
   of the same rather than as someone talking to you. */
/* ⚠️ Fixed, not in the flow of the panel. It has to sit OVER the panel's right
   edge, and #side scrolls with overflow-y — which clips horizontally too — so
   anything in flow would be cut off at the edge instead of overhanging it, and
   would scroll out from under you halfway through a lesson. A fixed element is
   not clipped by an ancestor's overflow unless that ancestor has a transform
   or a filter, and #side has neither. */
.teach {
  position: fixed; z-index: 20; left: 14px; top: 166px; width: 372px;
  /* ⚠️ No overflow scrolling here. overflow-y clips horizontally too, and the
     close button hangs off the corner on purpose. The longest card is four
     short paragraphs, which fits. */
  margin: 0; padding: 15px 16px; border-radius: 12px; font-size: 12.5px;
  background: #16161d; border: 1px solid var(--hot);
  animation: teachglow 2.8s ease-in-out infinite;
}
@keyframes teachglow {
  0%, 100% { box-shadow: 0 0 0 1px rgba(233,161,59,.20),
                         0 0 18px rgba(233,161,59,.18), 0 14px 34px rgba(0,0,0,.62); }
  50%      { box-shadow: 0 0 0 1px rgba(233,161,59,.44),
                         0 0 34px rgba(233,161,59,.42), 0 14px 34px rgba(0,0,0,.62); }
}
@media (prefers-reduced-motion: reduce) {
  .teach { animation: none; box-shadow: 0 0 0 1px rgba(233,161,59,.4),
                                        0 0 22px rgba(233,161,59,.3); }
}
/* on the corner, half off the card, so it reads as "shut this" rather than as
   one more thing to press in the row of controls */
.tshut {
  position: absolute; top: -13px; right: -13px; width: 27px; height: 27px;
  padding: 0; border-radius: 50%; font-size: 16px; line-height: 1;
  background: #23232c; border: 1px solid var(--hot); color: var(--ink);
  box-shadow: 0 2px 10px rgba(0,0,0,.6);
}
.tshut:hover { background: var(--hot); color: #17120a; }

.teach p { margin: 0 0 9px; }
.teach p:last-of-type { margin-bottom: 10px; }
.tlabel {
  display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--hot); margin-bottom: 6px;
}
.trow { display: flex; align-items: center; gap: 10px; }
.trow .tcount { color: var(--dim); font-size: 11px; margin-left: auto; }
.twait { color: var(--warm); font-size: 11.5px; font-style: italic; }


/* ── options ───────────────────────────────────────────────────────────────
   Down the side rather than a row of cycling buttons. A button labelled
   "Grain off" had to be read twice — once for what it does and once for which
   way it is pointing — and never showed what the other choices were. */
#opts { margin-top: 26px; }
#opts h2 { margin: 20px 0 2px; }
#opts h2:first-child { margin-top: 0; }
.ohead { color: var(--dim); font-size: 11.5px; margin: 0 0 6px; }
.opt { padding: 11px 0; border-bottom: 1px solid rgba(255,255,255,.055); }
.opt:last-child { border-bottom: 0; }
.orow { display: flex; align-items: center; gap: 10px; }
.oname { font-size: 13px; font-weight: 650; flex: 1; }
.onote { color: var(--dim); font-size: 11.5px; line-height: 1.45; margin-top: 5px; }

.seg { display: flex; gap: 5px; margin-top: 8px; }
.seg button { flex: 1; font-size: 12px; padding: 6px 8px; }
.seg button.on, .ladder button.on {
  background: var(--hot); border-color: var(--hot); color: #17120a; font-weight: 700;
}

/* The ladder: four rungs, two by two, and the chosen rung's note under them.
   The dials that spell a rung fold away below. */
.ladder { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; margin-top: 4px; }
.ladder button { font-size: 12.5px; padding: 7px 8px; }
.lnote { margin: 7px 0 2px; min-height: 2.9em; }
.fold {
  display: block; width: 100%; text-align: left; margin: 8px 0 4px; padding: 5px 8px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--dim);
  background: transparent; border-color: transparent;
}
.fold::before { content: '▸'; display: inline-block; width: 14px; }
.fold.open::before { content: '▾'; }
.fold:hover { background: #1c1c22; }

/* A switch, not a button that says which way it is off. */
.sw {
  flex: none; width: 40px; height: 22px; padding: 0; border-radius: 999px;
  position: relative; background: #22222a; border: 1px solid var(--line);
}
.sw .knob {
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: var(--dim);
  transition: left .15s ease, background .15s ease;
}
.sw.on { background: rgba(46,143,140,.45); border-color: var(--warm); }
.sw.on .knob { left: 20px; background: #dcf3f1; }

/* Each palette shown as a tile cut from it, because the name of a colour
   scheme tells you nothing about what it looks like. */
.glasses { display: flex; gap: 7px; margin-top: 9px; }
.glasses button { padding: 3px; line-height: 0; border-radius: 9px; }
.glasses button.on { border-color: var(--hot); box-shadow: 0 0 0 1px var(--hot); }

/* ⚠️ Named .carry, not .ghost. The header buttons carry class="ghost" for the
   quiet-button style, so an unscoped .ghost rule made them position:fixed,
   translated onto each other and pointer-events:none — two of the three were
   invisible and none of them could be clicked. */
.carry {
  position: fixed; z-index: 9; transform: translate(-50%, -50%);
  pointer-events: none; filter: drop-shadow(0 6px 14px rgba(0,0,0,.6));
}

@media (max-width: 760px) {
  body { grid-template-columns: 1fr; grid-template-rows: auto 1fr;
         grid-template-areas: "side" "stage"; }
  /* The board gets the larger share. With the ladder up front and the rows
     drawn on the glass, the panel has less to say than it did, and a Rose's
     ring of eighteen wants the height. */
  #side { border-right: 0; border-bottom: 1px solid var(--line); max-height: 33vh; }
  .head { padding-top: 12px; }
  .verdict, .clue, .snag { font-size: 12px; padding: 8px 10px; }
  /* nothing to overhang when the panel is the full width — sit it over the
     board instead, where there is room */
  .teach {
    left: 12px; right: 12px; width: auto; top: auto; bottom: 12px;
    max-height: 54dvh; overflow-y: auto;
  }
  /* clipped by that scroll, so it comes inside on a narrow screen */
  .tshut { top: 8px; right: 8px; }
}
