/* ==========================================================================
   Components
   ========================================================================== */

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 36px;
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:hover { background: var(--surface-hi); border-color: var(--accent); }
.btn:active { transform: translateY(1px); }

.btn--primary {
  color: var(--accent-contrast);
  background: var(--accent);
  border-color: var(--accent);
  font-weight: var(--fw-semi);
}
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn--ghost { background: transparent; border-color: transparent; color: var(--text-dim); }
.btn--ghost:hover { background: var(--surface-2); color: var(--text); border-color: transparent; }

.btn--ok      { color: var(--ok); border-color: color-mix(in oklab, var(--ok) 40%, var(--border)); background: var(--ok-soft); }
.btn--danger  { color: var(--danger); border-color: color-mix(in oklab, var(--danger) 40%, var(--border)); background: var(--danger-soft); }
.btn--sm      { min-height: 28px; padding: var(--sp-1) var(--sp-3); font-size: var(--fs-xs); }
.btn--lg      { min-height: 46px; padding: var(--sp-3) var(--sp-6); font-size: var(--fs-md); }
.btn--icon    { width: 36px; padding: 0; }
.btn--block   { width: 100%; }
.btn[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

/* ---------- Chips, badges, pills ---------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 2px var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
}
.chip--accent { color: var(--accent); background: var(--accent-soft); border-color: color-mix(in oklab, var(--accent) 35%, transparent); }
.chip--ok     { color: var(--ok);     background: var(--ok-soft);     border-color: color-mix(in oklab, var(--ok) 35%, transparent); }
.chip--warn   { color: var(--warn);   background: var(--warn-soft);   border-color: color-mix(in oklab, var(--warn) 35%, transparent); }
.chip--danger { color: var(--danger); background: var(--danger-soft); border-color: color-mix(in oklab, var(--danger) 35%, transparent); }

.level {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--fs-xs);
  color: var(--text-faint);
}
.level::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: var(--r-full);
  background: currentColor;
}
.level[data-level="beginner"]     { color: var(--ok); }
.level[data-level="intermediate"] { color: var(--info); }
.level[data-level="advanced"]     { color: var(--warn); }
.level[data-level="expert"]       { color: var(--danger); }

/* ---------- Cards ---------- */
.card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
a.card:hover, button.card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--sh-2);
}
.card__title { font-size: var(--fs-lg); font-weight: var(--fw-semi); }
.card__meta { display: flex; flex-wrap: wrap; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--text-faint); }
.card__body { font-size: var(--fs-sm); color: var(--text-dim); }
.card--panel { background: var(--bg-elev); }

.panel {
  padding: var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}
.panel__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.panel__title { font-size: var(--fs-lg); font-weight: var(--fw-semi); }

/* ---------- Mental model card ---------- */
.mental-model {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  background: linear-gradient(135deg, var(--accent-soft), transparent 70%);
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
  border-left-width: 3px;
  border-radius: var(--r-md);
}
.mental-model__label {
  flex: none;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  padding-top: 3px;
}
.mental-model__text { font-size: var(--fs-lg); font-weight: var(--fw-medium); }

/* ---------- Callouts ---------- */
.callout {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-faint);
  border-radius: var(--r-sm);
  font-size: var(--fs-md);
}
.callout__icon { flex: none; font-size: 1.05em; line-height: 1.5; }
.callout__body > * + * { margin-top: var(--sp-2); }
.callout__title { font-weight: var(--fw-semi); }
.callout--tip       { border-left-color: var(--ok);     background: color-mix(in oklab, var(--ok-soft) 60%, var(--surface)); }
.callout--info      { border-left-color: var(--info);   background: color-mix(in oklab, var(--info-soft) 60%, var(--surface)); }
.callout--warn      { border-left-color: var(--warn);   background: color-mix(in oklab, var(--warn-soft) 60%, var(--surface)); }
.callout--danger    { border-left-color: var(--danger); background: color-mix(in oklab, var(--danger-soft) 60%, var(--surface)); }
.callout--psych     { border-left-color: #b58cff; background: color-mix(in oklab, #b58cff1f 60%, var(--surface)); }
.callout--interview { border-left-color: var(--accent); background: color-mix(in oklab, var(--accent-soft) 60%, var(--surface)); }
.callout--history   { border-left-color: var(--text-faint); }

/* ---------- Code blocks ---------- */
.codeblock {
  border: 1px solid var(--code-border);
  border-radius: var(--r-md);
  background: var(--code-bg);
  overflow: hidden;
}
.codeblock__bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2) var(--sp-1) var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  background: color-mix(in oklab, var(--code-bg) 60%, var(--surface));
  border-bottom: 1px solid var(--code-border);
}
.codeblock__lang { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.06em; }
.codeblock pre {
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  overflow-x: auto;
  font-size: var(--editor-fs);
  line-height: var(--editor-lh);
  scrollbar-width: thin;
}
.codeblock__caption {
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  border-top: 1px solid var(--code-border);
  background: color-mix(in oklab, var(--code-bg) 70%, var(--surface));
}
.codeblock__out {
  border-top: 1px solid var(--code-border);
  max-height: 240px;
  overflow: auto;
}

/* Syntax tokens */
.tok-key { color: var(--tok-key); }
.tok-str { color: var(--tok-str); }
.tok-num { color: var(--tok-num); }
.tok-fn  { color: var(--tok-fn); }
.tok-cls { color: var(--tok-cls); }
.tok-com { color: var(--tok-com); font-style: italic; }
.tok-op  { color: var(--tok-op); }
.tok-pun { color: var(--tok-punct); }
.tok-rex { color: var(--tok-regex); }
.tok-prp { color: var(--tok-prop); }

/* ---------- Editor ---------- */
.editor {
  position: relative;
  background: var(--code-bg);
  border: 1px solid var(--code-border);
  border-radius: var(--r-md);
  overflow: hidden;
}
.editor--focus { border-color: var(--accent); box-shadow: var(--ring); }
.editor__scroll {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  max-height: var(--editor-max, 460px);
  min-height: 120px;
  overflow: auto;
  scrollbar-width: thin;
}
.editor__gutter {
  position: sticky;
  left: 0;
  z-index: 2;
  padding: var(--sp-3) var(--sp-2) var(--sp-3) var(--sp-3);
  font: var(--editor-fs)/var(--editor-lh) var(--font-mono);
  color: var(--code-gutter);
  text-align: right;
  background: var(--code-bg);
  border-right: 1px solid var(--code-border);
  user-select: none;
  white-space: pre;
}
.editor__area { position: relative; }
.editor__hl, .editor__input {
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  font: var(--editor-fs)/var(--editor-lh) var(--font-mono);
  white-space: pre;
  overflow-wrap: normal;
  tab-size: 2;
  border: 0;
}
.editor__hl {
  pointer-events: none;
  min-height: 100%;
  color: var(--tok-punct);
}
.editor__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  resize: none;
  color: transparent;
  caret-color: var(--text);
  background: transparent;
  outline: none;
  overflow: hidden;
}
.editor__input::selection { background: var(--selection); }
.editor__bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  background: color-mix(in oklab, var(--code-bg) 55%, var(--surface));
  border-bottom: 1px solid var(--code-border);
}

/* ---------- Console panel ---------- */
.console {
  display: flex;
  flex-direction: column;
  min-height: 120px;
  background: var(--bg-sunken);
  border: 1px solid var(--code-border);
  border-radius: var(--r-md);
  overflow: hidden;
}
.console__bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  background: color-mix(in oklab, var(--bg-sunken) 55%, var(--surface));
  border-bottom: 1px solid var(--code-border);
}
.console__out {
  flex: 1;
  max-height: var(--console-max, 460px);
  overflow: auto;
  padding: var(--sp-2) 0;
  font: var(--editor-fs)/1.6 var(--font-mono);
  scrollbar-width: thin;
}
.console__empty {
  padding: var(--sp-4);
  color: var(--text-faint);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
}
.logrow {
  display: flex;
  gap: var(--sp-2);
  padding: 2px var(--sp-3);
  border-left: 2px solid transparent;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  animation: log-in var(--dur-fast) var(--ease);
}
@keyframes log-in { from { opacity: 0; transform: translateX(-4px); } to { opacity: 1; transform: none; } }
.logrow + .logrow { border-top: 1px solid color-mix(in oklab, var(--border) 45%, transparent); }
.logrow__gut { flex: none; color: var(--text-faint); user-select: none; }
.logrow--warn  { color: var(--warn);   background: var(--warn-soft);   border-left-color: var(--warn); }
.logrow--error { color: var(--danger); background: var(--danger-soft); border-left-color: var(--danger); }
.logrow--info  { color: var(--info); }
.logrow--sys   { color: var(--text-faint); font-style: italic; }
.logrow--ok    { color: var(--ok); }

/* Value inspector */
.iv-str  { color: var(--tok-str); }
.iv-num  { color: var(--tok-num); }
.iv-bool { color: var(--tok-num); }
.iv-null { color: var(--text-faint); }
.iv-key  { color: var(--tok-prop); }
.iv-fn   { color: var(--tok-fn); font-style: italic; }
.iv-cls  { color: var(--tok-cls); }
.iv-pun  { color: var(--tok-punct); }
.iv-more { color: var(--text-faint); font-style: italic; }
details.iv { display: inline-block; vertical-align: top; }
details.iv > summary { cursor: pointer; list-style: none; }
details.iv > summary::-webkit-details-marker { display: none; }
details.iv > summary::before { content: "▸ "; color: var(--text-faint); }
details.iv[open] > summary::before { content: "▾ "; }
details.iv > div { padding-left: 1.5ch; }

/* ---------- Playground ---------- */
.playground {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.playground__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
}
.playground__title { font-size: var(--fs-md); font-weight: var(--fw-semi); }
.playground__body { padding: var(--sp-3); }
.playground__note {
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.playground__note strong { color: var(--text); }

/* ---------- Tabs ---------- */
.tabs {
  display: flex;
  gap: var(--sp-1);
  padding: var(--sp-1);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-dim);
  border-radius: var(--r-xs);
  white-space: nowrap;
}
.tab:hover { color: var(--text); background: var(--surface-2); }
.tab[aria-selected="true"] { color: var(--accent-contrast); background: var(--accent); }

/* ---------- Sidebar tree ---------- */
.tree { display: flex; flex-direction: column; gap: 2px; }
.tree__mod > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-dim);
  border-radius: var(--r-sm);
  cursor: pointer;
  list-style: none;
}
.tree__mod > summary::-webkit-details-marker { display: none; }
.tree__mod > summary:hover { background: var(--surface-2); color: var(--text); }
.tree__mod[open] > summary { color: var(--text); }
.tree__caret { flex: none; transition: transform var(--dur-fast) var(--ease); color: var(--text-faint); }
.tree__mod[open] .tree__caret { transform: rotate(90deg); }
.tree__num {
  flex: none;
  font: var(--fw-semi) var(--fs-xs)/1 var(--font-mono);
  color: var(--text-faint);
  min-width: 2ch;
}
.tree__list { display: flex; flex-direction: column; gap: 1px; padding: var(--sp-1) 0 var(--sp-2) var(--sp-4); }
.tree__link {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  text-decoration: none;
  border-radius: var(--r-xs);
  border-left: 2px solid transparent;
}
.tree__link:hover { background: var(--surface-2); color: var(--text); }
.tree__link[aria-current="page"] {
  color: var(--accent);
  background: var(--accent-soft);
  border-left-color: var(--accent);
  font-weight: var(--fw-medium);
}
.tree__state { flex: none; width: 14px; text-align: center; font-size: 10px; color: var(--text-faint); }
.tree__link[data-status="complete"] .tree__state { color: var(--ok); }
.tree__link[data-status="visited"] .tree__state { color: var(--warn); }

/* ---------- Mastery ring ---------- */
.ring { display: block; width: 34px; height: 34px; flex: none; }
.ring__track { stroke: var(--border); }
.ring__read { stroke: var(--accent); }
.ring__done { stroke: var(--ok); }
.ring circle { fill: none; stroke-width: 3.5; stroke-linecap: round; transform: rotate(-90deg); transform-origin: center; }
.ring__label { font: var(--fw-semi) 10px var(--font-mono); fill: var(--text-dim); }

.progressbar {
  height: 6px;
  background: var(--surface-2);
  border-radius: var(--r-full);
  overflow: hidden;
}
.progressbar__fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--ok));
  border-radius: var(--r-full);
  transition: width var(--dur-slow) var(--ease);
}

/* ---------- Exercise ---------- */
.exercise {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.exercise[data-state="passed"] { border-color: color-mix(in oklab, var(--ok) 55%, var(--border)); }
.exercise[data-state="failed"] { border-color: color-mix(in oklab, var(--danger) 45%, var(--border)); }
.exercise__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
}
.exercise__brief {
  padding: var(--sp-4);
  font-size: var(--fs-md);
  border-bottom: 1px solid var(--border);
}
.exercise__brief > * + * { margin-top: var(--sp-3); }
.exercise__body { padding: var(--sp-3); }
.exercise__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.difficulty { display: inline-flex; gap: 2px; }
.difficulty i {
  width: 6px; height: 6px;
  border-radius: var(--r-full);
  background: var(--border-strong);
}
.difficulty i.on { background: var(--warn); }

.results { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); }
.result {
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-sm);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--r-sm);
}
.result--ok   { border-left-color: var(--ok);     background: color-mix(in oklab, var(--ok-soft) 50%, var(--surface)); }
.result--fail { border-left-color: var(--danger); background: color-mix(in oklab, var(--danger-soft) 50%, var(--surface)); animation: shake var(--dur) var(--ease); }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px); }
  75% { transform: translateX(3px); }
}
.result__icon { flex: none; }
.result__name { font-weight: var(--fw-medium); }
.result__msg { color: var(--text-dim); font-family: var(--font-mono); font-size: var(--fs-xs); }
.diff { display: grid; gap: var(--sp-1); margin-top: var(--sp-2); font-family: var(--font-mono); font-size: var(--fs-xs); }
.diff__row { display: flex; gap: var(--sp-2); }
.diff__tag { flex: none; width: 8ch; color: var(--text-faint); }
.diff__val--exp { color: var(--ok); }
.diff__val--act { color: var(--danger); }

.hint {
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  background: var(--warn-soft);
  border-left: 3px solid var(--warn);
  border-radius: var(--r-sm);
  animation: view-in var(--dur) var(--ease);
}
.hint__label { font-weight: var(--fw-semi); color: var(--warn); }

/* ---------- Quiz ---------- */
.quiz { display: flex; flex-direction: column; gap: var(--sp-4); }
.quizq {
  padding: var(--sp-4);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.quizq__q { font-size: var(--fs-lg); font-weight: var(--fw-medium); margin-bottom: var(--sp-3); }
.quizq__opts { display: flex; flex-direction: column; gap: var(--sp-2); }
.opt {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-3);
  text-align: left;
  font-size: var(--fs-md);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.opt:hover:not(:disabled) { border-color: var(--accent); background: var(--surface-2); }
.opt__key {
  flex: none;
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  font: var(--fw-semi) var(--fs-xs)/1 var(--font-mono);
  color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-xs);
}
.opt[data-state="correct"]   { border-color: var(--ok);     background: var(--ok-soft); }
.opt[data-state="correct"] .opt__key { color: var(--ok); border-color: var(--ok); }
.opt[data-state="wrong"]     { border-color: var(--danger); background: var(--danger-soft); }
.opt[data-state="wrong"] .opt__key { color: var(--danger); border-color: var(--danger); }
.quizq__explain {
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  font-size: var(--fs-sm);
  background: var(--surface);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-sm);
  animation: view-in var(--dur) var(--ease);
}

/* ---------- Table ---------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--r-md); scrollbar-width: thin; }
.dtable { font-size: var(--fs-sm); }
.dtable th, .dtable td { padding: var(--sp-2) var(--sp-3); text-align: left; border-bottom: 1px solid var(--border); }
.dtable th { background: var(--surface-2); font-weight: var(--fw-semi); white-space: nowrap; }
.dtable tr:last-child td { border-bottom: 0; }
.dtable tbody tr:hover { background: var(--surface); }
.dtable code { font-size: 0.95em; }

/* ---------- Compare ---------- */
.compare { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.compare__col { display: flex; flex-direction: column; gap: var(--sp-2); }
.compare__title { font-size: var(--fs-sm); font-weight: var(--fw-semi); }

/* ---------- Steps ---------- */
.steps { counter-reset: step; display: flex; flex-direction: column; gap: var(--sp-4); }
.step { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: var(--sp-3); }
.step::before {
  counter-increment: step;
  content: counter(step);
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  font: var(--fw-bold) var(--fs-sm)/1 var(--font-mono);
  color: var(--accent-contrast);
  background: var(--accent);
  border-radius: var(--r-full);
}
.step__body > * + * { margin-top: var(--sp-2); }
.step__title { font-weight: var(--fw-semi); font-size: var(--fs-lg); }

/* ---------- Diagram ---------- */
.diagram {
  padding: var(--sp-4);
  overflow-x: auto;
  font: var(--fs-xs)/1.45 var(--font-mono);
  color: var(--text-dim);
  background: var(--code-bg);
  border: 1px solid var(--code-border);
  border-radius: var(--r-md);
  white-space: pre;
  scrollbar-width: thin;
}

/* ---------- Command palette ---------- */
.palette-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-palette);
  display: grid;
  align-items: start;
  justify-items: center;
  padding: min(12vh, 96px) var(--sp-4) var(--sp-4);
  background: rgb(0 0 0 / 0.55);
  backdrop-filter: blur(3px);
  animation: fade-in var(--dur-fast) var(--ease);
}
.palette {
  width: min(680px, 100%);
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-4);
  overflow: hidden;
  animation: pal-in var(--dur) var(--ease-spring);
}
@keyframes pal-in { from { opacity: 0; transform: translateY(-12px) scale(0.98); } to { opacity: 1; transform: none; } }
.palette__input {
  padding: var(--sp-4) var(--sp-5);
  font-size: var(--fs-xl);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
  outline: none;
}
.palette__input::placeholder { color: var(--text-faint); }
.palette__list { overflow-y: auto; padding: var(--sp-2); scrollbar-width: thin; }
.palette__group {
  padding: var(--sp-2) var(--sp-3) var(--sp-1);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.palette__item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  text-align: left;
  border-radius: var(--r-sm);
  color: var(--text-dim);
}
.palette__item[aria-selected="true"] { background: var(--accent-soft); color: var(--text); }
.palette__item mark { background: transparent; color: var(--accent); font-weight: var(--fw-semi); }
.palette__kind { flex: none; font-size: var(--fs-xs); color: var(--text-faint); }
.palette__empty { padding: var(--sp-6); text-align: center; color: var(--text-faint); }
.palette__foot {
  display: flex;
  gap: var(--sp-4);
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  border-top: 1px solid var(--border);
}

/* ---------- Toasts ---------- */
.toasts {
  position: fixed;
  right: var(--sp-4);
  bottom: var(--sp-4);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  max-width: min(380px, calc(100vw - var(--sp-6)));
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  background: var(--surface-hi);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-sm);
  box-shadow: var(--sh-3);
  pointer-events: auto;
  animation: toast-in var(--dur) var(--ease-spring);
}
@keyframes toast-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.toast--ok     { border-left-color: var(--ok); }
.toast--warn   { border-left-color: var(--warn); }
.toast--danger { border-left-color: var(--danger); }
.toast--leaving { opacity: 0; transform: translateX(20px); transition: all var(--dur) var(--ease); }

/* ---------- Modal ---------- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: var(--sp-4);
  background: rgb(0 0 0 / 0.6);
  backdrop-filter: blur(3px);
  animation: fade-in var(--dur-fast) var(--ease);
}
.modal {
  width: min(560px, 100%);
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-4);
  animation: pal-in var(--dur) var(--ease-spring);
}
/* Two-column dialogs (the share sheet) need room; it collapses to one column under 720px. */
.modal--wide { width: min(940px, 100%); max-height: min(92vh, 900px); }
.modal__head { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--border); }
.modal__title { font-size: var(--fs-lg); font-weight: var(--fw-semi); }
.modal__body { padding: var(--sp-5); overflow-y: auto; }
.modal__body > * + * { margin-top: var(--sp-4); }
.modal__foot { display: flex; justify-content: flex-end; gap: var(--sp-2); padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--border); }

/* ---------- Forms ---------- */
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field__label { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-dim); }
.input, .select, .textarea {
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-md);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  outline: none;
}
.input:focus-visible, .select:focus-visible, .textarea:focus-visible { border-color: var(--accent); box-shadow: var(--ring); }
.textarea { resize: vertical; min-height: 96px; font-family: var(--font-mono); font-size: var(--fs-sm); }
.switch { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); padding: var(--sp-2) 0; }
.switch__desc { font-size: var(--fs-xs); color: var(--text-faint); }
input[type="range"] { accent-color: var(--accent); }

/* ---------- Hero ---------- */
.hero { padding: var(--sp-7) 0 var(--sp-6); text-align: center; }
.hero__title { font-size: var(--fs-3xl); }
.hero__title em {
  font-style: normal;
  background: linear-gradient(120deg, var(--accent), #b58cff 60%, var(--ok));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.hero__sub { max-width: 62ch; margin: var(--sp-4) auto 0; font-size: var(--fs-lg); color: var(--text-dim); }
.hero__cta { display: flex; flex-wrap: wrap; gap: var(--sp-3); justify-content: center; margin-top: var(--sp-5); }
.stats { display: flex; flex-wrap: wrap; gap: var(--sp-5); justify-content: center; margin-top: var(--sp-6); }
.stat { text-align: center; }
.stat__n { font: var(--fw-bold) var(--fs-2xl)/1 var(--font-mono); color: var(--accent); }
.stat__l { font-size: var(--fs-xs); color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.07em; }

/* ---------- Empty state ---------- */
.empty { display: grid; place-items: center; gap: var(--sp-3); padding: var(--sp-8) var(--sp-4); text-align: center; color: var(--text-dim); }
.empty__icon { font-size: 2.5rem; opacity: 0.5; }

/* ---------- Teacher mode bar ---------- */
.teacher-bar {
  position: fixed;
  left: 50%;
  bottom: var(--sp-4);
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  max-width: calc(100vw - var(--sp-6));
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-sm);
  background: var(--surface-hi);
  border: 1px solid var(--accent);
  border-radius: var(--r-full);
  box-shadow: var(--sh-3);
}
.teacher-bar__time { font: var(--fw-bold) var(--fs-md)/1 var(--font-mono); color: var(--accent); min-width: 5ch; }
.teacher-bar__step { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 38ch; }

.talking-points {
  padding: var(--sp-4);
  background: color-mix(in oklab, #b58cff14 70%, var(--surface));
  border: 1px dashed color-mix(in oklab, #b58cff 45%, transparent);
  border-radius: var(--r-md);
}
.talking-points__label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #b58cff;
  margin-bottom: var(--sp-2);
}

/* ---------- Confetti canvas ---------- */
.confetti { position: fixed; inset: 0; z-index: var(--z-toast); pointer-events: none; }

/* The site footer is part of the app shell grid, so its styles live in layout.css. */

/* ==========================================================================
   Icons — inline SVG, inherits colour and size from its context.
   ========================================================================== */

.icon {
  display: inline-block;
  flex: none;
  vertical-align: -0.16em;
  overflow: visible;
}
.btn .icon,
.chip .icon,
.tab .icon { vertical-align: -0.14em; }
.btn--icon .icon { vertical-align: -0.2em; }

/* Icons carrying state colour without needing a wrapper class. */
.icon--ok { color: var(--ok); }
.icon--warn { color: var(--warn); }
.icon--danger { color: var(--danger); }
.icon--accent { color: var(--accent); }
.icon--dim { color: var(--text-faint); }

/* Spin/pulse are opt-in and respect the motion preference. */
.icon--spin { animation: icon-spin 1.1s linear infinite; }
@keyframes icon-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .icon--spin { animation: none; }
}

/* A large decorative icon for empty states and feature rows. */
.icon-tile {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid color-mix(in oklab, var(--accent) 30%, transparent);
  border-radius: var(--r-sm);
}
.icon-tile--plain { color: var(--text-dim); background: var(--surface-2); border-color: var(--border); }

/* ==========================================================================
   Reward bar — the moment right after a win.
   Fixed to the bottom, never covers content it interrupts, dismissible by
   keyboard, and it slides rather than pops so it reads as arriving, not alarming.
   ========================================================================== */

.reward {
  position: fixed;
  z-index: var(--z-toast);
  right: var(--sp-4);
  bottom: var(--sp-4);
  left: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  max-width: min(460px, calc(100vw - var(--sp-6)));
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
  background: linear-gradient(135deg,
    color-mix(in oklab, var(--accent) 16%, var(--bg-elev)),
    var(--bg-elev) 65%);
  border: 1px solid color-mix(in oklab, var(--accent) 40%, var(--border));
  border-radius: var(--r-lg);
  box-shadow: var(--sh-4);
  opacity: 0;
  transform: translateY(14px) scale(0.98);
  transition: opacity var(--dur) var(--ease), transform var(--dur-slow) var(--ease-spring);
}
.reward.is-in { opacity: 1; transform: none; }

.reward__mark {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
  border-radius: var(--r-full);
}
.reward__text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.reward__text strong { font-size: var(--fs-sm); }
.reward__sub {
  font-size: var(--fs-xs);
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.reward__actions { display: flex; gap: var(--sp-2); margin-left: auto; }

@media (max-width: 560px) {
  .reward { right: var(--sp-3); left: var(--sp-3); max-width: none; flex-wrap: wrap; }
  .reward__actions { width: 100%; }
  .reward__actions .btn { flex: 1; }
}

/* ==========================================================================
   Share sheet
   ========================================================================== */

.sharesheet {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: minmax(0, 1.15fr) minmax(260px, 1fr);
  align-items: start;
}
@media (max-width: 720px) {
  .sharesheet { grid-template-columns: minmax(0, 1fr); }
}

.sharesheet__preview {
  display: grid;
  place-items: center;
  padding: var(--sp-3);
  background:
    linear-gradient(45deg, var(--bg-sunken) 25%, transparent 25%) -8px 0/16px 16px,
    linear-gradient(-45deg, var(--bg-sunken) 25%, transparent 25%) -8px 0/16px 16px,
    var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.sharesheet__canvas {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  border-radius: var(--r-sm);
  box-shadow: var(--sh-3);
}
/* A story card is tall: cap its height so the sheet never scrolls the buttons away. */
.sharesheet__preview[data-format="story"] .sharesheet__canvas { width: auto; max-height: 52vh; }
.sharesheet__preview[data-format="square"] .sharesheet__canvas { width: auto; max-height: 44vh; }

.sharesheet__side { display: flex; flex-direction: column; gap: var(--sp-4); min-width: 0; }
.sharesheet__tabs { width: 100%; }
.sharesheet__tabs .tab { flex-direction: column; align-items: flex-start; gap: 2px; line-height: 1.2; }
.sharesheet__ratio { font-size: 10px; color: var(--text-faint); font-family: var(--font-mono); }
.sharesheet__caption { min-height: 84px; font-size: var(--fs-sm); }

.sharesheet__actions { display: grid; gap: var(--sp-2); grid-template-columns: 1fr 1fr; }
.sharesheet__actions .btn { justify-content: flex-start; min-height: 40px; }
.sharesheet__actions .btn--primary { grid-column: 1 / -1; justify-content: center; }

.sharesheet__status {
  min-height: 1.4em;
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--ok);
}
.sharesheet__privacy {
  margin: 0;
  font-size: var(--fs-xs);
  line-height: 1.55;
  color: var(--text-faint);
}
.sharesheet__privacy .icon { color: var(--text-dim); }

/* Sharing controls in the Progress view */
.sharestats { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr)); }
