/*
 * sample-embed.css — styling for the embedded samples that now live inside the
 * eight service pages: the three teacher tools (/syllabus, /rubric, /letter)
 * and the five student services (/shortlist, /resolve, /pursuit, /aid,
 * /roster). Every one of them renders its sample inline at #sample.
 *
 * The component CSS is ported from the (now-redirected) standalone
 * -sample.html pages and SCOPED ENTIRELY under `.sample-embed` — custom
 * properties included — so the service pages' own global typography (their
 * bare p/ul/table rules and root-level variables) is never restyled. On top of the
 * ported components sit the local widget-state rules (a tabbed draft viewer,
 * before/after toggles, evidence highlight-linking) and the shared
 * "One Class, Three Tools." story spine.
 *
 * TWO RULES THIS FILE MUST KEEP, both enforced by
 * tests/student-sample-embed-sync.test.ts:
 *
 *  1. Never declare `display` on the BARE `.sample-embed` selector. This sheet
 *     is unlayered and site-tailwind.css puts every utility in
 *     `@layer utilities`, so an unlayered declaration outranks `.hidden`
 *     regardless of specificity — and the four wizard pages hide #sample by
 *     adding `.hidden` to every `.intro-section` (activateWizard()). A
 *     `display` here would leave the sample on screen under the open wizard,
 *     which is exactly the bug the old `.demo-banner` had. Descendant rules
 *     (`.sample-stack { display:flex }`) are safe: the ancestor is already
 *     `display:none`.
 *  2. For the same layering reason, these rules beat Tailwind utilities on the
 *     same element. Content inside `.sample-embed` must be written in the
 *     component vocabulary below (.card, .chip, .eyebrow, .muted, ...), NOT in
 *     raw Tailwind utilities, or it will be silently restyled.
 *
 * Companion script: sample-embed.js. No fixed/sticky positioning anywhere, and
 * z-index is kept at or below 10, so the mobile nav drawer, the feedback FAB,
 * and the exit survey always sit above this content. Colors are restricted to
 * the official EduFinder palette already present in the sample pages, and the
 * bar fills mirror SEMANTIC_BAR_FILL in src/lib/shared/semantic-colors.ts.
 */

/* ── Scoped design tokens. Declared on `.sample-embed`, never on the document
      root, so they cannot leak into the surrounding page's typography. ── */
.sample-embed {
  --brand-blue: #3b82f6;
  /* The readable blue. --brand-blue is 3.68:1 on white, which clears the 3:1
     WCAG asks of borders, glows and icons but misses the 4.5:1 every run of
     small text owes; #1d4ed8 is 6.70:1 on --surface and 6.16:1 on the #eff6ff
     chips. Blue TEXT in this sheet uses this one, blue everything-else stays
     --brand-blue. Same value as the hub-chrome.css and learning-embed.css
     copies; tests/mono-label-contrast.test.ts reconciles them. */
  --brand-blue-label: #1d4ed8;
  /* The blue that CARRIES white text. --brand-blue is 3.68:1 against
     white, which is fine beside white and fails underneath it, so a filled
     button, badge or bar takes this one and everything else — borders, glows,
     icon tiles, focus rings, bars and dots that hold no words — stays
     --brand-blue. Same value as --brand-blue-label, and not by coincidence:
     the constraint is one constraint seen from both sides, blue-on-white and
     white-on-blue, and 6.70:1 either way. */
  --brand-blue-fill: #1d4ed8;
  --brand-navy: #1f2937;
  --surface: #ffffff;
  --border: rgba(31, 41, 55, .12);
  --text-primary: #1f2937;
  --text-secondary: rgba(31, 41, 55, .78);
  /* .66, not .62: at .62 this is 4.31:1 and misses AA for normal-size
     text. Full note in hub-chrome.css; the value must match there. */
  --text-tertiary: rgba(31, 41, 55, .66);
  --shadow-warm-sm: 0 1px 3px rgba(31, 41, 55, .05), 0 1px 2px rgba(31, 41, 55, .04);
  --shadow-warm-md: 0 4px 14px rgba(31, 41, 55, .06), 0 2px 4px rgba(31, 41, 55, .04);
  color: var(--text-primary);
}

/* ══ REGION 1: SHARED SHELL & COMPONENTS ═══════════════════════════════════
   Used by all eight embedded samples. Anything added here shows up on both
   the teacher and the student side, so keep it generic.
   ═══════════════════════════════════════════════════════════════════════ */

.sample-embed .sample-stack { display: flex; flex-direction: column; gap: 1.25rem; }
/* Flex items default to min-width:auto, so a wide descendant (the Aid form
   matrix) would push the whole page sideways instead of scrolling inside its
   own .table-scroll. Nothing in a sample may ever scroll the page body. */
.sample-embed .sample-stack > * { min-width: 0; }

/* Navy eyebrow pill, the same treatment as the "The problem" card pill. */
.sample-embed .embed-eyebrow {
  display: inline-block;
  background: var(--brand-navy);
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .12em;
  padding: .28rem .75rem;
  border-radius: 999px;
}

/* A muted lede/affordance line that stands in for the page's gray-500 ledes
   without being clobbered by the scoped `p` rule below. */
.sample-embed .embed-lede {
  color: var(--text-tertiary);
  font-size: 1rem;
  line-height: 1.7;
  max-width: 42rem;
  margin-bottom: 1.75rem;
}
.sample-embed .embed-hint {
  color: var(--text-tertiary);
  font-size: .82rem;
  line-height: 1.5;
  margin-top: .55rem;
}
.sample-embed .embed-hint i { color: var(--brand-blue); margin-right: .35rem; }
@media (min-width: 768px) {
  .sample-embed .embed-lede { font-size: 1.125rem; }
}

/* ── Ported base components (all scoped) ── */
.sample-embed .sample-note {
  background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 14px; padding: 1rem 1.25rem;
  color: #1e3a8a; font-size: .9rem; line-height: 1.6;
}
.sample-embed .card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 18px;
  box-shadow: var(--shadow-warm-sm); padding: 1.85rem 1.6rem;
}
/* Cards are gapped by `.sample-stack { gap: 1.25rem }` (above), which reaches
   DIRECT children only. A `[data-hl-scope]` wrapper is itself one such child
   (pursuit's spike ladder, shortlist's signal read, aid's mistake shield), so
   the cards INSIDE it fall out of the flex gap, and `.card` carries no margin
   of its own: they render touching at a 0px seam. State the same 1.25rem once
   here instead of in per-page `style="margin-top:1rem"` patches.
   Scoped to CONSECUTIVE CARDS on purpose: `[data-hl-scope]` also sits on the
   letter and rubric samples' own `article.card`, whose children are prose, so
   a looser `> * + *` would indent their paragraphs. */
.sample-embed [data-hl-scope] > .card + .card { margin-top: 1.25rem; }
.sample-embed .eyebrow { color: var(--brand-blue-label); font-size: .72rem; font-weight: 800; letter-spacing: .12em; }
.sample-embed .card h2 { margin-top: .3rem; color: var(--brand-navy); font-size: 1.3rem; font-weight: 700; letter-spacing: -.01em; }
.sample-embed .card h3 { color: var(--brand-navy); font-size: 1.05rem; font-weight: 700; margin-top: .2rem; }
.sample-embed .chips { display: flex; flex-wrap: wrap; gap: .4rem; margin: .6rem 0 .2rem; }
.sample-embed .chip { background: #eff6ff; color: #1d4ed8; font-size: .72rem; font-weight: 700; padding: .2rem .55rem; border-radius: 999px; }
.sample-embed .muted { color: var(--text-tertiary); font-size: .8rem; font-weight: 700; letter-spacing: .05em; margin-top: 1rem; }
.sample-embed p { line-height: 1.7; color: var(--text-secondary); }
/* list-style is restated because Tailwind's preflight zeroes it in @layer base
   and the ported sample markup relied on Tailwind's own list-disc utility,
   which this unlayered sheet outranks. Without this the teacher samples' lists
   render indented but marker-less. */
.sample-embed ul { margin: .5rem 0 0 1.2rem; color: var(--text-secondary); line-height: 1.6; list-style: disc; }
.sample-embed li { margin-bottom: .25rem; }
.sample-embed .story-link { color: var(--brand-blue-label); font-weight: 600; }
.sample-embed .story-link:hover { text-decoration: underline; }
.sample-embed .unit { border: 1px solid var(--border); border-radius: 12px; padding: 1.15rem 1.2rem; margin-top: .8rem; }

/* ══ REGION 2: TEACHER-SAMPLE COMPONENTS ═══════════════════════════════════
   /syllabus, /rubric, /letter only. The .table-scroll + table rules below are
   the exception: /aid's form matrix uses them too.
   ═══════════════════════════════════════════════════════════════════════ */

/* syllabus: lessons + AI callout */
.sample-embed .lesson { border-left: 3px solid #e5e7eb; background: #f9fafb; border-radius: 6px; padding: .6rem .8rem; margin-top: .6rem; font-size: .9rem; }
.sample-embed .ai { background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 8px; padding: .7rem .9rem; margin-top: .7rem; color: #1e3a8a; font-size: .9rem; }

/* pacing table — scrolls inside its own card on small screens, never the page */
/* position:relative makes this the containing block for the absolutely
   positioned .visually-hidden labels in the Aid form matrix. Without it they
   resolve against the initial containing block, escape the scroller entirely
   (an overflow ancestor only clips descendants it is a containing block for),
   and drag the page into a horizontal scroll. */
.sample-embed .table-scroll { position: relative; overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: .7rem; }
.sample-embed table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.sample-embed th { text-align: left; background: #f9fafb; padding: .5rem .7rem; font-size: .7rem; letter-spacing: .04em; color: #4b5563; white-space: nowrap; }
.sample-embed td { border-top: 1px solid #e5e7eb; padding: .5rem .7rem; vertical-align: top; color: var(--text-secondary); }

/* rubric: scan, roster, criteria, override, total, comment */
.sample-embed .scan {
  font-family: 'Segoe Print', 'Bradley Hand', 'Comic Sans MS', cursive;
  font-size: .98rem; color: #1f2937; line-height: 1.9;
  background: repeating-linear-gradient(#ffffff, #ffffff 30px, #eff6ff 31px);
  border: 1px solid var(--border); border-radius: 12px;
  padding: 1rem 1.1rem; margin-top: .7rem;
}
.sample-embed .scan .who { display: block; font-weight: 700; margin-bottom: .3rem; }
.sample-embed .roster { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }
.sample-embed .student { background: #f9fafb; color: #1f2937; font-size: .78rem; font-weight: 600; padding: .25rem .6rem; border-radius: 999px; }
.sample-embed .student.match { background: #ecfdf5; color: #047857; }
.sample-embed .crit { border: 1px solid var(--border); border-radius: 12px; padding: 1rem 1.1rem; margin-top: .7rem; }
.sample-embed .crit-head { display: flex; justify-content: space-between; align-items: baseline; gap: .6rem; }
.sample-embed .crit-head .name { color: var(--brand-navy); font-weight: 700; font-size: .98rem; }
.sample-embed .crit-head .pts { color: #1f2937; font-weight: 700; font-size: .9rem; white-space: nowrap; }
.sample-embed .conf { display: inline-block; font-size: .62rem; font-weight: 800; letter-spacing: .05em; padding: .1rem .45rem; border-radius: 999px; margin-right: .4rem; }
.sample-embed .conf-high { background: #ecfdf5; color: #047857; }
.sample-embed .conf-medium { background: #fffbeb; color: #b45309; }
.sample-embed .rationale { color: var(--text-tertiary); font-size: .86rem; margin-top: .35rem; }
.sample-embed .override { background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px; padding: .7rem .9rem; margin-top: .7rem; color: #b45309; font-size: .9rem; line-height: 1.6; }
.sample-embed .total { display: flex; justify-content: space-between; align-items: center; border-top: 1px solid var(--border); margin-top: .9rem; padding-top: .8rem; font-weight: 700; color: var(--brand-navy); }
.sample-embed .comment { border-left: 3px solid #bfdbfe; padding-left: .8rem; margin-top: .6rem; color: var(--text-secondary); font-size: .92rem; line-height: 1.7; }

/* An amber caution box, the counterpart to the blue `.ai` callout, used for
   the syllabus "standard take-home" weakness note. Same palette as `.override`
   and the letter's `.flag`. */
.sample-embed .caution { background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px; padding: .7rem .9rem; margin-top: .7rem; color: #b45309; font-size: .9rem; line-height: 1.6; }

/* letter: paragraphs, citations, coaching-read levels, quotes, flag */
.sample-embed .letter-para { font-family: Georgia, 'Times New Roman', serif; font-size: .98rem; color: var(--text-primary); margin-top: .9rem; }
.sample-embed .letter-para mark { background: #fffbeb; border-radius: 3px; padding: 0 .1rem; }
.sample-embed .cites { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; margin-top: .35rem; }
/* gray-500 to match the .cite pill beside it; gray-400 read 2.54:1 at 10.2px. */
.sample-embed .cites .label { color: #6b7280; font-size: .64rem; font-weight: 800; letter-spacing: .06em; }
.sample-embed .cite { background: #f9fafb; color: #6b7280; font-size: .68rem; font-weight: 700; padding: .12rem .5rem; border-radius: 999px; }
.sample-embed .level { display: inline-block; font-size: .7rem; font-weight: 800; padding: .15rem .55rem; border-radius: 999px; }
.sample-embed .level-strong { background: #ecfdf5; color: #047857; }
.sample-embed .level-developing { background: #fffbeb; color: #b45309; }
.sample-embed .quote { border-left: 3px solid #bfdbfe; padding-left: .8rem; margin-top: .6rem; font-style: italic; color: var(--text-tertiary); font-size: .9rem; }
.sample-embed .flag { background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px; padding: .7rem .9rem; margin-top: .7rem; color: #b45309; font-size: .9rem; line-height: 1.6; }

/* ══ Interactive widgets ══════════════════════════════════════════════════
   Every control is CSS-hidden until sample-embed.js sets [data-sample-js] on
   <html>, so a no-JS visitor never sees a dead control and instead reads every
   pane stacked in the sample's original order (the old page, top to bottom).
   ═══════════════════════════════════════════════════════════════════════ */

/* Controls appear only once JS is running. */
html:not([data-sample-js]) .sample-embed [role="tablist"],
html:not([data-sample-js]) .sample-embed .sample-switch { display: none; }

/* Tiny captions that title each stacked pane for no-JS readers; hidden once JS
   drives the widget. */
html[data-sample-js] .sample-embed .pane-label { display: none; }
.sample-embed .pane-label { color: var(--text-tertiary); font-size: .75rem; font-weight: 700; letter-spacing: .05em; margin: .2rem 0; }

/* Segmented control shared by the tab strip and the before/after switches. */
.sample-embed .sample-tabs,
.sample-embed .sample-switch { display: flex; flex-wrap: wrap; gap: .4rem; margin: .2rem 0 .9rem; }
.sample-embed .seg-btn {
  cursor: pointer; border: 1px solid var(--border); background: #fff; color: #1f2937;
  font-size: .82rem; font-weight: 700; padding: .42rem .9rem; border-radius: 999px;
}
.sample-embed .seg-btn[aria-selected="true"],
.sample-embed .seg-btn[aria-pressed="true"] {
  background: var(--brand-blue-fill); color: #fff; border-color: var(--brand-blue-fill);
}
.sample-embed .seg-btn:focus-visible { outline: 2px solid #3b82f6; outline-offset: 2px; }
@media (hover: hover) {
  .sample-embed .seg-btn:not([aria-selected="true"]):not([aria-pressed="true"]):hover {
    background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe;
  }
}

/* Tab panes: JS toggles `hidden`; no-JS shows them all stacked. */
.sample-embed [role="tabpanel"][hidden] { display: none; }
/* The same 0px card seam the `[data-hl-scope]` rule fixes above, in its JS-OFF
   form: a `[data-tabs]` wrapper is itself one direct child of
   `.sample-stack { gap: 1.25rem }`, so the panes inside it fall out of the flex
   gap, and nothing hides them until sample-embed.js runs. /roster stacks three
   `.card` panes and /syllabus four, all touching, for a no-JS reader.
   `:not([hidden]) ~ :not([hidden])` is load-bearing rather than clever. Under
   JS exactly one pane is ever visible, so no pair matches and nothing moves.
   The naive `> [role="tabpanel"] + [role="tabpanel"]` would instead land the
   margin on the VISIBLE pane whenever an earlier pane is the hidden one — every
   pane but the first, and every deep link (/roster#sample-essays) — where it
   collapses against the tab strip's own bottom margin and drops the pane 1.6px
   below where the first tab renders it, so the sample twitches on every click. */
.sample-embed [data-tabs] > [role="tabpanel"]:not([hidden]) ~ [role="tabpanel"]:not([hidden]) { margin-top: 1.25rem; }
.sample-embed [role="tabpanel"]:focus-visible { outline: 2px solid #3b82f6; outline-offset: 2px; border-radius: 12px; }

/* Toggle panes: driven purely by the group's data-state. CSS cannot compare
   data-state to data-show generically, so each named widget gets an explicit
   pair of rules. Defaults match the state each group ships with (the real
   sample), so no-JS shows both panes and JS shows exactly one. */
html[data-sample-js] .sample-embed [data-toggle="ai-dial"][data-state="standard"] [data-show="resistant"],
html[data-sample-js] .sample-embed [data-toggle="ai-dial"][data-state="resistant"] [data-show="standard"],
html[data-sample-js] .sample-embed [data-toggle="override"][data-state="drafted"] [data-show="recorded"],
html[data-sample-js] .sample-embed [data-toggle="override"][data-state="recorded"] [data-show="drafted"],
html[data-sample-js] .sample-embed [data-toggle="intake-mode"][data-state="scan"] [data-show="online"],
html[data-sample-js] .sample-embed [data-toggle="intake-mode"][data-state="online"] [data-show="scan"],
html[data-sample-js] .sample-embed [data-toggle="deskread"][data-state="before"] [data-show="after"],
html[data-sample-js] .sample-embed [data-toggle="deskread"][data-state="after"] [data-show="before"],
html[data-sample-js] .sample-embed [data-toggle="track"][data-state="ap"] [data-show="ib"],
html[data-sample-js] .sample-embed [data-toggle="track"][data-state="ib"] [data-show="ap"],
html[data-sample-js] .sample-embed [data-toggle="walkthrough"][data-state="fafsa"] [data-show="css-profile"],
html[data-sample-js] .sample-embed [data-toggle="walkthrough"][data-state="css-profile"] [data-show="fafsa"] {
  display: none;
}

/* Evidence highlight-linking (rubric R1 scan, letter L1 letter body). Triggers
   are upgraded to buttons by JS; the plain markup carries no roles for no-JS. */
html[data-sample-js] .sample-embed [data-hl-key] { cursor: pointer; }
.sample-embed [data-hl-key]:focus-visible { outline: 2px solid #3b82f6; outline-offset: 2px; border-radius: 6px; }
.sample-embed [data-hl-for] { border-radius: 3px; }
.sample-embed [data-hl-for].is-hl { background: #fffbeb; }
.sample-embed .scan [data-hl-for].is-hl { background: #eff6ff; }
.sample-embed .crit-head.is-active .name { color: #1d4ed8; }
.sample-embed .crit-head.is-active { text-decoration: underline; text-decoration-color: #bfdbfe; text-underline-offset: 3px; }
.sample-embed .cite.is-active { background: #eff6ff; color: #1d4ed8; }
/* A .chip used as a highlight trigger (the student samples' claim chips) takes
   the same selected treatment as a chosen segmented-control button, so the
   pressed chip is as obvious as the sentence it lit. */
.sample-embed .chip.is-active { background: var(--brand-blue-fill); color: #fff; }
.sample-embed mark.is-active { outline: 2px solid #fde68a; outline-offset: 1px; }

/* ── S1 intake → draft flow (syllabus intro card) ── */
.sample-embed .flow { display: flex; flex-direction: column; gap: .9rem; margin-top: .8rem; align-items: stretch; }
.sample-embed .flow-col { flex: 1 1 0; border: 1px solid var(--border); border-radius: 12px; background: #f9fafb; padding: .95rem 1rem; }
.sample-embed .flow-label { color: var(--text-tertiary); font-size: .72rem; font-weight: 800; letter-spacing: .06em; margin-bottom: .5rem; }
.sample-embed .flow-arrow { display: flex; align-items: center; justify-content: center; color: var(--brand-blue); font-size: 1rem; }
@media (min-width: 640px) {
  .sample-embed .flow { flex-direction: row; align-items: center; }
  .sample-embed .flow-arrow i { transform: rotate(-90deg); }
}

/* ── L3 loop strip (letter) ── */
.sample-embed .loop-strip { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .3rem; }
.sample-embed .loop-step { background: #eff6ff; color: #1d4ed8; font-size: .8rem; font-weight: 700; padding: .35rem .7rem; border-radius: 999px; }
.sample-embed .loop-arrow { color: var(--brand-blue); font-size: .8rem; }

/* ── Story spine: "One Class, Three Tools." (byte-identical across pages) ── */
.sample-embed .story-spine { display: flex; flex-direction: column; gap: .9rem; margin-top: .4rem; }
.sample-embed .spine-node {
  display: flex; flex-direction: column; gap: .4rem;
  border: 1px solid var(--border); border-radius: 14px; background: #fff;
  padding: 1rem 1.1rem; box-shadow: var(--shadow-warm-sm); text-decoration: none;
}
.sample-embed .spine-stage { display: flex; align-items: center; gap: .55rem; }
.sample-embed .spine-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; flex-shrink: 0;
  background: var(--brand-blue-fill); color: #fff; border-radius: 999px; font-size: .82rem; font-weight: 800;
}
.sample-embed .spine-kicker { color: var(--brand-blue-label); font-size: .72rem; font-weight: 800; letter-spacing: .08em; }
.sample-embed .spine-tool { color: var(--brand-navy); font-weight: 700; font-size: .98rem; }
/* Each node's own tool glyph, pushed to the far end of the stage row. The three
   icons are the ones each tool page already uses in its section headings. */
.sample-embed .spine-glyph { color: var(--brand-blue); font-size: .84rem; margin-left: auto; }
.sample-embed .spine-node[aria-current="page"] { border-color: var(--brand-blue); background: #eff6ff; }
.sample-embed .spine-node:focus-visible { outline: 2px solid #3b82f6; outline-offset: 2px; }
/* "You are here" ships on all three nodes so the STORY-SPINE block stays
   byte-identical across the pages (tests/teacher-sample-embed-sync.test.ts);
   only the node carrying aria-current reveals it. */
.sample-embed .spine-here { display: none; }
.sample-embed .spine-node[aria-current="page"] .spine-here {
  display: inline-block; align-self: flex-start;
  background: var(--brand-blue-fill); color: #fff; font-size: .6rem; font-weight: 800;
  letter-spacing: .07em;
  padding: .12rem .45rem; border-radius: 999px;
}
.sample-embed .spine-edge { display: flex; align-items: center; gap: .5rem; color: var(--text-tertiary); font-size: .82rem; line-height: 1.45; padding: 0 .3rem; }
.sample-embed .spine-edge i { color: var(--brand-blue); flex-shrink: 0; }
/* The artifact that actually travels along the edge, named as an object rather
   than buried in the sentence. */
.sample-embed .spine-carry {
  background: #eff6ff; color: #1d4ed8; font-size: .68rem; font-weight: 800;
  letter-spacing: .05em;
  padding: .16rem .5rem; border-radius: 999px;
}
@media (hover: hover) {
  .sample-embed .spine-node:hover { border-color: #bfdbfe; box-shadow: var(--shadow-warm-md); }
}
@media (min-width: 768px) {
  .sample-embed .story-spine { flex-direction: row; align-items: stretch; }
  .sample-embed .spine-node { flex: 1 1 0; }
  .sample-embed .spine-edge { flex: 0 1 12rem; flex-direction: column; text-align: center; }
  .sample-embed .spine-edge i { transform: rotate(-90deg); }
}

/* ══ REGION 3: STUDENT-SAMPLE COMPONENTS ═══════════════════════════════════
   /shortlist, /resolve, /pursuit, /aid, /roster. Built from the canonical
   token system in src/lib/shared/semantic-colors.ts — the pill family mirrors
   SEMANTIC_HEX and the bar fills mirror SEMANTIC_BAR_FILL. Never hand-pick a
   color here; take it from one of those two records.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Semantic pills. A hand-mirror of SEMANTIC_HEX (bg / border / text),
      the same 50-weight background + 700-weight text the React
      SEMANTIC_CLASSES.pill bundles render. ── */
.sample-embed .pill {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .68rem; font-weight: 800; letter-spacing: .05em;
  padding: .16rem .5rem; border-radius: 999px; border: 1px solid transparent;
  white-space: nowrap;
}
.sample-embed .pill i { font-size: .62rem; }
.sample-embed .pill-danger  { background: #fef2f2; border-color: #fecaca; color: #b91c1c; }
.sample-embed .pill-caution { background: #fffbeb; border-color: #fde68a; color: #b45309; }
.sample-embed .pill-success { background: #ecfdf5; border-color: #a7f3d0; color: #047857; }
.sample-embed .pill-info    { background: #eff6ff; border-color: #bfdbfe; color: #1d4ed8; }
.sample-embed .pill-neutral { background: #f9fafb; border-color: #e5e7eb; color: #4b5563; }
.sample-embed .pill-accent  { background: #faf5ff; border-color: #e9d5ff; color: #6b21a8; }

/* ── Bar fills. A hand-mirror of SEMANTIC_BAR_FILL: the same hue families at
      their saturated 500 weight (info keeps the exact brand blue), because the
      50-weight pill backgrounds above are far too pale to read as a bar. ── */
.sample-embed .bar-danger  { background: #ef4444; }
.sample-embed .bar-caution { background: #f59e0b; }
.sample-embed .bar-success { background: #10b981; }
.sample-embed .bar-info    { background: #3b82f6; }
.sample-embed .bar-neutral { background: #d1d5db; }
.sample-embed .bar-accent  { background: #a855f7; }

/* ── Meters. One track holding one or more fills; widths ride inline on the
      markup so a no-JS, no-script visitor still sees the real proportions. ── */
.sample-embed .meter-track {
  display: flex; width: 100%; height: .62rem; border-radius: 999px;
  background: #f9fafb; overflow: hidden;
}
.sample-embed .meter-fill { height: 100%; }
.sample-embed .meter-fill + .meter-fill { border-left: 2px solid #fff; }
.sample-embed .meter-legend {
  display: flex; flex-wrap: wrap; gap: .35rem .9rem; margin-top: .55rem;
  font-size: .78rem; font-weight: 600; color: var(--text-tertiary);
}
.sample-embed .legend-item { display: inline-flex; align-items: center; gap: .4rem; }
.sample-embed .legend-dot { width: .6rem; height: .6rem; border-radius: 999px; flex-shrink: 0; }
.sample-embed .meter-pair { display: grid; gap: 1.1rem; margin-top: .8rem; }
@media (min-width: 640px) {
  .sample-embed .meter-pair { grid-template-columns: 1fr 1fr; gap: 1.6rem; }
}
.sample-embed .meter-title { color: var(--brand-navy); font-weight: 700; font-size: .92rem; margin-bottom: .5rem; }

/* ── Ladder: a ranked list of rows, each with its own meter. Shared by the
      Shortlist selectivity ladder and the Pursuit spike ladder. ── */
.sample-embed .ladder { display: flex; flex-direction: column; gap: 1rem; margin-top: .8rem; }
.sample-embed .ladder-row { border: 1px solid var(--border); border-radius: 12px; padding: .9rem 1rem; }
.sample-embed .ladder-head { display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap; }
.sample-embed .rank-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; flex-shrink: 0; align-self: center;
  background: var(--brand-navy); color: #fff; border-radius: 999px;
  font-size: .76rem; font-weight: 800;
}
.sample-embed .ladder-name { color: var(--brand-navy); font-weight: 700; font-size: 1rem; }
.sample-embed .ladder-meta { color: var(--text-tertiary); font-size: .8rem; font-weight: 600; margin-left: auto; white-space: nowrap; }
.sample-embed .ladder-row .meter-track { margin-top: .6rem; }
.sample-embed .ladder-row .meter-scale { display: flex; justify-content: space-between; margin-top: .3rem; font-size: .72rem; color: var(--text-tertiary); }
.sample-embed .spike-flag { background: var(--brand-blue-fill); color: #fff; font-size: .62rem; font-weight: 800; letter-spacing: .06em; padding: .14rem .5rem; border-radius: 999px; }
.sample-embed .ladder-group-label { color: var(--text-tertiary); font-size: .72rem; font-weight: 800; letter-spacing: .06em; margin: .9rem 0 -.2rem; }

/* Compact key/value strip under a ladder row (tuition, size, acceptance...). */
.sample-embed .stats { display: flex; flex-wrap: wrap; gap: .3rem .9rem; margin-top: .6rem; }
.sample-embed .stat { display: inline-flex; align-items: baseline; gap: .3rem; font-size: .8rem; }
.sample-embed .stat-k { color: var(--text-tertiary); font-weight: 600; }
.sample-embed .stat-v { color: var(--brand-navy); font-weight: 700; }

/* ── Rail: an ordered run of stops (Pursuit phases, Aid deadlines). Same
      responsive idiom as .story-spine — stacked on mobile, a row at md. ── */
.sample-embed .rail { display: flex; flex-direction: column; gap: .75rem; margin-top: .8rem; }
.sample-embed .rail-node {
  flex: 1 1 0; border: 1px solid var(--border); border-radius: 12px;
  background: #f9fafb; padding: .8rem .9rem;
}
.sample-embed .rail-when { color: var(--brand-blue-label); font-size: .7rem; font-weight: 800; letter-spacing: .07em; }
.sample-embed .rail-what { color: var(--brand-navy); font-weight: 700; font-size: .92rem; margin-top: .25rem; }
.sample-embed .rail-edge { display: flex; align-items: center; justify-content: center; color: var(--brand-blue); font-size: .8rem; }
.sample-embed .rail-marker {
  display: flex; align-items: flex-start; gap: .5rem; margin-top: .7rem;
  background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px;
  padding: .6rem .8rem; color: #b45309; font-size: .86rem; line-height: 1.55;
}
.sample-embed .rail-marker i { color: #b45309; margin-top: .18rem; flex-shrink: 0; }
.sample-embed .rail-ghost { color: var(--text-tertiary); font-size: .82rem; margin-top: .45rem; }
/* A rail carries four stops, so it needs more room than the two- and
   three-node blocks that turn horizontal at 768px. Tablets keep the stacked
   form rather than squeezing four columns into ~180px each. */
@media (min-width: 1024px) {
  .sample-embed .rail { flex-direction: row; align-items: stretch; }
  .sample-embed .rail-edge i { transform: rotate(-90deg); }
}

/* ── Load board: term columns of course slots (Resolve AP track). ── */
.sample-embed .terms { display: flex; flex-direction: column; gap: .8rem; margin-top: .8rem; }
.sample-embed .term { flex: 1 1 0; border: 1px solid var(--border); border-radius: 12px; padding: .9rem 1rem; }
.sample-embed .term-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; }
.sample-embed .term-head .name { color: var(--brand-navy); font-weight: 700; font-size: .98rem; }
.sample-embed .term-head .count { color: var(--text-tertiary); font-size: .78rem; font-weight: 700; }
.sample-embed .slot {
  display: flex; align-items: center; gap: .5rem; margin-top: .5rem;
  border: 1px solid #bfdbfe; background: #eff6ff; border-radius: 8px;
  padding: .45rem .7rem; color: #1e3a8a; font-size: .88rem; font-weight: 600;
}
.sample-embed .slot-context { border-color: var(--border); background: #f9fafb; color: var(--text-secondary); font-weight: 500; }
.sample-embed .slot-open { border-style: dashed; border-color: #d1d5db; background: transparent; color: var(--text-tertiary); font-weight: 500; }
.sample-embed .slot-deferred { border-color: #fde68a; background: #fffbeb; color: #b45309; }
.sample-embed .slot i { color: currentColor; font-size: .8rem; flex-shrink: 0; }
.sample-embed .rule-line {
  display: flex; align-items: center; gap: .4rem; margin-top: .7rem;
  border-top: 1px dashed var(--border); padding-top: .55rem;
  color: var(--text-tertiary); font-size: .78rem; font-weight: 700;
  letter-spacing: .05em;
}
@media (min-width: 640px) {
  .sample-embed .terms { flex-direction: row; align-items: flex-start; }
}

/* ── Subject rack: the IB Group 1-6 diploma package. ── */
.sample-embed .group-row {
  display: flex; align-items: flex-start; gap: .7rem; padding: .55rem 0;
  border-top: 1px solid var(--border);
}
.sample-embed .group-row:first-child { border-top: 0; }
.sample-embed .group-label {
  flex: 0 0 5.2rem; color: var(--text-tertiary); font-size: .7rem; font-weight: 800;
  letter-spacing: .06em; padding-top: .22rem;
}
.sample-embed .group-subject { flex: 1 1 auto; }
.sample-embed .group-subject .name { color: var(--brand-navy); font-weight: 700; font-size: .92rem; }
.sample-embed .group-note { color: var(--text-tertiary); font-size: .82rem; margin-top: .2rem; line-height: 1.5; }
.sample-embed .weight-hl { background: #1d4ed8; color: #fff; font-size: .62rem; font-weight: 800; letter-spacing: .06em; padding: .1rem .4rem; border-radius: 4px; margin-left: .4rem; }
.sample-embed .weight-sl { background: #e5e7eb; color: #4b5563; font-size: .62rem; font-weight: 800; letter-spacing: .06em; padding: .1rem .4rem; border-radius: 4px; margin-left: .4rem; }
/* The one subject that satisfies two groups at once gets a visible bracket. */
.sample-embed .span-bracket {
  border-left: 3px solid var(--brand-blue); border-radius: 3px;
  padding-left: .7rem; margin-left: -.7rem;
}
.sample-embed .core-nodes { display: grid; gap: .6rem; margin-top: .7rem; }
.sample-embed .core-node { border: 1px solid var(--border); border-radius: 12px; background: #f9fafb; padding: .7rem .85rem; }
.sample-embed .core-node .name { color: var(--brand-navy); font-weight: 700; font-size: .88rem; }
.sample-embed .core-node p { font-size: .84rem; margin-top: .2rem; }
@media (min-width: 640px) {
  .sample-embed .core-nodes { grid-template-columns: repeat(3, 1fr); }
}

/* ── Form matrix marks (Aid). The glyph IS the cell's content, so each one
      needs a text equivalent. Scoped rather than Tailwind's sr-only: this
      sheet already owns every other component here, and site-tailwind.css is
      only rebuilt by hand. ── */
.sample-embed .visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.sample-embed .mark-yes { color: #047857; }
.sample-embed .mark-no { color: #9ca3af; }
.sample-embed .due { display: inline-block; font-size: .72rem; font-weight: 700; white-space: nowrap; }
.sample-embed .due-early { color: #b45309; }

/* ── Tier groups (Roster reach / target / safety buckets). ── */
.sample-embed .tier-group { margin-top: .9rem; }
.sample-embed .tier-group-head { display: flex; align-items: center; gap: .5rem; }
.sample-embed .tier-group-head .name { color: var(--brand-navy); font-weight: 700; font-size: 1rem; }
.sample-embed .tier-row {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  border-top: 1px solid var(--border); padding: .5rem 0;
  font-size: .86rem; color: var(--text-secondary);
}
.sample-embed .tier-row .school { color: var(--brand-navy); font-weight: 700; }
.sample-embed .tier-row .next { margin-left: auto; color: var(--text-tertiary); font-size: .8rem; }

/* ── Definition and ordered lists. The student samples lean on <dl> for
      labelled facts; neither element had a scoped rule before. ── */
.sample-embed dl { margin: .5rem 0 0; }
.sample-embed dt { color: var(--text-tertiary); font-size: .72rem; font-weight: 800; letter-spacing: .05em; margin-top: .6rem; }
.sample-embed dd { margin: .15rem 0 0; color: var(--text-secondary); line-height: 1.6; }
.sample-embed ol { margin: .5rem 0 0 1.2rem; color: var(--text-secondary); line-height: 1.6; list-style: decimal; }

/* Motion is opt-in: every transition sits behind prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  .sample-embed .seg-btn { transition: background .15s ease, color .15s ease, border-color .15s ease; }
  .sample-embed [data-hl-for] { transition: background .18s ease; }
  .sample-embed .spine-node { transition: border-color .15s ease, box-shadow .15s ease; }
}
