/* course-wizard.css — the guided course-creation flow.
 *
 * Was a 45-line string concatenated inside course-creation-wizard.js's
 * _chrome(). It moved here for two reasons: the module was heading past the
 * context budget, and a stylesheet that is re-parsed on every render of every
 * step is a stylesheet in the wrong place.
 *
 * DESIGN SYSTEM. App-shell tokens only (--surface / --text / --accent /
 * --border / --good / --warn / --danger / --radius), which is what the rest of
 * this flow already used and what CODING-STANDARDS names as the canon for new
 * in-app UI. ZERO raw hex and zero magic colours — the discipline
 * outreach-funnel.css sets, applied to the shell's token family rather than
 * ui-kit's. That matters beyond tidiness: the courses UI was found carrying 19
 * hardcoded colours and rendering white cards on a dark page the moment a dark
 * theme landed (blueprint §9). Tokens are how that stops happening again.
 *
 * MOBILE FIRST. Base rules are the phone; desktop arrives in
 * @media (min-width: 900px). Courses are consumed on phones and built between
 * sessions on one, and mobile-first is a positioning claim for us (D35), not
 * just a breakpoint.
 */

/* ── Shell ─────────────────────────────────────────────────────────── */

/* ── How wide a wizard screen is ────────────────────────────────────────
   880 is the READING width: a single column of question cards, where a long
   measure is harder to read, not easier.

   `ccw-work` is the WORKSPACE width, and it is deliberately no cap at all —
   the same as #page-launch-phase-one, which is what a screen carrying the
   guided workspace has to match. Measured 2026-08-02 at a 1440px viewport:
   the website's main column came out at 970px and the wizard's at 482px,
   because this file capped at 880 and the website page capped at nothing. The
   rail is 380px in both, so the cap WAS the whole difference — the fixed rail
   ended up eating 44% of the course screen and 28% of the website's.

   ⚠️ This is a local width, which is the problem rather than the fix. There is
   no page-width contract anywhere in the design system — app-shell.css says so
   itself ("Each page may override max-width locally"). Recorded as DS-1 in
   docs/TODO.md; Alex's call, 2026-08-02, was to fix the symptom now and do the
   system properly later. When DS-1 lands, these three rules go with it. */
.ccw { max-width: 880px; margin: 0 auto; }
.ccw.ccw-work { max-width: none; }
.ccw.ccw-wide { max-width: 1180px; }

/* ── EIGHT RULES REMOVED HERE (A0y.3, 2026-08-04) — nothing produced them ──
   `.ccw-head`, `.ccw-actions`, `.ccw-crumbs`, `.ccw-crumb`, `.ccw-crumb.now`,
   `.ccw-crumb.done`, `.ccw-crumb-n`, `.ccw-crumb-sep`.

   Two separate deaths, both earlier in this same round:

     · **the step pills.** Alex asked for them deleted (see the note in
       `_chrome`), and the markup went — but the string that built it survived
       as a computed-then-`void`ed variable, so these five rules still had an
       author on paper and none in the browser. The variable is now gone too.
     · **the action bar.** `.ccw-head` / `.ccw-actions` dressed the two buttons
       removed from the head earlier in this round; the container went with
       them.

   ⚠️ `.crumb` and `.crumb-link` are a DIFFERENT thing and are still live — the
   Products / Courses breadcrumb at the top of the wizard. The names are one
   prefix apart, which is exactly the trap a grep-based sweep falls into: it
   was checked by reading both producers, not by matching the string. */

.ccw .ccw-card {
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); padding: 18px 14px;
}
.ccw .ccw-q { font-size: 21px; font-weight: 700; margin: 0 0 6px; line-height: 1.3; }
.ccw .ccw-sub { font-size: 14px; color: var(--text-3); margin: 0 0 18px; line-height: 1.55; }
.ccw .ccw-label { font-size: 12.5px; font-weight: 600; display: block; margin-bottom: 6px; }
.ccw .ccw-label .soft { font-weight: 400; color: var(--text-3); }
.ccw .ccw-step-of { font-size: 12px; color: var(--text-3); margin-bottom: 10px; }

/* ── The top bar clears the Help launcher ────────────────────────────
   Alex, 2026-08-03: "the help and the Save button at the top right are
   overlapping."

   ⚠️ ALREADY SOLVED ONCE, and this reuses that answer rather than re-deriving
   it. launch-studio.css carries the same rule for every #page-launch-* screen,
   with the measurements in its own comment: the "Ask AI / Help" launcher
   (support-widget.js) sits at top:14px right:20px in a ~108px band on desktop,
   and at ≤1024px it drops to the bottom-right leaving only the app-shell
   hamburger (~56px) up top. Same numbers here, because it is the same widget
   overlapping the same corner — the wizard simply was not covered by that
   selector.

   The right long-term fix is a page-width/gutter contract in the design system
   (DS-1 in docs/TODO.md), at which point this and launch-studio's copy both go. */
@media (min-width: 1025px) { .ccw .topbar-actions { margin-right: 96px; } }
@media (max-width: 1024px) { .ccw .topbar-actions { margin-right: 60px; } }

.ccw .ccw-foot {
  display: flex; gap: 10px; align-items: center; margin-top: 18px; flex-wrap: wrap;
}
/* ⚠️ THE FOOTER LOOKS THE SAME ON EVERY STEP, INCLUDING THE WIDE ONES.
   Alex, 2026-08-03: "the bottom bar doesn't conform to what the bottom bar
   should be looking like from the previous steps."

   Every step builds its footer from the same _chrome({footHtml}) — the markup
   and the button order were already identical. What differed was the WIDTH:
   `.ccw` is 880px and `.ccw-wide` (the Look step and the publish step) is
   1180px, so the same bar stretched 300px further and `.ccw-skip`'s
   `margin-left:auto` threw the skip link that much further from the buttons.
   Same bar, different shape, which is exactly what "doesn't conform" describes.

   Pinning the footer to the standard measure makes the two read as one bar
   again while the canvas above it keeps the width it needs. */
.ccw.ccw-wide .ccw-foot {
  max-width: 880px; width: 100%; margin-left: auto; margin-right: auto;
}
.ccw .ccw-skip {
  margin-left: auto; font-size: 12.5px; color: var(--text-3);
  text-decoration: underline; cursor: pointer; background: none; border: none;
}

/* ── Option cards ──────────────────────────────────────────────────── */

.ccw .ccw-opts { display: grid; gap: 10px; }
.ccw .ccw-opt {
  border: 1.5px solid var(--border); border-radius: var(--radius);
  padding: 16px; cursor: pointer; background: var(--surface); text-align: left;
  transition: border-color .12s, background .12s; font: inherit; color: inherit;
  min-height: 48px;
}
.ccw .ccw-opt:hover { border-color: var(--accent); }
.ccw .ccw-opt.on { border-color: var(--accent); background: var(--accent-softer); }
.ccw .ccw-opt .t,
.ccw .ccw-note .t { font-weight: 650; font-size: 15px; margin-bottom: 3px; }
.ccw .ccw-opt .d,
.ccw .ccw-note .d { font-size: 12.5px; color: var(--text-3); line-height: 1.45; }

/* An informational panel — the same box, but nothing to click.
   Alex, 2026-08-02, on the migration screen: "'What we need from you' and
   'What you get' are acting like buttons when you hover over them. I'm not
   sure why we're doing that because they're not buttons."
   They were `.ccw-opt` with an inline `cursor:default`, which is the giveaway:
   the class means "one of a set you choose between", so the pointer had to be
   patched out while the accent hover border stayed and went on promising a
   choice that does not exist. A thing that is not an option does not get the
   option class and then get corrected — it gets its own.

   ⚠️ THE CLASS IT GETS IS `.ccw-panel`, AND IT ALREADY EXISTED (line ~239).
   This fix originally declared a NEW `.ccw-note` here and never took effect:
   a WARNING box of that name already sat 118 lines below (warn-soft border and
   background, `.t`/`.d` in warn colours) and later-in-file wins — so the two
   explainer panels on the screen a coach sees straight after paying rendered
   as yellow alarms. The second collision of this kind in this file; the other
   was `.ccw-opt` restyling every option card as a monospace pill.

   Both had the same cause and the same cure: LOOK FOR THE CLASS BEFORE
   DECLARING IT. A neutral panel already existed and needed no new rule at all,
   which is why there is a comment here and no CSS. */

/* A chosen option card, and the one not chosen.
   The click handler used to set `disabled` and nothing else — and there was
   no [disabled] rule here, so the card kept its hover highlight and looked
   exactly as it had a moment earlier. Drafting a plan is two AI calls in the
   worst case, so "nothing happened" was the whole of the feedback for a wait
   that can run into tens of seconds. */
.ccw .ccw-opt[disabled] { cursor: default; opacity: 0.4; }
.ccw .ccw-opt[disabled]:hover { border-color: var(--border); }
.ccw .ccw-opt.on[disabled] { opacity: 1; border-color: var(--accent); background: var(--accent-softer); }

/* ── "We're drafting it" panel ─────────────────────────────────────── */
/* Shows what the plan is being built FROM — their own words, read back — so
   the wait has something to look at that proves the answers landed. */
.ccw .ccw-working { border: 1.5px solid var(--accent); border-radius: var(--radius);
  background: var(--accent-softer); padding: 18px; }
.ccw .ccw-working-head { display: flex; align-items: center; gap: 10px; font-weight: 650; font-size: 15px; }
.ccw .ccw-working-dots { display: inline-flex; gap: 4px; flex-shrink: 0; }
.ccw .ccw-working-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  display: block; animation: ccw-working-bounce 1.05s infinite ease-in-out; }
.ccw .ccw-working-dots i:nth-child(2) { animation-delay: .15s; }
.ccw .ccw-working-dots i:nth-child(3) { animation-delay: .30s; }
@keyframes ccw-working-bounce { 0%,80%,100% { transform: translateY(0); opacity:.45; }
  40% { transform: translateY(-5px); opacity: 1; } }
.ccw .ccw-working-from { margin-top: 14px; display: grid; gap: 9px; }
.ccw .ccw-working-from .r { font-size: 13.5px; line-height: 1.45; }
.ccw .ccw-working-from .r span.k { display: block; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-3); margin-bottom: 1px; }
.ccw .ccw-working-from .r span.v { color: var(--text); }
.ccw .ccw-working-foot { margin-top: 14px; font-size: 12.5px; color: var(--text-3); }
/* Respect a reader who has asked the OS to stop things moving. */
@media (prefers-reduced-motion: reduce) {
  .ccw .ccw-working-dots i { animation: none; opacity: 1; }
}

/* ── Plan editor ───────────────────────────────────────────────────── */

.ccw .ccw-hint {
  display: inline-block; font-size: 11.5px; background: var(--warn-soft);
  color: var(--warn); border: 1px solid var(--warn-soft);
  border-radius: 8px; padding: 2px 8px; margin: 2px 4px 2px 0;
}
.ccw .ccw-mod {
  border: 1px solid var(--border); border-radius: var(--radius);
  margin-bottom: 12px; overflow: hidden;
}
.ccw .ccw-mod-head {
  display: flex; gap: 8px; align-items: center; padding: 10px 12px;
  background: var(--surface-2); border-bottom: 1px solid var(--border-soft);
}
.ccw .ccw-mod-head input { flex: 1; min-width: 0; }
.ccw .ccw-mod-n { font-size: 12px; color: var(--text-3); flex: none; }
.ccw .ccw-lesson {
  display: flex; gap: 8px; align-items: center; padding: 8px 12px;
  border-bottom: 1px solid var(--border-soft); flex-wrap: wrap;
}
.ccw .ccw-lesson:last-child { border-bottom: none; }
.ccw .ccw-lesson input[data-lt] { flex: 2; min-width: 140px; }
.ccw .ccw-lesson input[data-lc] { flex: 3; min-width: 160px; }
.ccw .ccw-lesson-add { padding: 8px 12px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.ccw .ccw-ib {
  border: none; background: none; cursor: pointer; font-size: 13px;
  padding: 6px 8px; border-radius: 6px; color: var(--text-3);
}
.ccw .ccw-ib:hover { background: var(--surface-2); color: var(--text); }
.ccw .ccw-ib.danger { color: var(--danger); }
.ccw .ccw-filled {
  font-size: 11px; background: var(--good-soft); color: var(--good);
  padding: 2px 7px; border-radius: 8px; flex: none;
}
.ccw .ccw-rowtools { flex: none; display: flex; }

/* ── Progressive reveals — REMOVED 2026-08-03 ───────────────────────────
   `.ccw-reveal` drew a dashed box that turned solid and tinted when its
   checkbox was ticked. Alex: "I don't know why this shows how the shading is
   meant and what it's meant to mean. Is this consistent with the other UI, the
   UX, or the other pages? I don't think so."

   He is right on both counts. Dashed-means-off / tinted-means-on is a
   vocabulary that appears nowhere else in the product, and it sat directly
   beside a radio group where the identical tint meant nothing. The four
   settings are four questions now (_renderSetupQ), drawn with `.ccw-opt` — the
   same option card as every other question in the wizard, where `.on` is the
   only state and it means the one thing it means everywhere.

   `.ccw-toggle` STAYS — Go live's "Publish anyway" checkbox still uses it. */
.ccw .ccw-toggle {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer; font-size: 13px; min-height: 48px;
}
.ccw .ccw-toggle input { accent-color: var(--accent); }
.ccw .ccw-rec {
  font-size: 11px; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); border-radius: 20px; padding: 1px 8px; margin-left: 6px;
}

/* ── Checklist / rings / celebration ───────────────────────────────── */

.ccw .ccw-check-row {
  display: flex; gap: 10px; align-items: center; padding: 10px 12px;
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  margin-bottom: 8px; flex-wrap: wrap;
}
.ccw .ccw-check-row.done { opacity: .62; }
.ccw .ccw-check-row .lbl { flex: 1; min-width: 180px; font-size: 14px; }
.ccw .ccw-ring { width: 74px; height: 74px; flex: none; }
.ccw .ccw-fill-box { width: 100%; padding: 10px 12px 4px; }
.ccw .ccw-group-h {
  font-size: 12px; font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .04em; margin: 12px 0 6px;
}
.ccw .ccw-cele { text-align: center; padding: 34px 18px; }
.ccw .ccw-cele .big { font-size: 52px; line-height: 1; margin-bottom: 12px; }
.ccw .ccw-cele-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

.ccw .ccw-note {
  border: 1px solid var(--warn-soft); background: var(--warn-soft);
  border-radius: var(--radius); padding: 14px 16px; margin-bottom: 16px;
}
.ccw .ccw-note .t { font-weight: 650; font-size: 14px; margin-bottom: 6px; }
.ccw .ccw-note .d { font-size: 12.5px; color: var(--warn); line-height: 1.5; }
.ccw .ccw-panel {
  border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 14px 16px;
}
.ccw .ccw-panel .t { font-size: 13px; font-weight: 700; margin-bottom: 10px; }
.ccw .ccw-inline { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end; }
.ccw .ccw-inline > div { min-width: 110px; }
.ccw .ccw-msg { font-size: 12.5px; margin-top: 8px; color: var(--text-3); }
.ccw input.input, .ccw select.select, .ccw textarea.textarea { font: inherit; }
.ccw .ccw-answer { width: 100%; font-size: 16px; padding: 12px 14px; }

/* ── "What we already know" ────────────────────────────────────────── */

.ccw .ccw-known { display: grid; gap: 10px; margin-bottom: 16px; }
.ccw .ccw-known-row {
  display: flex; gap: 10px; align-items: baseline;
  padding: 10px 12px; border-radius: var(--radius); background: var(--surface-2);
}
.ccw .ccw-known-row .k {
  font-size: 11.5px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .03em; flex: none; min-width: 92px;
}
.ccw .ccw-known-row .v { font-size: 14px; line-height: 1.5; }
.ccw .ccw-swatch {
  width: 18px; height: 18px; border-radius: 5px; display: inline-block;
  vertical-align: -3px; border: 1px solid var(--border-strong); margin-right: 6px;
}
/* ── Chips ─────────────────────────────────────────────────────────────
   The pill itself is `.chip`, from css/guided-workspace.css — the workspace
   the wizard already wears (its shell is `ccw wz-shell gw`), so the component
   was loaded the whole time.

   There WAS a `.ccw-chip` here: a 20px-radius, 12.5px imitation of the 999px
   pill next to it. Alex, 2026-08-02, on the plan step's chips: "If you look at
   their website area, we have nice designed pills for this. These are ugly
   buttons. You check this on this needs to be fixed across wherever you've
   done this." Those were unclassed; these were a lookalike. Both are the same
   mistake at different distances, so both are gone.

   What survives is the two-line offer chip, which is a genuine extension
   rather than a copy — `.chip-src` modifies the component, it does not
   replace it.

   `.ccw-chips` (the row) stays: it is a tighter gap than the workspace's own
   `.chips` row, which is a spacing choice on this screen, not a second pill. */
.ccw .ccw-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.ccw .chip { cursor: pointer; font-family: inherit; min-height: 36px; }

/* ── Provenance: show it, offer it, never assume it (D51) ──────────────
   Nothing we hold is written into an input, so every borrowed value has to
   carry its own origin instead — on the "what we know" rows, and on each
   offer chip. The tag is the feature, not a footnote: it is the difference
   between a value that appeared from nowhere and one that reads as the app
   having paid attention. */

.ccw .ccw-src {
  display: block; margin-top: 3px;
  font-size: 11px; color: var(--text-3);
}
.ccw .ccw-fix {
  font-size: 12.5px; color: var(--text-3); line-height: 1.55; margin: 0 0 16px;
}
.ccw .ccw-fix a { color: var(--accent); }
.ccw .ccw-fix .soft { color: var(--text-3); }
.ccw .ccw-chips-lead { font-size: 12px; color: var(--text-3); margin-top: 14px; }
/* Two lines, so the source is readable rather than a tooltip nobody opens.
   Left-aligned and taller than a plain chip for the same reason. */
.ccw .chip.chip-src {
  text-align: left; padding: 6px 13px; border-radius: 14px;
  min-height: 44px; max-width: 100%;
}
.ccw .chip.chip-src .src {
  display: block; font-size: 10.5px; color: var(--text-3); line-height: 1.4;
}
.ccw .chip.chip-src .v {
  display: block; font-size: 13px; line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ccw .chip.chip-src:hover .src { color: var(--accent); }

/* ── Live preview panel ────────────────────────────────────────────── */

/* min-width:0 on the children is load-bearing, not defensive tidiness: a grid
   track sizes to its content by default, so one child that measures wider than
   the phone (the preview frame, mid-layout) widens the track and pushes the
   whole page — editor and all — off the right edge. */
.ccw .ccw-split { display: grid; gap: 16px; }
.ccw .ccw-split > * { min-width: 0; }
.ccw .ccw-preview {
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface-3); overflow: hidden;
}
.ccw .ccw-preview-bar {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  padding: 10px 12px; border-bottom: 1px solid var(--border); background: var(--surface);
}
.ccw .ccw-preview-bar .t { font-size: 12.5px; font-weight: 700; }
.ccw .ccw-preview-bar .s { font-size: 11.5px; color: var(--text-3); }
.ccw .ccw-vp { display: flex; gap: 4px; margin-left: auto; }
.ccw .ccw-vp button {
  border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
  border-radius: 20px; padding: 5px 11px; font: inherit; font-size: 12px; cursor: pointer;
}
.ccw .ccw-vp button.on { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.ccw .ccw-stage {
  padding: 12px; display: flex; justify-content: center; overflow: hidden;
}
/* WIDTH: 100% is load-bearing, and its absence was the preview bug.
 *
 * The stage is a flex container, so the mount div is a flex item with no
 * definite width — it sized to its content, and its content is an iframe,
 * whose default intrinsic width is 300px. So the div settled at 300px on
 * EVERY screen. CourseCoverPreview measures that div to decide its scale, so
 * an 878px-wide stage rendered the desktop preview (1280px) at scale 0.23 in a
 * 300px box, and the phone preview at 0.77 when it had room for 1.0.
 *
 * Measured on dev2 before the fix: stage 373 / host 300 on a phone, stage 878 /
 * host 300 on a desktop — the host never moved. That is "the course page
 * preview doesn't look good on mobile. Or in any of the previews", and it is
 * one declaration, not a component bug: the component's scale maths is right,
 * it was being handed a number that had nothing to do with the space available.
 */
.ccw .ccw-stage > * { max-width: 100%; width: 100%; }
.ccw .ccw-preview-bar { overflow-x: auto; }
/* The preview FRAME itself — `.ccw-frame-wrap`, its iframe, and the empty
   state — moved to css/course-preview-frame.css. It is the stylesheet of a
   component that has two consumers, and it lived here scoped to `.ccw`, so
   the Customize tab mounted the component and got none of it. What stays
   here is where the preview SITS, which is this page's business. */
.ccw .ccw-preview-toggle { width: 100%; margin-bottom: 12px; }

/* ── Template gallery ──────────────────────────────────────────────── */

/* The 31-card gallery grid that used to live here (.ccw-gal-cat / -grid /
   -card / -shot / -body / -tick) is GONE. Its emitter, _renderGalleryPostBuild,
   called two functions that did not exist and could only ever render an error
   — see the note where it used to be in course-creation-wizard.js. Orphaned
   CSS outlives the thing it dressed and reads as a feature that exists.
   `.ccw-gal` at the end of this file is the rail's design browser: same prefix,
   different component, and it has an emitter. */


/* Full-size look-at-it view, over the gallery. */
/* ⚠️ `.ccw-modal` WAS REMOVED 2026-08-06 — do not bring it back.
   It was the wizard's own modal shell, and its sheet was
   `width: min(100%, 1340px)`: a shell written for the TEMPLATE GALLERY, which
   is a big picker and wants the room. `_confirm` borrowed it for yes/no
   dialogs, so a two-line question rendered as an edge-to-edge banner with its
   buttons stranded in the corner. Alex, looking at one: *"This model doesn't
   look at all like our other nicely designed ones… This is a new style that I
   haven't seen before."*

   `_confirm` now calls `window.CBSheet.confirm` (ui-core.js), which is what
   the rest of this file and the rest of the app already use. The stylesheet
   goes with it rather than staying behind: a 1340px "sheet" left lying in the
   wizard's CSS is exactly what the next person builds a dialog out of. */
}

/* ── Desktop ───────────────────────────────────────────────────────── */

@media (min-width: 640px) {
  .ccw .ccw-card { padding: 26px; }
  /* `1fr 1fr 1fr` was right when the card was the full 880px shell. Inside the
     workspace the card shares the row with a 380px rail, so three fixed
     columns squeezed each option to ~190px and broke two-word headings across
     lines ("Brand / new"). auto-fit with a real minimum gives three across
     where there is room and two, then one, where there is not — the same cards
     either way, rather than a second set for the narrower column. */
  .ccw .ccw-opts.cols-3 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
  /* Two real alternatives (free address vs your own domain — L10). Same
     auto-fit reasoning as cols-3: a wider minimum because there are only two,
     so they stay side by side rather than stacking the moment the rail
     appears. Without this they inherited the base one-column grid and read as
     a list of two things rather than a choice between them. */
  .ccw .ccw-opts.cols-2 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
  /* aspect-ratio governs at every width now — nothing to override here. */
}

@media (min-width: 900px) {
  /* The preview is FIRST in the DOM (so a phone gets it next to the typing)
     and is placed into column 2 here. Sticky because the plan is taller than
     the screen: a live preview that scrolls away by module three is not a live
     preview. */
  .ccw .ccw-split { grid-template-columns: minmax(0, 1fr) 420px; align-items: start; }
  .ccw .ccw-split > .ccw-main { grid-column: 1; grid-row: 1; }
  .ccw .ccw-split > .ccw-side { grid-column: 2; grid-row: 1; position: sticky; top: 12px; }

  .ccw .ccw-preview-toggle { display: none; }
}

@media (min-width: 1200px) {

}

/* ── Toast ─────────────────────────────────────────────────────────── */
/* Body-level, so it sits outside .ccw. It was inline style in the JS for
   the same reason everything else here was: there was nowhere to put it. */
.ccw-toast {
  /* ⚠️ THIS LINE IS THE FIX FOR §DEAD-BUTTON, AND EVERY OTHER ATTEMPT MISSED IT.
     Alex, 2026-08-07, on a phone: *"I'll just tap it three or four times and
     maybe the fifth one will then move me through."*

     The toast element is created ONCE and cached (`_toastEl`,
     course-creation-wizard.js:115) and NEVER removed from the body — fading it
     only sets `opacity: 0`. An element at `opacity: 0` is still HIT-TESTABLE.
     So from the first toast of a session onward — and this wizard toasts
     constantly, "✓ Saved", "✓ Plan updated" — there was a permanent invisible
     bar, `position: fixed`, 26px off the bottom, up to 88vw wide, at z-index
     10010, sitting on top of everything.

     On a phone that is exactly where the primary button is. The clicks never
     reached the button at all, which is why moving the button onto a delegated
     listener changed nothing: the handler was never the problem.

     It explains every odd detail — mobile only (on desktop the button is not at
     bottom:26px), repeated taps eventually working (the bar is only as wide as
     its LAST message, so part of the button is exposed), leaving and coming
     back "fixing" it (different screen, button at a different height), and the
     intermittency (it starts only after the first toast is shown).

     A toast is never a control. `pointer-events: none` costs nothing and closes
     the whole class. Pinned by tests/toast-never-eats-a-tap.test.js, which
     hit-tests a point over the button rather than asserting the text. */
  pointer-events: none;
  position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%);
  background: var(--text); color: var(--surface);
  padding: 10px 18px; border-radius: var(--radius); font-size: 13.5px;
  z-index: 10010; transition: opacity .25s; max-width: 88vw; opacity: 0;
}

/* ── Release rhythm (2026-08-01) ────────────────────────────────────────
   The single on/off became three choices, one of which carries a number and
   a unit. Radios rather than a select because our users are non-technical
   coaches and the standards call for linear paths over grids of options —
   all three readable at once beats a dropdown that hides two of them. */
.ccw .ccw-radio {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 0; cursor: pointer; line-height: 1.5;
}
.ccw .ccw-radio input[type="radio"] {
  /* 48px targets are the rule; a radio cannot be 48px without looking wrong,
     so the LABEL is the target — the whole row is clickable and tall enough. */
  margin: 3px 0 0; width: 18px; height: 18px; flex-shrink: 0; cursor: pointer;
}
.ccw .ccw-radio > span { min-height: 26px; }
.ccw .ccw-inline-n { width: 68px; display: inline-block; padding: 4px 8px; }
.ccw .ccw-inline-u { width: auto; display: inline-block; padding: 4px 8px; }
@media (max-width: 640px) {
  /* On a phone the number and unit wrap under the sentence rather than
     squeezing it — a 375px row cannot hold "one module every [2] [weeks]"
     on one line without the controls becoming untappable. */
  .ccw .ccw-radio > span { display: block; }
  .ccw .ccw-inline-n, .ccw .ccw-inline-u { margin-top: 6px; }
}

/* ── Touch targets where there is no pointer ────────────────────────────
 *
 * CODING-STANDARDS: 48px. Audited 2026-08-01 against app-shell.css and found
 * three controls short of it — the offer chips (36px), the small icon buttons
 * (about 25px with their padding) and the radio rows (about 44px). All three
 * are sized for density on a desktop, which is the right call THERE: a 48px
 * chip in a row of six offers reads as six buttons rather than six
 * suggestions.
 *
 * So the fix is conditioned on the input device rather than the width. A
 * phone in landscape is still a thumb, and a 1280px touchscreen is still a
 * thumb; `pointer: coarse` is the actual fact, where `max-width: 640px` is a
 * proxy for it that gets both of those wrong. Same rule the Builder panel
 * uses on the same page.
 */
@media (pointer: coarse) {
  .ccw .chip { min-height: 48px; }
  .ccw .ccw-ib { min-height: 48px; min-width: 48px; }
  /* The radio's own box stays 18px — a 48px radio looks broken. The ROW is
     the target, which is why the label is what grows. */
  .ccw .ccw-radio { padding: 13px 0; }
  .ccw .ccw-radio > span { min-height: 22px; }
}

/* ── The Look step's two columns ───────────────────────────────────────
 *
 * Preview left, controls right — the website builder's own arrangement, so a
 * coach who has picked a palette for their site finds the same shape here.
 * The controls themselves are css/look-pickers.css; this is only where they
 * sit, which is the page's business and not the component's.
 *
 * 375px-first: stacked, preview first. The preview IS the point of the screen
 * — you are choosing by looking — so on a phone it goes above the swatches
 * rather than below them.
 */
.ccw .ccw-look-grid { display: flex; flex-direction: column; gap: 16px; }
.ccw .ccw-look-grid .lk-rail { display: flex; flex-direction: column; gap: 14px; }

@media (min-width: 1000px) {
  .ccw .ccw-look-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 18px; align-items: start; }
  .ccw .ccw-look-grid .ccw-preview { position: sticky; top: 16px; }
}

/* ── The rail's design card, before a design exists ──────────────────────
   The workspace (css/guided-workspace.css) draws the rail; what goes INSIDE
   its design card differs between the two flows and belongs to each. A
   website has already chosen its design before the questions start, so the
   website's card always has a picture. A course chooses at step 3, so for the
   whole of step 1 there is nothing to show — and an empty frame reads as
   broken where a sentence reads as a promise. */
.ccw .ccw-rail-shot { aspect-ratio: 16/9; overflow: hidden; background: var(--surface-3); }
.ccw .ccw-rail-shot img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }
.ccw .ccw-rail-name {
  padding: 12px 16px; font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700; font-size: 15px; letter-spacing: -0.01em;
}
.ccw .ccw-rail-soon {
  padding: 20px 18px; font-size: 13.5px; line-height: 1.55; color: var(--text-3);
  border-top: 1px solid var(--border-soft);
}
/* The suggestion chips are ours — the website's flow has no "you already told
   us this" case, because it has nowhere to have been told. They sit in the
   workspace's own `.chips` row, so only the button needs describing. */
.ccw .gw .chips .chip-src, .ccw .chips .chip-src {
  display: inline-flex; flex-direction: column; align-items: flex-start; gap: 2px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 8px 12px; cursor: pointer; text-align: left;
  max-width: 100%; min-height: 48px; justify-content: center;
}
.ccw .chips .chip-src:hover { border-color: var(--accent); background: var(--accent-softer, var(--accent-soft)); }
.ccw .chips .chip-src .src {
  font-family: "JetBrains Mono", monospace; font-size: 9.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-4);
}
.ccw .chips .chip-src .v { font-size: 13px; color: var(--text); }

/* Suggested-price chips on a phone.
   Measured at 375px on the price question: 36px tall, against the 48px
   CODING-STANDARDS asks for. They are the fastest way to answer that
   question on a phone — a chip you have to aim at is worse than no chip. */
@media (max-width: 760px) {
  .ccw .chip { min-height: 48px; padding-top: 12px; padding-bottom: 12px; }
  /* And the buttons beside them — Continue and "I'll decide later" measured
     37px. Scoped to `.ccw` rather than fixing `.btn` globally: app-shell's
     button is shared by every screen in the product, and a blanket height
     change is a change to all of them. The wizard is what was measured, so
     the wizard is what is fixed. */
  .ccw .btn { min-height: 48px; }
}

/* The celebration screen's oversized primary pair. Design audit F7: the size
   tweak was written inline on both buttons — a variation is a modifier class
   (design-system.md §2), so it lives here instead. */
.ccw .btn.ccw-btn-big { font-size: 15px; padding: 12px 24px; }

/* ── The "how does this work?" explainer ─────────────────────────────────
   Alex, 2026-08-02: "It needs to be a full explanation where they can
   actually go and open it." A <details> rather than a modal: the answer
   belongs beside the control it explains, and a coach reading it should not
   lose the screen they were filling in. */
.ccw .ccw-explain {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2);
}
.ccw .ccw-explain > summary {
  cursor: pointer; padding: 12px 14px; font-size: 13.5px; font-weight: 600;
  list-style: none; min-height: 48px; display: flex; align-items: center; gap: 8px;
}
.ccw .ccw-explain > summary::-webkit-details-marker { display: none; }
.ccw .ccw-explain > summary::before { content: "?"; flex: none;
  width: 20px; height: 20px; border-radius: 50%; background: var(--accent-soft);
  color: var(--accent-deep); font-size: 12px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; }
.ccw .ccw-explain[open] > summary { border-bottom: 1px solid var(--border-soft); }
.ccw .ccw-explain-b { padding: 4px 14px 14px; }
.ccw .ccw-explain-b p { font-size: 13.5px; line-height: 1.6; color: var(--text-2); margin: 10px 0 0; }
.ccw .ccw-explain-b a { color: var(--accent); text-decoration: underline; }

/* ── The Look step's own controls (2026-08-02) ───────────────────────────
   The nine LAYOUTS, the 31 worlds demoted to presets, and the cover photo.
   The palette and typeface grids beside them are look-pickers.css and are not
   touched here — the point of this screen is that they are the same control
   the coach met on the website.

   Measured, not assumed: the 31 templates are nine hero x modules
   combinations wearing 31 token blocks. See
   docs/projects/courses/look-step-spec.md. */
.ccw .ccw-laygrid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  /* Fallbacks only. The palette picker rewrites both on every tap, which is
     what makes the tiles agree with the page in front of them. */
  --lg-acc: var(--accent); --lg-mut: var(--text-2);
}
.ccw .ccw-lay {
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
  padding: 8px; border: 1.5px solid var(--border); border-radius: var(--radius);
  background: var(--surface); cursor: pointer; font: inherit; color: inherit;
  text-align: left;
}
.ccw .ccw-lay:hover { border-color: var(--accent); }
.ccw .ccw-lay.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.ccw .ccw-lay .g {
  display: block; width: 100%; background: var(--surface-2);
  border-radius: calc(var(--radius) - 4px); padding: 4px 0; text-align: center;
}
.ccw .ccw-lay .g svg { width: 100%; height: auto; display: block; }
.ccw .ccw-lay .n { font-size: 11px; line-height: 1.35; color: var(--text-2); }

/* The worlds. Deliberately a dense list of names rather than 31 thumbnails:
   a whole page at thumbnail size is unreadable however correctly it scales,
   and the preview beside them is showing the real thing the moment one is
   tapped. */
.ccw .ccw-worlds { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.ccw .ccw-world {
  display: block; padding: 7px 9px; min-width: 0;
  border: 1.5px solid var(--border); border-radius: calc(var(--radius) - 4px);
  background: var(--surface); cursor: pointer; font: inherit; color: inherit;
  text-align: left;
}
.ccw .ccw-world:hover { border-color: var(--accent); }
.ccw .ccw-world.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.ccw .ccw-world .n,
.ccw .ccw-world .f {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ccw .ccw-world .n { font-size: 12px; font-weight: 650; }
.ccw .ccw-world .f { font-size: 10.5px; color: var(--text-2); }

/* The cover photo's own row. The PICKER's styles are not here — it is the
   website's component (js/photo-picker.js) and css/photo-stage.css owns them,
   which is why this screen opts into `.pho`. The search box, grid and cell
   rules that used to sit here went with the bespoke picker they styled:
   `.ccw-imgsearch`, `.ccw-imggrid` and `.ccw-imgcell` have no markup left.
   48px targets — this rail is used on a phone, where it stacks under the
   preview. */
.ccw .ccw-imgrow { display: flex; gap: 8px; flex-wrap: wrap; }
.ccw .ccw-imgrow .btn { flex: 1 1 auto; min-height: 44px; }

@media (max-width: 760px) {
  /* One column of layout tiles on a phone: two put the caption on four lines
     and the glyph below anything readable. */
  .ccw .ccw-laygrid { grid-template-columns: 1fr; }
  .ccw .ccw-lay { flex-direction: row; align-items: center; gap: 10px; min-height: 48px; }
  .ccw .ccw-lay .g { width: 96px; flex: none; }
  .ccw .ccw-world { min-height: 48px; }
}

/* ── A one-line composer (2026-08-02) ───────────────────────────────────
   A name is not a paragraph. Alex: "The box is too big for the text. It
   should just be like a smaller thing for the name, suitable for the name."
   Same composer shell, so it still reads as Maya's control and still carries
   Speak and Send — only the field changes shape. */
/* ⚠️ `textarea` as well as `input` — the one-line answer box became a
   one-line TEXTAREA (§NAME-PILL, 2026-08-07). It was the only `<input>` among
   the wizard's textareas, and Chrome's password manager only offers saved
   credentials on `<input>`, so that element type was the whole trigger.
   `resize: none` and `overflow: hidden` are what keep a textarea LOOKING like
   the single-line box Alex asked for: *"The box is too big for the text."* */
.ccw .composer.one-line input.ccw-answer,
.ccw .composer.one-line textarea.ccw-answer {
  width: 100%; border: 0; background: none; font: inherit; color: inherit;
  padding: 12px 14px 4px; outline: none; min-height: 44px;
  resize: none; overflow: hidden; line-height: 1.4;
}
.ccw .composer.one-line input.ccw-answer::placeholder,
.ccw .composer.one-line textarea.ccw-answer::placeholder { color: var(--text-2); opacity: .7; }

/* The second thought, not the main action: suggestions have already arrived,
   so asking for another six is a link rather than a button. */
.ccw .ccw-link {
  background: none; border: 0; padding: 6px 4px; font: inherit; font-size: 12.5px;
  color: var(--accent); text-decoration: underline; cursor: pointer; min-height: 44px;
}
.ccw .ccw-link:hover { opacity: .8; }

/* ── Pointing at the control instead of describing it (2026-08-04) ──────
   Alex: "have you built really good UX that takes you directly to the problem…
   a super stupid approach, that people can just fix it without having to go
   anywhere?" When Next is refused because a button on the SAME screen has not
   been pressed, the answer is to show them the button, not to name it.

   Two pulses and stop. A ring that keeps breathing reads as a state the coach
   has to clear; this is a gesture that finishes on its own.
   `prefers-reduced-motion` gets the ring without the movement — the point is
   the emphasis, and the emphasis survives without the animation. */
@keyframes ccw-nudge-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
  50%      { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 35%, transparent); }
}
.ccw .ccw-nudge {
  animation: ccw-nudge-pulse .7s ease-in-out 2;
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 8px;
}
@media (prefers-reduced-motion: reduce) {
  .ccw .ccw-nudge { animation: none; }
}

/* ── The value levers (2026-08-02) ──────────────────────────────────────
   What replaced the market statistic under the price box. Ticked is what a
   course at this price usually includes — and every row is something the coach
   can actually deliver themselves. */
.ccw .ccw-levers { border-top: 1px solid var(--border-soft); padding-top: 14px; }
.ccw .ccw-levers .lv-h { font-weight: 650; font-size: 14px; }
.ccw .ccw-lever {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px;
  border: 1px solid var(--border); border-radius: calc(var(--radius) - 4px);
  margin-bottom: 6px; cursor: pointer; min-height: 48px; background: var(--surface);
}
.ccw .ccw-lever:hover { border-color: var(--accent); }
.ccw .ccw-lever input { flex: none; width: 18px; height: 18px; accent-color: var(--accent); }
.ccw .ccw-lever .t { flex: 1 1 auto; font-size: 13.5px; }
.ccw .ccw-lever .tag {
  flex: none; font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-2); border: 1px solid var(--border); border-radius: 999px; padding: 3px 8px;
}
.ccw .ccw-lever .tag.rec { color: var(--accent); border-color: var(--accent); }
/* There was an `.is-dfy` variant here — greyed-out rows for the three things
   the self-serve builder does not make, tagged "we build this for you". Removed
   2026-08-02. Alex: "we're not offering done-for-you service at this stage.
   They shouldn't even be aware of done-for-you services." A greyed-out row is
   an advertisement whatever it says. See LEVERS in course-creation-wizard.js. */

/* ── The plan, read first (2026-08-02) ──────────────────────────────────
   The layout is css/review-canvas.css — this is only what goes INSIDE its
   canvas. Alex: "The lesson plan should be showing everything and everything
   should be legible in one go, not having to drag and scroll through open text
   boxes." So a lesson is a line of text until you open it. */
.ccw .pl-mod-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.ccw .pl-mtitle {
  flex: 1 1 auto; min-width: 0; font-size: 17px; font-weight: 700;
  border-color: transparent; background: transparent; padding-left: 6px;
}
.ccw .pl-mtitle:hover { border-color: var(--border); }
.ccw .pl-mtitle:focus { border-color: var(--accent); background: var(--surface); }

/* A lesson at rest: everything visible, nothing truncated. */
.ccw .pl-row {
  display: flex; align-items: flex-start; gap: 12px; width: 100%;
  padding: 12px 12px; border: 1px solid var(--border-soft); border-radius: var(--radius);
  background: var(--surface); cursor: pointer; text-align: left; font: inherit;
  color: inherit; margin-bottom: 6px; min-height: 48px;
}
.ccw .pl-row:hover { border-color: var(--accent); background: var(--surface-2); }
.ccw .pl-row .n {
  flex: none; font-variant-numeric: tabular-nums; font-weight: 700;
  font-size: 12px; color: var(--text-2); padding-top: 2px;
}
.ccw .pl-row .body { flex: 1 1 auto; min-width: 0; }
.ccw .pl-row .t { display: block; font-weight: 650; font-size: 14px; }
/* No ellipsis and no nowrap anywhere in here — the whole point is that the
   line is READABLE. It wraps instead. */
.ccw .pl-row .c { display: block; font-size: 12.5px; color: var(--text-2); margin-top: 2px; }
.ccw .pl-row .meta { flex: none; font-size: 11.5px; color: var(--text-2); padding-top: 2px; }
.ccw .pl-filled {
  margin-left: 8px; font-size: 10.5px; color: var(--accent);
  border: 1px solid var(--accent); border-radius: 999px; padding: 1px 7px;
}

/* The lesson's picture, chosen at the plan stage (Alex, 2026-08-02). Sits
   BESIDE the row rather than inside it, because the row is a <button> and a
   button inside a button is not markup a browser will honour — the picture
   would not be separately clickable, which is the whole feature. 48px on the
   short side so it is a real touch target on a phone. */
.ccw .pl-rowwrap { display: flex; align-items: flex-start; gap: 8px; }
.ccw .pl-rowwrap .pl-row { margin-bottom: 6px; }
.ccw .pl-thumb {
  flex: none; width: 64px; height: 48px; margin-bottom: 6px; padding: 0;
  border: 1px solid var(--border-soft); border-radius: calc(var(--radius) - 4px);
  background: var(--surface-2); overflow: hidden; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ccw .pl-thumb:hover, .ccw .pl-thumb.on { border-color: var(--accent); }

/* ── The expanded lesson keeps its picture, and can be clicked shut ──────
   Alex, 2026-08-03: "when you expand it, you should still be able to see your
   image for that segment so you could change it still then" and "when you click
   on it again it should collapse… because that's an intuitive UX".

   The wrapper is the same `.pl-rowwrap` the collapsed row uses, so the thumb
   sits in exactly the same place whichever state the lesson is in — that is
   what stops the picture jumping when it opens. */
.ccw .pl-rowwrap > .pl-edit { flex: 1; min-width: 0; }
.ccw .pl-edit-collapse {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; margin: -4px 0 8px; padding: 0 0 8px;
  background: none; border: none; border-bottom: 1px solid var(--border-soft);
  cursor: pointer; font: inherit; color: inherit; text-align: left; min-height: 34px;
}
.ccw .pl-edit-collapse .t { font-weight: 650; font-size: 14px; }
.ccw .pl-edit-collapse .x { font-size: 12px; color: var(--text-3); flex: none; }
.ccw .pl-edit-collapse:hover .x { color: var(--accent); }

/* The picker's own chrome — a heading and a way out that is not a deletion. */
.ccw .pl-thumbpick-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 12.5px; font-weight: 650; margin-bottom: 8px;
}
.ccw .pl-thumbpick-act {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px;
}
/* ⚠️ `.ccw-skip` carries `margin-left:auto`, which would shove "No picture"
   to the far edge and make the two exits read as unrelated. They belong
   together — one keeps, one clears. */
.ccw .pl-thumbpick-act .ccw-skip { margin-left: 0; }

/* A6 — the picture is as tall as the words beside it. Alex: "it'd be nice if
   the image was the perfect height that matched the same height as the module
   text." `align-self: stretch` lets it take the row's height instead of a fixed
   48px, and the min-height keeps a one-line lesson from collapsing it to
   nothing. The 4:3 box is gone, so `object-fit: cover` (already set) does the
   cropping. */
.ccw .pl-rowwrap > .pl-thumb {
  align-self: stretch; height: auto; min-height: 48px; margin-bottom: 6px;
}
/* ⚠️ …but ONLY while the lesson is collapsed. Alex, 2026-08-03: "when you
   expand it the image gets longer like that. It should stay the same thumbnail
   that it was when it's collapsed. There'll be a big gap below it but we'll
   just stay there."

   Matching the row's height is right for a two-line row and wrong for a tall
   editor: stretch turned a 64x48 picture into a 64x600 column of cropped grass.
   The expanded state keeps the collapsed size and sits at the top, so the
   picture does not move at all when the lesson opens — which was the point of
   sharing the wrapper in the first place. */
.ccw .pl-rowwrap.is-open > .pl-thumb {
  align-self: flex-start; height: 48px; min-height: 0;
}
.ccw .pl-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ccw .pl-thumb .ph { font-size: 16px; color: var(--text-3); line-height: 1; }
/* Still being fetched, not missing. Alex, 2026-08-02: "as long as you know
   that they're still loading and it is still trying to load, it could drop you
   in there sooner." A shimmer says working; the bare ＋ said empty. */
.ccw .pl-thumb.loading {
  cursor: progress;
  background: linear-gradient(100deg,
    var(--surface-2) 30%, var(--border-soft) 50%, var(--surface-2) 70%);
  background-size: 260% 100%;
  animation: ccw-thumbshimmer 1.25s ease-in-out infinite;
}
@keyframes ccw-thumbshimmer {
  from { background-position: 160% 0; }
  to   { background-position: -60% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ccw .pl-thumb.loading { animation: none; }
}

/* ── What the drop zone accepts, as marks rather than a sentence ──────
   Alex, 2026-08-02: "For the drag-and-drop we should be using images not all
   this block of text." The formats used to be a four-line paragraph naming
   eleven extensions inside the drop zone. The lane, the drop and the file rows
   are launch-studio.css's (see the `.brl` scope there) — these three rules are
   the only thing this screen adds, because it is the only thing that screen
   does not already have. */
.ccw .ccw-kinds {
  display: flex; gap: 14px; justify-content: center; flex-wrap: wrap;
  margin-top: 12px;
}
.ccw .ccw-kind { font-size: 12px; color: var(--text-3); white-space: nowrap; }
.ccw .ccw-kind b { font-size: 14px; font-weight: 400; }
/* ⚠️ NAMED `ccw-optional`, NOT `ccw-opt`. This was `.ccw-opt` for six hours and
   it silently restyled every option card in the wizard: `.ccw .ccw-opt` is the
   big choice CARD (line 84), this is a 9.5px "Optional" badge, and because this
   block comes later in the file it won every property it declares. "What have
   you got so far?" rendered as three uppercase monospace pills.

   The lesson is the name, not the cascade: a badge and a card are different
   things and a four-letter abbreviation shared between them will collide again.
   Nothing here is scoped tightly enough to protect against a duplicate class —
   only a distinct one is. */
.ccw .ccw-optional {
  font-family: "JetBrains Mono", monospace; font-size: 9.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-3); background: var(--surface-3);
  padding: 3px 7px; border-radius: 999px; margin-left: 6px; vertical-align: middle;
}

/* The recordings still being transcribed, on the hold-before-drafting screen. */
.ccw .ccw-uplist-plain {
  list-style: none; margin: 12px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.ccw .ccw-uplist-plain li { font-size: 13px; color: var(--text-2); }

/* One press, one answer: while a saved answer is in flight the card is inert,
   so the second press of a slow button has nothing to hit. See _freezeStep. */
.ccw.is-busy { opacity: .62; cursor: progress; }
.ccw.is-busy * { pointer-events: none; }
/* The picker, opened under the lesson it belongs to. `pho` is the opt-in for
   css/photo-stage.css, which owns the picker's own styles — the same borrowing
   the Look step does. */
.ccw .pl-thumbpick {
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  background: var(--surface-2); padding: 12px; margin: 0 0 10px 72px;
}
@media (max-width: 560px) { .ccw .pl-thumbpick { margin-left: 0; } }

/* …and open, which is the only form on screen. */
.ccw .pl-edit {
  border: 1.5px solid var(--accent); border-radius: var(--radius);
  padding: 12px; margin-bottom: 6px; background: var(--surface);
}
.ccw .pl-edit-row { display: flex; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.ccw .pl-edit-row .input { flex: 1 1 200px; min-width: 0; }
.ccw .pl-edit-act { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.ccw .pl-mod-foot { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 12px; }

/* Overview: the module list as a table of contents you can jump from. */
.ccw .ccw-plan-sum { margin-top: 18px; border-top: 1px solid var(--border-soft); padding-top: 14px; }
.ccw .pl-sumrow {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 8px;
  background: none; border: 0; border-bottom: 1px solid var(--border-soft);
  cursor: pointer; font: inherit; color: inherit; text-align: left; min-height: 48px;
}
.ccw .pl-sumrow:hover { background: var(--surface-2); }
.ccw .pl-sumrow .n { flex: none; font-variant-numeric: tabular-nums; font-size: 12px; color: var(--text-2); }
.ccw .pl-sumrow .t { flex: 1 1 auto; font-weight: 650; font-size: 14px; }
.ccw .pl-sumrow .m { flex: none; font-size: 12px; color: var(--text-2); }

/* Maya's thread on this screen is css/assistant-panel.css's — .rc-mmsg with
   its .rc-ava and .rc-mbub, exactly as the website's copy step draws it.
   A local imitation lived here (`.rc-thread .ccw-msg`, a flat grey line and a
   tinted box) alongside chips that carried no class at all. Alex, 2026-08-02:
   "If you look at their website area, we have nice designed pills for this.
   These are ugly buttons." The component was already loaded — the markup
   simply was not asking for it. There is deliberately no rule here: the
   component already lays the thread out (flex column, gap, padding) and the
   canvas already gives it its scroll. */

@media (max-width: 760px) {
  .ccw .pl-row { flex-wrap: wrap; }
  .ccw .pl-row .meta { width: 100%; padding-left: 26px; }
}

/* The canvas sets the height on this screen, not the panel.
   review-canvas.css pins Maya at `calc(74vh + 46px)` because the website's
   copy step always has a full page of sections beside her. A course module
   with two lessons does not, and the fixed height stranded her chips and
   composer a long way below the footer. Sized to content here, with a floor so
   she is not a sliver on a one-lesson module. */
.ccw .rc-maya { height: auto; align-self: start; max-height: none; }
.ccw .rc-maya .rc-thread { min-height: 180px; }
.ccw .rc-canvas { min-height: 340px; }

/* ── The Look step, on the website's photo stage (2026-08-02) ───────────
   Layout, preview and options all come from css/photo-stage.css. This is only
   what is different about a course: the strip holds layout GLYPHS rather than
   photographs, and the rail carries the action at the top because Alex asked
   for the controls to surround the workspace rather than sit in a bar below
   the fold. */
.ccw .pho-strip .pho-thumb.ccw-lay {
  width: 96px; height: 72px; flex: none; padding: 4px; display: flex;
  align-items: center; justify-content: center; background: var(--surface-2);
  --lg-acc: var(--accent); --lg-mut: var(--text-2);
}
.ccw .pho-strip .pho-thumb.ccw-lay .g { display: block; width: 100%; }
.ccw .pho-strip .pho-thumb.ccw-lay svg { width: 100%; height: auto; display: block; }

/* ── The Look step's left list, which is now the SELECTOR ──────────────
   Alex, 2026-08-02: "on the left you have your layout, cover photo, colour,
   and typeface. You just click on that and whichever one you click appears in
   the right column." So the selected row has to read as selected — before, it
   was a scroll link and nothing was ever current. */
.ccw .ccw-jump.on {
  background: var(--accent-soft); border-radius: 8px;
  box-shadow: inset 2px 0 0 var(--accent);
}
.ccw .ccw-jump.on .t { color: var(--accent-deep); font-weight: 700; }
/* Open the real page in a browser tab, on the canvas bar, exactly where the
   website's Preview sits. */
.ccw .pho-ctx .ccw-openpv { padding: 6px 12px; font-size: 12.5px; }
/* The canvas box the render is fitted INTO. `pho-page` brings the height and
   the centring from css/photo-stage.css; this only says the mount fills it. */
.ccw .pho-page > .ccw-frame-wrap { margin: 0; }

.ccw .ccw-look-go { display: flex; gap: 8px; flex-wrap: wrap; padding: 12px; }
.ccw .ccw-look-go .btn { flex: 1 1 auto; min-height: 44px; }

/* The left rail: a table of contents for the right one. */
.ccw .ccw-jump {
  display: flex; flex-direction: column; gap: 1px; width: 100%; text-align: left;
  padding: 10px 12px; background: none; border: 0;
  border-bottom: 1px solid var(--border-soft); cursor: pointer; font: inherit;
  color: inherit; min-height: 48px;
}
.ccw .ccw-jump:hover { background: var(--surface-2); }
.ccw .ccw-jump .t { font-size: 13px; font-weight: 650; }
.ccw .ccw-jump .v { font-size: 11.5px; color: var(--text-2); }

/* The preview sits in the stage's own canvas, so it does not need the wizard's
   panel chrome — only centring. */
.ccw .pho-canvas .ccw-frame-wrap { margin: 0 auto; }

/* The rail's example label + flick. It is a LABEL first: the card used to show
   one specific template as "what you're working toward" with nothing saying it
   was not theirs, which is the fault this row exists to fix. */
.ccw .ccw-rail-ex {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 6px 10px 2px;
}
.ccw .ccw-rail-ex .lbl {
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-2);
}
/* 44px, not the 32px I first wrote — this rail is used on a phone and the
   house rule is a thumb-sized target. The browser test caught it. */
.ccw .ccw-rail-ex .ccw-ib { min-height: 44px; min-width: 44px; }

/* The manage board's section heading. `.sec-h` is the website's, and its
   sub-label rule is not `.mg-` prefixed so it stayed behind in
   launch-studio.css — which the wizard does not load. Two words of styling,
   rather than pulling in 1,700 lines for them. */
.ccw .sec-h { font-size: 15px; font-weight: 700; margin: 22px 0 12px; }
.ccw .sec-h .s { font-weight: 400; font-size: 12.5px; color: var(--text-2); }


/* ── Approving the plan, module by module (2026-08-02) ──────────────────
   The tab states are the website's — css/review-canvas.css already draws
   `.rc-ptab.done` and `.rc-ptab.locked` for the copy step's page tabs, and the
   plan step wears the same sheet, so a module tab needs nothing new. What is
   here is only what a MODULE has and a page does not: the approved primary,
   which is a way back in rather than a spent button.

   Alex, 2026-08-02: "you need to approve the modules or approve the overview
   and then each module... It just skipped everything and moved me to the next
   step." */
.ccw .rc-final.is-approved {
  background: var(--good-soft); color: var(--good); border: 1px solid var(--good);
}
.ccw .rc-final.is-approved:hover { background: var(--surface); }
.ccw .rc-final[disabled] { opacity: .5; cursor: default; }
.ccw .rc-final[disabled]:hover { background: var(--accent); }

/* The blank-skeleton escape, offered where it can be judged — under the finish
   bar, at the weight of a footnote. It replaced a full-screen chooser that
   asked for the same decision before the coach had seen anything. */
.ccw .ccw-skip { margin: 10px 0 0; display: inline-block; }


/* ══════════════════════════════════════════════════════════════════════
   THE RAIL'S DESIGN BROWSER (2026-08-02)

   A miniature of the hero carousel on start.replicants.ai/dfy/: the picture is
   the control, the arrows sit ON it, and the name and position ride in a scrim
   across the bottom. It replaced a line of text under the thumbnail reading
   "EXAMPLE · 3 OF 4" with a single → beside it.

   Alex: "We get rid of that line with the arrow and we get to have a
   back-and-forth arrow, a bit more like the design we've done for the website
   templates... and maybe some pills so they can filter them."

   The arrows are ALWAYS visible rather than hover-revealed. The landing page
   can afford hover because it is a marketing page on a desktop; this is a
   380px rail that has to work under a thumb, and a control you have to
   discover is a control most people never find.
   ══════════════════════════════════════════════════════════════════════ */

.ccw .ccw-gal {
  position: relative; aspect-ratio: 16/9; overflow: hidden;
  background: var(--surface-3); display: block;
}
.ccw .ccw-gal img {
  width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block;
}
.ccw .ccw-gal-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 32px; height: 32px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(255,255,255,0.92); color: var(--text);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 12px -4px rgba(17,16,34,0.5);
  transition: background .12s, transform .12s;
}
.ccw .ccw-gal-nav svg { width: 16px; height: 16px; }
.ccw .ccw-gal-nav:hover { background: #fff; transform: translateY(-50%) scale(1.08); }
.ccw .ccw-gal-nav.prev { left: 8px; }
.ccw .ccw-gal-nav.next { right: 8px; }
/* The caption is a scrim, not a bar: it sits over the picture so the frame
   stays one object rather than becoming a picture with furniture under it. */
.ccw .ccw-gal-cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; align-items: baseline; gap: 8px; padding: 20px 12px 9px;
  background: linear-gradient(180deg, rgba(17,16,34,0), rgba(17,16,34,0.72));
  color: #fff; pointer-events: none;
}
.ccw .ccw-gal-cap .n {
  font-family: "Bricolage Grotesque", sans-serif; font-weight: 700;
  font-size: 14px; letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ccw .ccw-gal-cap .p {
  margin-left: auto; font-family: "JetBrains Mono", monospace;
  font-size: 10.5px; opacity: 0.8; flex: none;
}

/* The filter row scrolls sideways rather than wrapping to four lines — eleven
   categories in a 380px rail is a wall, and the strip idiom is already the
   house answer to that (css/photo-stage.css `.pho-strip`). */
/* `min-width: 0` is load-bearing, not tidiness: a flex/grid child sizes to its
   content by default, so a row of eleven pills measures wider than the phone
   and pushes the whole rail — and therefore the page — sideways. Measured at
   375px, where the design card, its head and the meta block all overflowed.
   The scroll box only scrolls once it is allowed to be narrower than its
   contents. */
.ccw .ccw-gal-pills {
  display: flex; gap: 6px; padding: 10px 12px; overflow-x: auto;
  min-width: 0; max-width: 100%;
  scrollbar-width: none; -ms-overflow-style: none;
}
.ccw .ccw-gal-pills::-webkit-scrollbar { display: none; }
.ccw .ccw-gal-pills .chip { flex: none; font-size: 12px; padding: 6px 11px; min-height: 32px; }
.ccw .ccw-gal-pills .chip .n { color: var(--text-4); font-size: 11px; }
.ccw .ccw-gal-pills .chip.on {
  background: var(--text); color: var(--bg); border-color: var(--text);
}
.ccw .ccw-gal-pills .chip.on .n { color: var(--bg); opacity: .7; }
/* Under a thumb the pills are the one thing here that must clear 48px; the
   arrows are 32px circles ON a picture, where the whole frame is the target. */
/* Two queries, deliberately, the way the rest of this file does it: a phone in
   landscape is still a thumb (pointer), and a narrow window is still a small
   screen (width). Either one gets the bigger targets. */
@media (pointer: coarse) {
  .ccw .ccw-gal-pills .chip { min-height: 48px; }
  .ccw .ccw-gal-nav { width: 44px; height: 44px; }
}
@media (max-width: 760px) {
  .ccw .ccw-gal-pills .chip { min-height: 48px; }
  .ccw .ccw-gal-nav { width: 44px; height: 44px; }
}

/* ── The uploads lane on the content-dump screen ────────────────────────
   Alex, 2026-08-02: "It's mainly that they'll be uploading course content."
   Deliberately NOT a copy of the website's four-panel bring-content screen —
   the wizard's own card holds it, so this is just the drop target and the list
   of what landed. 48px minimum on the remove button, like every other control
   in this flow. */
.ccw .ccw-updrop {
  margin-top: 16px; padding: 22px 16px; text-align: center; cursor: pointer;
  border: 1.5px dashed var(--border); border-radius: var(--radius);
  background: var(--surface-2); transition: border-color .12s, background .12s;
}
.ccw .ccw-updrop:hover, .ccw .ccw-updrop:focus-visible, .ccw .ccw-updrop.on {
  border-color: var(--accent); background: var(--surface);
}
.ccw .ccw-updrop .ic { font-size: 20px; color: var(--text-3); line-height: 1; }
.ccw .ccw-updrop .t { margin-top: 8px; font-size: 14px; font-weight: 600; }
.ccw .ccw-updrop .s {
  margin-top: 4px; font-size: 12.5px; color: var(--text-2);
  max-width: 46ch; margin-left: auto; margin-right: auto; line-height: 1.5;
}
.ccw .ccw-uplist:not(:empty) { margin-top: 10px; display: grid; gap: 6px; }
.ccw .ccw-uprow {
  display: flex; align-items: center; gap: 10px; min-height: 48px;
  padding: 6px 8px 6px 10px; border: 1px solid var(--border-soft);
  border-radius: calc(var(--radius) - 4px); background: var(--surface);
}
.ccw .ccw-uprow .fi {
  flex: none; font-size: 10px; font-weight: 700; letter-spacing: .04em;
  color: var(--text-2); background: var(--surface-3);
  border-radius: 4px; padding: 3px 6px;
}
.ccw .ccw-uprow .fm { flex: 1 1 auto; min-width: 0; }
/* No ellipsis: a coach needs to read which file this is. It wraps. */
.ccw .ccw-uprow .fn { display: block; font-size: 13px; font-weight: 600; }
.ccw .ccw-uprow .fs { display: block; font-size: 11.5px; color: var(--text-2); }
.ccw .ccw-uprow .fx {
  flex: none; width: 48px; min-height: 48px; border: 0; background: none;
  color: var(--text-3); font-size: 14px; cursor: pointer; border-radius: 8px;
}
.ccw .ccw-uprow .fx:hover { color: var(--danger, #c0392b); background: var(--surface-2); }

/* ══════════════════════════════════════════════════════════════════════
   STEP 5 — ONE LESSON'S WORKSPACE (`.lw-*`)

   Alex, 2026-08-03, on the Fill step: "you should be modelling on the same
   almost identical UI to what you've built for the course plan… We're going to
   turn this into a really, really important content construction UI that we're
   going to build more and more on. It is actually going to be a little bit more
   like the UI that we've built for the designing of your course page."

   So the frame is the plan editor's (rc-ptabs / rc-grid / rc-canvas / rc-finish
   — none of it redeclared here), and inside the canvas one lesson gets the LOOK
   step's shape: a rail of tools down one side, the thing itself in the middle.

   ⚠️ The rail is drawn from LESSON_TOOLS in course-creation-wizard.js. Nothing
   below counts the tools or names one — a fourth (recording, slides→video, the
   cloned-voice read) styles itself.
   ══════════════════════════════════════════════════════════════════════ */

/* Maya's slot. `display:contents` because her node is created ONCE and
   re-appended into a freshly rendered grid on every repaint — the wrapper has
   to carry no box of its own, or `.rc-maya`'s sticky column would be nested
   inside a static one and stop sticking. */
.ccw .ccw-maya-slot { display: contents; }

/* The three marks on a collapsed lesson row: what it has, what it still needs. */
.ccw .lw-dots { display: inline-flex; gap: 5px; align-items: center; }
.ccw .lw-dot {
  width: 22px; height: 22px; border-radius: 7px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 11px;
  background: var(--surface-3); filter: grayscale(1); opacity: .45;
}
.ccw .lw-dot.on { background: var(--good-soft); filter: none; opacity: 1; }
.ccw .pl-thumb.lw-static { cursor: default; }
.ccw .pl-thumb.lw-static:hover { border-color: var(--border-soft); }

/* ── The workspace ─────────────────────────────────────────────────── */
.ccw .lw { display: block; }
.ccw .lw-head {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 0 2px 12px; margin-bottom: 14px; border-bottom: 1px solid var(--border-soft);
}
.ccw .lw-back {
  flex: none; background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--text-3);
}
.ccw .lw-back:hover { color: var(--accent); }
.ccw .lw-hmeta { flex: 1 1 220px; min-width: 0; }
.ccw .lw-htitle {
  display: block; font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700; font-size: 17px; line-height: 1.25;
}
.ccw .lw-hcovers { display: block; font-size: 12.5px; color: var(--text-2); margin-top: 3px; }
.ccw .lw-hnav { flex: none; display: flex; align-items: center; gap: 6px; }
/* "Preview this module", in both places it appears. Small and quiet: it sits
   beside the ‹ › pair in a lesson and beside the module title in the module
   list, and in neither is it the thing to do next. */
.ccw .ccw-modpv { flex: none; font-size: 12px; padding: 6px 11px; white-space: nowrap; }
.ccw .lw-modbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 0 2px 10px; margin-bottom: 12px; border-bottom: 1px solid var(--border-soft);
}
.ccw .lw-modwhat {
  flex: 1 1 auto; min-width: 0; font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700; font-size: 15px; line-height: 1.3;
}
.ccw .lw-hcount { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--text-3); }
.ccw .lw-hnav .ccw-ib[disabled] { opacity: .35; cursor: default; }

.ccw .lw-body { display: grid; grid-template-columns: 224px minmax(0, 1fr); gap: 16px; align-items: start; }

/* ── The rail ──────────────────────────────────────────────────────── */
.ccw .lw-rail { display: flex; flex-direction: column; gap: 6px; }
.ccw .lw-tool {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 10px 11px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); cursor: pointer; font: inherit; color: inherit;
}
.ccw .lw-tool:hover { border-color: var(--border-strong); background: var(--surface-2); }
.ccw .lw-tool.on { border-color: var(--accent); background: var(--accent-softer); }
.ccw .lw-tool .ic { flex: none; font-size: 17px; line-height: 1; }
.ccw .lw-tool .tx { flex: 1 1 auto; min-width: 0; }
.ccw .lw-tool .tx b { display: block; font-size: 13px; font-weight: 650; }
.ccw .lw-tool .tx i { display: block; font-style: normal; font-size: 11px; color: var(--text-3); margin-top: 1px; }
/* The tick is a slot whether or not it is earned, so the labels do not shift
   sideways the moment a lesson gets its video. */
.ccw .lw-tool .st {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; background: var(--surface-3); color: transparent;
}
.ccw .lw-tool .st.on { background: var(--good); color: #fff; }
.ccw .lw-soon {
  margin: 10px 2px 0; font-size: 11px; line-height: 1.5; color: var(--text-3);
}

/* ── The pane ──────────────────────────────────────────────────────── */
.ccw .lw-pane { min-width: 0; }
.ccw .lw-p { display: block; }
.ccw .lw-p-head { margin-bottom: 10px; }
.ccw .lw-p-head b { display: block; font-size: 14px; font-weight: 650; }
.ccw .lw-p-head span { display: block; font-size: 12.5px; color: var(--text-2); margin-top: 2px; }
.ccw .lw-p-act { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.ccw .lw-p .textarea { width: 100%; }

/* What is attached right now — one row, with the way to undo it. */
.ccw .lw-current {
  display: flex; align-items: center; gap: 10px; margin-bottom: 12px;
  padding: 9px 11px; border: 1px solid var(--good); border-radius: var(--radius);
  background: var(--good-soft);
}
.ccw .lw-current img { flex: none; width: 64px; height: 40px; object-fit: cover; border-radius: 6px; display: block; }
.ccw .lw-current .ic { flex: none; font-size: 20px; }
.ccw .lw-current .tx { flex: 1 1 auto; min-width: 0; }
.ccw .lw-current .tx b { display: block; font-size: 13px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ccw .lw-current .tx i { display: block; font-style: normal; font-size: 11.5px; color: var(--text-2); }

/* The video chooser. Same grouping as before — what you brought for THIS
   course first, the library underneath. */
.ccw .lw-vgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; margin-bottom: 12px; }
.ccw .lw-vtile {
  display: block; width: 100%; text-align: left; padding: 6px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); cursor: pointer; font: inherit; color: inherit;
}
.ccw .lw-vtile:hover { border-color: var(--accent); }
.ccw .lw-vtile img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 6px; display: block; margin-bottom: 5px; }
.ccw .lw-vtile .ph {
  display: flex; align-items: center; justify-content: center;
  width: 100%; aspect-ratio: 4 / 3; border-radius: 6px; margin-bottom: 5px;
  background: var(--surface-3); font-size: 20px;
}
.ccw .lw-vtile b { display: block; font-size: 12px; font-weight: 600; line-height: 1.3; }
.ccw .lw-vnote { display: block; font-style: normal; font-size: 11px; color: var(--text-3); margin-top: 2px; }
.ccw .lw-vnote.ok { color: var(--good); }

/* The link-instead row, hidden until asked for. */
.ccw .lw-flink { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.ccw .lw-flink[hidden] { display: none; }
/* ⚠️ Same trap as `.ccw-opts[hidden]`: `.lw-p-act` is `display: flex`, and an
   author rule beats the UA's `[hidden] { display: none }` however specific the
   UA one looks. Without this the "Replace it" choices would render permanently
   open while the attribute said otherwise — which is the exact clutter this
   change removes. */
.ccw .lw-p-act[hidden] { display: none; }
.ccw .lw-flink [data-ccw-furl] { flex: 2 1 220px; }
.ccw .lw-flink [data-ccw-fname] { flex: 1 1 160px; }

/* Narrow: the rail goes on top and scrolls sideways. A 224px column beside a
   writing box on a laptop half-screen leaves neither of them usable. */
@media (max-width: 900px) {
  .ccw .lw-body { grid-template-columns: minmax(0, 1fr); }
  .ccw .lw-rail { flex-direction: row; overflow-x: auto; gap: 8px; padding-bottom: 4px; }
  .ccw .lw-tool { width: auto; flex: 0 0 auto; }
  .ccw .lw-tool .tx i { display: none; }
  .ccw .lw-soon { display: none; }
}

/* A destructive action inside the shared action row. `.nav-btn` is the quiet
   left-hand slot (guided-workspace.css); this is that button when pressing it
   removes something. Quiet AND unmistakable — demoting a delete without
   marking it is how it becomes the easy gesture. */
.ccw .composer-row .nav-btn.danger { color: var(--danger); border-color: var(--danger-soft); }
.ccw .composer-row .nav-btn.danger:hover { background: var(--danger-soft); color: var(--danger); }

/* `hidden` on an option grid. `.ccw .ccw-opts` sets `display: grid`, and an
   author rule beats the UA's `[hidden] { display: none }` however specific the
   UA one looks — so without this the Go-live step's access options would sit
   permanently open while the attribute said otherwise. Same reason
   review-canvas.css carries its own `[hidden]` rules. */
.ccw .ccw-opts[hidden] { display: none; }

/* ── "Still to set up" — the levers notice (Go live) ─────────────────────
   A list, never a gate. Alex: "You can still publish without that being set
   up but that'd just be a flag." So it wears `.ccw-note` (the existing warn
   panel) and carries no disabled state, no checkbox and no confirmation —
   nothing here can stop the button beside it. */
.ccw .ccw-lever-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.ccw .ccw-lever-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 11px; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--border-soft);
}
.ccw .ccw-lever-row .ic { flex: none; font-size: 14px; line-height: 1; }
.ccw .ccw-lever-row .tx { flex: 1 1 220px; min-width: 0; font-size: 13px; line-height: 1.45; }
.ccw .ccw-lever-row .tx b { font-weight: 650; }
/* The reason sits under the ask, quieter — it answers "why does this matter"
   without competing with "what do I do". */
.ccw .ccw-lever-row .tx i { display: block; font-style: normal; font-size: 12px; color: var(--text-3); margin-top: 2px; }
.ccw .ccw-lever-row .btn { flex: none; }

/* ── What each palette colour does ──────────────────────────────────────
   Alex, 2026-08-03: "you need to know where each of the four colours is used
   on the page when you come to create your own palette."

   Quiet by design: it explains the grid above it and must not compete with it.
   The swatch is the link between the two — same colour, named. */
.ccw .ccw-palkey {
  margin-top: 12px; padding: 10px 12px;
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  background: var(--surface-2);
  display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center;
}
.ccw .ccw-palkey .t {
  width: 100%; font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-3); margin-bottom: 2px;
}
.ccw .ccw-palkey .row { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-2); }
.ccw .ccw-palkey .row i {
  width: 14px; height: 14px; border-radius: 4px; flex: none;
  border: 1px solid rgba(0,0,0,.14); display: block;
}
/* A0t.2 — the swatch IS the picker now. Styled to look exactly like the static
   swatch it replaced (same 14px, same radius, same hairline) so the panel does
   not suddenly read as a form; the only new signal is the cursor and the hover
   ring, which say "this is yours to change" without shouting it. */
.ccw .ccw-palkey .row { cursor: pointer; }
.ccw .ccw-palkey .row input[type="color"].sw {
  width: 16px; height: 16px; flex: none; padding: 0; cursor: pointer;
  border: 1px solid rgba(0,0,0,.14); border-radius: 4px; background: none;
  -webkit-appearance: none; appearance: none;
}
/* The native control paints its own inset swatch with a border and padding —
   without these two the colour shows as a small dot inside a grey box. */
.ccw .ccw-palkey .row input[type="color"].sw::-webkit-color-swatch-wrapper { padding: 0; }
.ccw .ccw-palkey .row input[type="color"].sw::-webkit-color-swatch { border: none; border-radius: 3px; }
.ccw .ccw-palkey .row input[type="color"].sw::-moz-color-swatch { border: none; border-radius: 3px; }
.ccw .ccw-palkey .row:hover input[type="color"].sw { box-shadow: 0 0 0 3px var(--accent-soft); }

.ccw .ccw-palkey-b { width: 100%; display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.ccw .ccw-palkey-b .pk-save,
.ccw .ccw-palkey-b .pk-reset {
  padding: 6px 12px; border-radius: 8px; font: inherit; font-size: 12.5px; cursor: pointer;
}
.ccw .ccw-palkey-b .pk-save { border: none; background: var(--accent); color: #fff; font-weight: 600; }
.ccw .ccw-palkey-b .pk-reset { border: 1px solid var(--border); background: var(--surface); color: var(--text-2); }
.ccw .ccw-palkey-b .pk-reset:hover { border-color: var(--accent); }
.ccw .ccw-palkey[hidden] { display: none; }

/* ── The footer's step strip ─────────────────────────────────────────────
   Alex, 2026-08-03: "we're not thinking it through in steps, just bunging
   everything down." The strip is how the coach knows there IS a sequence and
   where they are in it — without it, one question at a time reads as a screen
   that keeps changing for no reason.

   Hidden entirely when there is only one step, which is the "no footer at all"
   case: a progress indicator for a sequence of one is furniture. */
.ccw .ccw-steps {
  display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px;
}
.ccw .ccw-step {
  font-size: 11.5px; font-weight: 600; padding: 4px 10px; border-radius: 999px;
  background: var(--surface-2); color: var(--text-3); border: 1px solid var(--border-soft);
}
.ccw .ccw-step.on { background: var(--accent-softer); color: var(--accent-deep); border-color: var(--accent); }
.ccw .ccw-step.done { color: var(--good); background: var(--good-soft); border-color: transparent; }

/* ── "Here's what happens next" — the step reveal ────────────────────────
   Alex, 2026-08-03: "Maybe a very simple animation of each step of what's
   going to happen now… the purpose of this is to get them excited and ready to
   delve into the next step."

   Sequential, not decorative: each line arrives after the one above it, so the
   eye is walked down the list instead of meeting four things at once. The
   stagger is `--i`, set per item, which is why the markup carries an index.

   ⚠️ Deliberately SHORT (0.28s, 70ms apart). This runs at a moment the coach
   is already waiting; an animation they have to sit through would be the
   opposite of the point. */
.ccw .ccw-next {
  list-style: none; margin: 0 auto; padding: 0;
  max-width: 460px; text-align: left;
  display: flex; flex-direction: column; gap: 8px;
}
.ccw .ccw-next li {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 11px 13px; border-radius: var(--radius);
  background: var(--surface-2); border: 1px solid var(--border-soft);
  opacity: 0; transform: translateY(6px);
  animation: ccw-next-in .28s ease-out forwards;
  animation-delay: calc(var(--i, 0) * 70ms);
}
@keyframes ccw-next-in { to { opacity: 1; transform: none; } }
.ccw .ccw-next .ic { flex: none; font-size: 17px; line-height: 1.3; }
.ccw .ccw-next .tx { min-width: 0; }
.ccw .ccw-next .tx b { display: block; font-size: 14px; font-weight: 650; }
.ccw .ccw-next .tx i {
  display: block; font-style: normal; font-size: 12.5px;
  color: var(--text-2); margin-top: 2px; line-height: 1.45;
}

/* ⚠️ The same content, instantly. This is pure encouragement, so it must
   degrade to the identical list rather than to nothing — an animation that
   cannot be turned off is an accessibility fault, and one carrying the only
   explanation of the next step would be a content fault too. */
@media (prefers-reduced-motion: reduce) {
  .ccw .ccw-next li { opacity: 1; transform: none; animation: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   LEVER BLOCKS IN THE PLAN (L18 stage 2)

   Alex, 2026-08-03: lever blocks are "almost modules in themselves". So they
   are drawn AS modules — same card, same ▲ ▼ ✕ — with one badge saying which
   promise put them there. Not a different component: a coach reordering their
   course should not have to learn two shapes.
   ══════════════════════════════════════════════════════════════════════ */
.ccw .pl-lever-badge {
  display: inline-flex; align-items: center; gap: 7px;
  margin-bottom: 10px; padding: 5px 11px; border-radius: 999px;
  background: var(--accent-softer); color: var(--accent-deep);
  font-size: 11.5px; font-weight: 650; letter-spacing: .01em;
}
.ccw .pl-lever-badge .d {
  width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none;
}
/* A dashed left edge, not a colour swap: the block is part of the course, and
   a differently-coloured card would read as a warning rather than a kind. */
.ccw .pl-mod.is-lever { border-left: 3px dashed var(--accent); padding-left: 13px; }
.rc .rc-ptab.is-lever { border-style: dashed; }
.rc .rc-ptab.is-lever.active { border-style: solid; }

/* "+ Add a module" opens this when the coach has lever blocks to choose from.
   Absolutely positioned so opening it cannot reflow the tab strip underneath
   the cursor — the strip is what they just clicked in. */
.ccw .rc-ptab-chromes { position: relative; }
.ccw .pl-addmenu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 20;
  min-width: 240px; padding: 6px; display: flex; flex-direction: column; gap: 2px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 12px 32px rgba(0,0,0,.14);
}
/* ⚠️ Author `display:flex` beats the UA's [hidden] rule — the same trap that
   bit .ccw-opts and .lw-p-act earlier. Without this the menu is permanently
   open. */
.ccw .pl-addmenu[hidden] { display: none; }
.ccw .pl-addopt {
  display: block; width: 100%; text-align: left; cursor: pointer; font: inherit;
  padding: 9px 11px; border: 1px solid transparent; border-radius: 9px;
  background: none; color: inherit;
}
.ccw .pl-addopt:hover { background: var(--surface-2); border-color: var(--border); }
.ccw .pl-addopt b { display: block; font-size: 13.5px; font-weight: 650; }
.ccw .pl-addopt i { display: block; font-style: normal; font-size: 11.5px; color: var(--text-3); margin-top: 1px; }

/* "Switched on per account" — the L24 deferral note.
   Deliberately NOT the warning tone `.ccw-note` carries. This is news about
   OUR rollout, not a problem with the coach's course, and an amber panel would
   read as something they got wrong. Alex intends to close this in 48 hours;
   the styling should not outlive that with a scar. */
.ccw .ccw-note.ccw-note-soft {
  background: var(--accent-softer);
  border-color: var(--accent-soft, rgba(106,76,241,.22));
}
.ccw .ccw-note.ccw-note-soft .t { color: var(--accent-deep); }

/* A toggle whose label wraps onto two lines — the switch plus an explanation
   under it. `.ccw-toggle` alone is a centred inline-flex row, which puts the
   checkbox halfway down a two-line label. */
.ccw .ccw-toggle.ccw-toggle-block {
  display: flex; align-items: flex-start; gap: 9px; min-height: 0;
  line-height: 1.45;
}
/* ⚠️ THE [hidden] GUARD, FOR THE SIXTH TIME TODAY. `.ccw-toggle` sets
   `display: inline-flex`, which beats the UA's `[hidden]` rule — so without
   this a toggle rendered hidden is simply visible. Every previous instance
   (.ccw-opts, .lw-p-act, .pl-addmenu, .mg-panel, .st-setup) was the same
   mistake found the same way: by checking the class's display before trusting
   the attribute. */
.ccw .ccw-toggle[hidden] { display: none; }

/* "You also said this course includes" — the L23 #4 reminder on the Fill step.
   Deliberately NOT styled as a checklist: these cannot be ticked off from here
   (we do not know whether a coach has added their templates) and a checkbox
   that never goes green is worse than a sentence. */
.ccw .ccw-promised {
  margin-top: 14px; padding: 12px 14px;
  border: 1px dashed var(--border-strong, #cbd0d6); border-radius: 12px;
  background: var(--surface-2);
}
.ccw .ccw-promised .t {
  font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 8px;
}
.ccw .ccw-promised .r { display: flex; gap: 10px; flex-wrap: wrap; padding: 3px 0; font-size: 12.5px; }
.ccw .ccw-promised .r b { font-weight: 650; }
.ccw .ccw-promised .r span { color: var(--text-3); }

/* ── The 1:1 step's day picker (L23 #5) ──────────────────────────────
   Toggle buttons rather than seven checkboxes: picking working days is a
   glance-and-tap job, and a column of labelled boxes is the shape this flow
   keeps removing. `aria-pressed` carries the state for anyone not looking at
   the colour — the buttons are the control, not decoration around a hidden
   input, so the pressed state has to be announced. */
.ccw .ccw-days { display: flex; gap: 6px; flex-wrap: wrap; }
.ccw .ccw-day {
  flex: 1 1 auto; min-width: 52px; min-height: 44px; padding: 8px 4px;
  border: 1px solid var(--border-soft); border-radius: 10px;
  background: var(--surface-1); color: var(--text-2);
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.ccw .ccw-day:hover { border-color: var(--border-strong, #cbd0d6); }
.ccw .ccw-day.on {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}

/* ── The step crumb (2026-08-03) ──────────────────────────────────────
   Alex: "add it to the breadcrumbs… I don't want it to be overly dominant."
   ONE crumb that opens on demand, in the breadcrumb line every screen already
   draws — deliberately not the six pills that were deleted on 2026-08-02. */
.ccw .ccw-stepcrumb { position: relative; display: inline-flex; }
.ccw .ccw-steptog {
  background: none; border: 0; font: inherit; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px; padding: 0;
}
.ccw .ccw-steptog .cv { font-size: 9px; opacity: .65; }
.ccw .ccw-steptog:hover { color: var(--accent); }
.ccw .ccw-stepmenu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 60;
  min-width: 210px; padding: 6px; display: flex; flex-direction: column; gap: 2px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 24px 60px -28px rgba(0,0,0,.45);
}
/* ⚠️ The [hidden] guard — an author `display` beats the UA rule, and this file
   has been bitten by exactly that before. Without it the menu never closes. */
.ccw .ccw-stepmenu[hidden] { display: none; }
.ccw .ccw-stepmi {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: none; border: 0; font: inherit; font-size: 13px; color: var(--text-2);
  padding: 8px 10px; border-radius: 8px; cursor: pointer;
}
.ccw .ccw-stepmi b {
  font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--text-4);
  width: 14px; flex-shrink: 0;
}
.ccw .ccw-stepmi:hover { background: var(--surface-2); color: var(--text); }
.ccw .ccw-stepmi.on { background: var(--accent-soft); color: var(--accent-deep); }
.ccw .ccw-stepmi.on b { color: var(--accent); }
/* Not reachable yet: visibly inert, and its title says what to finish. */
.ccw .ccw-stepmi.off { opacity: .45; cursor: default; }
.ccw .ccw-stepmi.off:hover { background: none; color: var(--text-2); }

/* ── "From your material" (2026-08-03) ────────────────────────────────
   Alex: "That library of valuable content that's been crystallised needs to be
   visible to the tenant so they understand that this is where the course
   content is coming from… We don't want to overpower the UI with too much
   stuff going on. That's too complex but it needs to be somehow like you must
   be able to click through to see everything that's going on."

   So it is ONE line at rest — the same weight as a caption, deliberately
   quieter than the module tabs it sits above — and the whole library only when
   it is asked for. */
.ccw .ccw-mat { margin: 0 0 14px; }
.ccw .ccw-matbar {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 9px 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface-1); color: var(--text-2);
  font: inherit; font-size: 13px; cursor: pointer;
  transition: border-color .12s, background .12s;
}
.ccw .ccw-matbar:hover { border-color: var(--accent); background: var(--accent-soft); }
.ccw .ccw-matbar .mi { color: var(--accent); font-size: 12px; flex-shrink: 0; }
.ccw .ccw-matbar .mt { flex: 1; min-width: 0; }
.ccw .ccw-matbar .mt b { color: var(--text); }
.ccw .ccw-matbar .mv {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--accent);
}
.ccw .ccw-matbar .mv .cv { font-size: 9px; }
.ccw .ccw-matbody {
  margin-top: 8px; padding: 6px 4px; max-height: 340px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px;
}
/* ⚠️ The [hidden] guard — an author `display` beats the UA rule. Four separate
   controls in this project have shipped permanently open without it. */
.ccw .ccw-matbody[hidden] { display: none; }
.ccw .ccw-mat .mat-point {
  padding: 10px 12px; border-radius: 10px; border: 1px solid transparent;
}
.ccw .ccw-mat .mat-point:hover { background: var(--surface-1); border-color: var(--border); }
.ccw .ccw-mat .mat-topic {
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-4); margin-bottom: 3px;
}
.ccw .ccw-mat .mat-what { font-size: 13.5px; color: var(--text); line-height: 1.45; }
/* Their sentences, verbatim — set as a quotation so it is obvious at a glance
   which words are theirs and which are ours. */
.ccw .ccw-mat .mat-quotes {
  margin: 6px 0 0; padding: 0 0 0 11px; list-style: none;
  border-left: 2px solid var(--border-strong, #cbd0d6);
  display: flex; flex-direction: column; gap: 4px;
}
.ccw .ccw-mat .mat-quotes li {
  font-size: 12.5px; line-height: 1.5; color: var(--text-3); font-style: italic;
}

/* The no-material case is a STATEMENT, not a control — there is nothing to
   open. Same bar, without anything that invites a press. */
.ccw .ccw-matbar.is-flat { cursor: default; }
.ccw .ccw-matbar.is-flat:hover { border-color: var(--border); background: var(--surface-1); }
/* Inside the lesson editor the bar sits between the heading and the writing
   box, so it needs air below it rather than above. */
.ccw .lw-p > .ccw-mat { margin: 2px 0 12px; }

/* A0ac — the pending-lesson list on Go live is a set of DOORS, not names.
   Alex: "it should take you directly to where the issues are to resolve one by
   one." Styled as rows rather than buttons-in-a-row: eleven of these is a list
   to work down, and a wrapped row of pills reads as tags you cannot act on. */
.ccw .ccw-pendlist { display: grid; gap: 4px; margin-top: 6px; }
.ccw .ccw-pend {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; text-align: left;
  padding: 8px 10px;
  border: 1px solid var(--border-soft); border-radius: 8px;
  background: var(--surface); color: var(--text);
  font: inherit; font-size: 13px; cursor: pointer;
}
.ccw .ccw-pend:hover { border-color: var(--accent); background: var(--accent-softer, rgba(99,102,241,.06)); }
.ccw .ccw-pend .go { color: var(--accent); font-weight: 600; white-space: nowrap; flex: none; }

/* ── The Classroom board (the last screen of "How it opens") ──────────
 *
 * Alex, 2026-08-04: *"use nice images… it makes it intriguing so I would do
 * something very visual with what is being delivered."* Borrowed from the
 * games format picker: a responsive grid, line art in currentColor, a card
 * that carries its own selected state.
 *
 * ⚠️ The art is inline SVG stroked with currentColor, never an image file.
 * It inherits the theme (so it is correct in dark mode without a second
 * asset), it cannot 404, and it costs no request. Same reason the twelve
 * game-format thumbnails are drawings.
 */
/* The "set it up" nudge on the AI block's heading. A label, not a badge with a
   count — there is nothing to count, and a number would imply a queue. Alex,
   2026-08-06: *"a little notification on there to set it up properly."* */
.ccw .mg-dot {
  display: inline-block; margin-left: 8px; padding: 2px 8px;
  border-radius: 999px; font-size: 11px; font-weight: 650; letter-spacing: .01em;
  background: var(--accent-soft, rgba(108,99,255,0.12)); color: var(--accent);
  vertical-align: middle;
}

/* ⚠️ THE BOARD. Alex, comparing with the Games screen: *"they, in their games,
   put this white background and white border and it looks like each of the
   slots are mounted on a white background. Can you do the same thing for the AI
   class assistant?"*

   The cards were sitting straight on the page, so six outlines floated with
   nothing holding them. Mounting them on one white panel is what makes them
   read as a set of slots rather than six loose boxes — and it is the same
   treatment the Games grid uses. */
/* The provenance line under "You also said this course includes". Quieter than
   the promises above it — it is an answer to "where did that come from?", not
   another claim. */
.ccw .ccw-promised-src {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--border-soft, rgba(128,128,128,0.16));
  font-size: 12px; line-height: 1.5; color: var(--text-3);
}
.ccw .ccw-promised-src .ccw-cl-read { margin-left: 4px; }

/* 479 — the recording, playable in the pane. A coach checking "is this the
   right take?" can only answer that by listening, and sending them off to find
   the file again is the friction this pane exists to remove. */
.ccw .lw-audio {
  display: block; width: 100%; margin: 10px 0 2px;
}

.ccw .ccw-cl-board {
  background: #fff;
  border: 1px solid var(--border-soft, rgba(128,128,128,0.16));
  border-radius: 16px;
  padding: 16px;
  margin: 4px 0 2px;
  box-shadow: 0 1px 2px rgba(16,16,32,0.04);
}

.ccw .ccw-cl-grid {
  display: grid; gap: 14px; margin: 4px 0 2px;
  /* ⚠️ THREE ACROSS, FIXED (2026-08-06). `auto-fill` gave FOUR then TWO on his
     screen — Alex: *"we've got six but we've kind of put it into two rows: four
     and then two. Can just have two rows of three if that will look neater."*
     Six items divide into three, and auto-fill cannot know that: it fits as
     many as the width allows and leaves the remainder stranded. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* ⚠️ AFTER the base rule, not before it — and it was before it for one commit.
   Same specificity means later wins, so a media query that precedes the rule it
   overrides is a rule that never applies. Caught by the suite's own
   "three across" test matching this block instead of the base one. */
@media (max-width: 720px) {
  /* Three columns of nothing is worse than two columns of something. */
  .ccw .ccw-cl-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ccw .ccw-cl-board { padding: 12px; }
}

/* ⚠️ WHITE, AND SMALLER (2026-08-06). Alex, pointing at the Games screen:
   *"The layout is with a nice white background on the back. It gets more out of
   the colours and things like that… I also think we need to put all of them in
   smaller boxes but then allow it to expand."*
   `--surface` is the app's card white; `--surface-2` was a grey wash that
   flattened the line art and the accent on the switch. */
.ccw .ccw-cl-card {
  display: flex; flex-direction: column; gap: 6px;
  padding: 12px 13px 12px; border-radius: 12px;
  border: 1.5px solid var(--border, rgba(128,128,128,0.22));
  background: var(--surface, #fff);
  transition: border-color .12s ease, transform .12s ease;
}
/* The switch leads, beside the art — his "put the on/off button at the top". */
.ccw .ccw-cl-top {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.ccw .ccw-cl-read {
  align-self: flex-start; margin-top: 2px; padding: 0;
  background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 12.5px; color: var(--accent); text-decoration: underline;
}
/* The expansion. Everything the card used to say out loud lives here now. */
.ccw .ccw-cl-d {
  margin: 4px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--text-3);
}
.ccw .ccw-cl-card.on { border-color: currentColor; background: var(--surface-3, rgba(128,128,128,0.07)); }

/* ⚠️ GREYED HERE, NEVER BY DRAWING IT WORSE. The card asks the coach whether
 * they want the thing, and nobody wants something that looks unfinished — so
 * an unavailable tool keeps the same art and the same explanation. */
.ccw .ccw-cl-card.unavailable { opacity: 0.68; }

.ccw .ccw-cl-art { display: block; height: 40px; width: auto; opacity: 0.85; }

/* ── The published ("Your course is live") screen — eyeball round E3.
   Same board + card family as the Class Assistant above; these add only what
   an ACTION card needs that a toggle card does not: an action row, inputs
   that fill the card, and the two wide slots (the composer, and Share when
   it stands alone). */
.ccw .ccw-pub-grid {
  display: grid; gap: 14px; margin: 4px 0 2px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 720px) {
  .ccw .ccw-pub-grid { grid-template-columns: 1fr; }
}
.ccw .ccw-pub-card { padding: 16px; gap: 8px; }
.ccw .ccw-pub-card.wide { grid-column: 1 / -1; }
.ccw .ccw-pub-card .input,
.ccw .ccw-pub-card .textarea { width: 100%; }
.ccw .ccw-pub-card .input[readonly] { font-size: 12.5px; color: var(--text-2); }
.ccw .ccw-pub-actions {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 2px;
}
.ccw .ccw-pub-actions .btn { text-decoration: none; }

/* E7 — the decision-overload rule: selling cards close to one line. Same
   open/closed idea as the Class Assistant cards' Read-more, as a header
   toggle. Everything tokens; the chevron is the only new glyph. */
.ccw .ccw-pub-head {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: none; border: 0; padding: 0; cursor: pointer; text-align: left;
  font: inherit; min-height: 32px;
}
.ccw .ccw-pub-head .ccw-cl-n { margin: 0; }
.ccw .ccw-pub-state {
  font-size: 12px; font-weight: 700; color: var(--good, #1c7a4a);
  background: color-mix(in srgb, var(--good, #1c7a4a) 12%, transparent);
  border-radius: 999px; padding: 2px 9px;
}
.ccw .ccw-pub-chev {
  margin-left: auto; color: var(--text-3); font-size: 13px;
  transition: transform .15s ease;
}
.ccw .ccw-pub-card.collapsible .ccw-pub-body { display: none; }
.ccw .ccw-pub-card.collapsible.open .ccw-pub-body {
  display: flex; flex-direction: column; gap: 8px; margin-top: 6px;
}
.ccw .ccw-pub-card.collapsible.open .ccw-pub-chev { transform: rotate(180deg); }
.ccw .ccw-pub-sub { margin: 2px 0 0; }
/* Closed cards read as quiet rows, not half-empty boxes. */
.ccw .ccw-pub-card.collapsible { padding: 13px 16px; }
.ccw .ccw-pub-card.collapsible.open { padding: 16px; }

.ccw .ccw-cl-h { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ccw .ccw-cl-n { font-weight: 650; font-size: 14px; }
/* Information, not an instruction — the same register the games
 * recommendation uses. It never looks like a tick. */
.ccw .ccw-cl-rec {
  /* ⚠️ `align-self: flex-start` IS THE PILL. The card is a flex COLUMN, so a
     child stretches to its full width by default — the radius has nothing to
     round and the label wraps. This is the same rule that broke when the
     element became a <div>; stating it here means the markup cannot break it
     again. */
  align-self: flex-start;
  display: inline-block; width: auto; max-width: 100%;
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  white-space: nowrap;
  padding: 2px 8px; border-radius: 999px;
  /* White, so it lifts off the card rather than sitting in it — his "the
     suggestion should pop out". The shadow is what makes white-on-white read. */
  background: #fff; color: var(--text-2);
  border: 1px solid var(--border, rgba(128,128,128,0.28));
  box-shadow: 0 1px 3px rgba(16,16,32,0.10);
}

.ccw .ccw-cl-p { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--text-2); }
.ccw .ccw-cl-s {
  margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-3);
  padding-left: 10px; border-left: 2px solid var(--border, rgba(128,128,128,0.25));
}
.ccw .ccw-cl-s span {
  display: block; font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; margin-bottom: 2px;
}

.ccw .ccw-cl-t {
  margin-top: auto; align-self: flex-start; display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 12px 5px 6px; border-radius: 999px; cursor: pointer;
  border: 1.5px solid var(--border, rgba(128,128,128,0.3));
  background: transparent; color: inherit; font-size: 13px; font-weight: 600;
}
.ccw .ccw-cl-knob {
  width: 26px; height: 15px; border-radius: 999px; position: relative;
  border: 1.5px solid currentColor; opacity: 0.55; transition: opacity .12s ease;
}
.ccw .ccw-cl-knob::after {
  content: ''; position: absolute; top: 1.5px; left: 2px;
  width: 9px; height: 9px; border-radius: 50%; background: currentColor;
  transition: transform .12s ease;
}
.ccw .ccw-cl-card.on .ccw-cl-knob { opacity: 1; }
.ccw .ccw-cl-card.on .ccw-cl-knob::after { transform: translateX(11px); }

.ccw .ccw-cl-needs {
  margin-top: auto; font-size: 12.5px; line-height: 1.5; color: var(--text-3);
  padding: 8px 10px; border-radius: 10px;
  background: var(--surface-3, rgba(128,128,128,0.07));
}

@media (prefers-reduced-motion: reduce) {
  .ccw .ccw-cl-card, .ccw .ccw-cl-knob, .ccw .ccw-cl-knob::after { transition: none; }
}

/* ── "Who needs you" — the report ─────────────────────────────────────
 * Deliberately quiet. This is a list of people who are struggling, read by
 * the person answerable for them; it is not a dashboard and nothing on it
 * should feel like a score.
 */
.ccw .ccw-needs-list { display: flex; flex-direction: column; gap: 12px; }

.ccw .ccw-needs-card {
  border: 1.5px solid var(--border, rgba(128,128,128,0.22));
  border-radius: 14px; padding: 14px 16px;
  background: var(--surface-2, transparent);
}
.ccw .ccw-needs-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.ccw .ccw-needs-name { font-weight: 650; font-size: 15px; }
.ccw .ccw-needs-prog { font-size: 12.5px; color: var(--text-3); }

/* The specific thing that happened, above the general reasons — a coach can
 * act on "stopped in Recall in the park" and cannot act on "at risk". */
.ccw .ccw-needs-fact { margin: 8px 0 0; font-size: 13.5px; line-height: 1.5; }

.ccw .ccw-needs-why {
  margin: 8px 0 0; padding-left: 18px;
  font-size: 12.5px; line-height: 1.6; color: var(--text-3);
}

/* The drafted message. Quiet, and clearly a draft rather than a sent thing:
   it is an editable field, not a rendered message bubble. */
.ccw .ccw-needs-draft { margin-top: 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface-2); padding: 10px 12px; }
.ccw .ccw-needs-draft-h { display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; font-weight: 650; color: var(--text-3); text-transform: uppercase;
  letter-spacing: .04em; margin-bottom: 6px; }
.ccw .ccw-needs-copy { border: 1px solid var(--border); background: var(--surface);
  border-radius: 7px; padding: 3px 10px; font-size: 12px; font-weight: 600; cursor: pointer;
  text-transform: none; letter-spacing: 0; }
.ccw .ccw-needs-copy:hover { background: var(--surface-2); }
.ccw .ccw-needs-draft-t { width: 100%; border: 1px solid var(--border); border-radius: 8px;
  padding: 9px 10px; font: inherit; font-size: 13px; line-height: 1.55; resize: vertical;
  background: var(--surface); color: var(--text-1); }
.ccw .ccw-needs-draft-n { margin: 6px 0 0; font-size: 11.5px; color: var(--text-3); }
/* Four actions wrap on a narrow screen rather than overflowing the card. */
.ccw .ccw-needs-acts { display: flex; gap: 10px; align-items: center; margin-top: 12px; flex-wrap: wrap; }
.ccw .ccw-needs-skip {
  border: 0; background: transparent; color: var(--text-3);
  font-size: 13px; cursor: pointer; text-decoration: underline;
}

/* ── "Where it loses people" — Sticking points ────────────────────────
 * A report about the COURSE, not about people, so it can be plainer than
 * "Who needs you" — there is nobody here to be careful about.
 */
.ccw .ccw-stick-grp { margin-top: 18px; }
.ccw .ccw-stick-grp-h {
  font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 8px;
}
.ccw .ccw-stick-card {
  border: 1.5px solid var(--border, rgba(128,128,128,0.22));
  border-radius: 12px; padding: 12px 14px; margin-bottom: 8px;
  background: var(--surface-2, transparent);
}
.ccw .ccw-stick-n { font-weight: 620; font-size: 14px; }
.ccw .ccw-stick-f { font-size: 12.5px; line-height: 1.55; color: var(--text-3); margin-top: 3px; }

.ccw .ccw-stick-ai {
  margin-top: 22px; padding-top: 16px;
  border-top: 1px solid var(--border, rgba(128,128,128,0.22));
}
/* The cost is stated next to the button that incurs it, not in a footnote. */
.ccw .ccw-stick-note { font-size: 12.5px; line-height: 1.55; color: var(--text-3); margin: 8px 0 0; }
.ccw .ccw-stick-sugg { margin: 8px 0 0; padding-left: 18px; font-size: 13.5px; line-height: 1.7; }

/* ── The Tutor's own settings ─────────────────────────────────────────── */
.ccw .ccw-cl-row { margin-top: auto; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ccw .ccw-cl-more {
  border: 0; background: transparent; color: inherit; cursor: pointer;
  font-size: 12.5px; font-weight: 600; text-decoration: underline; padding: 0;
}

.ccw .ccw-tut-l { display: block; font-weight: 620; font-size: 14px; margin-bottom: 6px; }
.ccw .ccw-tut-note { font-size: 12.5px; line-height: 1.55; color: var(--text-3); margin: 8px 0 0; }

.ccw .ccw-tut-mods { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.ccw .ccw-tut-mod {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  border: 1.5px solid var(--border, rgba(128,128,128,0.25));
  background: transparent; color: inherit; cursor: pointer;
  border-radius: 10px; padding: 8px 12px; text-align: left;
}
.ccw .ccw-tut-mod.on { border-color: currentColor; background: var(--surface-3, rgba(128,128,128,0.08)); }
/* Off is shown by the border and the label, never by making the text
 * unreadable — a coach has to be able to read what they are switching off. */
.ccw .ccw-tut-mod:not(.on) .ccw-tut-mod-n { text-decoration: line-through; opacity: 0.7; }
.ccw .ccw-tut-mod-n { font-size: 13.5px; font-weight: 600; }
.ccw .ccw-tut-mod-c { font-size: 11.5px; color: var(--text-3); }

/* ── Who is paired — the safeguarding list ────────────────────────────── */
.ccw .ccw-pairs { display: flex; flex-direction: column; gap: 10px; }
.ccw .ccw-pair {
  border: 1.5px solid var(--border, rgba(128,128,128,0.22));
  border-radius: 12px; padding: 12px 14px;
  background: var(--surface-2, transparent);
}
.ccw .ccw-pair-who { font-size: 14.5px; font-weight: 620; }
.ccw .ccw-pair-who span { color: var(--text-3); font-weight: 400; }
.ccw .ccw-pair-meta { font-size: 12.5px; color: var(--text-3); margin-top: 2px; }
.ccw .ccw-pair-acts { display: flex; gap: 14px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.ccw .ccw-pair-sep,
.ccw .ccw-pair-block {
  border: 0; background: transparent; cursor: pointer;
  font-size: 12.5px; text-decoration: underline; padding: 0;
}
.ccw .ccw-pair-sep { color: var(--text-2); }
/* The permanent one is weighted differently from the reversible one, so the
 * dangerous action never looks like the ordinary action. */
.ccw .ccw-pair-block { color: #b4232a; font-weight: 600; }

/* The first task picker. One list, one chosen — a radio in behaviour, but the
   chosen row is pressable again to clear, so there is no state without an exit. */
.ccw .ccw-ft-list { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.ccw .ccw-ft { display: flex; gap: 10px; align-items: flex-start; width: 100%; text-align: left;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  padding: 11px 13px; cursor: pointer; font: inherit; }
.ccw .ccw-ft:hover { background: var(--surface-2); }
.ccw .ccw-ft.on { border-color: var(--accent, #4f46e5); box-shadow: 0 0 0 1px var(--accent, #4f46e5) inset; }
.ccw .ccw-ft-tick { width: 18px; height: 18px; flex: 0 0 18px; border-radius: 50%;
  border: 1px solid var(--border); display: flex; align-items: center; justify-content: center;
  font-size: 11px; margin-top: 1px; }
.ccw .ccw-ft.on .ccw-ft-tick { background: var(--accent, #4f46e5); border-color: var(--accent, #4f46e5); color: #fff; }
.ccw .ccw-ft-main { display: flex; flex-direction: column; gap: 2px; }
.ccw .ccw-ft-t { font-size: 14px; font-weight: 600; }
.ccw .ccw-ft-m { font-size: 12px; color: var(--text-3); }
.ccw .ccw-ft-clear { margin-top: 10px; border: 0; background: none; padding: 4px 0;
  font-size: 12.5px; color: var(--text-3); text-decoration: underline; cursor: pointer; }

/* ── §RECORD-IN-PLACE — the voiceover recorder ────────────────────────────
   Lives inside CBSheet.panel's shell, so this styles only what is INSIDE the
   body: the sheet's own chrome (overlay, head, foot, buttons) comes from
   rel-editor and is deliberately not restated here. */
.ccw-rec { display: flex; flex-direction: column; gap: 12px; }
.ccw-rec-stage { min-height: 240px; display: flex; flex-direction: column; }
.ccw-rec-stage .dv { flex: 1; min-height: 0; }
.ccw-rec-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface-2); }
.ccw-rec-time { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 15px; }
.ccw-rec-slide { font-size: 12.5px; color: var(--text-3); }
/* The recording light. Named and animated because "am I actually recording?"
   is the question a coach asks every few seconds, and a static dot answers it
   less well than a pulsing one. */
.ccw-rec-dot { width: 10px; height: 10px; border-radius: 50%; background: #dc2626;
  animation: ccw-rec-pulse 1.4s ease-in-out infinite; flex-shrink: 0; }
@keyframes ccw-rec-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .ccw-rec-dot { animation: none; } }
.ccw-rec-foot { display: flex; justify-content: flex-end; }
/* ⚠️ NARROW SCREENS AFTER THE BASE RULE, NOT BEFORE IT. Equal specificity
   means the later rule wins, so a media query written above the rule it
   overrides never applies — a bug this stylesheet has already shipped once. */
@media (max-width: 640px) {
  .ccw-rec-bar { gap: 8px; }
  .ccw-rec-bar .btn, .ccw-rec-bar .ccw-ib { flex: 1 1 auto; }
}

/* ── §AI-TOOL-SCREENS T2 — the empty Classroom screens ────────────────────
   Alex: *"design each of them so that they look great when there's nothing
   there but they kind of tease… it gets me excited about what will be
   coming."*

   ⚠️ THE SKETCH MUST NOT READ AS DATA. Everything inside `.ccw-tease-sketch`
   is a grey bar with no text in it — there are no invented students anywhere
   in this component — and it is deliberately desaturated and slightly faded so
   it reads as a drawing of a screen rather than a screen. The frame carries a
   visible label saying so. */
.ccw .ccw-tease { margin-top: 14px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--surface); padding: 18px; }
.ccw .ccw-tease-head { display: flex; gap: 12px; align-items: flex-start; }
.ccw .ccw-tease-ic { font-size: 22px; line-height: 1.1; flex-shrink: 0; }
.ccw .ccw-tease-say { display: flex; flex-direction: column; gap: 3px; }
.ccw .ccw-tease-say b { font-size: 15px; font-weight: 650; }
.ccw .ccw-tease-say i { font-style: normal; font-size: 13px; color: var(--text-3); }

.ccw .ccw-tease-frame { margin: 14px 0 12px; border: 1px dashed var(--line);
  border-radius: 12px; background: var(--surface-2); padding: 10px 12px 12px; }
/* Reads BEFORE the sketch, and is the only part of the frame a screen reader
   is given — the sketch itself is aria-hidden. */
.ccw .ccw-tease-tag { font-size: 11.5px; letter-spacing: .02em; text-transform: uppercase;
  color: var(--text-4); margin-bottom: 10px; }
.ccw .ccw-tease-sketch { display: flex; flex-direction: column; gap: 10px; opacity: .72; }

.ccw .ccw-sk { display: inline-block; height: 9px; border-radius: 99px;
  background: var(--line); flex-shrink: 0; }
.ccw .ccw-sk-faint { background: var(--surface-3, var(--line)); opacity: .6; }
.ccw .ccw-sk-dot { width: 20px; height: 20px; border-radius: 50%; }
.ccw .ccw-sk-pill { height: 20px; border-radius: 99px; }
.ccw .ccw-sk-sw { width: 30px; height: 17px; border-radius: 99px; background: var(--line);
  margin-left: auto; flex-shrink: 0; }
.ccw .ccw-sk-tick { width: 16px; height: 16px; border-radius: 5px;
  border: 1.5px solid var(--line); flex-shrink: 0; }
.ccw .ccw-sk-amp { font-size: 11px; color: var(--text-4); }
.ccw .ccw-sk-sp { flex: 1; }
.ccw .ccw-sk-bar { height: 9px; border-radius: 99px; background: var(--line); }

.ccw .ccw-sk-row { display: flex; align-items: center; gap: 8px; }
.ccw .ccw-sk-card { flex-direction: column; align-items: stretch; gap: 8px;
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
  background: var(--surface); }
.ccw .ccw-sk-l { display: flex; align-items: center; gap: 8px; }
.ccw .ccw-sk-pick { border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px; background: var(--surface); }
.ccw .ccw-sk-mod { border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 12px; background: var(--surface); }

.ccw .ccw-tease-when { margin: 0; font-size: 13px; color: var(--text-2); line-height: 1.55; }
.ccw .ccw-tease-when b { font-weight: 650; color: var(--text-1); }

/* ⚠️ AFTER the base rules, not before — equal specificity means the later rule
   wins, so a media query above the rule it overrides never applies. This
   stylesheet has already shipped that bug once. */
@media (max-width: 640px) {
  .ccw .ccw-tease { padding: 14px; }
  .ccw .ccw-sk-row { flex-wrap: wrap; }
}

/* ── U8.3 — the Undo arrow in the wizard topbar ───────────────────────────
   Alex: *"We really do need some level of undo/redo buttons on every step…
   Don't just work in there anywhere to get a step back."* One control, same
   pixel position on every screen, drawn by _chrome.

   ⚠️ DISABLED IS VISIBLE, NOT HIDDEN. A control that vanishes teaches a coach
   it is unreliable; one that is present and greyed, with a hover saying why,
   teaches them where the boundary is. So the disabled state keeps its size
   and its label and only loses contrast. */
.ccw .ccw-undo { display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--text-2); font-size: 13px;
  font-weight: 550; cursor: pointer; }
.ccw .ccw-undo svg { width: 15px; height: 15px; flex-shrink: 0; }
.ccw .ccw-undo:hover:not([disabled]) { background: var(--surface-2); color: var(--text-1); }
.ccw .ccw-undo[disabled] { cursor: default; opacity: .45; }

/* ⚠️ AFTER the base rules — equal specificity, later wins. On a narrow topbar
   the label goes and the arrow stays, because the arrow is the control. */
@media (max-width: 640px) {
  .ccw .ccw-undo span { display: none; }
  .ccw .ccw-undo { padding: 6px 8px; }
}

/* ── U8.4 — the first-enrolment prompt ────────────────────────────────────
   Alex: *"maybe set a trigger in there when the settings get requested when
   their first students start signing up."*

   ⚠️ IT IS A CARD WITH A DOOR, NOT A BANNER THAT BLOCKS. A coach whose first
   student has just arrived is having a good day; they must not be made to do
   settings before they can look at their own course. So it sits inside the AI
   block in the normal flow, is dismissible only by doing the thing (it is
   derived, so it disappears when the work is done), and never covers
   anything. */
.ccw .ccw-aitrig { display: flex; align-items: center; gap: 12px;
  margin: 0 0 12px; padding: 14px 16px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface-2); }
.ccw .ccw-aitrig-ic { font-size: 20px; line-height: 1; flex-shrink: 0; }
.ccw .ccw-aitrig-tx { display: flex; flex-direction: column; gap: 2px;
  flex: 1; min-width: 0; }
.ccw .ccw-aitrig-tx b { font-size: 14.5px; font-weight: 650; }
.ccw .ccw-aitrig-tx i { font-style: normal; font-size: 13px; color: var(--text-3); }
.ccw .ccw-aitrig-go { flex-shrink: 0; }

/* ⚠️ AFTER the base rule — equal specificity, later wins. On a narrow screen
   the button goes full width under the text rather than squeezing it. */
@media (max-width: 640px) {
  .ccw .ccw-aitrig { flex-wrap: wrap; }
  .ccw .ccw-aitrig-go { width: 100%; }
}

/* ── The course address panel ────────────────────────────────────────────
   Alex, 2026-08-12: *"you should be publishing, deciding, and we just sign the
   name of the folder. You should be signed in the name of the course URL so you
   see the whole thing up at the same time because you can have multiple
   courses."*

   So the address is ONE control, drawn as the URL itself: fixed segments the
   coach cannot type into sit flush against the two they can, and the seams are
   collapsed borders rather than gaps — the reading has to be "this is my
   address", not "these are three fields". Everything here uses the app's own
   tokens; there are no colours in this block. */
.ccw .ccw-url {
  display: flex; align-items: stretch; flex-wrap: wrap; gap: 0;
  font-family: "JetBrains Mono", monospace;
  font-size: 13px;
}
.ccw .ccw-url > * {
  border: 1px solid var(--border); border-radius: 0; padding: 9px 10px;
  background: var(--surface); color: var(--text); min-width: 0;
  font-family: inherit; font-size: inherit; line-height: 1.3;
}
.ccw .ccw-url > *:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.ccw .ccw-url > *:last-child  { border-radius: 0 var(--radius) var(--radius) 0; }
.ccw .ccw-url > * + * { border-left: 0; }
.ccw .ccw-url .fix {
  flex: 0 0 auto; background: var(--surface-2); color: var(--text-3);
  display: flex; align-items: center; white-space: nowrap;
}
.ccw .ccw-url .fix.sep { padding-left: 0; padding-right: 0; }
.ccw .ccw-url input { flex: 1 1 150px; min-width: 110px; }
.ccw .ccw-url input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-softer);
  position: relative; z-index: 1;
}
.ccw .ccw-url input.bad { border-color: var(--danger); position: relative; z-index: 1; }

/* The two outcome notes: what the address will be, and what is in the way.
   `.ccw-note` is warn-toned by default — these are the other two tones. */
.ccw .ccw-note.ok { background: var(--good-soft); border-color: var(--good-soft); }
.ccw .ccw-note.ok .t { color: var(--good); }
.ccw .ccw-note.ok .d { color: var(--good); word-break: break-all; }
.ccw .ccw-note.bad { background: var(--danger-soft); border-color: var(--danger-soft); }
.ccw .ccw-note.bad .t, .ccw .ccw-note.bad .d { color: var(--danger); }

/* "2 courses are already here" — the existing folder, made visible. It is not a
   new permutation to build: every course a tenant owns already shares one course
   site and therefore one folder. */
.ccw .ccw-addr-sibs { border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden; }
.ccw .ccw-addr-sibs .hd {
  padding: 10px 12px; background: var(--surface-2); font-size: 12.5px; font-weight: 650;
}
.ccw .ccw-addr-sibs .rw {
  display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
  padding: 9px 12px; border-top: 1px solid var(--border-soft); font-size: 12.5px;
}
.ccw .ccw-addr-sibs .rw .u {
  color: var(--text-3); font-family: "JetBrains Mono", monospace;
  font-size: 11.5px; word-break: break-all; text-align: right;
}
.ccw .ccw-addr-live {
  font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 999px;
  background: var(--good-soft); color: var(--good);
}

/* ── H · The sign-up page preview ─────────────────────────────────────────
   Alex, 2026-08-13: *"they'll be able to preview it."* Read-only, so this is
   the one rail card with no controls to style — a badge saying which door the
   course has, and the real page in a frame.
   Every colour here is a design-system token; the page INSIDE the frame carries
   its own --cp-* palette from the course's template and must not inherit ours. */
.ccw .ccw-enrolprev {
  display: flex; flex-direction: column; gap: 10px;
}
.ccw .ccw-enrolprev-badge {
  align-self: flex-start;
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px;
  background: var(--surface-2); color: var(--muted);
  border: 1px solid var(--border);
}
/* A tall frame rather than a scaled screenshot: the point is to read the page,
   and a coach checking their sign-up form should see it at its real size. */
.ccw .ccw-enrolprev-frame {
  width: 100%; height: 560px; border: 1px solid var(--border);
  border-radius: 12px; background: #fff; display: block;
}
.ccw .ccw-enrolprev-load,
.ccw .ccw-enrolprev-msg {
  padding: 18px; border: 1px dashed var(--border); border-radius: 12px;
  color: var(--muted); font-size: 14px; line-height: 1.55;
}
@media (max-width: 720px) {
  .ccw .ccw-enrolprev-frame { height: 460px; }
}
