/* ============================================================
   Piero — "Graph Paper" design system
   ============================================================
   A warm math-notebook page: dark slate ink for everything written, a teacher's
   red pen for the marks that matter (section eyebrows, the
   active tab, the one emphasized word, the primary button), and
   blue ballpoint for data — bars, chart lines, counts. White
   cards are reserved for what leaves the page: messages home,
   the student's own speech.

   Radii are small and square-ish (buttons 3px, cards 4px);
   speech bubbles are the exception (16px with one 4px corner).
   Hairlines do the framing — no hard black borders, no shadows.

   TOKEN NAMES ARE UNCHANGED from the previous "Evening Board"
   palette so the templates keep working: --cream now holds the
   dark ink, and --brass now holds the red pen. Only the values
   moved. (The handoff's own palette table is written the same
   way.)

   The lesson player has its own CSS (lesson_player.css), which
   carries this same palette onto the teaching board; it loads
   this file for the topbar chrome. This file styles the shell
   pages (home, dashboard, session room, lessons, memory,
   questions, practice).
   ============================================================ */

@import url("https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400..600;1,6..72,400..600&family=Public+Sans:ital,wght@0,300..600;1,400&family=IBM+Plex+Mono:ital,wght@0,400;0,500;1,400&display=swap");

:root {
    /* --- Surfaces ----------------------------------------- */
    --board:        #FAF8F2;                      /* the warm paper page */
    --grid-line:    rgba(43, 93, 168, 0.065);     /* the faint graph-paper rule */
    --paper:        #FFFFFF;                      /* white cards (messages home) */
    --paper-ink:    #22303A;
    --paper-meta:   #64747F;
    --card:         rgba(255, 255, 255, 0.72);    /* lifted artifacts on the field */
    --card-shadow:  0 8px 28px rgba(34, 48, 58, 0.055);

    /* --- Ink hierarchy (--cream = the primary ink) --------- */
    --cream:        #22303A;
    --ink-body:     rgba(34, 48, 58, 0.9);
    --ink-2:        #5B6B76;
    --ink-3:        #64747F;
    --ink-4:        #64747F;

    /* --- Red pen accent (--brass = the red pen) ------------ */
    --brass:        #C2402A;
    --brass-dim:    rgba(194, 64, 42, 0.4);
    --brass-wash:   rgba(194, 64, 42, 0.06);
    --brass-wash-2: rgba(194, 64, 42, 0.12);
    --brass-hl:     rgba(194, 64, 42, 0.28);      /* inline highlight wash */
    /* The wash behind the row you are on right now (the current grade, the
       current session). Lighter than --brass-wash because it sits under a
       whole row of type, not a chip (design export, 2026-08-16). */
    --brass-wash-row: rgba(194, 64, 42, 0.05);

    /* --- Blue ballpoint: everything that is DATA ----------- */
    --ballpoint:      #2B5DA8;
    --ballpoint-dim:  rgba(43, 93, 168, 0.35);    /* working, not solid yet */
    --ballpoint-wash: rgba(43, 93, 168, 0.08);

    /* --- Hairlines ---------------------------------------- */
    --hair-row:     rgba(34, 48, 58, 0.12);
    --hair-section: rgba(34, 48, 58, 0.16);
    --hair-card:    rgba(34, 48, 58, 0.16);
    --hair-card-2:  rgba(34, 48, 58, 0.22);
    /* The heavy rule a section hangs off — darker and thicker than every
       other line on the page, which is how "rules, not cards" reads as
       structure without drawing a box (design export, 2026-08-16). */
    --hair-rule:    rgba(34, 48, 58, 0.5);

    /* --- Mastery tones (Memory / progress data) -----------
       Proven = ballpoint, working = the dim ballpoint, a gap =
       the red pen: the same two inks the rest of the page uses. */
    --solid:        #2B5DA8;
    --shaky:        rgba(43, 93, 168, 0.35);
    --gap:          #C2402A;

    /* --- Type families ------------------------------------ */
    --font-serif:   "Newsreader", Georgia, serif;
    --font-ui:      "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --font-mono:    "IBM Plex Mono", "SF Mono", Menlo, monospace;

    /* --- Radii -------------------------------------------- */
    --r-btn:  3px;
    --r-card: 4px;
    --r-chip: 3px;

    /* --- Motion ------------------------------------------- */
    --ease-out:    cubic-bezier(0.4, 0, 0.2, 1);
    --ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
    --t-fast:      120ms;
    --t-med:       180ms;
    --t-slow:      420ms;

    /* --- Layout ------------------------------------------- */
    /* The reading column, 1000px since the 08.16 redesign (quality pass,
       2026-08-16). It was 820px, and Home/Dashboard opted into a wider 1000px
       column of their own — which meant the page jumped 90px sideways every
       time you moved between tabs, and the red margin rule appeared and
       disappeared with it. The 96px margin column and the margin rule are
       system-wide rules in the design system, so the wide measure is now the
       product's measure and every tab shares it. */
    --max-content: 1000px;
}

/* --- Reset + base ----------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* One continuous sheet of graph paper runs behind the shell. It gives Home,
   Dashboard, Practice, orientation, and the lesson room one recognizable math-
   notebook identity without becoming a separate card or illustration. */
body {
    font-family: var(--font-ui);
    background-color: var(--board);
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 30px 30px;
    /* Let the red notebook margin replace a vertical grid rule instead of
       sitting beside one and looking like an accidental double line. */
    background-position: 0 0, 12px 0;
    background-attachment: fixed;
    color: var(--ink-body);
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    min-height: 100vh;
}
a { color: inherit; text-decoration: none; }
::selection { background: rgba(194, 64, 42, 0.18); color: var(--cream); }

/* One consistent keyboard-focus language: the same red orbit used by Piero's
   portal, kept outside the control so it never changes layout. */
:where(a, button, input, textarea, select, [role="button"]):focus-visible {
    outline: 2px solid rgba(194, 64, 42, 0.72);
    outline-offset: 4px;
}

/* --- Top bar: brand + nav + one quiet action, one hairlined row ----
   Transparent so the paper grid runs behind it; one hairline closes it off
   (it replaces the old Greek-key meander strip, now deleted from the base
   template). */
.nb-topbar {
    padding: 17px 48px;
    display: flex;
    align-items: center;
    gap: 34px;
    background: transparent;
    border-bottom: 1px solid rgba(34, 48, 58, 0.16);
}
.nb-brand {
    color: var(--cream);
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 24px;
    letter-spacing: 0.01em;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    gap: 10px;
}
/* The head-only chalk lockup (Zeno.mountHead) beside the wordmark — still used
   by the standalone lesson-player topbar. */
.nb-brand-mascot { width: 26px; height: 26px; flex: none; }
.nb-brand-word { position: relative; }
.nb-brand-lockup { display: inline-flex; align-items: center; gap: 4px; }

/* Shell brand: the full-body mini Piero standing beside the wordmark + the flat
   chalk portal at his feet (portal-jump handoff §1). The mini and
   portal sit in a fixed 46x26 stage, absolutely positioned so the row never
   shifts; portal.js mounts the rig (window.Zeno.mount) and drives the jump. */
.nb-brand-stage { position: relative; width: 46px; height: 26px; flex: none; }
.nb-brand-mini {
    position: absolute; left: 0; top: -14px; width: 44px; height: 46px;
    transform-origin: 50% 88%; will-change: transform;
}
.nb-brand-portal {
    position: absolute; left: 44px; top: -3px; width: 40px; height: 50px;
    overflow: visible; opacity: 0; pointer-events: none;
}
/* One Piero per page. A page that mounts its own big rig — the session room
   (`room`) and Home's rail (`rail`) — declares it in the `zeno_home` block, the
   shell puts that on <body data-zeno-home>, and the topbar lockup goes away
   here so he is never on screen twice (founder, 2026-08-16). Pages that declare
   nothing default to `topbar` and are untouched by this rule.

   visibility (NOT display): the 46px stage box must keep its space, or the
   auto-centered nav sits ~25px further left and the whole topbar lurches on
   every jump (founder, 2026-07-12). Hidden, not removed, for a second reason
   too — #zeno-logo is the one element zeno_chat.js listens on, and Home's rail
   opens the chat by forwarding its click to it, so the element must stay in the
   DOM with a real layout box (the chat panel positions itself off its rect). */
body[data-zeno-home="room"] .nb-brand-stage,
body[data-zeno-home="rail"] .nb-brand-stage { visibility: hidden; }

/* Nav links live in the same bar: mono caps, active = ink + a red pen underline. */
.nb-tabs {
    display: flex;
    align-items: center;
    gap: 34px;
    margin: 0 auto;
    padding: 0;
    border: none;
    background: transparent;
}
.nb-tab {
    position: relative;
    display: inline-flex;
    align-items: center;
    padding: 4px 0;
    color: var(--ink-3);
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 10.5px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    background: transparent;
    border: none;
    cursor: pointer;
    transition: color var(--t-fast) ease;
}
.nb-tab:hover { color: var(--ink-2); }
/* The weight stays 500 on the active tab: only the color changes, so marking a
   tab never re-flows the row — the labels must sit at the SAME x on every page
   (founder, 2026-07-12 — no shifting on the jump). */
.nb-tab.active { color: var(--cream); }
/* Red pen underline under the active tab, absolutely positioned so it adds no
   height and no width (it replaces the old brass diamond). */
.nb-tab.active::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: -3px;
    height: 2px;
    background: var(--brass);
}
/* The old mono tab numerals are gone in Evening Board. */
.nb-tab-icon { display: none; }

.nb-topbar-actions {
    color: var(--ink-3);
    font-family: var(--font-ui);
    font-size: 12px;
    display: flex;
    align-items: center;
    /* Enough air when a focused page supplies more than one quiet action. */
    gap: 22px;
}
.nb-topbar-actions a {
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-3);
    transition: color var(--t-fast) ease;
}
.nb-topbar-actions a:hover { color: var(--cream); }
.nb-topbar-actions .sep { color: var(--hair-card-2); }

/* Once a student begins tutoring, the website shell becomes a focused room.
   The ordinary destinations return only after wrap; Developer mode never adds
   this class. A deliberate early departure gets one clear action of its own. */
.nb-session-focusbar {
    display: none;
    align-items: center;
    gap: 24px;
    margin-left: auto;
}
body.session-focus-active .nb-tabs,
body.session-focus-active .nb-topbar-actions { display: none; }
body.session-focus-active .nb-session-focusbar { display: flex; }
body.session-focus-active .nb-brand-body { pointer-events: none; }
.nb-session-focus-state {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-2);
}
.nb-session-focus-state i {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--brass);
    box-shadow: 0 0 0 4px rgba(194, 64, 42, 0.08);
}
.nb-session-focus-action {
    border: 0;
    border-bottom: 1px solid rgba(194, 64, 42, 0.38);
    padding: 5px 0 3px;
    background: transparent;
    color: var(--brass);
    font-family: var(--font-mono);
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    cursor: pointer;
}
.nb-session-focus-action:hover { border-color: var(--brass); }

/* Early-departure confirmation. It explains the consequence before acting,
   while keeping Pause visibly distinct as the ordinary short-break choice. */
body.session-leave-open { overflow: hidden; }
.nb-session-leave {
    position: fixed;
    inset: 0;
    z-index: 10050;
    display: grid;
    place-items: center;
    padding: 24px;
}
.nb-session-leave[hidden] { display: none; }
.nb-session-leave-backdrop {
    position: absolute;
    inset: 0;
    border: 0;
    background: rgba(34, 48, 58, 0.42);
    backdrop-filter: blur(3px);
    cursor: default;
}
.nb-session-leave-sheet {
    position: relative;
    width: min(520px, 100%);
    padding: 34px 36px 30px;
    border: 1px solid rgba(34, 48, 58, 0.24);
    border-top: 3px solid var(--brass);
    background-color: var(--paper);
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 30px 30px;
    box-shadow: 0 24px 70px rgba(34, 48, 58, 0.25);
}
.nb-session-leave-kicker {
    display: block;
    margin-bottom: 12px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.17em;
    text-transform: uppercase;
    color: var(--brass);
}
.nb-session-leave-sheet h2,
.nb-session-interrupted-home h1 {
    margin: 0;
    font-family: var(--font-serif);
    font-weight: 500;
    color: var(--cream);
}
.nb-session-leave-sheet h2 { font-size: 34px; line-height: 1.1; }
.nb-session-leave-sheet p {
    margin: 16px 0 24px;
    font-family: var(--font-ui);
    font-size: 15px;
    line-height: 1.65;
    color: var(--ink-body);
}
.nb-session-leave-actions {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
}
.nb-session-stay,
.nb-session-confirm-leave {
    min-height: 42px;
    padding: 10px 17px;
    border-radius: 3px;
    font-family: var(--font-ui);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
}
.nb-session-stay {
    border: 1px solid rgba(34, 48, 58, 0.28);
    background: rgba(247, 243, 234, 0.82);
    color: var(--cream);
}
.nb-session-confirm-leave {
    border: 1px solid var(--brass);
    background: var(--brass);
    color: var(--paper);
}
.nb-session-confirm-leave:disabled { opacity: 0.62; cursor: wait; }

/* The one outside page allowed after a deliberate departure. It does not turn
   Home into a place to browse; it is a receipt and one route back to Piero. */
.nb-session-interrupted-home {
    width: min(690px, 100%);
    margin: clamp(70px, 14vh, 150px) auto 0;
    padding: 42px 46px 38px;
    border-top: 3px solid var(--brass);
    border-bottom: 1px solid var(--hair-card);
    background: rgba(247, 243, 234, 0.82);
    box-shadow: var(--card-shadow);
}
.nb-session-interrupted-home h1 {
    font-size: clamp(38px, 6vw, 56px);
    line-height: 1.02;
}
.nb-session-interrupted-home > p {
    max-width: 55ch;
    margin: 18px 0 26px;
    font-family: var(--font-serif);
    font-size: 19px;
    line-height: 1.55;
    color: var(--ink-body);
}
.nb-session-interrupted-home > small {
    display: block;
    max-width: 62ch;
    margin-top: 22px;
    font-family: var(--font-ui);
    font-size: 12px;
    line-height: 1.55;
    color: var(--ink-2);
}

@media (max-width: 600px) {
    .nb-session-focusbar { gap: 14px; }
    .nb-session-focus-state { font-size: 9px; letter-spacing: 0.11em; }
    .nb-session-focus-action { font-size: 9px; }
    .nb-session-leave-sheet { padding: 28px 24px 24px; }
    .nb-session-leave-actions { flex-direction: column-reverse; }
    .nb-session-stay, .nb-session-confirm-leave { width: 100%; }
    .nb-session-interrupted-home { margin-top: 48px; padding: 34px 24px 30px; }
}

/* --- Page surface: full-width paper; the reading column sits inside
   .nb-page-col so the margin rule + ghost jots ride the full width. --- */
.nb-page { position: relative; background: transparent; }   /* the living map shows through */
.nb-page-col {                       /* the old .nb-page column, moved inward */
    max-width: var(--max-content);
    margin: 0 auto;
    /* 44px of head room, the measure the mockups are drawn at. */
    padding: 44px 24px 72px;
    min-height: 60vh;
    /* Positioned so the reading column paints ABOVE the background canvas.
       A canvas at z-index 0 outranks ordinary unpositioned text in the paint
       order, so without this the drawing would lie on top of the page. */
    position: relative;
    z-index: 1;
}
.nb-binding { display: none; }

/* --- The living-paper background canvas (design export, 2026-08-16) -------
   static/js/paper.js draws into this: ruled axes, a function plotting itself
   with its vertex ringed in red pen, and compass-and-straightedge
   constructions ruling themselves in out in the margins. It lies flat across
   the whole page surface behind the reading column.

   Three things keep it harmless. pointer-events:none — it can never take a
   click, so every link and button under it still works. z-index 0 with
   .nb-page-col at 1 — it is always the bottom layer of the page. And it is
   painted, never laid out: absolute positioning means it adds no height and
   cannot push anything around.

   The mount lives in templates/_site_base.html; read the comment there for
   how a page chooses its variant. The three funnel pages carry their own copy
   of the same mount because they do not extend the shell. */
.nb-paper-bg {
    position: absolute;
    top: 0; left: 0; right: 0;
    width: 100%;
    /* ONE SCREEN TALL, not one document tall. The export's canvas is
       `height:100%`, which is right for a mockup that is about a screenful
       long and wrong for us: our real pages run to 4,000–5,500px, and at
       full document height three things break at once. The drawing's own
       geometry is measured off the canvas — paper.js puts the axes at 0.54
       of the height and scatters constructions across it — so on a 5,500px
       page the curve is drawn a thousand pixels below the fold and most
       figures are somewhere nobody is looking. The backing store balloons
       (5,500px at a retina 2x is 32 million pixels, ~128MB, and past about
       8,000 CSS px the browser refuses the allocation outright). And
       paper.js's own "pause when it scrolls off screen" check can never
       fire, because a document-tall canvas is always partly on screen.

       So: the drawing lives on the first screenful of the sheet and scrolls
       away with it, which is also the scale the mockups were drawn at.
       max-height keeps it inside a page shorter than the viewport. Explicit
       top/left/right rather than `inset` — inset would also set bottom, and
       bottom plus top plus a height is over-constrained. */
    height: 100vh;
    max-height: 100%;
    z-index: 0;
    pointer-events: none;
}
/* Standalone hosts: the three funnel templates do not extend the shell, so
   they hang the canvas straight off <body class="nb-paper-host">. The shell
   can lift one known wrapper (.nb-page-col) above a z-index:0 canvas; a whole
   <body> has no such single wrapper, and forcing position/z-index onto every
   child would quietly clobber anything that positions itself. So here the
   canvas drops UNDER everything instead at z-index -1 — still above the
   page's cream-and-grid background, which the browser paints first as the
   page background, and below every scrap of content without touching any of
   it. Same picture, nothing else disturbed. */
.nb-paper-host { position: relative; }
.nb-paper-host > .nb-paper-bg { z-index: -1; }
/* --- Page atmosphere: the notebook's red margin rule + ghost pencil jots ---
   The rule is the vertical line ruled down a sheet of school paper — one
   hairline of red pen, 72px in, running the full height.

   It is ON EVERY PAGE (quality pass, 2026-08-16). It used to be scoped to Home
   and Dashboard, so the line appeared when you opened those two tabs and
   vanished again when you left — the sheet of paper changed identity as you
   moved around the product. The design system lists the margin rule as a
   system-wide rule, alongside the 96px margin column, so it is ruled on every
   page now.

   The overflow clip below did NOT follow it product-wide, and must not:
   `overflow: hidden` makes an element the scroll container for everything
   inside it, which would kill the sticky question rail on /practice/homework
   (.nb-hw-rail). It stays on the two pages that already had it, where it
   guards the ghost jots. The margin rule itself needs no clipping — it is an
   absolutely positioned hairline inside the page box, and every shell page was
   measured at 1440px with no horizontal overflow. --- */
body.home-page .nb-page, body.dash-page .nb-page { overflow: hidden; }
.nb-page::before {
    content: '';
    position: absolute; left: 72px; top: 0; bottom: 0;
    width: 1.5px;
    background: rgba(194, 64, 42, 0.22);
    pointer-events: none;
}
.nb-page-jot {
    position: absolute;
    font-family: var(--font-serif); font-style: italic;
    pointer-events: none; white-space: nowrap;
}
/* Blue pencil, the faintest thing on the page. */
.nb-page-jot-a { right: 6%; top: 64px;    font-size: 25px; color: rgba(43, 93, 168, 0.10); transform: rotate(2deg); }
.nb-page-jot-b { left: 4%;  bottom: 120px; font-size: 22px; color: rgba(43, 93, 168, 0.10); transform: rotate(-2.5deg); }
.nb-page-jot-c { right: 7%; top: 80px;    font-size: 24px; color: rgba(43, 93, 168, 0.10); transform: rotate(1.5deg); }

/* ============================================================
   THE LEDGER VOCABULARY  (design export, 2026-08-16)
   ============================================================
   The redesign's rule is "rules, not cards": a section hangs off one heavy
   rule and its rows divide with hairlines, instead of every group being
   parked in its own bordered box. A box now means one thing only — "this is
   a discrete artifact" (the appointment plate, the two Dashboard charts).

   These are the shared pieces every redesigned page builds from, so Home,
   Dashboard and Session all measure the same down the page. Page-specific
   composition still goes in that page's own <style> block.
   ============================================================ */

/* --- 1. The 96px margin column -----------------------------
   Every ledger, table and dated entry starts with the same 96px column, so
   dates, course names and section numbers stack in one straight line down
   the page no matter which section they belong to.

   Extend it by overriding grid-template-columns and KEEPING 96px first —
   e.g. a row with a tally and a flag on the right:
       .my-row { grid-template-columns: 96px minmax(0, 1fr) 148px 58px; }
   Override align-items too where a row wants centering instead of a shared
   baseline (bars and bar rows want center). */
.nb-margincol {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr);
    column-gap: 28px;
    row-gap: 0;
    align-items: baseline;
}

/* --- 2. The section rule -----------------------------------
   The heavy line a section hangs off. .nb-rule-top for a block that hangs
   BELOW its rule (a ledger under its eyebrow), .nb-rule for a block that
   closes with one (the masthead, above everything the page then reports).
   A line INSIDE a section — a table's column heads — wants 2b, not this. */
.nb-rule     { border-bottom: 1.5px solid var(--hair-rule); }
.nb-rule-top { border-top: 1.5px solid var(--hair-rule); }

/* --- 2b. The head rule (the middle weight) -----------------
   The export draws THREE line weights, not two, and this is the one in the
   middle: the same dark ink as the section rule but a thinner 1px, used where
   a line divides something INSIDE a section — a table's column heads from its
   rows, or the top figures of a panel from the detail under them. Reaching for
   the 1.5px section rule there says "a new section starts here", which is a
   louder claim than a column head is making. */
.nb-rule-head { border-bottom: 1px solid var(--hair-rule); }

/* --- 3. The row divider ------------------------------------
   The hairline between rows inside a section. Much lighter than the section
   rule: rows are the same kind of thing repeated, not a new structure. */
.nb-hairrow { border-bottom: 1px solid var(--hair-row); }

/* --- 4. The washed current row -----------------------------
   The one row that is happening now — the current grade, the session about
   to start. The wash bleeds 14px past the reading column on both sides so
   the row reads as marked by hand rather than as a chip sitting inside it.

   CONTRACT: a row that can carry .nb-current must set its own vertical
   padding with `padding-block`, never the `padding` shorthand. Page CSS
   loads after this file, so a shorthand would wipe the horizontal padding
   here and the wash would crop tight against the text. */
.nb-current {
    background: var(--brass-wash-row);
    margin-inline: -14px;
    padding-inline: 14px;
}

/* --- 5. The letter home ------------------------------------
   A letter looks like a letter: a letterhead line naming who wrote to whom
   with the sent time set right, the body in reading serif, and an italic
   red-pen signature. It is set narrow (62ch) because it is prose, not data.
   The letterhead hairline is heavier than a row divider and lighter than a
   section rule — a letter is an object inside an entry, not a new section. */
.nb-letter { margin: 24px 0 0; max-width: 62ch; }
.nb-letter-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 0 0 7px;
    border-bottom: 1px solid rgba(34, 48, 58, 0.32);
}
.nb-letter-label {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 9.5px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--cream);
}
.nb-letter-time {
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-3);
    white-space: nowrap;
}
.nb-letter-body {
    font-family: var(--font-serif);
    font-size: 16px;
    line-height: 1.62;
    color: var(--cream);
    margin: 13px 0 0;
    text-wrap: pretty;
}
.nb-letter-sign {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 16px;
    line-height: 1.6;
    color: var(--brass);
    margin: 11px 0 0;
}

/* --- 6. Mono labels and figures ----------------------------
   The small print of the system: column heads, dates, tallies. Uppercase
   mono, wide tracking, 9.5–11px. .nb-mono-label is the quiet label; figures
   are ballpoint because ballpoint is what the data is written in. */
.nb-mono-label {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 9.5px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-3);
}
.nb-mono-fig {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ballpoint);
}

/* --- 7. The dated entry's date -----------------------------
   A ledger entry stands its date in the 96px margin column: the weekday as a
   quiet mono label, the day and a three-letter month big in red pen, the clock
   underneath. Home's record and the Dashboard's latest sitting are the same
   object, so they share these classes and the same server-side date split
   (app.py's `ledger_date` filter) — they were drifting apart within a day of
   the redesign landing, one printing "15 Aug" and the other "August 15"
   (quality pass, 2026-08-16). */
.nb-entry-date {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-top: 5px;
}
.nb-entry-day {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 19px;
    line-height: 1.1;
    letter-spacing: -0.01em;
    color: var(--brass);
    /* If the server ever falls back to a raw timestamp (a date it could not
       parse), it wraps inside the margin column instead of running across the
       entry. */
    overflow-wrap: anywhere;
}
.nb-entry-time {
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-top: 3px;
}

/* --- Headings --------------------------------------------- */
.nb-h1 {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 48px;
    line-height: 1.05;
    letter-spacing: -0.008em;
    color: var(--cream);
    margin: 0 0 40px;
}
/* Emphasis inside a heading (the student's name) is red-pen italic serif. */
.nb-h1 em, .nb-h2 em {
    font-style: italic;
    color: var(--brass);
}
.nb-h1-sub {
    font-family: var(--font-ui);
    font-weight: 400;
    font-size: 14px;
    color: var(--ink-2);
    margin: -28px 0 36px;
    max-width: 56ch;
    line-height: 1.5;
}
.nb-h2 {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 40px;
    line-height: 1.08;
    letter-spacing: 0;
    color: var(--cream);
    margin: 0 0 10px;
}
.nb-h3 {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 22px;
    color: var(--cream);
    margin: 0 0 10px;
}

/* --- Eyebrow / section label -------------------------------
   The page's section markers are numbered mono eyebrows in red pen —
   "01 · NEXT SESSION" — the whole label one weight, one size, one color.
   (The date eyebrow above the greeting is the quiet exception: ink, not red.) */
.nb-eyebrow {
    font-family: var(--font-mono);
    font-weight: 400;
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin: 0 0 14px;
}
.nb-section-label {
    display: flex;
    align-items: baseline;
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--brass);
    margin: 44px 0 16px;
}
.nb-section-num {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 11px;
    letter-spacing: 0.2em;
    color: var(--brass);
}
.nb-section-sep { color: var(--brass); margin: 0 6px; }

/* --- Buttons ----------------------------------------------- */
/* Primary: a flat red-pen block, paper-colored mono type, nothing else —
   the engraved inner hairline the brass button carried is gone. */
.nb-featured-cta {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    background: var(--brass);
    color: var(--board);
    padding: 14px 26px;
    border: none;
    border-radius: 0;
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    cursor: pointer;
    box-shadow: 0 2px 0 rgba(122, 38, 24, 0.18);
    transition: filter var(--t-fast) ease, transform var(--t-fast) ease,
                box-shadow var(--t-fast) ease;
}
.nb-featured-cta:hover {
    filter: brightness(1.05);
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(122, 38, 24, 0.16);
}
.nb-featured-cta:active { transform: translateY(0); box-shadow: none; }
.nb-featured-cta:focus-visible { outline: 2px solid var(--ballpoint); outline-offset: 3px; }
.nb-featured-cta--locked {
    background: rgba(34, 48, 58, 0.11);
    color: var(--ink-3);
    cursor: not-allowed;
    filter: none;
}
.nb-featured-cta--locked:hover { filter: none; }
.nb-featured-cta--locked:hover { transform: none; box-shadow: none; }
/* Ghost: hairline border, quiet ink. */
.nb-button-secondary {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--hair-card);
    border-radius: var(--r-btn);
    padding: 8px 14px;
    font-family: var(--font-ui);
    font-weight: 500;
    font-size: 13px;
    color: var(--ink-2);
    text-decoration: none;
    white-space: nowrap;
    background: transparent;
    cursor: pointer;
    transition: color var(--t-fast) ease, border-color var(--t-fast) ease;
}
.nb-button-secondary:hover { color: var(--ink-body); border-color: var(--cream); }

/* --- Home: next-session row -------------------------------- */
.nb-nextsession {
    display: flex;
    align-items: center;
    gap: 22px;
    padding: 26px 28px;
    border: 1px solid var(--hair-card);
    border-radius: 2px;
    background: var(--card);
    box-shadow: var(--card-shadow);
    margin: 8px 0 12px;
}
.nb-nextsession-body { flex: 1; }
.nb-nextsession-actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}
.nb-nextsession-title {
    font-family: var(--font-serif);
    font-size: 22px;
    font-weight: 500;
    letter-spacing: 0;
    color: var(--cream);
    margin: 0 0 5px;
}
.nb-nextsession-sub {
    font-family: var(--font-ui);
    font-size: 13.5px;
    color: var(--ink-2);
    margin: 0;
    line-height: 1.5;
}

/* --- Home: where you stand --------------------------------- */
.nb-standing { margin: 8px 0 12px; }
.nb-standing-level {
    font-family: var(--font-serif);
    font-size: 22px;
    font-weight: 500;
    letter-spacing: 0;
    color: var(--cream);
    margin: 0 0 20px;
}
/* The level itself is the emphasized word: red-pen italic serif, no rule
   under it (the underline was an Evening Board device). */
.nb-standing-level em {
    font-style: italic;
    color: var(--brass);
}
/* Level headline: the progress ring beside the grade-level line + caption. */
.nb-standing-headline {
    display: flex;
    align-items: center;
    gap: 16px;
    margin: 0 0 22px;
}
.nb-standing-ring { flex: none; display: block; }
/* The ring reads a percentage — data, so it's ballpoint. */
.nb-standing-ring-pct {
    font-family: var(--font-mono);
    font-size: 12.5px;
    fill: var(--ballpoint);
}
.nb-standing-headtext { display: flex; flex-direction: column; gap: 3px; }
.nb-standing-headline .nb-standing-level { margin: 0; }
.nb-standing-caption {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--ink-3);
    margin: 0;
    line-height: 1.4;
}
.nb-band-rows { display: flex; flex-direction: column; gap: 13px; margin: 0 0 20px; }
.nb-band-row { display: flex; align-items: center; gap: 16px; }
.nb-band-name {
    font-family: var(--font-ui);
    font-size: 12px;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink-2);
    width: 96px;
    flex: none;
    text-align: right;
}
/* Progress bars are DATA: solid ballpoint for what's proven, the dim
   ballpoint for what's started but not solid, over a faint ink track. */
.nb-band-bar {
    flex: 1;
    height: 5px;
    border: none;
    background: rgba(34, 48, 58, 0.09);
    display: flex;
    overflow: hidden;
}
.nb-band-fill { background: var(--ballpoint); height: 100%; }
.nb-band-working { background: var(--ballpoint-dim); height: 100%; }
.nb-band-pct {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ballpoint);
    flex: none;
    width: 38px;
    text-align: right;
}
/* "Next up" is the kicker — a red-pen margin note against a red wash. */
.nb-standing-line {
    font-family: var(--font-ui);
    font-size: 13.5px;
    color: var(--ink-body);
    margin: 16px 0 4px;
    line-height: 1.5;
    background: var(--brass-wash);
    border-left: 3px solid var(--brass);
    padding: 12px 16px;
}
.nb-standing-line b { font-weight: 600; color: var(--cream); }
.nb-standing-flash {
    font-family: var(--font-ui);
    font-size: 13px;
    color: var(--ballpoint);
    background: var(--ballpoint-wash);
    border: 1px solid var(--ballpoint-dim);
    padding: 8px 12px;
    margin: 14px 0 0;
    border-radius: var(--r-chip);
}

/* --- Home: last session + messages, side by side ----------- */
.nb-home-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px;
    margin-top: 44px;
}
.nb-home-grid .nb-section-label { margin-top: 0; }
@media (max-width: 900px) { .nb-home-grid { grid-template-columns: 1fr; } }

.nb-lastsession { border: none; padding: 0; margin: 0; }
.nb-lastsession-body {
    font-family: var(--font-serif);
    font-size: 16.5px;
    color: var(--ink-body);
    line-height: 1.7;
    margin: 0 0 12px;
}
/* The counts are data — mono ballpoint. */
.nb-lastsession-counts {
    font-family: var(--font-mono);
    font-size: 11.5px;
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--ballpoint);
    margin: 0;
}

/* --- Messages home: white cards — what LEAVES the page ------- */
.nb-message-card {
    background: var(--paper);
    color: var(--paper-ink);
    border: 1px solid rgba(34, 48, 58, 0.14);
    border-radius: 2px;
    padding: 17px 19px;
    margin: 0 0 12px;
}
.nb-message-meta {
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.04em;
    color: var(--paper-meta);
    margin-bottom: 6px;
    text-transform: none;
}
.nb-message-bubble {
    background: transparent;
    border: none;
    padding: 0;
    font-family: var(--font-serif);
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--paper-ink);
}
.nb-message-status {
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--paper-meta);
    text-align: right;
    margin-top: 6px;
}

/* --- Benchmark CTA strip (no placement yet) ----------------- */
.nb-placement-strip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    border: 1px dashed var(--hair-card-2);
    border-radius: var(--r-card);
    padding: 20px 24px;
    margin: 0 0 14px;
    text-decoration: none;
    color: inherit;
}
.nb-placement-strip:hover { background: rgba(34, 48, 58, 0.03); }
.nb-placement-body { display: flex; flex-direction: column; gap: 4px; }
.nb-placement-title { font-family: var(--font-serif); font-weight: 500; font-size: 19px; color: var(--cream); }
.nb-placement-sub { font-family: var(--font-ui); font-size: 13.5px; color: var(--ink-2); line-height: 1.5; max-width: 56ch; }

/* --- Progress page: placement card + history rows ----------- */
.nb-placement-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    border: 1px solid var(--hair-card);
    border-radius: var(--r-card);
    padding: 20px 24px;
    margin: 0 0 12px;
}
.nb-placement-card-body { display: flex; flex-direction: column; gap: 5px; }
.nb-placement-level { font-family: var(--font-serif); font-weight: 500; font-size: 22px; color: var(--cream); }
.nb-placement-detail {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.1em;
    color: var(--ink-3);
    text-transform: uppercase;
}

.nb-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 6px;
    border-bottom: 1px solid var(--hair-row);
    color: var(--ink-body);
    cursor: pointer;
    transition: background var(--t-fast) ease;
}
.nb-row:hover { background: rgba(34, 48, 58, 0.03); }
.nb-row-num {
    width: 28px;
    height: 28px;
    border: 1px solid var(--hair-card);
    border-radius: var(--r-chip);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-2);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}
.nb-row-title {
    flex: 1;
    font-family: var(--font-ui);
    font-size: 15px;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--ink-body);
}
.nb-row-meta {
    color: var(--ink-3);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.04em;
    margin-right: 4px;
    white-space: nowrap;
}
.nb-row-arrow { color: var(--ink-3); font-family: var(--font-ui); font-size: 14px; }

/* Mastery dots on progress rows — the Memory tones. */
.nb-mastery-row { align-items: center; }
.nb-mastery-state {
    width: 10px;
    height: 10px;
    border: 1px solid var(--hair-card-2);
    border-radius: 2px;
    flex: 0 0 auto;
}
.nb-mastery-state.nb-mastery-done    { background: rgba(43, 93, 168, 0.2); border-color: var(--solid); }
.nb-mastery-state.nb-mastery-current { background: var(--brass-wash-2); border-color: var(--brass); }
.nb-mastery-state.nb-mastery-todo    { background: transparent; border-style: dashed; border-color: rgba(34, 48, 58, 0.3); }
.nb-row-locked { opacity: 0.45; pointer-events: none; }

/* --- Empty state — serif italic, quiet ---------------------- */
.nb-empty-note {
    font-family: var(--font-serif);
    font-style: italic;
    color: var(--ink-2);
    font-size: 16px;
    margin: 8px 0;
    line-height: 1.5;
}

/* --- Lessons (4a): course header + change-course ------------ */
.nb-subject-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0 0 40px;
}
.nb-subject-row .nb-h2 { margin: 0; }
.nb-dropdown { position: relative; display: inline-flex; align-items: center; }
.nb-dropdown-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: 1px solid var(--hair-card);
    border-radius: var(--r-btn);
    color: var(--ink-2);
    font-family: var(--font-ui);
    font-size: 13px;
    cursor: pointer;
    padding: 8px 14px;
    line-height: 1;
    transform: none;
    transition: color var(--t-fast) ease, border-color var(--t-fast) ease;
}
.nb-dropdown-toggle:hover { color: var(--ink-body); border-color: var(--cream); }
.nb-dropdown-menu {
    position: absolute;
    top: 100%;
    right: 0;
    left: auto;
    margin-top: 8px;
    background: var(--paper);
    border: 1px solid var(--hair-card);
    border-radius: var(--r-card);
    padding: 6px;
    box-shadow: 0 12px 30px rgba(34, 48, 58, 0.14);
    z-index: 10;
    min-width: 220px;
    display: none;
}
.nb-dropdown.open .nb-dropdown-menu { display: block; }
.nb-dropdown-menu a {
    display: block;
    padding: 10px 14px;
    color: var(--ink-body);
    font-family: var(--font-ui);
    font-size: 14px;
    font-weight: 400;
    border-radius: var(--r-chip);
    transition: background 100ms ease;
}
.nb-dropdown-menu a:hover { background: rgba(34, 48, 58, 0.05); }
.nb-dropdown-menu a.active { color: var(--brass); }
.nb-dropdown-menu a.disabled { color: var(--ink-3); cursor: not-allowed; font-style: italic; }
.nb-dropdown-menu a.disabled:hover { background: transparent; }
.nb-view-link {
    display: inline-block;
    font-family: var(--font-mono);
    color: var(--ink-3);
    text-decoration: none;
    margin: 4px 0 32px;
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.nb-view-link:hover { color: var(--ink-body); }

/* --- Lessons (4a): the unit ledger --------------------------- */
.nb-chapter { margin: 40px 0 0; padding-bottom: 4px; }
.nb-chapter:first-of-type { margin-top: 0; }
.nb-chapter-header {
    display: flex;
    align-items: baseline;
    gap: 14px;
    margin-bottom: 6px;
    padding-bottom: 0;
    border-bottom: none;
}
.nb-unit-label {
    color: var(--brass);
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 11px;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    min-width: 0;
}
.nb-chapter-title {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 23px;
    letter-spacing: 0;
    color: var(--cream);
    margin: 0;
    flex: 1;
}
.nb-chapter-count {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-3);
    white-space: nowrap;
}
.nb-lesson-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--hair-section); }
.nb-lesson-list li { margin: 0; padding: 0; }
.nb-lesson-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 6px;
    border-bottom: 1px solid var(--hair-row);
    color: var(--ink-body);
    cursor: pointer;
    transition: background var(--t-fast) ease;
}
.nb-lesson-row:hover { background: rgba(34, 48, 58, 0.03); }
/* A playable row carries two buttons — "lesson" and "refresher" — instead of
   the arrow (founder, 2026-08-12: the arrow + lone chip read as confusing).
   The title is plain text; the buttons are the only links. */
.nb-lesson-row-wrap {
    display: flex;
    align-items: center;
    border-bottom: 1px solid var(--hair-row);
}
.nb-lesson-row-wrap .nb-lesson-row { flex: 1; border-bottom: none; }
.nb-lesson-btn {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-4);
    border: 1px solid var(--hair-row);
    border-radius: 3px;
    padding: 3px 8px;
    margin-left: 10px;
    white-space: nowrap;
    transition: color var(--t-fast) ease, border-color var(--t-fast) ease;
}
.nb-lesson-btn:hover { color: var(--ink-body); border-color: var(--ink-4); }
.nb-lesson-icon {
    color: var(--ink-4);
    font-family: var(--font-ui);
    font-size: 12px;
    width: 16px;
    display: inline-flex;
    justify-content: center;
}
.nb-lesson-title {
    flex: 1;
    font-family: var(--font-ui);
    font-size: 15px;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--ink-2);
}
.nb-lesson-arrow { color: var(--ink-4); font-size: 13px; }
/* Row states (4a): mastered ✓ brass, in-progress ● brass on a brass wash,
   untouched ○ faint. The index doesn't carry mastery data yet — these light
   up as soon as rows are tagged. */
.nb-lesson-row.mastered .nb-lesson-icon { color: var(--brass); }
.nb-lesson-row.mastered .nb-lesson-title { color: var(--ink-body); }
.nb-lesson-row.current {
    background: var(--brass-wash);
    margin: 0 -14px;
    padding-left: 20px;
    padding-right: 20px;
}
.nb-lesson-row.current .nb-lesson-icon { color: var(--brass); }
.nb-lesson-row.current .nb-lesson-title { color: var(--cream); font-weight: 500; }
.nb-lesson-row.current .nb-lesson-arrow {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.1em;
    color: var(--brass);
}

/* --- Question-slot rows (Questions tab + Experimental review) --
   A concept row carrying four compact Q1-Q4 tokens instead of one link.
   The row is a div (it holds four links), so no pointer; the slots are the
   click targets. Present = brass, hairline, tappable; missing = dimmed
   dashed placeholder, so every concept shows four. */
.nb-q-row { cursor: default; }
.nb-q-concept { color: var(--ink-body); }
.nb-q-slots { display: inline-flex; gap: 8px; flex-shrink: 0; }
.nb-q-slot {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em;
    min-width: 30px; padding: 4px 8px; text-align: center;
    border: 1px solid var(--brass-dim); border-radius: 4px;
    color: var(--brass); text-decoration: none;
    transition: background var(--t-fast) ease, border-color var(--t-fast) ease;
}
.nb-q-slot:hover { background: var(--brass-wash-2); border-color: var(--brass); }
.nb-q-slot-empty {
    color: var(--ink-4); border-color: var(--hair-row);
    border-style: dashed; cursor: default;
}
.nb-q-slot-empty:hover { background: none; border-color: var(--hair-row); }

/* --- Course outline back link -------------------------------- */
.nb-back-link {
    display: inline-block;
    font-family: var(--font-mono);
    color: var(--ink-3);
    font-size: 12px;
    letter-spacing: 0.06em;
    margin: 0 0 24px;
    transition: color var(--t-fast) ease;
}
.nb-back-link:hover { color: var(--ink-body); }

/* --- Journal entries (legacy page, kept in-system) ----------- */
.nb-journal-header { text-align: left; margin: 0 0 48px; }
.nb-journal-header .nb-eyebrow { margin-bottom: 12px; }
.nb-journal-entry {
    padding: 24px 0 28px;
    border-bottom: 1px solid var(--hair-row);
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px 24px;
    align-items: baseline;
}
.nb-journal-entry:first-of-type { border-top: 1px solid var(--hair-section); padding-top: 28px; }
.nb-journal-entry-title {
    color: var(--cream);
    font-family: var(--font-serif);
    font-size: 20px;
    font-weight: 500;
    margin-right: 12px;
}
.nb-journal-entry-date {
    display: inline;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.04em;
    color: var(--ink-3);
}
.nb-journal-entry-retake {
    grid-column: 2;
    grid-row: 1;
    align-self: start;
    font-family: var(--font-mono);
    color: var(--ink-3);
    font-size: 11px;
    letter-spacing: 0.06em;
}
.nb-journal-entry-retake:hover { color: var(--ink-body); }
.nb-journal-entry-body {
    grid-column: 1 / -1;
    font-family: var(--font-ui);
    color: var(--ink-2);
    font-size: 14.5px;
    line-height: 1.55;
    margin-top: 4px;
}

/* --- Tutor header (avatar + identity, where still used) ------ */
.nb-tutor-header { display: flex; align-items: center; gap: 14px; margin: 0 0 26px; }
.nb-tutor-avatar {
    width: 46px;
    height: 46px;
    border: 1px solid var(--hair-card-2);
    border-radius: 50%;
    background: var(--brass-wash-2);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 20px;
    color: var(--brass);
}
.nb-tutor-id { display: flex; flex-direction: column; gap: 2px; }
.nb-tutor-name { font-family: var(--font-serif); font-weight: 500; font-size: 17px; color: var(--cream); }
.nb-tutor-role {
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    color: var(--ink-3);
    text-transform: uppercase;
}

/* --- Legacy featured card / unit rows (still referenced) ----- */
.nb-featured {
    border: 1px solid var(--hair-card);
    border-radius: var(--r-card);
    background: transparent;
    padding: 24px 28px;
    margin: 8px 0 12px;
    display: flex;
    align-items: center;
    gap: 24px;
    transition: background var(--t-fast) ease;
    cursor: pointer;
}
.nb-featured:hover { background: rgba(34, 48, 58, 0.03); }
.nb-featured-time {
    border: 1px solid var(--hair-card);
    border-radius: var(--r-chip);
    background: var(--brass-wash-2);
    padding: 12px 14px;
    text-align: center;
    color: var(--cream);
    font-family: var(--font-ui);
    min-width: 72px;
}
.nb-featured-time .num { font-size: 26px; font-weight: 700; line-height: 1; display: block; }
.nb-featured-time .unit {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    margin-top: 4px;
    color: var(--ink-2);
}
.nb-featured-body { flex: 1; }
.nb-featured-title { font-family: var(--font-serif); font-size: 21px; font-weight: 500; color: var(--cream); margin: 0 0 4px; }
.nb-featured-sub { font-family: var(--font-ui); font-size: 13.5px; color: var(--ink-2); margin: 0 0 8px; }
.nb-featured-tag { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; color: var(--ink-3); }

.nb-unit-row {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 16px 6px;
    border-bottom: 1px solid var(--hair-row);
    cursor: pointer;
    transition: background var(--t-fast) ease;
}
.nb-unit-row:hover { background: rgba(34, 48, 58, 0.03); }
.nb-unit-title { flex: 1; font-family: var(--font-ui); font-size: 15px; font-weight: 500; color: var(--ink-body); }
.nb-unit-arrow { color: var(--ink-3); font-size: 12px; }
.nb-unit-row.disabled { cursor: not-allowed; }
.nb-unit-row.disabled:hover { background: transparent; }
.nb-unit-row.disabled .nb-unit-title { color: var(--ink-3); }
.nb-preview-pane { padding-top: 12px; }
.nb-preview-pane-empty { font-family: var(--font-serif); font-style: italic; color: var(--ink-2); font-size: 16px; }
.nb-lessons-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 56px;
    margin-top: 12px;
}
.nb-experimental { margin-top: 28px; }
.nb-experimental .nb-h3 {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 20px;
    color: var(--cream);
    margin: 0 0 10px;
}

/* --- Dashboard (the parent's in-depth view) -----------------
   The deeper view behind Home, on real data (founder,
   2026-07-29). Hairlined cards, brass for what moved, the
   mastery tones for direction. Charts are inline SVG drawn from
   coordinates the server computed — no chart library, no build
   step. Reuses the existing tokens throughout. */
.nb-dash-card {
    border: 1px solid var(--hair-card);
    border-radius: 2px;
    padding: 24px 28px;
    margin: 8px 0 12px;
    background: var(--card);
    box-shadow: var(--card-shadow);
}
.nb-dash-overview {
    display: grid;
    grid-template-columns: 1.15fr 1fr 1fr;
    margin: 8px 0 6px;
    border: 1px solid var(--hair-card);
    border-top: 2px solid var(--brass);
    background: var(--card);
    box-shadow: var(--card-shadow);
}
.nb-dash-overview-item {
    min-width: 0;
    min-height: 142px;
    padding: 22px 24px;
    display: flex;
    flex-direction: column;
    border-left: 1px solid var(--hair-row);
}
.nb-dash-overview-item:first-child { border-left: none; }
.nb-dash-overview-primary { background: rgba(43, 93, 168, 0.035); }
.nb-dash-overview-label,
.nb-dash-kicker {
    font-family: var(--font-mono);
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-3);
}
.nb-dash-overview-value {
    margin-top: 11px;
    font-family: var(--font-serif);
    font-size: 34px;
    font-weight: 500;
    line-height: 1.05;
    color: var(--cream);
}
.nb-dash-overview-topic {
    margin-top: 12px;
    font-family: var(--font-serif);
    font-size: 19px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--cream);
}
.nb-dash-overview-meta {
    margin-top: 8px;
    font-family: var(--font-ui);
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink-3);
}
.nb-dash-overview-track {
    height: 3px;
    margin-top: auto;
    background: var(--hair-row);
    overflow: hidden;
}
.nb-dash-overview-track i { display: block; height: 100%; background: var(--ballpoint); }
.nb-dash-section-label {
    margin: 38px 0 12px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--brass);
}
.nb-dash-card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
    margin-bottom: 22px;
}
.nb-dash-card-title {
    margin: 6px 0 0;
    font-family: var(--font-serif);
    font-size: 24px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--cream);
}
.nb-dash-band-rows { margin-bottom: 0; }
.nb-dash-divider { height: 1px; margin: 26px 0 20px; background: var(--hair-card); }
.nb-dash-baseline {
    margin: 22px 0 0;
    padding: 12px 14px;
    border-left: 2px solid var(--ballpoint-dim);
    background: var(--ballpoint-wash);
    font-family: var(--font-ui);
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--ink-2);
}
.nb-dash-plan-card {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
    gap: 0;
}
.nb-dash-plan-main { padding-right: 30px; }
.nb-dash-plan-focus { padding-left: 30px; border-left: 1px solid var(--hair-card); }
.nb-dash-plan-focus .nb-dash-row { align-items: flex-start; flex-direction: column; gap: 4px; }
.nb-dash-plan-focus .nb-dash-row-meta { text-align: left; }
.nb-dash-plan-note { grid-column: 1 / -1; }
.nb-dash-inline-empty {
    margin: 14px 0 0;
    font-family: var(--font-serif);
    font-size: 15px;
    font-style: italic;
    color: var(--ink-3);
}
.nb-dash-flow-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 22px;
}
.nb-dash-flow-grid .nb-dash-card { margin: 0; }
.nb-dash-evidence-card { display: flex; flex-direction: column; min-height: 190px; }
.nb-dash-evidence-card > .nb-dash-note { margin-top: auto; padding-top: 18px; }
.nb-dash-participation-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(300px, .65fr);
    gap: 22px;
    align-items: stretch;
}
.nb-dash-participation-grid .nb-dash-card { margin: 0; }
.nb-participation-side {
    display: flex;
    flex-direction: column;
    gap: 22px;
    min-width: 0;
}
.nb-accountability-card { display: flex; flex-direction: column; }
.nb-accountability-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-top: 16px;
}
.nb-accountability-head > div { display: flex; flex-direction: column; gap: 7px; }
.nb-accountability-value {
    font-family: var(--font-serif);
    font-size: 42px;
    font-weight: 500;
    line-height: .9;
    color: var(--cream);
}
.nb-follow-chip {
    display: inline-flex;
    align-items: center;
    min-height: 25px;
    padding: 4px 9px;
    border: 1px solid var(--hair-card-2);
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: 8.5px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink-2);
    white-space: nowrap;
}
.nb-follow-chip.is-completed {
    border-color: rgba(43, 93, 168, .34);
    background: var(--ballpoint-wash);
    color: var(--ballpoint);
}
.nb-follow-chip.is-interrupted {
    border-color: rgba(194, 64, 42, .35);
    background: rgba(194, 64, 42, .06);
    color: var(--brass);
}
.nb-accountability-list {
    margin: 20px 0 0;
    padding: 0;
}
.nb-accountability-list > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 9px 0;
    border-top: 1px solid var(--hair-row);
}
.nb-accountability-list dt,
.nb-accountability-list dd { margin: 0; }
.nb-accountability-list dt {
    font-family: var(--font-ui);
    font-size: 12.5px;
    color: var(--ink-2);
}
.nb-accountability-list dd {
    font-family: var(--font-mono);
    font-size: 9.5px;
    color: var(--cream);
    text-align: right;
}
.nb-accountability-card > .nb-dash-note { margin-top: auto; padding-top: 16px; }
.nb-engagement-card { display: flex; flex-direction: column; min-width: 0; }
.nb-engagement-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 24px;
}
.nb-engagement-scores {
    flex: none;
    display: grid;
    grid-template-columns: repeat(2, minmax(112px, auto));
    gap: 0;
}
.nb-engagement-score {
    min-width: 128px;
    padding: 0 18px;
    border-left: 1px solid var(--hair-row);
    text-align: right;
}
.nb-engagement-score:first-child { border-left: none; }
.nb-engagement-score-label {
    display: block;
    margin-bottom: 10px;
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ink-3);
}
.nb-engagement-score-value {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
}
.nb-engagement-score-value strong {
    font-family: var(--font-serif);
    font-size: 42px;
    font-weight: 500;
    line-height: .9;
    color: var(--cream);
}
.nb-engagement-score-value i {
    margin-left: 3px;
    font-family: var(--font-mono);
    font-size: 11px;
    font-style: normal;
    color: var(--ink-3);
}
.nb-engagement-score small {
    display: block;
    margin-top: 7px;
    font-family: var(--font-mono);
    font-size: 8.5px;
    font-weight: 400;
    letter-spacing: .03em;
    color: var(--ink-3);
}
.nb-engagement-score.is-empty .nb-engagement-score-value strong { color: var(--ink-3); }
.nb-engagement-reading {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-top: 24px;
    font-family: var(--font-ui);
}
.nb-engagement-reading strong { color: var(--cream); font-size: 15px; }
.nb-engagement-reading span { color: var(--ink-2); font-size: 13px; line-height: 1.45; }
.nb-engagement-meter { margin-top: 18px; }
.nb-engagement-meter-track {
    position: relative;
    display: block;
    height: 6px;
    border-radius: 999px;
    background: linear-gradient(90deg,
        rgba(194, 64, 42, .42) 0 50%,
        rgba(43, 93, 168, .24) 50% 80%,
        rgba(43, 93, 168, .72) 80% 100%);
}
.nb-engagement-meter-track i {
    position: absolute;
    top: 50%;
    width: 13px;
    height: 13px;
    border: 2px solid var(--board);
    border-radius: 50%;
    background: var(--cream);
    box-shadow: 0 0 0 1px rgba(34, 48, 58, .3);
    transform: translate(-50%, -50%);
}
.nb-engagement-meter-labels {
    display: grid;
    grid-template-columns: 1fr .6fr .4fr;
    gap: 8px;
    margin-top: 8px;
    font-family: var(--font-mono);
    font-size: 8.5px;
    letter-spacing: .04em;
    color: var(--ink-3);
}
.nb-engagement-meter-labels span:nth-child(2) { text-align: center; }
.nb-engagement-meter-labels span:last-child { text-align: right; }
.nb-engagement-waiting {
    max-width: 58ch;
    margin: 24px 0 0;
    padding: 13px 15px;
    border-left: 2px solid var(--ballpoint-dim);
    background: var(--ballpoint-wash);
    font-family: var(--font-ui);
    font-size: 13px;
    line-height: 1.55;
    color: var(--ink-2);
}
.nb-engagement-card > .nb-dash-note { margin-top: auto; padding-top: 20px; }
.nb-dash-session-copy {
    margin: 16px 0 0;
    max-width: 64ch;
    font-family: var(--font-serif);
    font-size: 17px;
    line-height: 1.6;
    color: var(--ink-body);
}
.nb-dash-strength-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 32px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.nb-dash-strength-grid li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 18px;
    padding: 12px 0;
    border-top: 1px solid var(--hair-row);
}
.nb-dash-strength-grid li:nth-child(-n + 2) { border-top: none; }
.nb-dash-stats { display: flex; gap: 44px; flex-wrap: wrap; }
.nb-dash-stat { display: flex; flex-direction: column; gap: 7px; }
.nb-dash-stat-value {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 32px;
    line-height: 1;
    color: var(--cream);
}
/* The stat label sits under its figure in quiet lowercase mono. */
.nb-dash-stat-label {
    font-family: var(--font-mono);
    font-weight: 400;
    font-size: 10.5px;
    letter-spacing: 0.08em;
    text-transform: none;
    color: var(--ink-3);
    white-space: nowrap;
}
.nb-dash-note {
    font-family: var(--font-ui);
    font-size: 13px;
    color: var(--ink-2);
    line-height: 1.5;
    margin: 20px 0 0;
}
/* The "3/4" denominator rides small beside its figure. */
.nb-dash-stat-of { font-size: 20px; color: var(--ink-3); }

/* Two cards abreast (consistency + accuracy, strengths + focus). The columns
   stretch so paired cards share a bottom edge — a ragged pair reads as broken. */
.nb-dash-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 34px;
    align-items: stretch;
}
.nb-dash-grid > div { min-width: 0; display: flex; flex-direction: column; }
.nb-dash-grid > div > .nb-dash-card { flex: 1; display: flex; flex-direction: column; }
/* The closing note settles on the card's floor, so the stretched card reads as
   composed rather than as a figure with a hole under it. */
.nb-dash-grid > div > .nb-dash-card > .nb-dash-note { margin-top: auto; padding-top: 20px; }

/* Hero figure + its delta chip, on one baseline. */
.nb-dash-hero {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.nb-dash-hero-figure { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.nb-dash-hero-value {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 52px;
    line-height: 1;
    color: var(--cream);
}

/* Delta chip — a teacher's mark: the number circled by hand in red pen, the
   oval sitting very slightly off-square on the page. What moved UP is the red
   circle; what moved down or held flat is circled in plain ink instead, so the
   red stays reserved for the thing worth pointing at. */
.nb-chip {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    padding: 4px 11px;
    border-radius: 999px;
    border: 1.2px solid var(--hair-card-2);
    color: var(--ink-2);
    background: transparent;
    transform: rotate(-2deg);
}
.nb-chip-up   { color: var(--brass); border-color: rgba(194, 64, 42, 0.55); background: transparent; }
.nb-chip-down { color: var(--ink-2); border-color: rgba(34, 48, 58, 0.45);  background: transparent; }
.nb-chip-sm   { padding: 3px 9px; font-size: 9.5px; letter-spacing: 0.06em; }

/* Trajectory chart — inline SVG on server-computed coordinates. The SVG holds
   only lines and fills and is stretched to its box (preserveAspectRatio="none");
   the path is all horizontal/vertical segments, so a non-uniform scale leaves it
   exact, and non-scaling-stroke keeps every stroke a true 1-2px. Text and the end
   dot are HTML, positioned by percent — nothing scales itself illegible. */
.nb-chart-wrap { display: flex; gap: 8px; margin: 22px 0 0; }
.nb-chart-yaxis {
    position: relative;
    width: 26px;
    flex: none;
    height: 150px;
    font-family: var(--font-mono);
    font-size: 9.5px;
    color: var(--ink-3);
}
.nb-chart-yaxis span { position: absolute; right: 0; transform: translateY(-50%); }
/* Grade-ladder axis: the rungs are named grades, not numbers, so the column has
   to hold "Geometry" without wrapping. */
.nb-chart-yaxis-grade { width: 48px; }
.nb-chart-plot { position: relative; flex: 1; min-width: 0; }
.nb-chart { display: block; width: 100%; height: 150px; }
.nb-chart-grid { stroke: var(--hair-row); stroke-width: 1; vector-effect: non-scaling-stroke; }
/* A rung is a GRADE BOUNDARY — the line stepping across one is the whole point
   of the chart, so it reads heavier than an ordinary gridline. */
.nb-chart-rung { stroke: var(--hair-card); stroke-width: 1.5; }
/* The line and its fill are the measurement: blue ballpoint. */
.nb-chart-area { fill: var(--ballpoint-wash); stroke: none; }
.nb-chart-line {
    fill: none;
    stroke: var(--ballpoint);
    stroke-width: 2;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}
/* The placement date is a teacher's mark ON the measurement — red, dashed. */
.nb-chart-mark { stroke: rgba(194, 64, 42, 0.5); stroke-width: 1.5; stroke-dasharray: 3 4; vector-effect: non-scaling-stroke; }
.nb-chart-dot {
    position: absolute;
    width: 7px; height: 7px;
    margin: -3.5px 0 0 -3.5px;
    border-radius: 50%;
    background: var(--ballpoint);
}
.nb-chart-mark-label {
    position: absolute;
    top: 2px;
    margin-left: 7px;
    font-family: var(--font-mono);
    font-size: 9.5px;
    color: var(--brass);
    white-space: nowrap;
}
.nb-chart-xaxis {
    display: flex;
    justify-content: space-between;
    margin: 7px 0 0;
    font-family: var(--font-mono);
    font-size: 9.5px;
    color: var(--ink-3);
}

/* The run of recent checkpoints — one square per graded answer, oldest first:
   right = filled ballpoint, a miss = the empty square the teacher ringed in
   red. Both are the same size, so the run reads as one line of marking. */
.nb-marks { display: flex; flex-wrap: wrap; gap: 4px; margin: 20px 0 0; }
.nb-mark {
    width: 8px; height: 8px;
    border: 1.2px solid var(--ballpoint);
    background: var(--ballpoint);
}
.nb-mark.is-miss { background: transparent; border-color: var(--brass); }

/* Weekly session bars — eight columns, the dashed rule is the weekly intent. */
.nb-weekbars {
    position: relative;
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 8px;
    margin: 24px 0 0;
}
.nb-weekbars-target {
    position: absolute;
    left: 0; right: 0;
    /* The student's real weekly target, measured from the foot of the track. */
    bottom: calc(18px + 72px * var(--target-days, 2) / 7);
    border-top: 1.5px dashed rgba(194, 64, 42, 0.5);
    pointer-events: none;
}
/* Per-sitting engagement bars — the same column, one per sitting instead of one
   per week, so the count is whatever the record holds (up to _ENGAGEMENT_SITTINGS).
   Capped width: this card is full-width, and 1fr columns across all of it turn a
   handful of sittings into slabs. */
.nb-engbars {
    position: relative;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 8px;
    margin: 36px 0 0;
    max-width: 560px;
}
/* Scores live in a narrow high band, so bar-to-bar height alone is unreadable —
   the dashed rule is the 80 the card's own "Engaged" label is drawn at, and the
   eye reads position against it. Measured from the foot of the 72px track. */
.nb-engbars-band {
    position: absolute;
    left: 0; right: 0;
    bottom: calc(18px + 72px * 80 / 100);
    border-top: 1.5px dashed rgba(194, 64, 42, 0.5);
    pointer-events: none;
}
.nb-weekbar, .nb-engbar { display: flex; flex-direction: column; align-items: stretch; gap: 8px; min-width: 0; }
/* No track behind the bar at all — on paper a tinted block reads as a full
   week's worth. The hairline under it is the axis the bars stand on. */
.nb-weekbar-track, .nb-engbar-track {
    position: relative;
    height: 72px;
    background: transparent;
    border-bottom: 1px solid var(--hair-row);
    display: flex;
    align-items: flex-end;
}
.nb-engbar-score {
    position: absolute;
    top: -16px;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--font-mono);
    font-size: 8.5px;
    color: var(--ink-3);
}
.nb-engbar.is-last .nb-engbar-score { color: var(--ink-2); font-weight: 600; }
.nb-weekbar-fill, .nb-engbar-fill {
    width: 100%;
    background: rgba(43, 93, 168, 0.4);
    border-radius: 2px;
    min-height: 0;
}
/* The bar for right now is the solid one — the rest are the record behind it. */
.nb-weekbar.is-current .nb-weekbar-fill,
.nb-engbar.is-last .nb-engbar-fill { background: var(--ballpoint); }
.nb-weekbar-label, .nb-engbar-label {
    font-family: var(--font-mono);
    font-size: 9.5px;
    color: var(--ink-3);
    text-align: center;
    height: 10px;
    line-height: 10px;
}
.nb-weekbar.is-current .nb-weekbar-label,
.nb-engbar.is-last .nb-engbar-label { color: var(--ink-2); }

/* Now & next. */
.nb-dash-now {
    font-family: var(--font-serif);
    font-size: 22px;
    color: var(--cream);
    margin: 10px 0 0;
    line-height: 1.25;
}
.nb-dash-then { display: block; margin: 26px 0 0; }
.nb-dash-next {
    list-style: none;
    counter-reset: nb-next;
    margin: 10px 0 0;
    padding: 0;
}
.nb-dash-next li {
    counter-increment: nb-next;
    display: flex;
    gap: 12px;
    align-items: baseline;
    padding: 8px 0;
    border-top: 1px solid var(--hair-row);
    font-size: 14px;
    color: var(--ink-body);
}
.nb-dash-next li::before {
    content: counter(nb-next);
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--ballpoint);
    flex: none;
    width: 12px;
}

/* Strength / focus rows. */
.nb-dash-rows { list-style: none; margin: 8px 0 0; padding: 0; }
/* Title on the left, its mono meta on the right, a hairline under each — the
   left accent bar is gone. A focus area is underlined in red pen instead: the
   teacher's mark on the item that needs the time. */
.nb-dash-row {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    gap: 18px;
    padding: 12px 0;
    border-bottom: 1px solid var(--hair-row);
}
.nb-dash-row:last-child { border-bottom: none; }
.nb-dash-row-title {
    font-family: var(--font-ui);
    font-size: 14px;
    color: var(--cream);
    line-height: 1.35;
}
.nb-dash-row-focus .nb-dash-row-title { border-bottom: 2px solid rgba(194, 64, 42, 0.4); }
.nb-dash-row-meta {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: lowercase;
    color: var(--ink-3);
    line-height: 1.4;
    text-align: right;
    flex: none;
}

/* The delta chip column on a subject bar. */
.nb-band-delta { flex: none; width: 46px; display: flex; justify-content: flex-end; }

/* --- The in-between window: 761-909px ------------------------
   Tighten the shell's own air before the phone layout takes over, keeping the
   four product destinations on one readable row without sideways scrolling. */
@media (max-width: 920px) {
    .nb-topbar { padding: 17px 22px; gap: 18px; }
    .nb-tabs { gap: 18px; }
}

/* --- Orientation cards -----------------------------------------------
   The content that pins to the sheet during the first meeting (founder,
   2026-08-15): the weekly packages while the parent chooses, the standing
   schedule as a receipt, the selling visuals, and the in-conversation inputs.

   These live here, not in a page, because static/js/tutor.js draws them and
   that one script drives BOTH rooms — the public one at /welcome/orientation
   and the product one at /tutor. They used to be written into the public
   room's own style block, and /tutor got only the first half: the map
   glimpse rendered there with zero-width dots (an invisible selling visual)
   and the payment offer as a default grey browser button. Shared markup
   needs shared styling, or the next card drifts the same way. */
.nb-orient-options { display: flex; gap: 12px; }
.nb-orient-option {
    flex: 1; text-align: center; padding: 14px 16px; cursor: pointer;
    border: 1px solid rgba(34, 48, 58, 0.35); border-radius: 3px;
    background: transparent; font-family: var(--font-serif);
}
.nb-orient-option:hover { border-color: var(--ballpoint); background: rgba(43, 93, 168, 0.07); }
.nb-orient-option .n { font-size: 26px; color: var(--cream); display: block; }
.nb-orient-option .per { font-family: var(--font-ui); font-size: 12px; color: var(--ink-2); display: block; margin-top: 2px; }
.nb-orient-option .price { font-family: var(--font-mono); font-size: 11.5px; color: var(--brass); display: block; margin-top: 8px; }
.nb-orient-hint { font-family: var(--font-ui); font-size: 11.5px; color: var(--ink-3); text-align: center; margin: 10px 0 0; }
.nb-orient-sched { font-family: var(--font-serif); font-size: 17px; color: var(--cream); text-align: center; margin: 0; }
.nb-orient-note { font-family: var(--font-ui); font-size: 11.5px; color: var(--ink-3); text-align: center; margin: 8px 0 0; }

/* The map glimpse — the teaser of the concept/prerequisite map that pops up
   while Piero introduces the benchmark (FUNNEL.md stage 2): one row per grade
   band, each a strip of small dots in the same mastery tones the Memory tab
   uses (proven = ballpoint, working = the dim ballpoint, a gap = the red
   pen, untouched = a faint ink ring). */
.nb-glimpse-rows { display: flex; flex-direction: column; gap: 7px; }
.nb-glimpse-row { display: flex; align-items: center; gap: 12px; }
.nb-glimpse-band {
    flex: none; width: 96px; text-align: right;
    font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--ink-3);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nb-glimpse-dots { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
.nb-glimpse-dot {
    width: 7px; height: 7px; border-radius: 50%; flex: none;
    background: transparent; border: 1px solid rgba(34, 48, 58, 0.22);
}
.nb-glimpse-dot.st-green  { background: var(--solid); border-color: var(--solid); }
.nb-glimpse-dot.st-orange { background: var(--shaky); border-color: var(--ballpoint-dim); }
.nb-glimpse-dot.st-red    { background: var(--gap); border-color: var(--gap); }
.nb-glimpse-caption {
    font-family: var(--font-ui); font-size: 11.5px; color: var(--ink-3);
    text-align: center; margin: 12px 0 0;
}

/* The payment offer — after the package and the schedule are set, Piero
   offers to finalize now. Taking it leaves for /enrollment; skipping just
   closes the card and never blocks the benchmark (FUNNEL.md: payment is
   offered here, not required here). */
.nb-offer-price { font-family: var(--font-serif); font-size: 26px; color: var(--cream); text-align: center; margin: 0; }
.nb-offer-text { font-family: var(--font-ui); font-size: 12.5px; color: var(--ink-2); text-align: center; margin: 8px 0 0; }
.nb-offer-actions { display: flex; flex-direction: column; align-items: center; gap: 9px; margin-top: 14px; }
.nb-offer-go {
    display: inline-block; background: var(--brass); color: var(--board);
    padding: 12px 24px; border: none; border-radius: 0;
    font-family: var(--font-mono); font-size: 11px; font-weight: 500;
    letter-spacing: 0.14em; text-transform: uppercase; cursor: pointer;
}
.nb-offer-go:hover { filter: brightness(1.07); }
.nb-offer-skip {
    background: none; border: none; padding: 0; cursor: pointer;
    font-family: var(--font-ui); font-size: 11.5px; color: var(--ink-3);
    text-decoration: underline; text-underline-offset: 3px;
}
.nb-offer-skip:hover { color: var(--ink-2); }

/* The in-conversation input — the little box that pops up inside the talk
   when Piero asks for something typed (the phone number first), instead of a
   static form page (founder, 2026-08-15). Submitting sends the value as the
   parent's own turn. */
.nb-orient-input-label { font-family: var(--font-ui); font-size: 13px; color: var(--ink-2); display: block; margin-bottom: 8px; text-align: center; }
.nb-orient-input-row { display: flex; gap: 8px; align-items: center; }
.nb-orient-input {
    flex: 1; min-width: 0; padding: 10px 12px;
    border: 1px solid rgba(34, 48, 58, 0.35); border-radius: 3px;
    background: var(--paper); color: var(--paper-ink);
    font-family: var(--font-ui); font-size: 15px;
}
.nb-orient-input:focus { outline: none; border-color: var(--ballpoint); }
.nb-orient-input-send {
    flex: none; background: var(--brass); color: var(--board); border: none;
    padding: 11px 18px; border-radius: 0; cursor: pointer;
    font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
    letter-spacing: 0.14em; text-transform: uppercase;
}
.nb-orient-input-send:hover:not(:disabled) { filter: brightness(1.07); }
.nb-orient-input-send:disabled { opacity: 0.45; cursor: default; }

/* --- Narrow screens -----------------------------------------
   The shell was laid out for the desktop board; below ~760px the
   topbar row and the two-up grids have to give, or the page
   scrolls sideways. */
@media (max-width: 760px) {
    /* Orientation cards, narrow: packages stack, and the band label gives up
       width to its dots. Shared by both rooms, like the rules themselves. */
    .nb-orient-options { flex-direction: column; }
    .nb-glimpse-band { width: 66px; }
    .nb-topbar { padding: 14px 18px; gap: 14px; flex-wrap: wrap; }
    .nb-tabs { gap: 18px; margin: 0; flex-wrap: wrap; row-gap: 8px; }
    .nb-tab { padding: 8px 0; }
    .nb-topbar-actions { margin-left: auto; }
    .nb-page-col { padding: 34px 18px 56px; }
    .nb-h1 { font-size: 34px; margin-bottom: 26px; }
    .nb-h1-sub { margin-top: -16px; }
    .nb-h2 { font-size: 28px; }
    .nb-dash-grid { grid-template-columns: 1fr; gap: 8px; }
    .nb-dash-overview { grid-template-columns: 1fr; }
    .nb-dash-overview-item { min-height: 0; border-left: none; border-top: 1px solid var(--hair-row); }
    .nb-dash-overview-item:first-child { border-top: none; }
    .nb-dash-overview-track { margin-top: 16px; }
    .nb-dash-plan-card { grid-template-columns: 1fr; }
    .nb-dash-participation-grid { grid-template-columns: 1fr; }
    .nb-engagement-head { flex-direction: column; }
    .nb-engagement-scores { width: 100%; grid-template-columns: 1fr 1fr; }
    .nb-engagement-score { min-width: 0; padding: 0 14px; text-align: left; }
    .nb-engagement-score:first-child { padding-left: 0; }
    .nb-engagement-score-value { justify-content: flex-start; }
    .nb-dash-plan-main { padding-right: 0; }
    .nb-dash-plan-focus { margin-top: 26px; padding: 24px 0 0; border-left: none; border-top: 1px solid var(--hair-card); }
    .nb-dash-strength-grid { grid-template-columns: 1fr; }
    .nb-dash-strength-grid li:nth-child(2) { border-top: 1px solid var(--hair-row); }
    .nb-dash-card { padding: 18px 18px; }
    .nb-dash-hero-value { font-size: 40px; }
    /* A ragged flex wrap misaligns the stat rows; two tidy columns instead. */
    .nb-dash-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 18px; }
    .nb-dash-stat-label { white-space: normal; }
    .nb-band-name { width: 66px; font-size: 11px; }
    .nb-band-row { gap: 10px; }
    .nb-band-delta { width: 32px; }
    .nb-weekbars, .nb-engbars { gap: 5px; }
    .nb-chart, .nb-chart-yaxis { height: 120px; }
    .nb-nextsession { flex-direction: column; align-items: flex-start; gap: 14px; }
    .nb-nextsession-actions { align-items: flex-start; }
    .nb-page-jot { display: none; }
}

/* Planned lesson rows (map nodes with no spine yet) — Lessons outline v4 */
.nb-lesson-planned { opacity: .45; cursor: default; }
.nb-lesson-planned .nb-lesson-title { font-style: italic; }

/* --- Site-wide Piero chat --------------------------------------------------
   One predictable tutor dock. It opens in the lower corner opposite the Piero
   already on the page, instead of floating over him or duplicating him inside
   the box; a quiet control can move it when it covers something important. */
.nb-zchat {
    position: fixed;
    z-index: 80;
    right: 18px;
    bottom: 18px;
    width: min(432px, calc(100vw - 36px));
    height: min(580px, calc(100dvh - 92px));
    min-height: 440px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--board);
    border: 1px solid var(--hair-card-2);
    border-top: 3px solid var(--brass);
    border-radius: 10px;
    box-shadow: 0 22px 60px rgba(34, 48, 58, 0.18),
                0 3px 12px rgba(34, 48, 58, 0.08);
    opacity: 0;
    transform: translateY(18px) scale(0.985);
    transform-origin: 100% 100%;
    transition: opacity 180ms var(--ease-out), transform 180ms var(--ease-out),
                height 180ms var(--ease-out);
}
.nb-zchat.is-open { opacity: 1; transform: none; }
.nb-zchat.is-empty { height: min(500px, calc(100dvh - 92px)); }
.nb-zchat.is-docked-left { right: auto; left: 18px; transform-origin: 0 100%; }
.nb-zchat.is-docked-right { right: 18px; left: auto; transform-origin: 100% 100%; }

.nb-zchat-new {
    flex-shrink: 0;
    min-height: 36px;
    padding: 0 11px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    line-height: 1;
    color: var(--ink-3);
    background: none;
    border: 1px solid transparent;
    border-radius: 7px;
    cursor: pointer;
    transition: color var(--t-fast) var(--ease-out),
                background var(--t-fast) var(--ease-out);
}
.nb-zchat-new:hover { color: var(--ink-body); background: var(--ballpoint-wash); }
.nb-zchat-new[hidden] { display: none; }

/* Piero's nudge — a small aside from the mark for a student who has never
   opened the chat. Shown once, fades on its own, never returns once answered. */
.nb-znudge {
    position: fixed;
    z-index: 79;
    max-width: 230px;
    padding: 9px 13px;
    text-align: left;
    font-family: var(--font-serif);
    font-size: 14px;
    line-height: 1.35;
    color: var(--ink-body);
    background: var(--board);
    border: 1px solid var(--hair-card-2);
    border-top: 2px solid var(--brass);
    border-radius: 5px;
    cursor: pointer;
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity var(--t-med) var(--ease-out),
                transform var(--t-med) var(--ease-out);
}
.nb-znudge.is-open { opacity: 1; transform: none; }
.nb-znudge:hover { border-color: var(--brass); }
.nb-znudge::before {
    content: '';
    position: absolute;
    top: -5px;
    left: 18px;
    width: 8px;
    height: 8px;
    background: var(--board);
    border-left: 1px solid var(--brass);
    border-top: 1px solid var(--brass);
    transform: rotate(45deg);
}
@media (prefers-reduced-motion: reduce) {
    .nb-znudge, .nb-zchat { transition: none; }
    .nb-zchat-mic { animation: none !important; }
}

.nb-zchat-head {
    display: flex;
    align-items: center;
    min-height: 64px;
    gap: 7px;
    padding: 9px 9px 8px 14px;
    border-bottom: 1px solid var(--hair-row);
    background: linear-gradient(90deg, rgba(43, 93, 168, .06), transparent 58%);
}
.nb-zchat-identity {
    min-width: 0;
    display: flex;
    flex: 1;
    align-items: center;
    gap: 0;
}
.nb-zchat-identity-copy {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.nb-zchat-title {
    font-family: var(--font-serif);
    font-size: 21px;
    font-weight: 500;
    line-height: 1.15;
    color: var(--cream);
}
.nb-zchat-head-actions {
    display: flex;
    align-items: center;
    flex: none;
    gap: 1px;
}
.nb-zchat-dock-toggle {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    flex: none;
    padding: 0;
    color: var(--ink-3);
    background: none;
    border: 1px solid transparent;
    border-radius: 50%;
    font-family: var(--font-ui);
    font-size: 17px;
    cursor: pointer;
    transition: color var(--t-fast) ease, background var(--t-fast) ease;
}
.nb-zchat-dock-toggle:hover { color: var(--ink-body); background: var(--ballpoint-wash); }
.nb-zchat-session {
    overflow: hidden;
    color: var(--ink-3);
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: .07em;
    text-overflow: ellipsis;
    text-transform: uppercase;
    white-space: nowrap;
}
.nb-zchat-close {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    flex: none;
    background: none;
    border: 1px solid transparent;
    border-radius: 50%;
    padding: 0;
    line-height: 1;
    font-size: 21px;
    color: var(--ink-3);
    cursor: pointer;
    transition: color var(--t-fast) ease, background var(--t-fast) ease;
}
.nb-zchat-close:hover { color: var(--ink-body); background: var(--ballpoint-wash); }

.nb-zchat-thread {
    min-height: 0;
    flex: 1;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 16px 15px 18px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    scrollbar-width: thin;
    scrollbar-color: var(--hair-card-2) transparent;
}
.nb-zchat-msg {
    max-width: 88%;
    padding: 9px 12px;
    font-size: 13.5px;
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.nb-zchat-tutor {
    align-self: flex-start;
    font-family: var(--font-serif);
    font-size: 15.5px;
    color: var(--ink-body);
    background: var(--ballpoint-wash);
    border: 1px solid rgba(43, 93, 168, .08);
    border-radius: 4px 13px 13px 13px;
}
.nb-zchat-pending { color: var(--ink-3); font-style: italic; }
.nb-zchat-error { color: var(--gap); background: var(--brass-wash); }
.nb-zchat-student {
    align-self: flex-end;
    font-family: var(--font-ui);
    background: var(--ballpoint);
    color: white;
    border: 1px solid var(--ballpoint);
    border-radius: 13px 13px 4px 13px;
}
.nb-zchat-intro {
    order: 2;
    margin-top: 3px;
    padding: 12px 0 0;
    border-top: 1px solid var(--hair-row);
}
.nb-zchat-intro-label {
    display: block;
    margin: 0 0 4px;
    color: var(--brass);
    font-family: var(--font-mono);
    font-size: 8.5px;
    letter-spacing: .13em;
    text-transform: uppercase;
}
.nb-zchat-intro > p {
    margin: 0 0 10px;
    color: var(--ink-2);
    font-size: 12px;
    line-height: 1.5;
}
.nb-zchat-starters {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 7px;
}
.nb-zchat-starter {
    min-height: 43px;
    padding: 8px 9px;
    color: var(--ballpoint);
    background: rgba(255, 255, 255, .58);
    border: 1px solid var(--hair-card-2);
    border-radius: 7px;
    font-family: var(--font-ui);
    font-size: 10.8px;
    line-height: 1.3;
    text-align: left;
    cursor: pointer;
    transition: background var(--t-fast) ease, border-color var(--t-fast) ease;
}
.nb-zchat-starter:hover { background: var(--ballpoint-wash); border-color: var(--ballpoint-dim); }

/* Server-confirmed writes are receipts, visually separate from conversation. */
.nb-zchat-note {
    width: min(92%, 340px);
    align-self: center;
    display: flex;
    align-items: flex-start;
    gap: 9px;
    color: var(--ink-body);
    background: var(--brass-wash);
    border: 1px solid var(--brass-dim);
    border-radius: var(--r-chip);
    padding: 9px 10px;
}
.nb-zchat-note-check {
    display: grid;
    place-items: center;
    width: 18px;
    height: 18px;
    flex: none;
    border-radius: 50%;
    color: white;
    background: var(--brass);
    font-family: var(--font-ui);
    font-size: 11px;
    font-weight: 600;
}
.nb-zchat-note-copy { display: flex; min-width: 0; flex-direction: column; gap: 2px; }
.nb-zchat-note-copy strong {
    color: var(--brass);
    font-family: var(--font-mono);
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: .08em;
    text-transform: uppercase;
}
.nb-zchat-note-copy span { font-size: 11.5px; line-height: 1.4; }

.nb-zchat-form {
    flex: none;
    padding: 10px 12px 11px;
    background: rgba(255, 255, 255, .68);
    border-top: 1px solid var(--hair-row);
}
.nb-zchat-composer {
    display: flex;
    align-items: flex-end;
    gap: 7px;
    padding: 4px 5px 4px 10px;
    background: var(--paper);
    border: 1px solid var(--hair-card-2);
    border-radius: 12px;
    transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
.nb-zchat-composer:focus-within {
    border-color: var(--ballpoint-dim);
    box-shadow: 0 0 0 2px rgba(43, 93, 168, .08);
}
.nb-zchat-mic {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    flex: none;
    margin: 1px 0;
    padding: 0;
    color: var(--ballpoint);
    background: var(--ballpoint-wash);
    border: 1px solid rgba(43, 93, 168, .16);
    border-radius: 50%;
    cursor: pointer;
    touch-action: none;
    transition: color var(--t-fast) ease, background var(--t-fast) ease,
                border-color var(--t-fast) ease, transform var(--t-fast) ease;
}
.nb-zchat-mic[hidden] { display: none; }
.nb-zchat-mic svg { width: 18px; height: 18px; }
.nb-zchat-mic:hover:not(:disabled) { border-color: var(--ballpoint-dim); transform: translateY(-1px); }
.nb-zchat.is-recording .nb-zchat-mic {
    color: white;
    background: var(--brass);
    border-color: var(--brass);
    animation: nbZchatMicPulse 1.15s ease-in-out infinite;
}
.nb-zchat-mic:disabled { opacity: .42; cursor: default; }
@keyframes nbZchatMicPulse {
    50% { box-shadow: 0 0 0 5px rgba(194, 64, 42, .11); }
}
.nb-zchat-voice-status {
    display: block;
    margin: 6px 9px 0;
    color: var(--ballpoint);
    font-family: var(--font-ui);
    font-size: 11px;
    line-height: 1.35;
}
.nb-zchat-voice-status[hidden] { display: none; }
.nb-zchat.is-recording .nb-zchat-voice-status { color: var(--brass); }
.nb-zchat-hint {
    display: block;
    margin: 5px 7px 0;
    color: var(--ink-3);
    font-family: var(--font-mono);
    font-size: 8.5px;
    letter-spacing: .03em;
}
.nb-zchat-input {
    flex: 1;
    resize: none;
    min-height: 34px;
    max-height: 108px;
    padding: 7px 3px 6px;
    font-family: var(--font-ui);
    font-size: 14px;
    line-height: 1.45;
    color: var(--ink-body);
    background: transparent;
    border: 0;
}
.nb-zchat-input::placeholder { color: var(--ink-4); }
.nb-zchat-input:focus { outline: none; }
.nb-zchat-send {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    flex: none;
    padding: 0 0 2px;
    font-family: var(--font-ui);
    font-size: 20px;
    line-height: 1;
    color: white;
    background: var(--brass);
    border: none;
    border-radius: 50%;
    cursor: pointer;
    transition: opacity var(--t-fast) ease, transform var(--t-fast) ease;
}
.nb-zchat-send:hover:not(:disabled) { transform: translateY(-1px); }
.nb-zchat-send:disabled { opacity: .28; cursor: default; }
.nb-zchat.is-sending .nb-zchat-composer { opacity: .72; }

.nb-brand-mini[role="button"]:focus-visible,
.nb-zchat button:focus-visible {
    outline: 2px solid var(--ballpoint);
    outline-offset: 2px;
}

@media (max-width: 600px) {
    .nb-zchat {
        top: auto !important;
        right: 8px;
        bottom: 8px;
        left: 8px !important;
        width: auto;
        height: min(620px, calc(100dvh - 40px));
        min-height: 0;
        transform: translateY(12px) scale(.99);
        transform-origin: 50% 100%;
        border-radius: 14px;
    }
    .nb-zchat.is-empty { height: min(500px, calc(100dvh - 40px)); }
    .nb-zchat::before { display: none; }
    .nb-zchat-head { min-height: 60px; padding: 8px 7px 7px 12px; }
    .nb-zchat-title { font-size: 19px; }
    .nb-zchat-session { font-size: 8.5px; }
    .nb-zchat-dock-toggle { display: none; }
    .nb-zchat-thread { padding: 14px 12px 16px; }
    .nb-zchat-form { padding: 8px 9px 9px; }
    .nb-zchat-hint { display: none; }
    .nb-zchat-new { min-height: 38px; font-size: 8.5px; padding: 0 9px; }
    .nb-zchat-close { width: 40px; height: 40px; }
    .nb-zchat-send { width: 40px; height: 40px; }
    .nb-znudge { max-width: 200px; font-size: 13px; }
}


@media (prefers-reduced-motion: reduce) {
    .nb-zchat { transition: none; transform: none; }
}

/* Home, Dashboard and Practice switch immediately. Session entry keeps its
   deliberate room transition; ordinary tab changes do not make the page wait
   for each section to fade in before it becomes readable. */

/* The lesson player loads this file for its topbar chrome (the brand block)
   and styles the board below with static/css/lesson_player.css. Both are paper
   now, so the bar needs nothing player-specific: it takes the .nb-topbar
   hairline like every other page. */
