/* ══════════════════════════════════════════════════════════════════════
   css/manage-board.css — the MANAGE BOARD, as a component

   "Your website is live" — the board a coach lands on once the thing exists:
   a live banner with Visit and Preview, a row of stat tiles, a grid of
   "Make a change" cards each pointing into the right editor, a thumbnail of
   the real thing, a manage list, and an unpublished-changes bar.

   Alex, 2026-08-02: "there's another page, a third page, that when you go to
   manage your website, we need to also create a page like this to manage your
   course using the exact same UI for them to jump into the different parts of
   their course and edit. Now you shouldn't be rebuilding any of this from
   scratch. You should just be taking the components that were already made and
   just repurposing them for the course."

   Every rule was scoped to `#page-launch-manage`. Same extraction, same risk
   and same proof as review-canvas.css and photo-stage.css: an id selector
   becomes a class one, and tests/browser/manage-board-css.browser.js renders
   the website's own markup before and after. The host must opt in with `mg`.
   ══════════════════════════════════════════════════════════════════════ */

.mg .mg-live { background: linear-gradient(110deg, #10331f 0%, #14532d 60%, #1c6b3a 100%); border-radius: var(--radius-lg); color: #fff; padding: 22px 26px; display: flex; align-items: center; gap: 18px; position: relative; overflow: hidden; margin-bottom: 18px; }
.mg .mg-live::before { content:""; position:absolute; inset:0; background: radial-gradient(circle at 90% 50%, rgba(93,212,168,0.32), transparent 60%); pointer-events:none; }
.mg .mg-live .lp { width: 12px; height: 12px; border-radius: 50%; background: #6ee7b7; flex-shrink: 0; position: relative; z-index: 1; }
.mg .mg-live .lt { flex: 1; position: relative; z-index: 1; }
.mg .mg-live .lt .tag { font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: #6ee7b7; }
.mg .mg-live .lt h1 { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 24px; margin: 3px 0 2px; letter-spacing: -0.015em; }
.mg .mg-live .lt .u { font-family: "JetBrains Mono", monospace; font-size: 13px; color: rgba(255,255,255,0.82); }
.mg .mg-live .la { display: flex; gap: 10px; position: relative; z-index: 1; }
.mg .mg-live .la a, .mg .mg-live .la button { border-radius: 11px; padding: 12px 18px; font-size: 13.5px; font-weight: 600; display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; cursor: pointer; border: none; text-decoration: none; }
.mg .mg-live .la .primary { background: #fff; color: #14532d; }
.mg .mg-live .la .ghost { background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.16); color: #fff; }
.mg .mg-live .la svg { width: 14px; height: 14px; }
.mg .mg-stats { display: grid; grid-template-columns: repeat(4,1fr); gap: 12px; margin-bottom: 20px; }
.mg .mg-stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius, 10px); padding: 16px 18px; }
.mg .mg-stat .k { font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-3); }
.mg .mg-stat .v { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 26px; margin-top: 6px; letter-spacing: -0.01em; }
.mg .mg-stat .d { font-size: 11.5px; color: var(--text-3); margin-top: 2px; display: inline-flex; align-items: center; gap: 5px; }
.mg .mg-stat .d.up { color: var(--good); }
.mg .mg-stat .d svg { width: 12px; height: 12px; }
@media (max-width: 880px) { .mg .mg-stats { grid-template-columns: 1fr 1fr; }
}

/* The board's section heading, in the kit (2026-08-06, funnel Manage board).
   `.sec-h` was scoped to `#page-launch-manage` (website) and `.ccw` (course
   wizard) — a third host had no heading style at all. Values are the
   website's own. Specificity note, checked against app.html load order:
   `#page-launch-manage .sec-h` (1,1,0) still beats this on the website, and
   `.ccw .sec-h` (course-wizard.css, loaded AFTER this file) still wins its
   deliberate smaller size on the course board. */
.mg .sec-h { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 18px; letter-spacing: -0.01em; margin: 0 2px 12px; }
.mg .sec-h .s { font-weight: 400; font-size: 13px; color: var(--text-3); font-family: "Inter", sans-serif; margin-left: 8px; }
.mg .mg-grid { display: grid; grid-template-columns: minmax(0,1fr) 320px; gap: 18px; align-items: start; }
.mg .mg-edits { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.mg .mg-edit { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 18px 20px; display: flex; flex-direction: column; transition: border-color .15s, box-shadow .15s, transform .15s; cursor: pointer; }
.mg .mg-edit:hover { border-color: var(--accent-2, var(--accent)); box-shadow: 0 22px 50px -38px rgba(106,76,241,0.5); transform: translateY(-2px); }
.mg .mg-edit .ei { width: 40px; height: 40px; border-radius: 11px; background: var(--accent-soft); color: var(--accent-deep); display: flex; align-items: center; justify-content: center; margin-bottom: 13px; }
.mg .mg-edit .ei svg { width: 20px; height: 20px; }
.mg .mg-edit .en { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 16px; letter-spacing: -0.01em; }
.mg .mg-edit .ed { font-size: 13px; color: var(--text-2); margin-top: 4px; line-height: 1.5; flex: 1; }
.mg .mg-edit .eg { margin-top: 14px; font-size: 13px; font-weight: 600; color: var(--accent); display: inline-flex; align-items: center; gap: 6px; }
.mg .mg-edit .eg svg { width: 13px; height: 13px; }
/* §MANAGE-RETHINK row 1 — the "Next" strip: the board's opening line, one
   priority per stage. `.warn` is the finish stage (the old .mg-republish
   warning, same slot — U10.1's placement and §PUB-STATE.3's spacing carried
   over); the default dress is the accent, for invite/teach. */
.mg .mg-next { margin-top: 16px; margin-bottom: 18px; background: var(--accent-soft, #efedff); border: 1px solid #ddd9ff; border-radius: var(--radius, 10px); padding: 14px 18px; display: flex; align-items: center; gap: 13px; }
.mg .mg-next.warn { background: var(--warn-soft, #fbf3df); border-color: #ecd6a8; }
.mg .mg-next .ri { width: 32px; height: 32px; border-radius: 8px; background: #fff; border: 1px solid #ddd9ff; color: var(--accent, #6c63ff); display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 15px; }
.mg .mg-next.warn .ri { border-color: #ecd6a8; color: var(--warn, #b8860b); }
.mg .mg-next .rt { flex: 1; font-size: 13px; color: var(--text-2); line-height: 1.45; }
.mg .mg-next .rt b { color: var(--text); }
.mg .mg-next .rb { background: var(--accent, #6c63ff); color: #fff; border: none; border-radius: 9px; padding: 10px 16px; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.mg .mg-next.warn .rb { background: var(--warn, #b8860b); }

/* The three groups. A shut group is one quiet row; open carries the cards.
   The active group's border says which one the board opened for you. */
.mg .mg-group { border: 1px solid var(--border); border-radius: 14px; background: var(--surface); margin-bottom: 12px; overflow: hidden; }
.mg .mg-group.open { border-color: color-mix(in srgb, var(--accent) 30%, var(--border)); box-shadow: 0 1px 6px color-mix(in srgb, var(--accent) 8%, transparent); }
.mg .mg-ghead { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; padding: 13px 15px; background: none; border: 0; cursor: pointer; font: inherit; color: inherit; }
.mg .mg-ghead .gi { width: 28px; height: 28px; border-radius: 8px; background: var(--accent-soft, #efedff); color: var(--accent, #6c63ff); display: grid; place-items: center; font-size: 14px; flex-shrink: 0; }
.mg .mg-ghead .gt { flex: 1; min-width: 0; }
.mg .mg-ghead .gt b { display: block; font-size: 14px; }
.mg .mg-ghead .gt span { display: block; font-size: 11.5px; color: var(--text-3); }
.mg .mg-ghead .gchev { color: var(--text-3); font-size: 14px; }
.mg .mg-group.shut .mg-ghead { opacity: .78; }
.mg .mg-group.shut .mg-gbody { display: none; }
.mg .mg-gbody { padding: 0 14px 14px; }

/* Rail state chips — only where the payload knows the truth. */
.mg .mg-chip { display: inline-block; font-size: 10px; font-weight: 700; border-radius: 99px; padding: 2px 8px; margin-left: 7px; vertical-align: 1px; }
.mg .mg-chip.on { background: var(--good-soft, #e7f6ec); color: #137a3c; }
.mg .mg-chip.off { background: var(--warn-soft, #fbf3df); color: #b4551a; }

/* The education strip under the rail — the artefact's approved sentence. */
.mg .mg-allin { margin-top: 14px; font-size: 11.5px; color: var(--text-3); line-height: 1.55; padding: 10px 12px; border: 1px dashed var(--border); border-radius: 10px; }
.mg .mg-rail { display: flex; flex-direction: column; gap: 14px; }
.mg .mg-rc { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
.mg .mg-rc .rc-h { padding: 14px 18px 10px; }
.mg .mg-rc .rc-h .t { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 15px; letter-spacing: -0.01em; }
.mg .mg-rc .rc-b { padding: 4px 14px 14px; }
.mg .mg-mini { margin: 4px 0 0; border: 1px solid var(--border); border-radius: 11px; overflow: hidden; }
.mg .mg-mini iframe { width: 100%; height: 280px; border: none; display: block; background: #fff; }
.mg .mg-links { display: flex; flex-direction: column; gap: 2px; }
.mg .mg-lnk { display: flex; align-items: center; gap: 11px; padding: 10px 10px; border-radius: 9px; font-size: 13.5px; color: var(--text-2); font-weight: 500; cursor: pointer; }
.mg .mg-lnk:hover { background: var(--surface-2); color: var(--text); }
.mg .mg-lnk .li { width: 18px; height: 18px; color: var(--text-3); flex-shrink: 0; }
.mg .mg-lnk .li svg { width: 18px; height: 18px; }
.mg .mg-lnk .ar { margin-left: auto; color: var(--text-4); }
.mg .mg-lnk .ar svg { width: 14px; height: 14px; }
@media (max-width: 1080px) { .mg .mg-grid { grid-template-columns: 1fr; }
}

@media (max-width: 760px) { .mg .mg-live { flex-direction: column; align-items: flex-start; } .mg .mg-edits { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════════════════
   MANAGE — the list that replaces the six-tab editor (L21)

   Alex, 2026-08-03, pointing at the WEBSITE's manage screen: "You've got
   Manage and you've got Pages… use the same UI design principles." So this is
   that screen's Manage list — a quiet stack of labelled rows, not another grid
   of cards. The green cards above it are the things the onboarding flow
   covers; this is everything else, and the two must not look like the same
   kind of choice.
   ══════════════════════════════════════════════════════════════════════ */
.mg .mg-manage {
  display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--surface); overflow: hidden;
}

/* §MANAGE-THUMB — the course-page thumbnail box, above the Manage list. Holds
   the still image first, then CourseCoverPreview's crop-mode frame (a
   .ccw-frame-wrap) once the real render lands; both wear the same frame so the
   swap is a change of picture, not of furniture. */
.mg .mg-shot {
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--surface); overflow: hidden;
}
.mg .mg-shot .ccw-rail-shot { aspect-ratio: 16/9; overflow: hidden; background: var(--surface-3); }
.mg .mg-shot .ccw-rail-shot img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }
.mg .mg-shot .ccw-rail-name { padding: 8px 12px; font-size: 11.5px; color: var(--text-3); }
/* The mounted frame brings its own component stylesheet
   (course-preview-frame.css) — the box above is all this screen adds. */
.mg .mg-mrow {
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  gap: 2px 12px; width: 100%; text-align: left; cursor: pointer; font: inherit;
  padding: 13px 15px; background: none; border: 0; color: inherit;
}
.mg .mg-mrow + .mg-mrow { border-top: 1px solid var(--border-soft); }
.mg .mg-mrow:hover { background: var(--surface-2); }
.mg .mg-mrow .t { font-size: 13.5px; font-weight: 650; }
.mg .mg-mrow .h { grid-column: 1; font-size: 11.5px; color: var(--text-3); }
.mg .mg-mrow .g { grid-column: 2; grid-row: 1 / span 2; color: var(--text-3); font-size: 17px; }

/* The panel a row opens. NOT a modal — that part of the original note was right
   and stands: these components were built for a page-width tab body, and
   squeezing a members table into a dialog is how a reused component starts
   needing its own CSS. Alex pointed at the website's "Manage your domain"
   dialog as the better feel, and it is, for a domain; it is max-width 620px and
   these five are page-width components.

   ⚠️ BUT THE PLACEMENT WAS WRONG, AND THE NOTE DESCRIBED AN INTENTION THE
   MARKUP NEVER DELIVERED. It said "full width under the board". The panel was
   emitted inside _manageListHtml(), which lands in the SECOND column of
   `.mg-grid` — `320px`. So a members table was being squeezed into a sidebar
   rail, underneath everything the coach had not clicked, which is exactly what
   the note was trying to avoid.

   Alex, 2026-08-03: "They open up below and that's really bad UX… They need to
   just open up on their own page." So the panel is now a SIBLING of `.mg-board`
   and the board is hidden while it is open — its own page, full measure. */
.mg .mg-panel {
  padding: 16px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--surface);
}
/* ⚠️ The [hidden] guard, for the FOURTH time in this file — an author `display`
   beats the UA rule, and `.mg-board` is the element whose failure would leave
   the coach staring at a blank screen. */
.mg .mg-board[hidden] { display: none; }
/* ⚠️ The [hidden] guard again — an author `display` beats the UA rule. Three
   places have now been caught by this; here the panel would simply never
   close. */
.mg .mg-panel[hidden] { display: none; }
.mg .mg-panel-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding-bottom: 12px; margin-bottom: 14px; border-bottom: 1px solid var(--border-soft);
}
.mg .mg-panel-back {
  background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
  font-size: 12.5px; font-weight: 600; color: var(--text-3);
}
.mg .mg-panel-back:hover { color: var(--accent); }
.mg .mg-panel-title {
  font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 16px;
}

/* ══════════════════════════════════════════════════════════════════════
   THE PANEL, IN THE WIZARD'S IDIOM — A0d.2 (2026-08-03)

   Alex: "we've designed a really nice UI for each of the steps and I think
   when you even come to manage it, you're using the old UI. Can you just check
   each step when you come to manage it?"

   He is right, and the check found it is NOT a design-system mismatch. Both
   sides sit on the same app-shell token base — course-page.css's own header
   says so, and the counts agree (169 token references against 196). Manage is
   the same colours and the same type in an OLDER LAYOUT IDIOM: the wizard
   gives every step a card with a small bold title inside it, and Manage gives
   flat sections under a 16px display heading on plain background.

   So this is an ADAPTATION, scoped to `.mg-panel`, mapping the handful of
   primitives that carry the difference. Deliberately NOT a rewrite of 252
   occurrences across five working modules, and deliberately scoped so that
   course-page.js — which renders these same five components on its own page —
   is untouched. One word from Alex ("rewrite") and this comes out again.

   WHAT IS NOT TOUCHED, and why: `.cpg-item` rows keep their hairline
   separators. Giving them the wizard's hover-highlight row treatment would put
   a click affordance on rows that are not clickable — most carry their own
   action buttons — and a false affordance is a worse fault than an old one.
   ══════════════════════════════════════════════════════════════════════ */

/* A section becomes a card, exactly as `.ccw-panel` is one. `.mg-panel` is the
   step card; these are the sub-cards inside it — the same nesting the wizard
   uses, not a card inside a card for its own sake. */
.mg .mg-panel .cpg-panel {
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: 14px 16px; margin-bottom: 14px;
}
.mg .mg-panel .cpg-panel:last-child { margin-bottom: 0; }

/* Down from a 16px display heading to the wizard's in-card title. It is inside
   a card now, under `.mg-panel-title`, which is itself 16px Bricolage — two
   display headings stacked is the "wall of text" reading Alex has objected to
   twice, on the plan step and here. */
.mg .mg-panel .cpg-section-title {
  font-family: inherit; font-size: 13px; font-weight: 700;
  letter-spacing: 0; margin-bottom: 0;
}
.mg .mg-panel .cpg-section-sub { font-size: 12.5px; color: var(--text-3); margin: 5px 0 0; }
.mg .mg-panel .cpg-section-title + .cpg-section-sub { margin-bottom: 10px; }
.mg .mg-panel .cpg-msg { font-size: 12.5px; margin-top: 8px; color: var(--text-3); }

/* §QUICK-LINKS.1 — the grab-and-copy rows above the Analytics title. */
.mg-qlinks .ql-row { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 12.5px; }
.mg-qlinks .ql-row:last-child { border-bottom: 0; }
.mg-qlinks .ql-l { flex: none; font-weight: 600; color: var(--text-2); min-width: 92px; }
.mg-qlinks .ql-u { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-3); font-family: "JetBrains Mono", monospace; font-size: 11px; }
.mg-qlinks .ql-copy { flex: none; border: 1px solid var(--border); background: transparent; border-radius: 7px; padding: 4px 10px; font-size: 11.5px; font-weight: 600; cursor: pointer; color: var(--text-2); }
.mg-qlinks .ql-copy:hover { border-color: var(--accent); color: var(--accent); }

/* ── .mg-republish — the "you have unpublished edits" bar ───────────────────
   ⚠️ THIS CLASS WAS LEFT BEHIND BY THE MANAGE-RETHINK. The redesign moved the
   treatment to `.mg-next.warn` (see the note above, "the old .mg-republish
   warning, same slot") and styled that — but every caller still emits
   `.mg-republish`, so the bar has been rendering with NO styling at all: a
   full-size raw SVG arrow, unstyled text and a browser-default button. That is
   what Alex photographed on 2026-08-16.

   FIVE screens emit it, not one — launch-studio.js (Manage), community-games.js
   in four places, and funnel-management.js — so it is fixed HERE rather than by
   renaming the class at one call site and leaving the other four broken.

   Deliberately NOT scoped under `.mg`: Games and Funnels render it outside that
   container, and scoping it is how it came to be missed in the first place. */
.mg-republish { display: none; }
.mg-republish.show {
  display: flex; align-items: center; gap: 13px;
  margin-top: 16px; margin-bottom: 18px; padding: 14px 18px;
  background: var(--warn-soft, #fbf3df); border: 1px solid #ecd6a8;
  border-radius: var(--radius, 10px);
}
.mg-republish .ri {
  width: 32px; height: 32px; border-radius: 8px; flex-shrink: 0;
  background: #fff; border: 1px solid #ecd6a8; color: var(--warn, #b8860b);
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
/* The icon is an <svg> on some screens and a text glyph on others — size both. */
.mg-republish .ri svg { width: 16px; height: 16px; }
.mg-republish .rt { flex: 1; font-size: 13px; color: var(--text-2); line-height: 1.45; }
.mg-republish .rt b { color: var(--text); }
.mg-republish .rb {
  background: var(--warn, #b8860b); color: #fff; border: 0; border-radius: 9px;
  padding: 10px 16px; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.mg-republish .rb:hover { filter: brightness(1.06); }
@media (max-width: 620px) {
  .mg-republish.show { align-items: flex-start; flex-wrap: wrap; }
  .mg-republish .rb { width: 100%; }
}

/* The same omission, in the newer class: `.mg-next .ri` sizes the badge but
   never the icon inside it, so an <svg> there fills all 32px edge to edge. */
.mg .mg-next .ri svg { width: 16px; height: 16px; }

/* ── The desk (#fm-workspace-view) — the render fills the height ──────────────
   R6-3, Alex 2026-08-28: "There's an obvious issue there you'll see with the
   height of the preview pane." The pane was the shared inline-preview's fixed
   300px (.rc-prev-inline .rc-prev-stage in launch-studio.css — courses and the
   chrome tabs still want that, so it is overridden HERE, desk-scoped, not
   changed there). The chain: the desk column fills the viewport, the stage row
   is its one flexible member, and lsPrevFit reads stage.clientHeight so the
   frame follows on its own. 128px — the one constant in the chain — covers the
   page's top offset AND the app container's own bottom padding (at 48px the
   document scrolled by exactly that padding: measured 78px, not guessed). */
#fm-workspace-view .st-grid {
  display: flex;
  flex-direction: column;
  min-height: calc(100dvh - 128px);
}
#fm-workspace-view [data-fm-ws-stage] {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
#fm-workspace-view [data-fm-ws-stage] .rc-prev-panel.rc-prev-inline {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
#fm-workspace-view [data-fm-ws-stage] .rc-prev-panel.rc-prev-inline .rc-prev-stage {
  /* flex-basis 0, NOT auto: auto sizes from content, and the content is the
     scaler the LAST fit produced — leaving the full view left a 751px scaler
     that held the desk stage at 751 (measured). Basis 0 = purely the leftover
     space, whatever the previous fit drew. */
  height: auto;
  flex: 1 1 0px;
  min-height: 300px;
  overflow: hidden;
}

/* ── The full view — body.fm-ws-focus (R6-3, "Fill the Screen") ──────────────
   The ONE workspace goes fixed over the whole viewport; the desk chrome hides;
   the render floats on a deep quiet canvas with a ~5% gutter so the page pops
   out like a document on a backing sheet (Alex's Word-document analogy,
   2026-08-28). z 8500 sits UNDER Maya's panel (9000), the checklist (9500)
   and modals (9999) — she floats on the room, never behind it. */
body.fm-ws-focus #fm-workspace-view {
  position: fixed;
  inset: 0;
  z-index: 8500;
  background: linear-gradient(180deg, #413e77, #34315c);
  overflow: hidden;
}
body.fm-ws-focus #fm-workspace-view .st-grid {
  /* !important because the desk writes max-width:1240px INLINE on this node —
     measured: a 1728px window rendered a 1067px room (Alex: "it's not filling
     the screen"). The room takes the whole window; the desk keeps its cap. */
  max-width: none !important;
  height: 100%;
  min-height: 0;
  padding: 0 !important;
  margin: 0;
}
/* The desk's own chrome leaves the room. The strip too (B18): a live funnel's
   "see what's left" row painted a white band across the top of the full view. */
body.fm-ws-focus #fm-workspace-view .st-head,
body.fm-ws-focus #fm-workspace-view [data-fm-ws-pages],
body.fm-ws-focus #fm-workspace-view [data-fm-ws-strip],
body.fm-ws-focus #fm-workspace-view .rc-prev-bar { display: none; }
/* The gutter: the page floats. */
body.fm-ws-focus #fm-workspace-view [data-fm-ws-stage] {
  height: 100%;
  padding: min(9vh, 72px) 5vw 5vh;
}
body.fm-ws-focus #fm-workspace-view [data-fm-ws-stage] .rc-prev-panel.rc-prev-inline {
  height: 100%;
  border: 0;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .45);
}
body.fm-ws-focus #fm-workspace-view [data-fm-ws-stage] .rc-prev-panel.rc-prev-inline .rc-prev-stage {
  min-height: 0;
}
/* V3b: the floating top bar is GONE (Alex: "completely unnecessary…
   a duplication if you get the funnel thing there"). The deck carries the
   page name, the page arrows and the ✕ — one band, at the top. */

/* Item 5 — the "Updated just now" chip: proof the change landed, both views. */
#fm-workspace-view [data-fm-ws-updchip] {
  position: fixed;
  top: 64px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 8600;
  background: var(--rk-navy);
  color: var(--rk-white);
  font-size: var(--rk-text-xs);
  font-weight: var(--rk-weight-semi);
  border-radius: 999px;
  padding: 6px 14px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, .3);
  pointer-events: none;
  opacity: 1;
  transition: opacity .5s ease;
}
#fm-workspace-view [data-fm-ws-updchip].gone { opacity: 0; }


/* ── §4.8 — the blueprint render for planned pages (P2-3, "The First Look") ──
 *
 * A `planned` page shows the greyed wireframe from the approved artefact
 * instead of a render: grey structure blocks, the coach's own facts as chips,
 * Maya's fear-reversal banner. The `.fm-planned` class on the surface root
 * hides the iframe stage AND the "Exactly as it will publish" note — both
 * would be lies about a page that does not exist yet. Drawn by
 * `wsBlueprintHtml` (funnel-management.js); the state is server truth only.
 */
.rc-prev-inline.fm-planned .rc-prev-stage,
.rc-prev-inline.fm-planned .rc-prev-note { display: none; }
.fm-bp { display: none; }
.rc-prev-inline.fm-planned .fm-bp {
  display: block; background: var(--rk-cloud); border: var(--rk-border);
  border-radius: var(--rk-radius-lg); padding: 22px 26px; min-height: 340px;
}
.fm-bp-banner {
  display: flex; align-items: flex-start; gap: 11px; background: var(--rk-white);
  border: var(--rk-border); border-radius: 12px; padding: 11px 15px;
  margin: 0 auto 18px; max-width: 780px; box-shadow: var(--rk-shadow-sm);
}
.fm-bp-av {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, var(--salmon, #ff8a75), var(--rose, #f65f8e) 55%, var(--plum, #8b5cf6));
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 12px;
}
.fm-bp-av .mhq-mark { width: 70%; height: 70%; display: block; }
.fm-bp-banner p { margin: 0; font-size: var(--rk-text-sm); color: var(--rk-navy); line-height: 1.5; }
.fm-bp-banner p b { font-weight: var(--rk-weight-semi); }
/* The wireframe itself is deliberately quiet — .75, per the artefact. */
.fm-bp-wf { opacity: .75; max-width: 780px; margin: 0 auto; }
.fm-bp-blk {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; background: var(--rk-gray-light); border-radius: 8px;
  margin-bottom: 10px; padding: 6px 14px;
}
.fm-bp-blk.dash { background: none; border: 1.5px dashed var(--rk-gray); }
.fm-bp-lbl {
  font-size: var(--rk-text-xs); font-weight: var(--rk-weight-semi); color: var(--rk-slate);
  letter-spacing: .05em; text-transform: uppercase;
}
.fm-bp-lbl i {
  font-style: normal; font-weight: var(--rk-weight-normal); text-transform: none;
  letter-spacing: 0; color: var(--rk-slate-light);
}
.fm-bp-fact {
  font-size: var(--rk-text-xs); color: var(--rk-navy); font-weight: var(--rk-weight-semi);
  background: var(--rk-white); border: var(--rk-border); border-radius: 999px;
  padding: 3px 11px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 760px) {
  .rc-prev-inline.fm-planned .fm-bp { padding: 14px; min-height: 260px; }
  .fm-bp-blk { padding: 6px 10px; }
}

/* ── §4.8 — the `planned` chip + the bar on a planned page (P2-4) ──────────
 * One chip everywhere a waiting page is named: desk tabs, full-view bar +
 * name menu, phone sheet. It says `planned` — present, deliberate, not-now —
 * never "empty" or "todo". On a planned page the controls with no meaning
 * there go: widths (nothing rendered to size), History (restore = a write =
 * the flip), Open in a new tab (a blank draft). On a LIVE page the bar shows
 * the artefact's frame-1 quiet chips: "<name> · after this page".
 */
.fm-pl-chip {
  display: inline-block; margin-left: 7px; padding: 1px 8px; border-radius: 999px;
  background: var(--rk-blue-light); color: var(--rk-navy);
  font-size: var(--rk-text-xs); font-weight: var(--rk-weight-semi);
  letter-spacing: .02em; text-transform: none; vertical-align: 1px;
}
.rc-prev-inline.fm-planned .rc-prev-seg,
.rc-prev-inline.fm-planned [data-fm-ws-tab] { display: none; }

/* ── B10-b — the green Approve + the tabs as the map ──────────────────────
 * Alex (GO, 2026-08-28): *"The approval button should always be visible as a
 * clear next step, as a standout button."* ONE green control on the screen,
 * two positions (desk head + full-view bar), one data hook
 * ([data-fm-ws-approve]), one owner of whether it shows (wsSyncApprove).
 * ⚠️ [hidden] must ALWAYS win: these display rules would otherwise override
 * the attribute's UA default and the button would show on a planned page. */
.fm-approve-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: var(--rk-space-2) var(--rk-space-4);
  background: var(--rk-success); color: var(--rk-white);
  border: 1px solid var(--rk-success); border-radius: var(--rk-radius-md);
  font-size: var(--rk-text-sm); font-weight: var(--rk-weight-semi);
  cursor: pointer; white-space: nowrap;
}
.fm-approve-btn:hover { filter: brightness(1.07); }
.fm-approve-btn[hidden] { display: none !important; }
/* V3: Approve and the save live in the DECK now (one band, one place);
   the head/thumb/fbar copies of the green button are gone with their CSS. */

/* ── B18 — the editors live in the full view now, so everything they open
 * must clear its z-plane (the view is fixed at 8500). CBPhotoCrop (9200)
 * and CBMediaPicker (100080) already do; the Polish tray and the CBSheet
 * family sit at 4000 and would open INVISIBLY BEHIND the one UI. Scoped
 * lift — their stacking everywhere else is untouched. */
body.fm-ws-focus .cbvt-overlay,
body.fm-ws-focus .rel-editor-overlay { z-index: 8800; }


/* ── W5 — the share card (the moment it goes live) ────────────────────────
 * The address as a person would paste it + what the pasted link shows.
 * One Copy button; the existing copyUrl flashes the check. */
.mg-share {
  display: flex; align-items: center; gap: 14px;
  border: 1px solid var(--rk-border, #e5e2f2); border-radius: var(--rk-radius-lg, 12px);
  background: var(--rk-white, #fff); padding: 13px 15px; margin-bottom: var(--rk-space-4);
}
.mg-share .th {
  width: 84px; height: 56px; flex: none; border-radius: 8px;
  background: linear-gradient(135deg, #1e1b4b, #4f46c9); color: #fff;
  display: flex; align-items: center; justify-content: center; text-align: center;
  font-size: 9px; font-weight: 700; padding: 4px; overflow: hidden;
}
.mg-share .tx { flex: 1; min-width: 0; }
.mg-share .tx b { font-size: var(--rk-text-sm); }
.mg-share .u {
  font-family: ui-monospace, monospace; font-size: 11.5px; color: var(--rk-primary, #6c63ff);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mg-share .d { font-size: var(--rk-text-xs); color: var(--rk-slate, #6b7280); }
.mg-share .rb { cursor: pointer; white-space: nowrap; }
@media (max-width: 640px) { .mg-share .th { display: none; } }

/* E4 — the analyst's door hides on phones: the phone room is over budget
 * (B14) and the board card carries the same door there. */
@media (max-width: 640px) { .fm-adv-btn { display: none !important; } }

/* ── B14 — THE PHONE ROOM (approved artefact "The Phone Room") ────────────
 * Alex: *"We're losing way too much of the top third of the screen… only
 * show what's actually needed in different states."* One 44px bar, a 3px
 * hairline, a floating Edit pill — and the render gets the rest. Everything
 * below exists ONLY under 640px; the desk is untouched. The controls the
 * bar replaces stay in the DOM (hidden) because the sheets proxy them —
 * one mechanism, two faces. */
.fm-ph-bar, .fm-ph-prog { display: none; }
@media (max-width: 640px) {
  body.fm-room-open .fm-ph-bar {
    display: flex; align-items: center; gap: 4px;
    position: sticky; top: 0; z-index: 8300;
    height: 44px; padding: 0 4px;
    background: var(--rk-white, #fff); border-bottom: 1px solid var(--rk-border, #e5e2f2);
    margin: calc(-1 * var(--rk-space-4)) 0 0;   /* eat the grid's own top pad */
  }
  body.fm-room-open .fm-ph-bar button {
    border: 0; background: transparent; cursor: pointer; color: var(--rk-navy, #1f2430);
    padding: 10px 12px; font-size: var(--rk-text-md); min-height: 44px;
  }
  body.fm-room-open .fm-ph-bar .pb-back { font-size: 24px; line-height: 1; }
  body.fm-room-open .fm-ph-bar .pb-name {
    flex: 1; min-width: 0; text-align: left;
    font-weight: var(--rk-weight-semi); overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap;
  }
  body.fm-room-open .fm-ph-bar .pb-more { font-weight: 700; letter-spacing: 2px; }
  body.fm-room-open .fm-ph-prog {
    display: block; height: 3px; background: var(--rk-border, #e5e2f2);
    position: sticky; top: 44px; z-index: 8300; cursor: pointer;
  }
  body.fm-room-open .fm-ph-prog i {
    display: block; height: 100%; width: 0; background: var(--rk-success, #059669);
  }
  /* What the bar replaces leaves the screen (never the DOM): the title
     block + Back, the tabs, the strip, and the surface's own bar. */
  body.fm-room-open #fm-workspace-view .st-head > div:first-child,
  body.fm-room-open #fm-workspace-view [data-fm-ws-back],
  body.fm-room-open #fm-workspace-view .rc-prev-pages,
  body.fm-room-open #fm-workspace-view .fm-ws-strip,
  body.fm-room-open #fm-workspace-view .rc-prev-bar { display: none !important; }
  /* The full view has its own bar — ours steps back while it is up. */
  body.fm-ws-focus .fm-ph-bar, body.fm-ws-focus .fm-ph-prog { display: none !important; }
  /* The render owns the screen (the artefact's acceptance: ≥80% Looking,
     ≥85% Editing, measured). The desk chain's 128px constant covers desk
     chrome the phone room no longer shows — here the chain is the bar (44)
     + hairline (3) and nothing else, and the surface goes full-bleed. */
  body.fm-room-open #fm-workspace-view .st-grid {
    min-height: calc(100dvh - 50px); padding-bottom: 0;
  }
  body.fm-room-open #fm-workspace-view .st-head { margin: 0; }
  body.fm-room-open #fm-workspace-view [data-fm-ws-stage] .rc-prev-panel.rc-prev-inline {
    border: 0; border-radius: 0; box-shadow: none;
  }
}

/* V3: the Show|Edit seg is gone (Spec B-3) — the page is always editable. */

/* ── E2 — the picture tap-sheet ───────────────────────────────────────────
 * B12-d: tap a picture, the sheet appears AT the tap — no buttons living on
 * the page. Two rows at most; transient (any other tap dismisses); above
 * the room (8700) but under Maya (9000) and modals. */
.fm-img-sheet {
  position: fixed; z-index: 8700; min-width: 180px;
  background: var(--rk-white, #fff); color: var(--rk-text, #1f2430);
  border: 1px solid var(--rk-border, #d6d3f0); border-radius: var(--rk-radius-md, 12px);
  box-shadow: 0 10px 28px rgba(20, 16, 60, .22); overflow: hidden;
}
.fm-img-sheet button {
  display: block; width: 100%; text-align: left; border: 0; background: transparent;
  cursor: pointer; padding: 11px 16px; font-size: var(--rk-text-sm);
  font-weight: var(--rk-weight-semi); color: inherit;
}
.fm-img-sheet button + button { border-top: 1px solid var(--rk-border, #eceafb); }
.fm-img-sheet button:hover { background: var(--rk-primary-soft, #f1efff); }

/* The tabs ARE the map (B10-b): ✓ approved · ● writing… · planned. */
.rc-prev-pages .rc-prev-pg .pg-ok { color: var(--rk-success); font-weight: 700; }
.rc-prev-pages .rc-prev-pg.is-approved { border-color: var(--rk-success); }
.rc-prev-pages .rc-prev-pg .pg-busy {
  color: var(--rk-warning); display: inline-block;
  animation: fm-pg-busy 1.2s ease-in-out infinite;
}
@keyframes fm-pg-busy { 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) {
  .rc-prev-pages .rc-prev-pg .pg-busy { animation: none; }
}
.rc-pg-chip {
  display: inline-block; margin-left: 7px; padding: 1px 8px; border-radius: 999px;
  font-size: var(--rk-text-xs); font-weight: var(--rk-weight-semi); vertical-align: 1px;
}
.rc-pg-chip.busy { background: var(--rk-warning-bg); color: var(--rk-warning); }

/* ── B10-c — the progress strip (the checklist's always-visible face) ─────
 * Screen 7 of the Road to Live artefact: a slim bar under the tabs — green
 * fill, plain words, tap anywhere for the full list. When the last required
 * row ticks it goes green and carries the room's ONE green action: Go live.
 * Born [hidden]; wsRefreshStrip fills it from the readiness read. */
.fm-ws-strip {
  display: flex; align-items: center; gap: 10px;
  margin: 8px 0 0; padding: 8px 14px;
  background: var(--rk-white); border: var(--rk-border);
  border-radius: var(--rk-radius-lg); cursor: pointer;
  font-size: var(--rk-text-sm); color: var(--rk-slate);
}
.fm-ws-strip[hidden] { display: none !important; }
.fm-ws-strip:hover { background: var(--rk-silicon); }
.fm-ws-strip .fm-strip-bar {
  flex: 1 1 0; min-width: 40px; height: 6px; border-radius: 999px;
  background: var(--rk-gray-light); position: relative; overflow: hidden;
}
.fm-ws-strip .fm-strip-bar i {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--rk-success); border-radius: 999px;
  transition: width .4s ease;
}
.fm-ws-strip .fm-strip-lbl { font-weight: var(--rk-weight-semi); color: var(--rk-navy); white-space: nowrap; }
.fm-ws-strip .fm-strip-more { color: var(--rk-slate-light); white-space: nowrap; }
.fm-ws-strip.done { background: var(--rk-success-bg); border-color: var(--rk-success); }
/* W5 — the phone: the health line + Republish don't fit one row at 412 and
 * the button clipped off-screen (caught by the W5 drive). Wrap instead. */
@media (max-width: 640px) {
  .fm-ws-strip { flex-wrap: wrap; }
  .fm-ws-strip .fm-strip-lbl { white-space: normal; }
}
.fm-ws-strip.done:hover { background: var(--rk-success-bg); }
.fm-ws-strip .fm-strip-go {
  border: 0; background: var(--rk-success); color: var(--rk-white);
  border-radius: 999px; padding: 6px 16px; cursor: pointer;
  font-size: var(--rk-text-sm); font-weight: var(--rk-weight-semi); white-space: nowrap;
}
.fm-ws-strip .fm-strip-go:hover { filter: brightness(1.07); }
@media (max-width: 640px) {
  .fm-ws-strip { padding: 8px 12px; gap: 8px; }
  .fm-ws-strip .fm-strip-more { display: none; }  /* the tap IS the affordance */
}

/* ── B10-d — the what-happens-after questions (artefact screen 6) ─────────
 * Three beats in the kit's sheet: a lettered marker, the question, the FACTS
 * the platform already knows (fm-ap-fact — shown, not configured), and the
 * one pick / the promise ticks that are genuinely the coach's. */
.fm-ap { display: flex; flex-direction: column; gap: 18px; }
.fm-ap-q { display: flex; gap: 12px; align-items: flex-start; }
.fm-ap-n {
  flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%;
  background: var(--rk-blue-light); color: var(--rk-navy);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--rk-text-xs); font-weight: var(--rk-weight-semi);
}
.fm-ap-body { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.fm-ap-t { font-weight: var(--rk-weight-semi); color: var(--rk-navy); font-size: var(--rk-text-md); }
.fm-ap-fact {
  font-size: var(--rk-text-sm); color: var(--rk-slate);
  background: var(--rk-silicon); border-radius: var(--rk-radius-md);
  padding: 8px 12px; line-height: 1.45;
}
.fm-ap-opt {
  display: flex; gap: 8px; align-items: flex-start;
  font-size: var(--rk-text-sm); color: var(--rk-navy); cursor: pointer; line-height: 1.4;
}
.fm-ap-opt input { margin-top: 2px; accent-color: var(--rk-success); }
.fm-ap-in {
  border: var(--rk-border); border-radius: var(--rk-radius-md);
  padding: 8px 12px; font-size: var(--rk-text-sm); font-family: inherit; width: 100%;
}

/* ── B33 — "select a square and give feedback on that square" ──────────────
   The region picker over a captured or attached image. Above the panel and
   the sheets (they sit at 8600), because it IS the interaction while it is
   open. Dark ground so the picture is the only lit thing on the screen. */
.cbrx {
  position: fixed; inset: 0; z-index: 9200;
  display: flex; flex-direction: column;
  background: rgba(15, 13, 40, 0.92);
  opacity: 0; transition: opacity 140ms ease;
  -webkit-user-select: none; user-select: none;
}
.cbrx.ready { opacity: 1; }
.cbrx-bar {
  flex: 0 0 auto; padding: 14px 16px calc(14px + env(safe-area-inset-top, 0px));
  color: #fff; font-size: 15px; font-weight: 600; text-align: center;
}
.cbrx-stage {
  position: relative; flex: 1 1 auto; min-height: 0;
  display: flex; align-items: center; justify-content: center; padding: 0 12px;
}
.cbrx-stage img {
  max-width: 100%; max-height: 100%; object-fit: contain;
  touch-action: none; cursor: crosshair; border-radius: 6px;
}
.cbrx-box {
  position: absolute; pointer-events: none;
  border: 2px solid #6c63ff; border-radius: 4px;
  box-shadow: 0 0 0 9999px rgba(15, 13, 40, 0.55);
}
.cbrx-acts {
  flex: 0 0 auto; display: flex; gap: 10px; justify-content: center;
  padding: 14px 16px calc(16px + env(safe-area-inset-bottom, 0px));
}
.cbrx-b {
  appearance: none; border: 1px solid rgba(255, 255, 255, 0.35);
  background: transparent; color: #fff;
  padding: 12px 16px; border-radius: 999px;
  font-size: 15px; font-weight: 600; cursor: pointer; min-height: 44px;
}
.cbrx-b.cbrx-go { background: #6c63ff; border-color: #6c63ff; }
.cbrx-b:disabled { opacity: 0.45; cursor: default; }

/* V3: the tapped button's sheet became the deck's BUTTON face; its head/
   note rules went with it. .fm-img-sheet itself stays for the video sheet. */

/* ── B34c — "Where should this go?" ────────────────────────────────────────
   The order of this list is the opinion (B36): his own steps first, then
   places on this page, then the platform's destinations, and the ways OUT of
   the funnel last, behind a disclosure. Leaving is possible and deliberate,
   never the easy default. */
/* ⚠️ `.fm-modal-backdrop` carries NO css of its own — every other user of it
   sets position/z-index INLINE, and a drive caught this picker rendering in
   flow, behind the preview frame, unclickable. It gets its own backdrop, above
   the region picker (9200) since it opens over everything. */
.fm-wh-back {
  position: fixed; inset: 0; z-index: 9300;
  display: flex; align-items: center; justify-content: center;
  padding: var(--rk-space-4, 16px);
  background: rgba(30, 27, 75, 0.55);
}
.fm-wh {
  background: var(--rk-white, #fff); border-radius: var(--rk-radius-xl, 16px);
  width: 100%; max-width: 520px; max-height: 88vh; display: flex; flex-direction: column;
  box-shadow: var(--rk-shadow-lg, 0 18px 50px rgba(20, 16, 60, .3)); overflow: hidden;
}
.fm-wh-top {
  position: relative; padding: 16px 46px 13px 18px;
  border-bottom: 1px solid var(--rk-silicon, #e8e6f5);
}
.fm-wh-top b { display: block; font-size: var(--rk-text-lg, 17px); color: var(--rk-navy, #1f2430); }
.fm-wh-top span { display: block; margin-top: 3px; font-size: var(--rk-text-xs, 12px); color: var(--rk-slate, #5b5870); }
.fm-wh-x {
  position: absolute; top: 10px; right: 12px; border: 0; background: none;
  font-size: 24px; line-height: 1; color: var(--rk-slate-light, #8b87a3); cursor: pointer;
}
.fm-wh-body { overflow-y: auto; padding: 6px 0 14px; }
.fm-wh-grp {
  padding: 14px 18px 6px; font-size: var(--rk-text-xs, 12px); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--rk-slate-light, #8b87a3);
}
.fm-wh-row {
  display: block; width: 100%; text-align: left; border: 0; background: transparent;
  padding: 11px 18px; cursor: pointer; min-height: 44px;
}
.fm-wh-row:hover, .fm-wh-row:focus-visible { background: var(--rk-primary-soft, #f1efff); }
.fm-wh-row span { display: block; font-size: var(--rk-text-sm, 14px); font-weight: 600; color: var(--rk-navy, #1f2430); }
.fm-wh-row em { display: block; font-style: normal; margin-top: 1px; font-size: var(--rk-text-xs, 12px); color: var(--rk-slate, #5b5870); }
.fm-wh-row.on { background: var(--rk-primary-soft, #f1efff); }
.fm-wh-row.on span::after { content: ' \2713'; color: var(--rk-primary, #6c63ff); }
.fm-wh-none { padding: 4px 18px 8px; font-size: var(--rk-text-xs, 12px); color: var(--rk-slate, #5b5870); }
.fm-wh-out { margin: 12px 18px 0; border-top: 1px solid var(--rk-silicon, #e8e6f5); padding-top: 12px; }
.fm-wh-out summary { cursor: pointer; font-size: var(--rk-text-sm, 14px); font-weight: 600; color: var(--rk-slate, #5b5870); }
.fm-wh-out p { margin: 8px 0 12px; font-size: var(--rk-text-xs, 12px); color: var(--rk-slate, #5b5870); }
.fm-wh-out label { display: block; margin-bottom: 10px; font-size: var(--rk-text-xs, 12px); color: var(--rk-slate, #5b5870); }
.fm-wh-out input[type="url"], .fm-wh-out input[type="email"], .fm-wh-out input[type="tel"] {
  display: block; width: 100%; margin-top: 4px; padding: 10px 12px; min-height: 44px;
  border: 1px solid var(--rk-silicon, #e8e6f5); border-radius: var(--rk-radius-md, 10px);
  font-size: var(--rk-text-sm, 14px); color: var(--rk-navy, #1f2430); background: var(--rk-white, #fff);
}
.fm-wh-chk { display: flex; align-items: center; gap: 8px; }
.fm-wh-chk input { width: 18px; height: 18px; }
.fm-wh-save {
  width: 100%; min-height: 44px; border: 0; border-radius: var(--rk-radius-md, 10px);
  background: var(--rk-primary, #6c63ff); color: #fff; font-size: var(--rk-text-sm, 14px);
  font-weight: 600; cursor: pointer;
}

/* ── B34d — "Where everything goes" ────────────────────────────────────────
   The same shell as the destination picker (one idea of a list, not two).
   `.warn` marks the two a coach should look at: a link that goes nowhere and
   one that leaves the funnel. `.flat` is the read-only state in Show mode —
   a row that cannot be acted on must not look like a button. */
.fm-wm-row {
  display: block; width: 100%; text-align: left; border: 0; background: transparent;
  padding: 11px 18px; min-height: 44px; border-bottom: 1px solid var(--rk-silicon, #f0eef8);
}
.fm-wm-row:not(.flat) { cursor: pointer; }
.fm-wm-row:not(.flat):hover, .fm-wm-row:not(.flat):focus-visible { background: var(--rk-primary-soft, #f1efff); }
.fm-wm-row span {
  display: block; font-size: var(--rk-text-sm, 14px); font-weight: 600;
  color: var(--rk-navy, #1f2430); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fm-wm-row em {
  display: block; margin-top: 1px; font-style: normal;
  font-size: var(--rk-text-xs, 12px); color: var(--rk-slate, #5b5870);
}
.fm-wm-row.warn { background: var(--rk-warning-bg, #fdf3e3); }
.fm-wm-row.warn em { color: var(--rk-warning, #9a5b12); font-weight: 600; }

.fm-swatches { display: flex; flex-wrap: wrap; gap: 10px; padding: 16px 18px; }
.fm-sw {
  width: 66px; height: 56px; border: 1px solid var(--rk-silicon, #e8e6f5);
  border-radius: var(--rk-radius-md, 10px); cursor: pointer; padding: 0;
  display: flex; align-items: flex-end; justify-content: center; overflow: hidden;
}
.fm-sw span {
  display: block; width: 100%; padding: 2px 0; text-align: center;
  font-size: 10px; font-family: ui-monospace, monospace;
  background: rgba(255, 255, 255, .88); color: #1f2430;
}

/* ══ V3b — THE DECK: one band, five faces, AT THE TOP ══════════════════════
   The approved artefact's deck (5e486833), with one deliberate departure that
   Alex made on 2026-08-31 after using it:

     *"The keyboard's popping up and hiding it. That should always be at the
     top."*

   The artefact drew the band at the BOTTOM. On a phone the keyboard takes the
   bottom third of the screen, so a bottom band is exactly where the tools
   cannot be at the one moment they are needed — while the coach is typing.
   Everything else here is the artefact's own: the dark ground, the funnel
   icon (a funnel, not a folder), Maya as a mark plus her NAME, Approve
   outlined in teal, and Save replacing both of them when there is something
   to save.

   z 9100: above Maya's panel (9000) so the chip that opens her is never
   buried, below the checklist (9500) and modals (9999). */
.fm-deck { display: none; }
body.fm-room-open #fm-workspace-view .fm-deck {
  position: fixed; left: 0; right: 0; top: 0; z-index: 9100;
  display: flex; align-items: center; gap: 7px;
  min-height: 52px; padding: 0 9px calc(0px + env(safe-area-inset-top, 0px));
  background: #23212f; color: #fff;
  font: 500 12px/1.3 "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
  white-space: nowrap;
}
/* The room's content starts BELOW the band, never under it. */
body.fm-room-open #fm-workspace-view .st-grid { padding-top: 60px; }
body.fm-ws-focus #fm-workspace-view [data-fm-ws-stage] { padding-top: 64px; }
.fm-deck .dk-grow { flex: 1; min-width: 0; }
.fm-deck .dk-btn {
  background: rgba(255, 255, 255, .14); border: 0; color: #fff;
  font: 600 12px/1 "Inter", -apple-system, sans-serif;
  padding: 9px 10px; border-radius: 7px; cursor: pointer; white-space: nowrap;
}
.fm-deck .dk-btn:hover:not([disabled]) { background: rgba(255, 255, 255, .26); }
.fm-deck .dk-btn[disabled] { opacity: .32; cursor: default; }
.fm-deck .dk-btn.dk-pri { background: #fff; color: #23212f; }
.fm-deck .dk-btn.dk-go { background: #10b981; color: #fff; }
.fm-deck .dk-btn.dk-go[hidden] { display: none !important; }
.fm-deck .dk-ic { padding: 9px; min-width: 34px; text-align: center; }
/* The funnel door, carrying this page's name — the identity the top pill
   used to hold, on the control that opens the list it belongs to. */
.fm-deck .dk-fun {
  display: inline-flex; align-items: center; gap: 6px; min-width: 40px;
  max-width: 46vw; overflow: hidden;
}
.fm-deck .dk-fun svg { width: 15px; height: 15px; display: block; flex: none; }
.fm-deck .dk-pg { overflow: hidden; text-overflow: ellipsis; font-weight: 600; }
/* ⭐ MAYA, AS A PERSON. Her mark, her name, and a slow pulse so she reads as
   someone waiting rather than an icon parked in a bar (Alex: "a little pulse
   should be there so that you see her living there"). */
.fm-deck .dk-maya {
  position: relative; display: inline-flex; align-items: center; gap: 6px; flex: none;
  background: rgba(255, 255, 255, .12); border: 0; color: #fff;
  padding: 5px 11px 5px 5px; border-radius: 999px; cursor: pointer;
  font: 600 12px/1 "Inter", -apple-system, sans-serif;
}
.fm-deck .dk-maya { animation: fm-maya-breathe 2.4s ease-in-out infinite; }
.fm-deck .dk-maya:hover { background: rgba(255, 255, 255, .24); animation: none; }
.fm-deck .dk-mav {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, #f0559a, #c23bd6);
  display: flex; align-items: center; justify-content: center;
  font: 800 12px/1 "Inter", -apple-system, sans-serif; color: #fff;
  animation: fm-maya-pulse 2.4s ease-in-out infinite;
}
/* Her own mark, sized to the disc it sits in — the same 72% the HQ rail
   uses, so the glyph reads identically wherever she appears. */
.fm-deck .dk-mark { width: 72%; height: 72%; display: block; }
/* ⭐ THE MOST IMPORTANT THING TO CLICK, so the pulse is on the whole chip and
   not only the disc. Alex: *"make the Maya in the header pulse so they see
   that as the most important thing that they should click on when they get
   there."* Two halves, deliberately: the ring travels outward from her mark,
   and the chip itself breathes. Both are shadow/background only — nothing
   here moves the band or reflows a neighbour. */
@keyframes fm-maya-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(240, 85, 154, .6); }
  55%      { box-shadow: 0 0 0 9px rgba(240, 85, 154, 0); }
}
@keyframes fm-maya-breathe {
  0%, 100% { background: rgba(255, 255, 255, .12); }
  55%      { background: rgba(240, 85, 154, .30); }
}
/* ⚠️ A pulse is decoration; someone who has asked for less motion gets a
   still mark, never a missing one. */
@media (prefers-reduced-motion: reduce) {
  .fm-deck .dk-mav, .fm-deck .dk-maya { animation: none; }
}
.fm-deck .dk-dot {
  width: 7px; height: 7px; border-radius: 50%; background: #fbbf24; flex: none;
}
.fm-deck .dk-dot[hidden] { display: none !important; }
/* B-5 — Approve: outlined, never filled. Every filled control in this band is
   something you can undo; the gate is the only one that is not. */
.fm-deck .dk-gate {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  background: transparent; color: #5eead4; border: 1.5px solid #10b981;
  border-radius: 7px; padding: 8px 12px; cursor: pointer; white-space: nowrap;
  font: 600 12px/1 "Inter", -apple-system, sans-serif;
}
.fm-deck .dk-gate:hover { background: rgba(16, 185, 129, .16); }
.fm-deck .dk-gate[hidden] { display: none !important; }
/* The tool faces' shared parts. */
.fm-deck .dk-what {
  display: inline-flex; flex-direction: column; min-width: 0; line-height: 1.25;
  font: 600 12px/1.25 "Inter", -apple-system, sans-serif;
  color: rgba(255, 255, 255, .78); overflow: hidden;
}
.fm-deck .dk-what b { color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-deck .dk-what em {
  font-style: normal; font-weight: 400; font-size: 10.5px;
  color: rgba(255, 255, 255, .62); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fm-deck .dk-what.warn em { color: #fbbf24; font-weight: 600; }
.fm-deck .dk-quo {
  font-size: 12px; color: rgba(255, 255, 255, .8);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fm-deck .dk-note {
  font-size: 11px; color: rgba(255, 255, 255, .62);
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
/* Phone | desktop. A second FACE for the surface's own seg, never a second
   owner of the width — see wsDeviceSeg. */
.fm-deck .dk-seg {
  display: inline-flex; flex: none; border-radius: 7px; overflow: hidden;
  background: rgba(255, 255, 255, .10);
}
.fm-deck .dk-seg button {
  border: 0; background: transparent; color: rgba(255, 255, 255, .62);
  padding: 7px 9px; cursor: pointer; line-height: 0;
}
.fm-deck .dk-seg button svg { width: 16px; height: 16px; display: block; }
.fm-deck .dk-seg button:hover { color: #fff; }
.fm-deck .dk-seg button.on { background: rgba(255, 255, 255, .22); color: #fff; }
/* The way out, hard right on every face. */
.fm-deck .dk-exit {
  border: 0; background: rgba(255, 255, 255, .14); color: #fff; flex: none;
  font-size: 13px; line-height: 1; cursor: pointer;
  width: 34px; height: 34px; border-radius: 7px; margin-left: 2px;
}
.fm-deck .dk-exit:hover { background: rgba(255, 255, 255, .26); }
/* B-8 — the first-run line, directly under the band. It could not stay IN the
   band once the page name moved there, and it must never eat a tap. */
.fm-deck-hint { display: none; }
body.fm-room-open #fm-workspace-view .fm-deck-hint {
  display: block; position: fixed; left: 0; right: 0;
  top: calc(52px + env(safe-area-inset-top, 0px)); z-index: 9099;
  background: rgba(35, 33, 47, .92); color: rgba(255, 255, 255, .82);
  font: 500 11.5px/1 "Inter", -apple-system, sans-serif;
  padding: 7px 12px; text-align: center; pointer-events: none;
}
body.fm-room-open #fm-workspace-view .fm-deck-hint[hidden] { display: none !important; }
@media (max-width: 640px) {
  body.fm-room-open #fm-workspace-view .fm-deck { gap: 5px; padding-left: 6px; padding-right: 6px; }
  .fm-deck .dk-btn { padding: 9px 8px; font-size: 11.5px; }
  .fm-deck .dk-seg button { padding: 7px 7px; }
  /* ⚠️ THE PAGE ARROWS GO ON A PHONE, and this is a measurement not a taste.
     412px cannot hold ‹ + funnel + › + phone|desktop + Maya + Approve + ✕:
     measured with all of them, the page NAME was squeezed to 3px — visibly
     nothing, and exactly the "crushed to Tr" fault B-2 exists to prevent.
     The arrows are the one control here that DUPLICATES another: the funnel
     door beside them lists every page and opens any of them. So the name
     keeps its room, and stepping pages on a phone is one tap through the
     door rather than zero taps through a control nobody can read next to. */
  .fm-deck [data-fm-deck-prev], .fm-deck [data-fm-deck-next] { display: none; }
  .fm-deck .dk-fun { max-width: 42vw; }
  .fm-deck .dk-gate { padding: 8px 10px; font-size: 11.5px; }
  /* ⚠️ ONE MAYA ON SCREEN. Her sheet is bottom-anchored and the band is at
     the top, so they no longer contend for space — but her minimised header
     row would still be a SECOND Maya affordance while the deck already
     carries her. The chip IS her closed state in this room. (The bottom
     offset that used to live here went with the band: nothing is down there
     to clear any more.) */
  body.fm-room-open .mpp.mpp-min { display: none !important; }
}

/* ── V3 (B-6) — the funnel sheet: pages + reorder + this page's tools ────── */
.fm-fsh .fm-fs-pg {
  display: flex; align-items: center; gap: 6px; padding: 0 10px;
  border-bottom: 1px solid var(--rk-silicon, #f0eef8);
}
.fm-fsh .fm-fs-pg:last-child { border-bottom: 0; }
.fm-fsh .fm-fs-open {
  flex: 1; min-width: 0; display: flex; justify-content: space-between; align-items: center;
  gap: 10px; border: 0; background: none; text-align: left;
  font-size: var(--rk-text-md, 15px); color: var(--rk-navy, #1f2430);
  padding: 12px 8px; cursor: pointer; border-radius: 8px;
}
.fm-fsh .fm-fs-pg.on .fm-fs-open { background: var(--rk-blue-light, #eef2ff); font-weight: var(--rk-weight-semi, 600); }
.fm-fsh .fm-fs-open:hover { background: var(--rk-cloud, #f7f6fc); }
.fm-fsh .fm-fs-open em {
  font-style: normal; font-size: var(--rk-text-xs, 12px);
  color: var(--rk-slate-light, #8b87a3); white-space: nowrap;
}
.fm-fsh .fm-fs-ord { display: flex; gap: 2px; flex: none; }
.fm-fsh .fm-fs-ord button {
  border: 0; background: none; color: var(--rk-slate, #5b5870); cursor: pointer;
  padding: 8px 9px; border-radius: 6px; font-size: 14px; line-height: 1;
}
.fm-fsh .fm-fs-ord button:hover { background: var(--rk-silicon, #e8e6f5); color: var(--rk-navy, #1f2430); }
.fm-fsh .fm-fs-ord button[disabled] { opacity: .3; cursor: default; }
.fm-fsh .fm-fs-row {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  width: 100%; border: 0; background: none; text-align: left;
  font-size: var(--rk-text-md, 15px); color: var(--rk-navy, #1f2430);
  padding: 12px 18px; cursor: pointer;
}
.fm-fsh .fm-fs-row:hover { background: var(--rk-cloud, #f7f6fc); }
.fm-fsh .fm-fs-row em {
  font-style: normal; font-size: var(--rk-text-xs, 12px);
  color: var(--rk-slate-light, #8b87a3); white-space: nowrap;
}

/* ── §DRAFT-VS-LIVE (2026-09-02) — the two page boxes ──────────────────────
   Alex: "we should have two boxes there and just say Live and Draft… that
   immediately creates visibility for everybody." Draft renders from the rows;
   Live frames the published bytes. The Live box is deliberately allowed to be
   EMPTY with a sentence in it — an unpublished course having no live version
   is the state the box exists to show, not a failure to render.

   ⚠️ `mg-pubshot`, NOT `mg-live`. `.mg-live` was already taken by the green
   state hero at the top of the board, and giving it an `aspect-ratio` here
   stretched that banner across the screen — caught by Alex in a screenshot
   within the hour. Class names in this file are shared with markup written
   years apart: grep before you coin one. */
.mg .mg-two { display: grid; gap: 14px; }
.mg .mg-ver-h { display: flex; align-items: baseline; gap: 8px; margin: 0 0 6px; }
.mg .mg-ver-t { font-size: 12px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; color: var(--text-2); }
.mg .mg-ver-s { font-size: 11.5px; color: var(--text-3); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mg .mg-pubshot { position: relative; aspect-ratio: 16/9; background: var(--surface-3); overflow: hidden; }
.mg .mg-pubshot iframe { position: absolute; top: 0; left: 0; width: 1280px; height: 860px;
  border: 0; transform-origin: top left; transform: scale(.243); pointer-events: none; }
.mg .mg-pubshot-empty { display: flex; align-items: center; justify-content: center; height: 100%;
  padding: 16px 18px; text-align: center; font-size: 12.5px; line-height: 1.5; color: var(--text-3); }

/* Both boxes open the real thing in a new tab. */
.mg .mg-shot.is-open { cursor: pointer; transition: box-shadow .15s, transform .15s; }
.mg .mg-shot.is-open:hover { transform: translateY(-1px); box-shadow: 0 8px 24px rgba(0,0,0,.10); }

/* ── Quick links ───────────────────────────────────────────────────────────
   A row hands you a LINK or the BUTTON that earns it — never a dead address.
   Alex: "I don't like this crossed out… it should have a button there." */
.mg-qlinks .ql-mid { flex: 1; min-width: 0; }
.mg-qlinks .ql-mid .ql-u { display: block; }
.mg-qlinks a.ql-u { color: var(--text-3); text-decoration: none; }
.mg-qlinks a.ql-u:hover { color: var(--accent); text-decoration: underline; }
.mg-qlinks .ql-note { font-size: 11.5px; color: var(--text-3); font-style: italic; }
.mg-qlinks .ql-act { flex: none; }
.mg-qlinks .ql-go { border: 1px solid var(--accent); background: var(--accent); color: #fff;
  border-radius: 7px; padding: 5px 12px; font-size: 11.5px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.mg-qlinks .ql-go:hover { filter: brightness(1.06); }

/* §MAYA-HATS — the Help handoff pill in Maya's thread (brain SPEC §14.5). */
.rc-mbub .rc-handoff { display: inline-block; margin-top: 8px; border: 1px solid var(--accent);
  background: transparent; color: var(--accent); border-radius: 999px; padding: 5px 12px;
  font-size: 12px; font-weight: 600; cursor: pointer; }
.rc-mbub .rc-handoff:hover { background: var(--accent); color: #fff; }
