/* Trellis — app-specific styles. Built on motif + spakit chrome.
 * The 3-pane map view (LHS list, center graph, RHS detail) is
 * Trellis-specific — keep it isolated to the .map-page container
 * so the other views render with normal motif page width. */

#root { padding: 0; }

/* The map view fills the viewport below the navbar; everything
 * else uses normal page padding. Column widths are CSS variables
 * so the splitter handles can update them without re-rendering;
 * persisted to localStorage and re-applied on next load. */
.map-page {
  --left-w: 14rem;
  --right-w: 22rem;
  position: fixed;
  top: var(--nav-height, 56px);
  left: 0; right: 0; bottom: 0;
  display: grid;
  grid-template-columns: var(--left-w) 4px 1fr 4px var(--right-w);
  overflow: hidden;
}

/* Splitter handles. Thin strip; cursor and a hover tint signal
 * draggability without wasting space. Pointer-events makes the
 * 4px column actually clickable. */
.splitter {
  cursor: col-resize;
  background: transparent;
  transition: background 100ms;
  touch-action: none;
}
.splitter:hover,
.splitter:active { background: #c5d4b8; }

/* Mobile hamburger button: sits at top-left of map area when LHS
 * is off-canvas. Hidden at wide widths. */
.map-hamburger {
  display: none;
  position: absolute;
  top: 0.5rem; left: 0.6rem;
  z-index: 6;
  width: 2.2rem; height: 2.2rem;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid #d6dccd;
  border-radius: 6px;
  font-size: 1.1rem; line-height: 1;
  cursor: pointer;
}
.map-hamburger:hover { background: #f3f7ee; }

/* Tablet: drop the LHS into an off-canvas drawer. The center
 * (map) and RHS still sit side-by-side. Splitter-left is hidden
 * because the drawer doesn't share the grid. */
@media (max-width: 1180px) {
  .map-page {
    grid-template-columns: 1fr 4px var(--right-w);
  }
  .splitter-left { display: none; }
  #left {
    display: block !important;
    position: fixed;
    top: var(--nav-height, 56px);
    left: 0; bottom: 0;
    width: 16rem;
    z-index: 10;
    transform: translateX(-101%);
    transition: transform 200ms ease;
    box-shadow: 2px 0 12px rgba(0,0,0,0.12);
  }
  #left.open { transform: translateX(0); }
  .map-hamburger { display: inline-flex; align-items: center; justify-content: center; }
  /* Push the scope-chip slightly right so the hamburger doesn't
   * overlap it. */
  .scope-chip { left: 3.4rem; }
}

/* Phone: stack RHS below the map. */
@media (max-width: 800px) {
  .map-page {
    grid-template-columns: 1fr;
    grid-template-rows: 60vh 0 1fr;
  }
  .splitter-right { display: none; }
  #side { border-left: none; border-top: 1px solid #e5e7eb; }
}

/* Non-map views get a sensible content frame. */
main#root > h1,
main#root > h2,
main#root > h3,
main#root > p,
main#root > ul,
main#root > details,
main#root > article {
  max-width: 56rem;
  margin-left: auto;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
}
.about-page { padding: 1.5rem 1rem 3rem; }
.about-page .lead { font-size: 1.1rem; color: var(--text, #333); }

.muted { color: #888; }
.small { font-size: 0.85rem; }

/* LHS list panel */
#left {
  background: #fafaf7;
  border-right: 1px solid #e5e7eb;
  overflow-y: auto;
  padding: 0.8rem 0.6rem 1rem;
}
.lp-heading { margin: 0.2rem 0.4rem 0.4rem; color: #2e4a25; font-size: 1rem; }
.lp-heading .muted { font-weight: 400; }
.lp-hint { margin: 0 0.4rem 0.8rem; }

.lp-group {
  cursor: pointer; font-size: 0.85rem; font-weight: 600;
  color: #2e4a25; padding: 0.4rem 0.5rem; list-style: none;
  user-select: none; border-radius: 4px; margin-top: 0.4rem;
}
.lp-group::-webkit-details-marker { display: none; }
.lp-group::before {
  content: '▸'; display: inline-block; margin-right: 0.35rem;
  color: #6b7280; transition: transform 100ms ease;
}
details[open] .lp-group::before { transform: rotate(90deg); }
.lp-group:hover { background: #ecf0e6; }
.lp-items {
  list-style: none; padding: 0;
  margin: 0.2rem 0 0.4rem 0.85rem;
  border-left: 1px solid #d6dccd;
}
.lp-item {
  display: flex; align-items: center; gap: 0.4rem;
  padding: 0.3rem 0.4rem 0.3rem 0.6rem;
  margin: 1px 0; cursor: pointer; font-size: 0.85rem;
  border-radius: 0 3px 3px 0; color: #333;
  transition: background 80ms ease;
}
.lp-item:hover { background: #ecf0e6; color: #2e4a25; }
.lp-item.selected { background: #4f7c40; color: #fff; font-weight: 500; }
.lp-item.selected:hover { background: #3e6431; }
.lp-item.neighbor { background: #f3f7ee; }
.lp-item .state-pip { width: 0.55rem; height: 0.55rem; flex-shrink: 0; }
.lp-item[data-state="learning"] .state-pip { background: #fde68a; border-color: #b45309; }
.lp-item[data-state="mastered"] .state-pip { background: #4ade80; border-color: #166534; }
.lp-item[data-state="stuck"]    .state-pip { background: #fca5a5; border-color: #b91c1c; }
.lp-item .lp-label { flex: 1; }

/* Active group: visually marks which LHS group the map is focused
 * on. The summary gets a tinted background and the small green dot. */
details.lp-group-active > summary.lp-group {
  background: #e6efde;
  color: #1e3719;
}
.lp-active-dot {
  display: inline-block;
  width: 0.5rem; height: 0.5rem;
  border-radius: 50%;
  background: #4f7c40;
  margin-left: 0.4rem;
  vertical-align: 0.05rem;
}

/* Map section */
#map-section {
  background: #fff;
  border-right: 1px solid #e5e7eb;
  overflow: hidden;
  position: relative;
}

/* Scope chip — sits at the top of the map area and tells the user
 * what's currently visible. Clickable "Show all" / "Focus on a
 * group" toggles. Floats over the SVG so the map can use the full
 * viewport when zoom/pan. */
.scope-chip {
  position: absolute;
  top: 0.5rem; left: 0.6rem;
  z-index: 5;
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.3rem 0.7rem;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid #d6dccd;
  border-radius: 999px;
  font-size: 0.85rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.scope-chip .scope-label { font-weight: 600; color: #2e4a25; }
.scope-chip .link-btn { color: #4f7c40; padding: 0; }
#graph {
  width: 100%; height: 100%;
  background: radial-gradient(circle at 50% 40%, #f8faf6, #ecf0e6 80%);
  cursor: grab;
}
#graph:active { cursor: grabbing; }

/* Edges */
.edge {
  stroke-width: 1.5; stroke: #b6bdb0; opacity: 0.65;
  transition: opacity 200ms ease;
}
.edge-prereq    { stroke: #4f7c40; }
.edge-extends   { stroke: #6b7280; stroke-dasharray: 4 3; }
.edge-co-occurs { stroke: #94a3b8; stroke-dasharray: 2 4; }
.edge.focus { stroke-width: 2.5; opacity: 1; }
.edge[data-dist="d1"]  { opacity: 0.85; }
.edge[data-dist="d2"]  { opacity: 0.30; }
.edge[data-dist="far"] { opacity: 0.08; }
.arrow-prereq    { fill: #4f7c40; }
.arrow-extends   { fill: #6b7280; }
.arrow-co-occurs { fill: #94a3b8; }

/* Group-graph suggestive flow edges. The relations between groups
 * are intentionally fuzzy (NOT literal prereqs), so we keep them
 * dashed — but visible. Stroke-width is set per-edge in JS by
 * cross-group concept-edge count, so heavier connections read as
 * thicker flow. */
.edge-leads-to {
  stroke: #6b7280;
  stroke-dasharray: 5 3;
  opacity: 0.9;
}
.arrow-leads-to { fill: #6b7280; }

/* Group nodes (meta-overview). Bigger than concept boxes, with a
 * progress strip at the bottom showing per-state concept counts. */
.group-node { cursor: pointer; }
.group-box {
  fill: #fafaf7;
  stroke: #4f7c40;
  stroke-width: 2.5;
  transition: fill 100ms ease, stroke-width 100ms ease;
}
.group-node:hover .group-box {
  fill: #f3f7ee;
  stroke-width: 3.5;
  filter: drop-shadow(0 1px 4px rgba(74,112,48,0.25));
}
.group-title {
  font-size: 16px;
  font-weight: 600;
  fill: #2e4a25;
  pointer-events: none;
  user-select: none;
}
.group-count {
  font-size: 11.5px;
  fill: #6b7280;
  pointer-events: none;
  user-select: none;
}
.group-progress-text {
  font-size: 10px;
  font-weight: 500;
  fill: #6b7280;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.group-bar { pointer-events: none; }
.group-bar-bg       { fill: #e5e7eb; }
.group-bar-mastered { fill: #4ade80; }
.group-bar-learning { fill: #fde68a; }
.group-bar-stuck    { fill: #fca5a5; }

/* Nodes */
.node { cursor: pointer; transition: opacity 200ms ease; }
.node-box {
  fill: #fff; stroke: #4f7c40; stroke-width: 2;
  transition: stroke-width 100ms ease;
}
.node[data-state="learning"] .node-box { fill: #fef3c7; stroke: #b45309; }
.node[data-state="mastered"] .node-box { fill: #166534; stroke: #166534; }
.node[data-state="stuck"]    .node-box { fill: #fee2e2; stroke: #b91c1c; }
.node.selected .node-box {
  stroke-width: 4;
  filter: drop-shadow(0 0 8px rgba(74,112,48,0.55));
}
.node.neighbor .node-box { stroke-width: 3; }
.node.preview .node-box {
  stroke-width: 3.5;
  filter: drop-shadow(0 0 6px rgba(74,112,48,0.7));
}

/* Bridge nodes: present because they neighbor the active group, but
 * not part of it. Slightly faded + thinner stroke so the focus
 * group reads as primary. Click still selects normally. */
.node.bridge .node-box {
  stroke-width: 1.3;
  stroke-dasharray: 2 2;
  opacity: 0.85;
}
.node.bridge .box-title { fill: #6b7280; }
.node.bridge .box-stat  { fill: #9ca3af; }

.node[data-dist="d2"]  { opacity: 0.50; }
.node[data-dist="far"] { opacity: 0.18; }

.box-title {
  font-size: 12.5px; font-weight: 600;
  fill: #2e4a25; pointer-events: none; user-select: none;
  letter-spacing: -0.005em;
}
.box-pip {
  fill: #fff; stroke: #b6bdb0; stroke-width: 1; pointer-events: none;
}
.node[data-state="learning"] .box-pip { fill: #fde68a; stroke: #b45309; }
.node[data-state="mastered"] .box-pip { fill: #4ade80; stroke: #166534; }
.node[data-state="stuck"]    .box-pip { fill: #fca5a5; stroke: #b91c1c; }

.box-stat {
  font-size: 9.5px; fill: #888; pointer-events: none;
  font-variant-numeric: tabular-nums; font-weight: 500;
}
.box-pin-mark {
  fill: #4f7c40; stroke: #2e4a25; stroke-width: 0.5;
  pointer-events: none; visibility: hidden;
}
.node.pinned .box-pin-mark { visibility: visible; }
.node.pinned .node-box { stroke-dasharray: 5 3; }
.node[data-state="mastered"] .box-title { fill: #fff; }
.node[data-state="mastered"] .box-stat  { fill: rgba(255,255,255,0.85); }
.node[data-state="mastered"] .box-pip   { stroke: rgba(255,255,255,0.6); }
.node[data-state="mastered"] .box-pin-mark { fill: #fff; stroke: rgba(0,0,0,0.3); }
.zoomed-out .box-title,
.zoomed-out .box-stat { display: none; }

/* RHS panel */
#side {
  padding: 1rem 1.2rem 2rem;
  overflow-y: auto;
  background: #fff;
}
#side h2 { color: #2e4a25; margin: 0 0 0.4rem; font-size: 1.2rem; }
#side h3 { color: #2e4a25; margin: 1.2rem 0 0.4rem; font-size: 0.95rem; }
#side p  { margin: 0.4rem 0; }
.tags { letter-spacing: 0.04em; text-transform: uppercase; font-size: 0.7rem; }

/* State chips: 4 buttons (unseen/learning/mastered/stuck) on a
 * single line. Compact sizing fits the default 22rem RHS without
 * wrapping; flex-wrap allows graceful break if user shrinks the
 * pane below ~280px. */
.state-row {
  display: flex; gap: 0.25rem; flex-wrap: wrap;
  margin: 0.6rem 0 0.4rem;
}
.state-chip {
  font: inherit; background: #fff; border: 1px solid #d1d5db;
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
  color: #555; font-size: 0.78rem; cursor: pointer;
  white-space: nowrap;
  flex: 0 1 auto;
}
.state-chip:hover { border-color: #4f7c40; color: #2e4a25; }
.state-chip.active { background: #4f7c40; color: #fff; border-color: #4f7c40; }

/* Notes: collapsible <details> block. Closed state shows a brief
 * preview of saved text (or a hint when empty); open state reveals
 * the editable textarea. Auto-opens when a note exists so users
 * always see what they wrote. */
.notes-block {
  margin: 1rem 0 0.6rem;
  border-top: 1px solid #f0f0ee;
  padding-top: 0.6rem;
}
.notes-block > summary {
  cursor: pointer;
  display: flex; align-items: baseline; gap: 0.5rem;
  list-style: none;
  font-size: 0.92rem;
  color: #2e4a25;
}
.notes-block > summary::-webkit-details-marker { display: none; }
.notes-block > summary::before {
  content: '▸';
  display: inline-block;
  color: #6b7280;
  font-size: 0.75rem;
  transition: transform 100ms;
}
.notes-block[open] > summary::before { transform: rotate(90deg); }
.notes-label { font-weight: 600; }
.notes-hint { flex: 1; }
.notes-block[open] .notes-hint { color: #9ca3af; }
textarea#note-area {
  width: 100%; resize: vertical; min-height: 3.5rem;
  margin-top: 0.5rem;
}

.related-list { list-style: none; padding: 0; margin: 0; }
.related-item {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  background: #fafaf7; border: 1px solid #e5e7eb;
  border-radius: 4px; margin: 0.25rem 0;
  cursor: pointer; font-size: 0.92rem;
}
.related-item:hover { border-color: #4f7c40; background: #f3f7ee; }
.state-pip {
  display: inline-block; width: 0.65rem; height: 0.65rem; border-radius: 50%;
  border: 1px solid #b6bdb0; flex-shrink: 0;
}
.state-unseen   .state-pip { background: #fff; }
.state-learning .state-pip { background: #fde68a; border-color: #b45309; }
.state-mastered .state-pip { background: #4ade80; border-color: #166534; }
.state-stuck    .state-pip { background: #fca5a5; border-color: #b91c1c; }
.rel-label { flex: 1; }
.rel-edge { white-space: nowrap; }

/* Resources — accordion. Each <li> is a row that's always visible
 * (mark pip + title link + kind + chevron). data-expanded=true
 * reveals the body containing source text + mark buttons (and the
 * remove control for user-added items). */
.resource-list { list-style: none; padding: 0; margin: 0.4rem 0; }
.resource-list.added-list { margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px dashed #e5e7eb; }
.resource-item-empty { padding: 0.3rem 0; }

.resource-item {
  border: 1px solid #ececea;
  border-radius: 4px;
  margin: 0.25rem 0;
  font-size: 0.88rem;
  background: #fff;
}
.resource-item.marked-saved { background: #f3f7ee; }
.resource-item.added { border-style: dashed; }

.res-row {
  display: flex; align-items: center; gap: 0.4rem;
  padding: 0.4rem 0.55rem;
}
.res-pip {
  flex-shrink: 0;
  display: inline-block;
  width: 0.55rem; height: 0.55rem;
  border-radius: 50%;
  border: 1px solid #b6bdb0;
  background: #fff;
}
.res-pip[data-mark="visited"] { background: #cbd5e1; border-color: #6b7280; }
.res-pip[data-mark="read"]    { background: #4ade80; border-color: #166534; }
.res-pip[data-mark="saved"]   { background: #fbbf24; border-color: #b45309; }

.res-title {
  flex: 1;
  color: #2e4a25;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.res-title:hover { text-decoration: underline; text-underline-offset: 2px; }
.resource-item.added .res-title { color: #1d4ed8; }
.res-kind {
  flex-shrink: 0;
  text-transform: lowercase;
}
.res-toggle {
  flex-shrink: 0;
  background: transparent; border: 0;
  cursor: pointer;
  color: #9ca3af;
  font-size: 0.85rem;
  padding: 0 0.3rem;
  transition: transform 120ms;
}
.resource-item[data-expanded="true"] .res-toggle { transform: rotate(180deg); color: #4f7c40; }

.res-body {
  display: none;
  border-top: 1px dashed #e5e7eb;
  padding: 0.45rem 0.55rem;
  flex-direction: column;
  gap: 0.35rem;
}
.resource-item[data-expanded="true"] .res-body { display: flex; }
.res-source { line-height: 1.2; }

.resource-marks {
  display: flex; gap: 0.3rem; flex-wrap: wrap; align-items: center;
}
.mark-btn {
  font-size: 0.72rem; padding: 0.12rem 0.5rem; border-radius: 999px;
  background: #fafaf7; color: #6b7280; border: 1px solid #e5e7eb;
}
.mark-btn:hover { color: #2e4a25; border-color: #4f7c40; }
.mark-btn.active { background: #4f7c40; color: #fff; border-color: #4f7c40; }

.add-resource-form, .add-student-form {
  display: grid; gap: 0.4rem; grid-template-columns: 1fr;
  margin: 0.6rem 0 1rem;
}
.add-resource-form .form-control,
.add-resource-form .form-select { font-size: 0.9rem; }

/* Progress view */
.progress-page { padding: 1.5rem 1rem 3rem; }
.prog-block {
  margin: 1rem 0 1.4rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid #f1f1ee;
}
.prog-block:last-of-type { border-bottom: 0; }
.prog-block h3 {
  color: #2e4a25; font-size: 1.05rem;
  margin: 0 0 0.5rem;
}
.prog-goal-head {
  display: flex; align-items: baseline; gap: 1rem;
}
.prog-goal-head h3 { flex: 1; margin: 0; }
.prog-bar {
  display: flex;
  height: 10px; width: 100%;
  background: #ececea; border-radius: 6px;
  overflow: hidden;
  margin: 0.4rem 0 0.5rem;
}
.prog-bar-fill { height: 100%; }
.prog-mastered { background: #4ade80; }
.prog-learning { background: #fde68a; }
.prog-stuck    { background: #fca5a5; }

.prog-list { list-style: none; padding: 0; margin: 0.4rem 0; }
.prog-list-item {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  background: #fafaf7;
  border: 1px solid #ececea;
  border-radius: 4px;
  margin: 0.3rem 0;
  cursor: pointer;
  font-size: 0.95rem;
}
.prog-list-item:hover { border-color: #4f7c40; background: #f3f7ee; }
.prog-list-item .prog-list-label { flex: 1; color: #2e4a25; }

.prog-timeline {
  margin-top: 1.5rem;
  border-top: 1px solid #ececea;
  padding-top: 0.8rem;
}
.prog-timeline > summary {
  cursor: pointer;
  font-weight: 500;
  color: #2e4a25;
  margin-bottom: 0.5rem;
}

.history-list { list-style: none; padding: 0; }
.history-item {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.4rem 0.6rem; border-bottom: 1px solid #f1f1ee;
  font-size: 0.92rem;
}
.history-item .hi-label { flex: 1; color: #2e4a25; }
.history-item .hi-ts { white-space: nowrap; }

/* Goal panel overlay (first-run + on-demand) */
.panel-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.35);
  display: flex; align-items: flex-start; justify-content: center;
  z-index: 100;
  padding: 4rem 1rem 1rem;
  overflow-y: auto;
}
.panel {
  background: #fff;
  border-radius: 10px;
  width: min(560px, 100%);
  padding: 1.5rem 1.6rem;
  position: relative;
  box-shadow: 0 6px 24px rgba(0,0,0,0.18);
}
.panel-close {
  position: absolute;
  top: 0.6rem; right: 0.8rem;
  background: transparent; border: 0;
  font-size: 1.5rem; line-height: 1; cursor: pointer;
  color: #6b7280;
}
.panel-close:hover { color: #111; }
.panel-actions {
  display: flex; gap: 0.6rem; align-items: center;
  margin-top: 1.5rem;
}

.goal-preset, .anchor-preset {
  display: flex; align-items: flex-start; gap: 0.7rem;
  padding: 0.7rem 0.6rem;
  border: 1px solid #e5e7eb; border-radius: 6px;
  margin: 0.3rem 0;
  cursor: pointer;
}
.goal-preset:hover, .anchor-preset:hover {
  border-color: #4f7c40; background: #f3f7ee;
}
.goal-preset input, .anchor-preset input { margin-top: 0.2rem; }
.goal-preset-body, .anchor-preset-body {
  display: flex; flex-direction: column; gap: 0.15rem;
  flex: 1;
}
.goal-preset-name, .anchor-preset-name {
  font-weight: 500; color: #2e4a25;
}
.goal-preset:has(input:checked),
.anchor-preset:has(input:checked) {
  border-color: #4f7c40; background: #ecf3e3;
}

/* RHS Where-am-I goal stub + first-run */
.rhs-firstrun {
  background: #f3f7ee;
  border: 1px solid #d6dccd;
  border-radius: 6px;
  padding: 0.8rem 1rem;
  margin: 0.4rem 0 1rem;
}
.rhs-firstrun h3 { margin: 0 0 0.3rem; color: #2e4a25; }
.rhs-goal {
  margin: 0.4rem 0 1rem;
}
.rhs-goal-name {
  font-weight: 600; color: #2e4a25;
  font-size: 0.95rem;
}
.rhs-goal-stub { padding: 0.5rem 0; }

/* Tier-gated locked variants. Mirror the regular block layouts so
 * the page does not jump when the user's tier changes — same
 * vertical space, content swapped. */
.notes-block.locked {
  margin: 1rem 0 0.6rem;
  padding: 0.6rem 0.8rem;
  border: 1px dashed #d6dccd;
  border-radius: 6px;
  background: #fafaf7;
}
.notes-locked-row {
  display: flex; align-items: center; gap: 0.6rem;
  margin-bottom: 0.3rem;
}
.notes-block.locked .notes-label { font-weight: 600; color: #2e4a25; }
.lock-badge {
  font-size: 0.7rem;
  background: #4f7c40;
  color: #fff;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  letter-spacing: 0.02em;
}
.add-resource-locked {
  padding: 0.5rem 0.6rem;
  border: 1px dashed #d6dccd;
  border-radius: 4px;
  background: #fafaf7;
  margin-top: 0.5rem;
}
.classroom-cap {
  padding: 0.6rem 0.8rem;
  border: 1px dashed #d6dccd;
  border-radius: 6px;
  background: #fafaf7;
  margin-top: 0.6rem;
}

/* Demo / preview banner — sits between navbar and the map-page
 * grid. Compact, prominent, with the sign-up CTA on the right. */
.demo-banner {
  position: fixed;
  top: var(--nav-height, 56px);
  left: 0; right: 0;
  height: 2.4rem;
  background: #ecf3e3;
  border-bottom: 1px solid #d6dccd;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  z-index: 9;
  font-size: 0.88rem;
  padding: 0 1rem;
}
.demo-banner strong { color: #2e4a25; }
.demo-banner .btn-link {
  color: #4f7c40;
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: 500;
}
.demo-banner .btn-link:hover { color: #2e4a25; }

/* Tier banner (from spakit) sits in normal flow above .map-page,
 * but .map-page is position:fixed so it covers the banner. Lift
 * the banner to fixed too and shift .map-page down by its height
 * so the Subscribe button is actually clickable for free-tier
 * users. */
#root > .tier-banner {
  position: fixed;
  top: var(--nav-height, 56px);
  left: 0; right: 0;
  z-index: 8;
  margin: 0;
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  height: 2.6rem;
  padding: 0 1rem;
  justify-content: center;
}
#root > .tier-banner + .map-page {
  top: calc(var(--nav-height, 56px) + 2.6rem);
}

/* Guest narrative pages (e.g. /#progress when not logged in) —
 * marketing-shaped layout with a real-looking mock card so the
 * value is concrete. */
.guest-page {
  max-width: 50rem;
  margin: 0 auto;
  padding: 2rem 1.2rem 4rem;
}
.guest-page h1 { color: #2e4a25; margin-top: 0; }
.guest-page .lead {
  font-size: 1.05rem;
  color: #444;
  margin-bottom: 1.5rem;
}
.guest-progress-mock {
  border: 1px solid #d6dccd;
  border-radius: 8px;
  padding: 1.2rem 1.4rem;
  background: #fafaf7;
  margin-bottom: 2rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.guest-progress-mock .prog-block:last-of-type { border-bottom: 0; padding-bottom: 0; }
.guest-dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.6rem 1.5rem;
  margin: 1rem 0 2rem;
}
.guest-dl dt {
  font-weight: 600;
  color: #2e4a25;
  padding-top: 0.1rem;
}
.guest-dl dd {
  margin: 0;
  color: #444;
}
.guest-cta {
  display: flex;
  gap: 0.8rem;
  margin-top: 1.5rem;
  flex-wrap: wrap;
}
@media (max-width: 600px) {
  .guest-dl { grid-template-columns: 1fr; gap: 0.2rem 0; }
  .guest-dl dd { margin-bottom: 0.8rem; }
}

/* Classroom view */
.student-list { list-style: none; padding: 0; }
.student-item {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid #e5e7eb; border-radius: 4px;
  margin: 0.3rem 0;
}
.student-item .student-name { font-weight: 500; flex: 1; }
.link-btn.danger { color: #b91c1c; }

/* Student switcher in navbar */
.student-switcher select {
  font-size: 0.9rem; padding: 0.25rem 0.5rem;
  border: 1px solid #d1d5db; border-radius: 4px;
  background: #fff; color: #333;
}
