/* ============================================================
   DEMO.CSS — the walkthrough that runs before your turn
   ------------------------------------------------------------
   Three regions, and the layout is the argument: the CODE on the left with one
   line lit, what that line DOES on the right, and underneath it the two things
   you would otherwise have to imagine — what the variables hold now, and what
   has appeared on screen so far.
   ============================================================ */

.demo-overlay {
  position: fixed;
  inset: 0;
  z-index: 12000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0.5rem, 3vw, 2rem);
  background: rgba(4, 8, 16, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: demoFade 0.18s ease-out;
}
@keyframes demoFade { from { opacity: 0; } to { opacity: 1; } }

/* The page behind must not scroll under the dialog. */
body.demo-open { overflow: hidden; }

.demo-window {
  width: min(1080px, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.55);
  overflow: hidden;
  animation: demoRise 0.24s cubic-bezier(0.22, 1.1, 0.4, 1);
}
@keyframes demoRise {
  from { opacity: 0; transform: translateY(14px) scale(0.985); }
  to { opacity: 1; transform: none; }
}

/* ── Head ─────────────────────────────────────────────────── */
.demo-head {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.9rem 1.1rem;
  border-bottom: 1px solid var(--border-color);
  background: var(--bg-surface);
  flex-shrink: 0;
}
.demo-head-icon {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border-radius: var(--radius-md);
  background: var(--color-primary-subtle);
  color: var(--color-primary);
  border: 1px solid color-mix(in srgb, var(--color-primary) 34%, transparent);
}
.demo-head-icon svg { width: 19px; height: 19px; }
.demo-head-text { flex: 1; min-width: 0; }
.demo-head-text h2 {
  margin: 0;
  font-size: 1.02rem;
  font-weight: 800;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
.demo-head-text p {
  margin: 0.1rem 0 0;
  font-size: 0.8rem;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.demo-head-actions { display: flex; align-items: center; gap: 0.45rem; flex-shrink: 0; }
.demo-icon-btn {
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.demo-icon-btn:hover { background: var(--bg-surface-hover); color: var(--text-primary); }
.demo-icon-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.demo-icon-btn svg { width: 16px; height: 16px; }
.demo-ghost {
  border: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-tertiary);
  font: inherit;
  font-size: 0.72rem;
  padding: 0.3rem 0.55rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
}
.demo-ghost:hover { color: var(--text-primary); background: var(--bg-surface-hover); }

/* ── Body: code | explanation ─────────────────────────────── */
.demo-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
}
.demo-code-pane {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-right: 1px solid var(--border-color);
  background: var(--bg-code, #0d1117);
}
.demo-pane-label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.42rem 0.75rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  border-bottom: 1px solid var(--border-color);
  flex-shrink: 0;
}
.demo-pane-label svg { width: 12px; height: 12px; }

.demo-code {
  flex: 1;
  min-height: 0;
  margin: 0;
  padding: 0.6rem 0;
  overflow: auto;
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  font-size: 0.815rem;
  line-height: 1.72;
  tab-size: 4;
}
.demo-line { display: flex; padding: 0 0.75rem; transition: background 0.18s ease; }
.demo-ln {
  flex-shrink: 0;
  width: 2.2em;
  text-align: right;
  padding-right: 0.9em;
  color: var(--text-tertiary);
  opacity: 0.5;
  user-select: none;
  font-variant-numeric: tabular-nums;
}
.demo-lt { white-space: pre; min-width: 0; }

/* The one line this step is about. Everything else stays legible rather than
   being dimmed to nothing — you need the surrounding code to make sense of it. */
.demo-line.is-on {
  background: color-mix(in srgb, var(--color-primary) 17%, transparent);
  box-shadow: inset 3px 0 0 var(--color-primary);
}
.demo-line.is-on .demo-ln { opacity: 1; color: var(--color-primary); font-weight: 700; }

/* ── Side: what it does, what it holds, what it printed ───── */
.demo-side {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background: var(--bg-base);
}
.demo-say {
  padding: 1rem 1.1rem;
  font-size: 0.9rem;
  line-height: 1.62;
  color: var(--text-secondary);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.demo-say p { margin: 0; }
.demo-say code {
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  font-size: 0.86em;
  background: var(--bg-surface-hover);
  border: 1px solid var(--border-color);
  border-radius: 3px;
  padding: 0.05em 0.3em;
  color: var(--text-primary);
  white-space: nowrap;
}
.demo-say strong { color: var(--text-primary); font-weight: 700; }
.demo-say em { color: var(--text-primary); font-style: italic; }
.demo-fade { animation: demoSay 0.22s ease-out; }
@keyframes demoSay { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.demo-recap h3 {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
  color: var(--color-success);
}
.demo-recap h3 svg { width: 15px; height: 15px; }
.demo-recap p { color: var(--text-secondary); }

/* ── The memory diagram ────────────────────────────────────────
   Boxes rather than chips, because the ideas that need demonstrating are about
   the RELATIONSHIPS between boxes: a pointer holds where another one is, a
   copy is a second box with the same number in it, and a local goes away. Each
   of those is a thing you can draw and cannot say in a row of text. */
.demo-mem {
  position: relative;
  padding: 0.4rem 1.1rem 0.85rem;
  flex-shrink: 0;
  min-height: 0;
}
.demo-mem.hidden { display: none; }

.demo-mem-arrows {
  position: absolute;
  left: 1.1rem;
  top: 0.4rem;
  pointer-events: none;
  overflow: visible;
  color: var(--color-primary);
  z-index: 2;
}
.demo-arrow {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  opacity: 0;
  animation: demoArrowIn 0.34s ease-out 0.08s forwards;
}
@keyframes demoArrowIn { to { opacity: 0.9; } }
.demo-arrow-null {
  fill: var(--text-tertiary);
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  font-size: 9px;
  letter-spacing: 0.04em;
}

/* Frames stack left to right; a caller and a callee are two groups, which is
   the point being made whenever both are on screen at once. */
.demo-mem-frames {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.9rem;
  align-items: flex-end;
  padding-top: 1.9rem;   /* room for the arrows to arc over the boxes */
  position: relative;
  z-index: 1;
}
.demo-frame { display: flex; flex-direction: column; gap: 0.22rem; min-width: 0; }
.demo-frame-label {
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  font-size: 0.62rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding-left: 0.1rem;
}
.demo-frame.is-bare .demo-frame-label { display: none; }
.demo-frame-boxes { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.demo-frame:not(.is-bare) .demo-frame-boxes {
  padding: 0.28rem;
  border: 1px dashed var(--border-color);
  border-radius: var(--radius-md);
}

.demo-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.05rem;
  min-width: 3.6rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  transition: border-color 0.22s ease, background 0.22s ease, transform 0.22s ease;
}
.demo-box-name { font-size: 0.64rem; color: var(--text-tertiary); line-height: 1.2; }
.demo-box-val {
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1.3;
  white-space: nowrap;
}

/* A box that has just appeared.

   A variable coming into existence is an EVENT — it is the thing the step is
   about — and at 0.34s from 0.9 scale it was over before you had looked at it.
   Now it arrives: it drops in from above, overshoots, and a ring of the accent
   opens out of its edge and fades, so the eye is taken to the box that is new
   rather than having to find it.

   Staggered by position, so two variables appearing together arrive one after
   the other. Simultaneous reads as a repaint; in sequence reads as two things
   happening. */
.demo-box.is-new {
  animation: demoBoxIn 0.52s cubic-bezier(0.22, 1.4, 0.4, 1) backwards;
  animation-delay: calc(var(--i, 0) * 110ms);
}
@keyframes demoBoxIn {
  0%   { opacity: 0; transform: translateY(-14px) scale(0.72); }
  55%  { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
/* The ring. Drawn on a pseudo-element so nothing about the box's own layout,
   border or background has to move to make it. */
.demo-box.is-new::after {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  border: 2px solid var(--color-primary);
  pointer-events: none;
  animation: demoBoxRing 0.72s ease-out backwards;
  animation-delay: calc(var(--i, 0) * 110ms);
}
@keyframes demoBoxRing {
  0%   { opacity: 0; transform: scale(0.72); }
  35%  { opacity: 0.85; }
  100% { opacity: 0; transform: scale(1.5); }
}
/* The ring is positioned against the box, so the box has to be a containing
   block for it — without this it would size itself to the frame instead. */
.demo-box { position: relative; }

/* A box whose value has just changed — the single most important thing on the
   panel, so it gets the accent and a beat of movement. */
.demo-box.is-changed {
  border-color: var(--color-warning);
  background: color-mix(in srgb, var(--color-warning) 14%, var(--bg-surface));
}
.demo-box.is-changed .demo-box-val {
  color: var(--color-warning);
  animation: demoValIn 0.46s cubic-bezier(0.3, 1.5, 0.5, 1);
}
@keyframes demoValIn {
  0% { opacity: 0; transform: translateY(-10px) scale(1.35); }
  60% { opacity: 1; }
  100% { transform: none; }
}
/* The box flinches with the number. Without it only the digits moved, which at
   this size is a flicker rather than a change. */
.demo-box.is-changed { animation: demoBoxHit 0.46s cubic-bezier(0.3, 1.5, 0.5, 1); }
@keyframes demoBoxHit {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.09); }
  100% { transform: scale(1); }
}

/* A pointer box: it holds a location, so it is drawn as one. */
.demo-box.is-ptr {
  border-color: color-mix(in srgb, var(--color-primary) 55%, var(--border-color));
  background: color-mix(in srgb, var(--color-primary) 9%, var(--bg-surface));
}
.demo-box.is-ptr .demo-box-val { color: var(--color-primary); }

/* And one that has gone out of scope, fading where it stood. */
.demo-frame.is-gone { opacity: 0.55; }
.demo-box.is-gone {
  border-style: dashed;
  animation: demoBoxOut 0.9s ease-in forwards;
}
@keyframes demoBoxOut {
  0% { opacity: 1; }
  55% { opacity: 0.7; transform: none; }
  100% { opacity: 0; transform: translateY(6px) scale(0.92); }
}

/* The value that travels when something is copied. */
.demo-flow-chip {
  position: absolute;
  z-index: 3;
  transform: translate(-50%, -50%);
  padding: 0.15rem 0.4rem;
  border-radius: var(--radius-sm);
  background: var(--color-warning);
  color: #1a1206;
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  font-size: 0.74rem;
  font-weight: 700;
  pointer-events: none;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
  transition: transform 0.62s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.62s ease-in;
}

/* What has appeared on screen so far. */
.demo-term {
  flex-shrink: 0;
  border-top: 1px solid var(--border-color);
  background: var(--bg-code, #0d1117);
  display: flex;
  flex-direction: column;
  max-height: 40%;
}
.demo-term-body {
  margin: 0;
  padding: 0.6rem 0.9rem 0.8rem;
  overflow: auto;
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--text-primary);
  white-space: pre-wrap;
  word-break: break-word;
  min-height: 3.2em;
}
.demo-term-idle { color: var(--text-tertiary); font-style: italic; opacity: 0.7; }
/* What a person typed, so it reads apart from what the program wrote. */
.demo-typed {
  color: var(--color-success);
  font-weight: 700;
  border-bottom: 1px dotted color-mix(in srgb, var(--color-success) 60%, transparent);
}

/* ── Foot: progress and navigation ────────────────────────── */
.demo-foot {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.65rem 1.1rem;
  border-top: 1px solid var(--border-color);
  background: var(--bg-surface);
  flex-shrink: 0;
}
.demo-dots { display: flex; flex-wrap: wrap; gap: 0.28rem; flex: 1; min-width: 0; }
.demo-dot {
  width: 9px; height: 9px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border-color);
  background: transparent;
  cursor: pointer;
  transition: background 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
}
.demo-dot:hover { transform: scale(1.25); border-color: var(--color-primary); }
.demo-dot.is-done { background: color-mix(in srgb, var(--color-primary) 45%, transparent); border-color: transparent; }
.demo-dot.is-on { background: var(--color-primary); border-color: var(--color-primary); transform: scale(1.3); }
.demo-dot-end { border-radius: 2px; }
.demo-dot:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.demo-nav { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; }
.demo-count {
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  font-size: 0.72rem;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
  min-width: 4.2em;
  text-align: center;
}
.demo-nav .btn svg { width: 14px; height: 14px; }

/* ── The library of walkthroughs ──────────────────────────── */
.demo-window-lib { width: min(900px, 100%); }
.demo-lib-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem 1.1rem 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.3rem;
}
.demo-lib-group > h3 {
  margin: 0 0 0.55rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.demo-lib-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 0.5rem;
}
.demo-card {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.65rem 0.7rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  transition: border-color 0.16s ease, transform 0.16s ease, background 0.16s ease;
}
.demo-card:hover { border-color: var(--color-primary); transform: translateY(-1px); background: var(--bg-surface-hover); }
.demo-card:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.demo-card-icon {
  width: 30px; height: 30px;
  flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  background: var(--color-primary-subtle);
  color: var(--color-primary);
}
.demo-card-icon svg { width: 15px; height: 15px; }
.demo-card-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.demo-card-text strong { font-size: 0.845rem; color: var(--text-primary); font-weight: 700; }
.demo-card-text em {
  font-style: normal;
  font-size: 0.71rem;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.demo-card-meta { display: flex; align-items: center; gap: 0.35rem; flex-shrink: 0; }
.demo-card-tick { width: 14px; height: 14px; color: var(--color-success); }
.demo-card-steps {
  font-family: var(--font-mono, ui-monospace, Consolas, monospace);
  font-size: 0.66rem;
  color: var(--text-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 3px;
  padding: 0.05rem 0.3rem;
}
/* Seen ones stay reachable but stop competing with the ones you have not met. */
.demo-card.is-seen { opacity: 0.72; }
.demo-card.is-seen:hover { opacity: 1; }

.demo-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.74rem;
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
}
.demo-switch input { accent-color: var(--color-primary); cursor: pointer; }

.demo-foot-lib { justify-content: space-between; }
.demo-foot-hint { font-size: 0.72rem; color: var(--text-tertiary); text-align: right; }

/* ── The button on the practice screen ────────────────────── */
.practice-demo-btn.has-demo { color: var(--color-primary); }
.practice-demo-btn.is-new { position: relative; }
/* A walkthrough you have not seen says so, once, without a word of copy. */
.practice-demo-btn.is-new::after {
  content: '';
  position: absolute;
  top: 2px; right: 2px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--color-warning);
  box-shadow: 0 0 0 2px var(--bg-surface);
  animation: demoPing 2.4s ease-in-out infinite;
}
@keyframes demoPing {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.35); opacity: 0.65; }
}

/* ── Narrow screens ───────────────────────────────────────── */
@media (max-width: 820px) {
  .demo-body { grid-template-columns: 1fr; grid-template-rows: minmax(140px, 1fr) minmax(0, 1.1fr); }
  .demo-code-pane { border-right: 0; border-bottom: 1px solid var(--border-color); }
  .demo-term { max-height: 34%; }
  .demo-head-text p { display: none; }
  .demo-foot { flex-wrap: wrap; gap: 0.6rem; }
  .demo-dots { order: 2; width: 100%; justify-content: center; }
  .demo-nav { order: 1; width: 100%; justify-content: space-between; }
  .demo-foot-hint { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-overlay, .demo-window, .demo-fade, .demo-var.is-changed,
  .practice-demo-btn.is-new::after { animation: none !important; }
  .demo-line, .demo-dot, .demo-card { transition: none !important; }
}

/* ── What builds on this ───────────────────────────────────────
   Offered on the last panel, because that is the moment the next idea makes
   sense. Two lessons had no program that could reach them, and a walkthrough
   only the shelf knows about is one nobody finds when it would help. */
.demo-next-up {
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.demo-next-label {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.demo-next-card {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  cursor: pointer;
  font: inherit;
  color: inherit;
  text-align: left;
  transition: border-color 0.16s ease, transform 0.16s ease;
}
.demo-next-card:hover { border-color: var(--color-primary); transform: translateX(2px); }
.demo-next-card:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.demo-next-card > i:first-child { width: 15px; height: 15px; flex-shrink: 0; color: var(--color-primary); }
.demo-next-card span { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.demo-next-card strong { font-size: 0.82rem; color: var(--text-primary); }
.demo-next-card em {
  font-style: normal;
  font-size: 0.7rem;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.demo-next-go { width: 13px; height: 13px; flex-shrink: 0; color: var(--text-tertiary); }

@media (prefers-reduced-motion: reduce) {
  .demo-next-card { transition: none !important; }
}

/* Newly printed output, marked for a moment so you can see which line of the
   program produced it. */
.demo-out-new {
  background: color-mix(in srgb, var(--color-success) 22%, transparent);
  border-radius: 2px;
  animation: demoOutIn 0.9s ease-out;
}
@keyframes demoOutIn {
  0% { background: color-mix(in srgb, var(--color-success) 45%, transparent); }
  100% { background: color-mix(in srgb, var(--color-success) 0%, transparent); }
}

/* The line being executed gets a moment of movement as it becomes the one. */
.demo-line.is-on { animation: demoLineIn 0.3s ease-out; }
@keyframes demoLineIn {
  from { background: color-mix(in srgb, var(--color-primary) 40%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
  .demo-box, .demo-box.is-new::after, .demo-box.is-changed .demo-box-val,
  .demo-box.is-gone, .demo-arrow, .demo-flow-chip, .demo-out-new,
  .demo-line.is-on {
    animation: none !important;
    transition: none !important;
    opacity: 1;
  }
  .demo-arrow { opacity: 0.9; }
}

/* ── Reading the walkthrough aloud ─────────────────────────────
   The toggle reads as a state, not a press: on, it takes the accent colour and
   a matching tint, so a glance at the header answers "is it going to talk?" */
.demo-voice-btn.is-on {
  color: var(--color-primary);
  border-color: color-mix(in srgb, var(--color-primary) 55%, transparent);
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
}
.demo-voice-btn.is-on:hover {
  background: color-mix(in srgb, var(--color-primary) 20%, transparent);
  color: var(--color-primary);
}

/* A code chip is read as one unit -- "star P", not "star" then "P" -- so it
   lights as one chip rather than letter by letter. Its own border and fill
   already set it apart from the prose, so the reading state moves those rather
   than only the text colour, which a chip's background would half-swallow. */
.demo-say code.rp-w.is-now {
  color: var(--color-primary);
  border-color: color-mix(in srgb, var(--color-primary) 60%, transparent);
  background: color-mix(in srgb, var(--color-primary) 16%, transparent);
}
.demo-say code.rp-w.is-said { color: var(--text-tertiary); }

/* The voice panel is opened FROM the walkthrough, so it has to sit over it --
   .demo-overlay is 12000 and .modal-overlay is 1000, which would otherwise put
   the settings behind the thing that asked for them. */
body.demo-open #speech-panel { z-index: 12500; }

/* ── The voice button's own options ────────────────────────────
   On the body, not inside the walkthrough: the window sits at z-index 12000
   and clips at its own rounded corner, so a menu hanging off a header button
   has to be a sibling of it and stacked above.

   Anchored to the button rather than to the pointer. It belongs to that one
   control — there is never a second one — and a menu that lands wherever the
   cursor happened to be reads as a page-wide context menu, which this is not. */
.demo-voice-menu {
  position: fixed;
  z-index: 12600;
  width: 300px;
  max-width: calc(100vw - 16px);
  padding: 0.3rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
  animation: demoMenuIn 0.14s ease-out;
}
@keyframes demoMenuIn {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}
.demo-voice-menu-title {
  padding: 0.4rem 0.55rem 0.3rem;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.demo-voice-menu-sep {
  height: 1px;
  margin: 0.25rem 0.35rem;
  background: var(--border-color);
}
.demo-voice-opt {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  width: 100%;
  padding: 0.45rem 0.55rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.demo-voice-opt:hover { background: var(--bg-surface-hover); }
.demo-voice-opt:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.demo-voice-opt strong {
  display: block;
  font-size: 0.79rem;
  font-weight: 700;
  color: var(--text-primary);
}
.demo-voice-opt em {
  display: block;
  font-style: normal;
  font-size: 0.7rem;
  line-height: 1.35;
  color: var(--text-tertiary);
  margin-top: 1px;
}
/* The tick box is always drawn, so the rows line up whether or not anything is
   checked — a mark that appears and shifts the text is harder to scan than one
   that fills. */
.demo-voice-tick {
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  margin-top: 1px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-color);
  border-radius: 5px;
  color: transparent;
  transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
}
.demo-voice-tick svg { width: 11px; height: 11px; }
.demo-voice-opt.is-on .demo-voice-tick {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
/* The settings row is an action, not a checkbox: no box to fill. */
.demo-voice-opt.is-plain .demo-voice-tick {
  border-color: transparent;
  color: var(--text-tertiary);
}

/* Reading every step is a standing choice, so the button says so even when it
   is not currently talking — a dotted underline rather than the lit state,
   which stays reserved for "it is speaking right now". */
.demo-voice-btn.is-auto:not(.is-on) {
  border-color: color-mix(in srgb, var(--color-primary) 45%, var(--border-color));
  color: var(--color-primary);
}

@media (prefers-reduced-motion: reduce) {
  .demo-voice-menu { animation: none; }
}
