/* MathedUp Teacher Toolkit — the toolkit's own pages, from ONE place.
 *
 * The five TOOLS route their chrome through scripts/toolkit/toolbar.js, so a restyle is one file
 * redeployed. The PAGES AROUND THEM did not: build_teach_page.py inlined 6,648 characters of CSS
 * into every one of the 15 topic pages and linked no stylesheet, and build_teach_index.py inlined
 * another 7,612 for the hub and each course landing. A design tweak meant editing a Python string,
 * rebuilding 17 pages and redeploying all of them; the same tweak on a tool took seconds.
 *
 * This file is the pages' equivalent, delivered the same proven way (scripts/toolkit/teach_style.py):
 * inlined as a fallback FIRST, <link>ed to /assets/mu-teach.css SECOND. The order is load-bearing —
 * the two copies have equal specificity, so the later one wins, and with the <link> first a page
 * built before a restyle would keep painting its stale inlined bytes over the freshly-deployed
 * asset. Drift between the copies is GATED, not trusted: scripts/toolkit/teach_style_qa.js.
 *
 * SCOPES. The two builders had drifted into disagreeing about what a card, a hero and a grid look
 * like, and 19 of their selectors would have cross-applied if this file were a naive union
 * (.card:hover, .go, and two different mobile breakpoints among them). So the surfaces are scoped:
 *   .t-topic  — a per-topic hub, /teach/<course>/<slug>/          (build_teach_page.py)
 *   .t-hub    — the /teach/ hub and the course landings           (build_teach_index.py)
 * Rules that are genuinely ONE rule live unscoped in the core below. Where the two surfaces differ
 * DELIBERATELY, the difference is a token set per scope (--hero-pad, --h1, --card-min) rather than
 * two copies of the rule, so the shape of the disagreement stays visible.
 */

/* ============================ tokens ============================ */
/* Chalk, at the values reference/design/design-thesis.md actually specifies. These pages shipped
   near-misses of all three core tokens, and the ink was the one that mattered: #1a1a1a is a COLD
   near-black, and the thesis says never pure black against Chalk. Warm neutrals throughout, warm
   shadows, and no muted grey that cannot clear 4.5:1 on the grounds it is painted on. */
:root{
  --cream:#F6F3EC;      /* page ground        (thesis) */
  --paper:#FFFDF8;      /* card / bar ground  (warm white, not #fff) */
  --ash:#EFEBE2;        /* sunk surfaces      (thesis) */
  --ink:#1A1917;        /* warm near-black    (thesis; never #000, never #1a1a1a) */
  --ink-hero:#2A2822;   /* the raised chips on the dark hero */
  --ink-hero-2:#3B372E;
  --border:#E7E1D6;     /* thesis */
  --border-strong:#D6CFBF;
  --muted:#6B6862;      /* 5.01:1 on cream */
  /* was #9a968f = 2.64:1 on cream, and it painted the footer, the spine counts, the topic counts
     and the "coming soon" pill. One token was most of this surface's contrast debt. */
  --faint:#6E685C;      /* 4.99:1 on cream, 5.44:1 on paper, 4.65:1 on ash */
  /* PRIMARY ACTION. The muted brick, not the brand's #DC2626 (owner, TT7). It is the quieter red
     AND the more legible button: white on it is 5.34:1 against brand coral's 4.83:1. */
  --coral:#C8321F;
  --coral-dark:#A82A19;
  --coral-pale:#f87171; /* on the dark hub hero */
  /* THE BOARD COLOUR. Was violet #6d28d9, which is not in the thesis at all - it appears there only
     as the Statistics STRAND colour, at a different value - and entered the toolkit in ab38f2f9
     ("Interactive board versions"), arriving with the feature that needed a colour rather than being
     chosen against the system. The thesis reserves blue for "interactive", which is exactly what a
     Board button is, and these pages ALREADY paint that blue on the breadcrumb: so this REMOVES a
     hue from the surface rather than adding one. Measured against the new red it is also the better
     pairing - 142 degrees of hue apart against violet's 103, and 2.7 lighter against violet's 5.1,
     so the two buttons read as different KINDS of action rather than different WEIGHTS of one. */
  --board:#1D4ED8;
  --board-dark:#1E40AF;
  --blue:#1D4ED8;       /* links (thesis: interactive) */
  /* success / complete (thesis). DARKENED from #059669 (owner, TT8): the thesis value is 3.77:1 on
     white and AA needs 4.5, and on the printables it paints the ANSWER — every mark scheme, every
     worked answer, every tick. 226 of the 231 contrast failures the widened craft gate found were
     this one value. #047857 clears AA on all three grounds this project paints on (white 5.48,
     cream 4.95, ash 4.61) and reads as the same green.
     NOT YET SWEPT SITE-WIDE: 24 other files still pin #059669 (dashboards, growth, the planner,
     login, summer-challenge). They are a separate decision, not a printables one. */
  --sage:#047857;
  --wrapw:1040px;
  --ease:.15s;          /* the thesis names ~150ms; this file shipped 120 */
  /* Warm-tinted, per the thesis. A neutral black shadow on a warm ground reads grey and cheap. */
  --shadow-lift:0 3px 14px rgba(74,60,42,.10);
  --shadow-pop:0 5px 16px rgba(26,25,23,.34);
}

/* ============================ shared core ============================ */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* Outfit, per reference/design/design-thesis.md: the live site ships Outfit for everything
   including headings, and a second display face is never introduced per page. Until TT7 these pages
   were the odd surface out, so a teacher clicked "Launch builder" from a Segoe UI page straight into
   the tools' Outfit toolbar. Segoe UI stays as the fallback, so a blocked webfont changes nothing. */
body{font-family:'Outfit','Segoe UI',Arial,sans-serif;background:var(--cream);color:var(--ink);line-height:1.45}
/* DECISION 7 (unified): the hub set text-decoration:none, the topic page did not. Every link on the
   topic page already killed its own underline (.top .bc a, .go, .go2, .goboard), so this is the same
   rendering with one rule instead of four. Proven, not assumed — the render diff is the gate. */
a{color:inherit;text-decoration:none}
.katex{white-space:nowrap}

/* QUALITY FLOOR, unannounced (design thesis). Measured before this landed: ONE :focus-visible rule
   across 38 to 106 interactive elements per page, so a keyboard user had almost nothing to follow.
   :focus-visible rather than :focus, so a mouse click does not leave a ring behind. */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,
textarea:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--coral); outline-offset:2px; border-radius:6px;
}
/* The thesis asks for this by name and no toolkit page honoured it. Motion here is decorative
   (a lift, a tint), so removing it costs nothing and stops it hurting. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    transition-duration:.01ms !important; animation-duration:.01ms !important;
    animation-iteration-count:1 !important; scroll-behavior:auto !important;
  }
}

/* hero — one dark band, two sizes. DECISIONS 1 and 2: the padding and the h1 size differ on
   purpose (the hub is a landing surface, a topic page is one a teacher returns to mid-lesson), so
   they are tokens set per scope rather than two rules that drifted apart. */
.hero{background:var(--ink);color:#fff;padding:var(--hero-pad)}
.hero .in{max-width:var(--wrapw);margin:0 auto}
.hero .kick{font-size:.72rem;letter-spacing:.13em;text-transform:uppercase;color:#f4b9b9;font-weight:700}
/* DECISION 2b (unified): the topic page said margin-bottom 8px and the hub 10px. Nothing referred
   to either, so it was drift, not a decision. One value — the topic hero is 2px taller. Recorded
   because the render diff caught me making this change without naming it. */
.hero h1{font-size:var(--h1);margin:4px 0 10px}
.hero h1 span{color:var(--coral-pale)}

/* DECISION 3 (unified): 20px on the topic page against 26px on the hub was drift, not a decision —
   nothing referred to either number. One value. */
.wrap{max-width:var(--wrapw);margin:0 auto;padding:24px 16px 60px}
.foot{max-width:var(--wrapw);margin:0 auto;padding:0 16px 40px;font-size:.78rem;color:var(--faint);text-align:center}

/* card — DECISION 5 (split): the SKIN is shared, so "what a card looks like" is one edit; the
   LAYOUT is scoped, because the two cards are genuinely different objects (a topic card is an icon
   beside a body with a description and two buttons; a hub card is a stacked title and one link).
   The topic card gains the hub's transition, which it never had. */
.card{background:var(--paper);border:1.5px solid var(--border);border-radius:12px;
      transition:border-color var(--ease),box-shadow var(--ease)}
/* DECISION 6 (unified): 1rem against 1.02rem was drift. The topic card's flex row is layout and
   stays in its own scope, below. */
.card .ct{font-weight:700;font-size:1rem}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--card-min),1fr));gap:12px}

/* DECISION 8 (unified): the topic page broke to one column at 520px and the hub at 560px. One
   responsive boundary for the toolkit; the VALUES either side stay per-scope. */
@media(max-width:560px){
  .grid{grid-template-columns:1fr}
}

/* ============================ .t-topic — a per-topic hub ============================ */
/* A CALM HERO (owner, TT7). The dark band and the spine were two bold elements competing, and the
   thesis says spend boldness in ONE place. With the hero at the page ground, the spine's gradient is
   the only loud thing on the page, and the topic name carries the only colour in the hero.
   The HUB keeps its dark hero on purpose: it is a landing surface arriving cold, it has no spine to
   compete with, and its bold element is the thing it is allowed to have. */
.t-topic{--hero-pad:30px 20px 24px;--h1:1.9rem;--card-min:300px}
.t-topic .hero{background:var(--cream);color:var(--ink);border-bottom:1px solid var(--border)}
/* --coral-dark, not --coral: brand coral on the cream ground is 4.36:1 and the kicker is 11.5px, so
   AA needs 4.5. Caught by the craft gate on the very first design change after that gate landed.
   --coral-dark is 5.84:1 and reads as the same red at this size. */
.t-topic .hero .kick{color:var(--coral-dark)}
.t-topic .hero h1 span{color:var(--ink)}

.t-topic .top{background:var(--paper);border-bottom:1.5px solid var(--border);padding:10px 20px;display:flex;align-items:center;gap:12px}
.t-topic .top img{height:28px}
.t-topic .top .bc{font-size:.8rem;color:var(--muted);margin-left:auto}
.t-topic .top .bc a{color:var(--blue)}
.t-topic .hero .in{position:relative}
.t-topic .hero .lede{font-size:.92rem;color:var(--muted);max-width:760px;margin:0 0 12px}
.t-topic .facts{display:flex;flex-wrap:wrap;gap:8px}
.t-topic .fact{font-size:.78rem;background:var(--paper);border:1px solid var(--border);border-radius:99px;padding:4px 12px;color:var(--muted)}

/* THE SPINE - the page's one bold element (design thesis: spend boldness in ONE place, keep
   everything else quiet). It replaces the dismissible "suggested approach" paragraph: the same
   claim, made by the object itself. Six phases, each a jump link carrying its resource count, over
   a gradient that shows guidance fading from left to right. */
.t-topic .spine{background:var(--paper);border-bottom:1.5px solid var(--border);padding:15px 20px 13px}
.t-topic .spine .in{max-width:var(--wrapw);margin:0 auto}
.t-topic .spine ol{list-style:none;display:grid;grid-template-columns:repeat(6,1fr);gap:8px}
.t-topic .spine li{min-width:0}
.t-topic .spine a{display:flex;flex-direction:column;align-items:center;gap:3px;text-align:center;
  padding:9px 6px 8px;border:1.5px solid transparent;border-radius:11px;transition:border-color var(--ease),background var(--ease)}
.t-topic .spine a:hover,.t-topic .spine a:focus-visible{border-color:var(--coral);background:#FCF0EE}
.t-topic .spine .sic{display:flex;color:var(--muted)}
.t-topic .spine a:hover .sic,.t-topic .spine a:focus-visible .sic{color:var(--coral)}
/* two lines' worth whether the name needs them or not, so the counts sit on one line across all
   six phases rather than stepping down under the one name that wraps */
.t-topic .spine .sname{font-weight:700;font-size:.83rem;line-height:1.25;min-height:2.5em;
  display:flex;align-items:center}
.t-topic .spine .sn{font-size:.68rem;font-weight:800;color:var(--faint)}
.t-topic .sgrad{display:flex;align-items:center;gap:10px;margin-top:9px;font-size:.66rem;
  font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--faint)}
.t-topic .sgrad i{flex:1;height:4px;border-radius:3px;
  background:linear-gradient(90deg,var(--coral) 0%,#f0b6b6 45%,var(--border) 100%)}
.t-topic .gi{display:flex;align-items:center;color:var(--faint)}
@media(max-width:760px){
  .t-topic .spine ol{grid-template-columns:repeat(3,1fr)}
  .t-topic .spine{padding:11px 14px 10px}
}
@media(max-width:430px){
  .t-topic .spine ol{grid-template-columns:repeat(2,1fr)}
  .t-topic .spine .sn{display:none}
}

.t-topic .grp{margin-bottom:26px}
.t-topic .gh{display:flex;align-items:baseline;gap:12px;margin:0 2px 11px;padding-bottom:7px;border-bottom:2px solid var(--border);flex-wrap:wrap}
.t-topic .gh h2{font-size:1.06rem}
.t-topic .gh p{font-size:.82rem;color:var(--muted)}

.t-topic .card{padding:14px 15px;display:flex;gap:12px;align-items:stretch}
/* OWNER, TT7: the coral ring that singled out the Fluency card is gone, which frees coral to mean
   "hovered" on this surface as it already does on the hub. The .feat class is no longer emitted.
   :not(.off) because a "coming soon" card lifted and turned coral too, promising a click it has no
   way to honour. Caught by hovering one and reading the painted border, after a first version of the
   check asked whether .card.off matches .card, which is true by construction and could never fail. */
.t-topic .card:not(.off):hover{border-color:var(--coral);box-shadow:var(--shadow-lift)}
.t-topic .card.off{opacity:.55}
/* The icon takes the ink of whatever it sits in, which is the whole reason for drawing them in
   currentColor: hovering a card moves its icon to coral along with the border, and the surface has
   one colour decision instead of 23 emoji each carrying their own. */
.t-topic .card .ci{flex:none;align-self:flex-start;display:flex;padding-top:1px;color:var(--muted)}
.t-topic .card:not(.off):hover .ci{color:var(--coral)}
.t-topic .card.off .ci{color:var(--faint)}
.mi{display:block}
.bi{display:inline-block;flex:none}
.t-topic .go,.t-topic .goboard,.t-topic .go2{display:inline-flex;align-items:center;gap:6px}
.t-hub .chip{align-items:center}
.t-topic .card .cb{flex:1;min-width:0;display:flex;flex-direction:column}
.t-topic .card .ct{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* THE TAG IS A LABEL, NOT A COLOUR. It carried four hues (sky / stone / violet / clay) on a card
   that also carried two button hues and coral again for hover: three colour meanings stacked on one
   mark, which the thesis forbids by name. The words are unchanged; only the paint is gone. */
.t-topic .tag{font-size:.58rem;font-weight:800;letter-spacing:.06em;border-radius:99px;
  padding:1.5px 7px;background:transparent;border:1px solid var(--border);color:var(--faint)}
.t-topic .card:not(.off):hover .tag{border-color:var(--border-strong)}
/* 466 words a page became 145: median 23 per card down to 7. The full text is not deleted, it moves
   behind the hover - the pattern /games/ already ships, with @media(hover:none) keeping it open
   where there is no hover to give. :focus-within so a keyboard reaches it too. */
.t-topic .card .cd{font-size:.85rem;color:#4B473F;margin:5px 0 10px}
.t-topic .cd-long{display:none;font-size:.82rem;color:var(--muted);line-height:1.5;
  margin:0 0 10px;padding-top:7px;border-top:1px dashed var(--border)}
.t-topic .card:hover .cd-long,.t-topic .card:focus-within .cd-long{display:block}
@media(hover:none){.t-topic .cd-long{display:block}}
.t-topic .card .ca{display:flex;flex-wrap:wrap;gap:8px;margin-top:auto}
.t-topic .go,.t-topic .go2,.t-topic .goboard{display:inline-block;font-size:.83rem;font-weight:700;border-radius:8px;padding:7px 15px}
/* ONE FILL PER CARD. Measured before this: 27 of 28 buttons on a topic page were a saturated fill,
   so nothing was primary because everything was. The references do not solve this with a softer red
   - Linear rations fill to one per view and ghosts the rest, Stripe runs filled / hairline / text as
   three ranks, Things 3 spends colour on state and not on buttons at all. So: a filled button means
   "the primary thing to do on THIS card", never "this card matters more than its neighbours". */
.t-topic .go{background:var(--coral);color:#fff}
.t-topic .go:hover{background:var(--coral-dark)}
/* A second action of the SAME kind is a hairline. mcqpaper offers Print papers AND Print key, and
   with both filled that one card shouted twice while every other card shouted once. */
.t-topic .ca .go ~ .go{background:transparent;color:var(--coral-dark);border:1.5px solid var(--border-strong)}
.t-topic .ca .go ~ .go:hover{background:transparent;border-color:var(--coral-dark)}
/* Board is secondary WHERE THERE IS A PRINT, and primary where it is the only thing on offer, so a
   board-only card never reads as secondary to its neighbours. The builder sets .ca-noprint rather
   than the stylesheet asking :has(), because the builder already knows and :has() is a browser
   support question a teacher should not have to win. */
.t-topic .goboard{background:transparent;color:var(--board-dark);border:1.5px solid var(--border-strong)}
.t-topic .goboard:hover{background:transparent;border-color:var(--board-dark)}
.t-topic .ca-noprint .goboard{background:var(--board);color:#fff;border-color:var(--board)}
.t-topic .ca-noprint .goboard:hover{background:var(--board-dark);border-color:var(--board-dark)}
.t-topic .go2{background:var(--paper);color:var(--muted);border:1.5px solid var(--border-strong)}
.t-topic .go2:hover{border-color:var(--ink);color:var(--ink)}
.t-topic .soon{font-size:.58rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;background:var(--ash);color:var(--faint);border-radius:99px;padding:2px 7px;white-space:nowrap}

@media(max-width:560px){
  .t-topic .hero h1{font-size:1.5rem}
  /* the phase header stacks rather than wrapping its own title mid-phrase */
  .t-topic .gh{display:block}
  .t-topic .gh p{margin-top:2px}
}

/* slim view: icons + titles + buttons only, one row per section. Toggle top-right, remembered
   across all /teach topics (localStorage, applied pre-paint from the head script). Descriptions
   stay in the DOM and reappear as hover tooltips.
   .slim sits on <html> and .t-topic on <body>, so these read html.slim > body.t-topic > … */
.t-topic .vtog{position:absolute;top:0;right:0;font-size:.78rem;font-weight:700;border:1.5px solid var(--border-strong);background:var(--paper);color:var(--muted);border-radius:99px;padding:5px 13px;cursor:pointer}
.t-topic .vtog:hover{border-color:var(--coral);color:var(--coral)}
.slim .t-topic .hero{padding:18px 20px 14px}
.slim .t-topic .hero .lede{display:none}
.slim .t-topic .grp{display:flex;align-items:flex-start;gap:14px;margin-bottom:0;border-bottom:1px solid var(--border);padding:9px 0}
.slim .t-topic .grp:last-of-type{border-bottom:none}
.slim .t-topic .gh{flex:0 0 200px;display:block;border-bottom:none;margin:0;padding:4px 0 0}
.slim .t-topic .gh h2{font-size:.9rem}
.slim .t-topic .gh p{display:none}
.slim .t-topic .grid{flex:1;display:flex;flex-wrap:wrap;gap:8px}
.slim .t-topic .card{position:relative;padding:6px 10px;border-radius:9px;gap:8px;align-items:center}
.slim .t-topic .card .ci{align-self:center;padding-top:0}
.slim .t-topic .card .cb{flex-direction:row;align-items:center;gap:10px}
.slim .t-topic .card .ct{font-size:.85rem;white-space:nowrap}
.slim .t-topic .card .tag{display:none}
.slim .t-topic .card .cd,.slim .t-topic .card .cd-long{display:none}
.slim .t-topic .card:hover .cd-long{display:block;position:absolute;top:calc(100% + 5px);left:0;z-index:40;width:280px;background:var(--ink);color:#fff;font-size:.76rem;line-height:1.45;padding:8px 11px;border-radius:8px;box-shadow:var(--shadow-pop);margin:0;border-top:none;padding-top:8px}
.slim .t-topic .card .ca{margin:0;gap:6px}
.slim .t-topic .card .go,.slim .t-topic .card .go2,.slim .t-topic .card .goboard{padding:4px 10px;font-size:.74rem}
.slim .t-topic .card .fbbox{display:none}
@media(max-width:700px){
  .slim .t-topic .grp{flex-direction:column;gap:6px}
  .slim .t-topic .gh{flex:none}
  .t-topic .vtog{position:static;margin-top:8px}
}

/* owner feedback mode (only the site owner ever sees this) */
.t-topic .fbtoggle{display:none;font-size:.75rem;font-weight:700;border:1.5px solid var(--coral);color:var(--coral);background:var(--paper);border-radius:99px;padding:5px 13px;cursor:pointer}
body.t-topic.owner .fbtoggle{display:inline-block}
body.t-topic.fbmode .fbtoggle{background:var(--coral);color:#fff}
.t-topic .fbbox{display:none;margin-top:10px;border-top:1px dashed var(--border);padding-top:9px}
body.t-topic.fbmode .fbbox{display:block}
.t-topic .fbbox textarea{width:100%;min-height:44px;font:inherit;font-size:.82rem;border:1.5px solid var(--border-strong);border-radius:8px;padding:6px 8px;resize:vertical}
.t-topic .fbrow{display:flex;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap}
.t-topic .fbrow select{font:inherit;font-size:.78rem;padding:4px 6px;border-radius:7px;border:1.5px solid var(--border-strong)}
.t-topic .fbflag{font-size:.78rem;font-weight:700;background:var(--coral);color:#fff;border:none;border-radius:8px;padding:6px 13px;cursor:pointer}
.t-topic .fbflag:hover{background:var(--coral-dark)}
.t-topic .fbmsg{font-size:.75rem;font-weight:700}
.t-topic .fbchips{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
.t-topic .fbstatus{font-size:.6rem;font-weight:800;border-radius:99px;padding:2px 8px;letter-spacing:.03em;cursor:help}
.t-topic .fbstatus.open{background:#fee2e2;color:var(--coral-dark)}
.t-topic .fbstatus.amber{background:#fef3c7;color:#92400e}
.t-topic .fbstatus.green{background:#dcfce7;color:#166534}
.t-topic .fbstatus.red{background:#fecaca;color:#991b1b}

/* ============================ .t-hub — the hub and the course landings ============================ */
.t-hub{--hero-pad:40px 20px 34px;--h1:2.3rem;--card-min:240px}

.t-hub .hero .lede,.t-hub .hero p{font-size:1.02rem;color:#d7d4cf;max-width:660px}
.t-hub .chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.t-hub .chip{background:rgba(255,255,255,.09);border:1px solid rgba(255,255,255,.22);border-radius:20px;padding:5px 13px;font-size:.8rem;color:#EFEADD;font-weight:600}
.t-hub .note{display:inline-block;background:#fff8e1;border:1px solid #fde68a;color:#8a6d1b;font-size:.78rem;border-radius:9px;padding:6px 12px;margin-top:18px}

.t-hub section{margin-bottom:38px}
.t-hub section h2{font-size:1.25rem;margin:0 2px 12px}
.t-hub .secsub{color:var(--muted);font-size:.92rem;max-width:720px;margin:-6px 2px 16px}
.t-hub section h2 .cl:hover{color:var(--coral)}
.t-hub section h2 .cn{font-size:.78rem;color:var(--faint);font-weight:600;margin-left:6px}

.t-hub .courses{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}
.t-hub .course{background:var(--paper);border:1.5px solid var(--border);border-radius:14px;padding:18px;position:relative;display:flex;flex-direction:column;gap:6px}
.t-hub .course.live{border-color:var(--coral);box-shadow:0 3px 16px rgba(220,38,38,.08)}
.t-hub .course.live:hover{box-shadow:0 6px 22px rgba(220,38,38,.16)}
.t-hub .course.soon{opacity:.75;border-style:dashed}
.t-hub .cbadge{position:absolute;top:-9px;right:14px;background:var(--coral);color:#fff;font-size:.68rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;border-radius:20px;padding:3px 10px}
.t-hub .cbadge.sb{background:var(--faint)}
.t-hub .cname{font-weight:800;font-size:1.12rem}
.t-hub .cmeta{font-size:.82rem;color:var(--muted)}
.t-hub .cgo{margin-top:6px;font-size:.85rem;font-weight:700;color:var(--coral)}

.t-hub .demo{background:var(--paper);border:1.5px solid var(--border);border-radius:16px;padding:24px}
.t-hub .demoin{display:flex;gap:26px;align-items:center;flex-wrap:wrap}
.t-hub .demotext{flex:1;min-width:260px}
.t-hub .democard{flex:1;min-width:300px;background:var(--cream);border:1.5px solid var(--border);border-radius:12px;padding:18px}
.t-hub .drow{display:flex;gap:14px;align-items:flex-start}
.t-hub .dq{font-size:1.05rem;margin-bottom:10px;min-height:3em;flex:1}
.t-hub .dfig{flex:0 0 auto}
.t-hub .dfig svg{display:block}
.t-hub .da{font-size:.95rem;background:var(--paper);border:1px solid var(--border);border-radius:9px;padding:10px 13px;margin-bottom:12px}
.t-hub .dbtns{display:flex;gap:8px}
.t-hub .btn{background:var(--coral);color:#fff;border:none;border-radius:9px;padding:9px 16px;font:700 14px 'Segoe UI',Arial,sans-serif;cursor:pointer}
.t-hub .btn:hover{background:var(--coral-dark)}
.t-hub .btn.ghost{background:var(--paper);color:var(--ink);border:1.5px solid var(--border-strong)}
.t-hub .btn.ghost:hover{border-color:var(--ink)}

.t-hub .journey{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px;counter-reset:jn}
.t-hub .jstep{background:var(--paper);border:1.5px solid var(--border);border-radius:12px;padding:13px 15px;display:flex;gap:12px;align-items:flex-start;position:relative;counter-increment:jn}
.t-hub .jstep::before{content:counter(jn);position:absolute;top:-8px;left:12px;background:var(--ink);color:#fff;font-size:.68rem;font-weight:800;border-radius:20px;padding:2px 8px}
.t-hub .jic{flex:0 0 auto;margin-top:3px;display:flex;color:var(--muted)}
.t-hub .jname{font-weight:800;font-size:.98rem}
.t-hub .jsub{font-size:.8rem;color:var(--muted);margin:1px 0 7px}
.t-hub .jchips{display:flex;flex-wrap:wrap;gap:5px}
.t-hub .jchip{background:var(--cream);border:1px solid var(--border);border-radius:20px;padding:2px 10px;font-size:.76rem;font-weight:600;color:#3A362E}

.t-hub .card{padding:15px 16px;display:flex;flex-direction:column;gap:5px}
/* DECISION 5b, SETTLED BY THE OWNER IN TT7: lift-on-hover is now BOTH surfaces. It was hub-only
   while the topic page still spent coral on a permanently-featured Fluency card; dropping that ring
   freed the colour, so the same gesture now means the same thing everywhere in the toolkit. */
.t-hub .card:hover{border-color:var(--coral);box-shadow:var(--shadow-lift)}
.t-hub .card .ct{font-size:1.02rem}
.t-hub .card .cs{font-size:.8rem;color:var(--muted)}
/* STRAND TAG (TT10, item 4) — the course landing painted all 15 topics identically.
   Thesis rules, non-negotiable and followed here: the strand mark is a LABELLED pill carrying the
   strand NAME (identity is never colour-alone, which is also what makes it CVD-safe), and it sits
   BESIDE the title — never as the card fill or border, because that mark is owned by the level flag
   and two colour meanings must not stack.

   The hue pair is inline per topic (it is data, not styling) and is INK-ON-TINT rather than the
   thesis's textOn() white/dark choice, because textOn() cannot save Number: #2a78d6 measures
   4.42:1 under white and 3.94:1 under ink, so neither option clears AA at pill size. Ink-on-tint is
   the house pattern already validated in print_palette.js's tag pairs; each strand's tint and ink
   are the SAME validated hue lightened and darkened, all seven measured at 4.8:1 or better. The
   palette is unchanged — only the way it is applied to text. */
.t-hub .strand-tag{display:inline-block;font-size:.66rem;font-weight:800;letter-spacing:.02em;
  padding:2px 8px;border-radius:5px;white-space:nowrap;align-self:flex-start}
/* The landing already GROUPS by strand, so the mark belongs on the group header and the anchor
   strip a teacher scans — a pill on all fifteen rows would repeat the header's own name. The dot
   is the thesis's own choice for a header that already carries the name ("the palette group headers
   keep the dot"), and the pale tint behind the heading is its other sanctioned application. */
.t-hub .strand h2 .sdot{display:inline-block;width:9px;height:9px;border-radius:50%;
  background:var(--strand-ink);margin-right:8px;vertical-align:1px;flex:none}
.t-hub .strand h2{background:linear-gradient(90deg,var(--strand-tint),transparent 62%);
  border-left:3px solid var(--strand-ink);padding:5px 0 5px 10px;border-radius:3px}
.t-hub .fbar .anch a .sdot{display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--strand-ink);margin-right:5px;vertical-align:0}
.t-hub .card .go{margin-top:8px;font-size:.82rem;font-weight:700;color:var(--coral);border:1.5px solid var(--coral);border-radius:20px;padding:5px 14px;align-self:flex-start;transition:all var(--ease)}
.t-hub .card:hover .go{background:var(--coral);color:#fff}

/* ---- course landing: sticky filter bar + strand sections + topic rows ---- */
.t-hub .fbar{position:sticky;top:0;z-index:30;background:var(--cream);border-bottom:1.5px solid var(--border);padding:10px 16px;display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.t-hub .fbar input{flex:1;min-width:220px;max-width:420px;font:600 15px 'Segoe UI',Arial,sans-serif;padding:9px 14px;border:1.5px solid var(--border-strong);border-radius:22px;background:var(--paper)}
.t-hub .fbar input:focus{border-color:var(--coral)}
.t-hub .fbar input:focus:not(:focus-visible){outline:none}
.t-hub .tsel{display:flex;gap:5px}
.t-hub .tsbtn{font:700 12.5px 'Segoe UI',Arial,sans-serif;padding:6px 13px;border-radius:20px;border:1.5px solid var(--border-strong);background:var(--paper);color:var(--ink);cursor:pointer}
.t-hub .tsbtn.on{background:var(--ink);color:#fff;border-color:var(--ink)}
.t-hub .anch{display:flex;gap:4px 12px;flex-wrap:wrap;font-size:.8rem;font-weight:700}
.t-hub .anch a{color:var(--muted);padding:4px 0}
.t-hub .anch a:hover{color:var(--coral)}
.t-hub section.strand h2{border-bottom:2px solid var(--border);padding-bottom:6px}
.t-hub .tlist{display:flex;flex-direction:column;gap:8px}
.t-hub .tpr{background:var(--paper);border:1.5px solid var(--border);border-radius:12px;padding:12px 16px;display:flex;gap:14px;align-items:center;transition:border-color var(--ease)}
.t-hub .tpr:hover{border-color:var(--coral)}
.t-hub .trmain{flex:1;min-width:0}
.t-hub .trhead{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.t-hub .trname{font-weight:800;font-size:1.02rem}
.t-hub .tchip{font-size:.68rem;font-weight:800;color:var(--muted);background:var(--cream);border:1px solid var(--border);border-radius:20px;padding:2px 9px;white-space:nowrap}
.t-hub .tchip.th{color:#7c2d12;background:#FEF3EB;border-color:#F5D8C2}
.t-hub .tchip.tf{color:#14532d;background:#F0FAF2;border-color:#CBEAD3}
.t-hub .fpline{display:flex;gap:9px;align-items:center;margin:6px 0 2px}
.t-hub .fp{display:inline-flex;gap:3.5px;flex-wrap:wrap}
.t-hub .fdot{width:9px;height:9px;border-radius:50%;border:1.5px solid var(--border-strong);background:var(--paper);display:inline-block}
.t-hub .fdot.on{background:var(--coral);border-color:var(--coral)}
.t-hub .fpn{font-size:.72rem;color:var(--faint);font-weight:600;white-space:nowrap}
.t-hub .trlinks{font-size:.8rem;color:var(--muted);margin-top:3px}
.t-hub .trlinks .ql{font-weight:700;color:var(--blue);margin-right:9px}
.t-hub .trlinks .ql:hover{text-decoration:underline}
.t-hub .pillgo{flex:0 0 auto;font-size:.84rem;font-weight:700;color:var(--coral);border:1.5px solid var(--coral);border-radius:22px;padding:8px 16px;white-space:nowrap;transition:all var(--ease)}
.t-hub .pillgo:hover{background:var(--coral);color:#fff}

.t-hub .trust{background:var(--ink);color:#fff;border-radius:16px;padding:26px 24px}
.t-hub .trust h2{color:#fff}
.t-hub .trow{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;margin-top:14px}
.t-hub .tcard{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.15);border-radius:12px;padding:15px}
.t-hub .tcard .tt{font-weight:800;margin-bottom:6px;color:var(--coral-pale)}
.t-hub .tcard p{font-size:.86rem;color:#d7d4cf}
.t-hub .back{font-size:.85rem;font-weight:700}
.t-hub .back a:hover{color:var(--coral)}

@media(max-width:560px){
  .t-hub .drow{flex-direction:column}
  .t-hub .dfig{margin:0 auto}
  .t-hub .tpr{flex-direction:column;align-items:stretch}
  .t-hub .pillgo{text-align:center}
  .t-hub .anch{display:none}
  .t-hub .hero h1{font-size:1.7rem}
  .t-hub .journey{grid-template-columns:1fr}
}
