/* =============================================
   REPLICANTS · App Shell — shared design system
   ============================================= */

/* ⚠️ THE TOKENS MOVED OUT — see css/design-tokens.css, linked before this sheet.
   They were lifted on 2026-09-11 so admin.html could render the coach's plan with
   the same values without loading this file's 97KB of app chrome (its `body`,
   `button` and `a` rules would have restyled every admin screen). This sheet still
   READS them; it no longer owns them. */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: "Inter", system-ui, -apple-system, sans-serif;
  font-size: 14.5px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}
.display { font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; letter-spacing: -0.015em; }
.mono { font-family: "JetBrains Mono", monospace; }
button { font-family: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }

/* ============ APP SHELL ============ */
/* NB the live shell wrapper in app.html is <div id="appShell"> — that's
   where the grid that lays out sidebar | main lives (see
   css/app-styles-v2.css:73 #appShell). The .app rule below is legacy /
   dead code retained only because some older pages may still reference
   the class; the active layout target is #appShell. */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;
}

/* Two independent collapse states drive the rail + subnav widths.
   Buttons + behaviour live in /app-shell.js. Detail rules (seam toggle,
   label cascade, collapsed-mode icons + tooltips, R-mark wink) are at the
   bottom of this file under "COLLAPSIBLE MENUS". State persisted in
   localStorage as 'rep-nav-collapsed' and 'rep-subnav-collapsed'. */
#appShell {
  transition: grid-template-columns .46s cubic-bezier(.33, 1.34, .5, 1);
}
#appShell.nav-collapsed { grid-template-columns: 76px 1fr; }
/* While restoring saved state on first paint, suppress all motion. */
#appShell.nav-instant, #appShell.nav-instant * { transition: none !important; }

aside.sidebar {
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: 22px 16px;
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px 18px;
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 14px;
}
.brand-mark {
  width: 30px; height: 30px;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%);
  display: flex; align-items: center; justify-content: center;
  color: #fff;
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: 16px;
  box-shadow: 0 4px 14px -4px rgba(106,76,241,0.5);
}
.brand-name {
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  letter-spacing: 0.2em;
  font-weight: 500;
  color: var(--text);
}
.nav-group { display: flex; flex-direction: column; gap: 2px; }
.nav-label {
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-4);
  padding: 14px 10px 6px;
  font-family: "JetBrains Mono", monospace;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 10px;
  border-radius: 9px;
  color: var(--text-2);
  font-size: 14px;
  font-weight: 500;
  transition: background .12s, color .12s;
}
.nav-item:hover { background: var(--surface-2); color: var(--text); }
.nav-item.active {
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-weight: 600;
}
.nav-item .ico { width: 18px; height: 18px; flex: 0 0 18px; opacity: 0.9; }
.nav-item .pill {
  margin-left: auto;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 999px;
  font-weight: 600;
}
.nav-item.active .pill { background: var(--accent-deep); }
/* The funnel trial gate (2026-09-27): "Free to start" on the Funnels row for an
   account without the plan (sidebar-nav.js _funnelsFreeTag). Quiet on purpose:
   it is a promise, not a sale. */
.nav-free-tag {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  white-space: nowrap;
}
.hamburger-item .nav-free-tag, .hamburger-head .nav-free-tag { margin-left: 8px; }

/* The scrollable middle of the rail (nav groups). flex:1 + min-height:0 lets
   it shrink inside the 100vh sticky aside; the foot below keeps margin-top:auto
   so Settings + the user card are always on screen. Slim themed scrollbar. */
.nav-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.nav-scroll::-webkit-scrollbar { width: 6px; }
.nav-scroll::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.nav-scroll::-webkit-scrollbar-track { background: transparent; }

/* Section labels inside the rail (e.g. the Admin group divider). Hidden in
   the collapsed rail — only icons fit there; an unstyled label previously
   overflowed the 64px rail as stray text (Alex, 2026-06-12). */
.nav-section-label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 10px 8px 4px;
  white-space: nowrap;
  overflow: hidden;
}
.nav-collapsed .nav-section-label { display: none; }

.sidebar-foot {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--border-soft);
}
.user-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 10px;
  border-radius: 11px;
  transition: background .12s;
  cursor: pointer;
}
.user-card:hover { background: var(--surface-2); }
.user-avatar {
  width: 34px; height: 34px;
  /* flex:0 0 34px so the circle can never be squeezed to an ellipse by a
     narrow card — it is the whole profile affordance on the collapsed rail. */
  flex: 0 0 34px;
  border-radius: 50%;
  background: linear-gradient(135deg, #b07aff 0%, #6a4cf1 100%);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700;
  font-size: 13px;
}
.user-name { font-weight: 600; color: var(--text); font-size: 14px; }
.user-plan { font-size: 11.5px; color: var(--text-3); }

/* main.main is used by standalone pages (setup.html, discover.html). Each
   page may override max-width locally for readability; this base rule keeps
   the content elastic by default rather than capping at a fixed pixel. */
main.main {
  padding: 28px 36px 80px;
  max-width: none;
}

/* TOPBAR */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 28px;
}
.crumbs {
  color: var(--text-3);
  font-size: 13px;
  display: flex;
  gap: 8px;
  align-items: center;
}
.crumbs .sep { color: var(--text-4); }
.crumbs .now { color: var(--text); font-weight: 500; }
.topbar-actions { display: flex; align-items: center; gap: 10px; }
.search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 12px;
  width: 280px;
  color: var(--text-3);
}
.search input {
  border: none; outline: none; background: transparent;
  font-family: inherit; font-size: 14px;
  flex: 1;
  color: var(--text);
}
.search kbd {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  color: var(--text-3);
  background: var(--surface-3);
  padding: 2px 6px;
  border-radius: 4px;
}
.icon-btn {
  width: 38px; height: 38px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-2);
  transition: background .12s, color .12s;
  position: relative;
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn .dot {
  position: absolute; top: 8px; right: 9px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--rose);
  border: 2px solid var(--surface);
}

/* ============ PAGE HEAD — design system component ============
   Every module page in /app.html uses this wrapper. Renders:
   - breadcrumb (optional, top, small muted text)
   - h1 (large, Bricolage Grotesque display font)
   - sub (subtitle, normal weight)
   - optional right-side meta block (e.g. status pill, time)
   Markup:
     <div class="page-head">
       <div>
         <div class="page-head-crumbs">
           <a class="crumb" href="...">Outreach</a>
           <span class="crumb-sep">/</span>
           <span class="crumb crumb-current">Dashboard</span>
         </div>
         <h1 class="display">Good morning, Alex 👋</h1>
         <div class="sub">Your community at a glance · 5 members, 11 posts this week</div>
       </div>
       <div class="page-head-meta">  optional right side
         <span class="status-pill">RUNNING</span>
       </div>
     </div>
   Source of truth: docs/design-system.md
*/
.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 28px;
}
.page-head > div:first-child { min-width: 0; flex: 1; }
/* 🔻 A CRUMB IS A TRAIL, NOT A SENTENCE — AND IT MUST NEVER SET THE PAGE WIDTH.
   Alex, 2026-08-25, looking at Maya's HQ: *"the breadcrumbs need to be fixed as
   well. They're too long and need to be managed better."* The last crumb there
   is a project name, and a project can be named anything, so the row grew until
   it filled the head. Uppercase mono at 0.18em tracking makes every character
   expensive, which is exactly why this row cannot be allowed to grow.

   Fixed here rather than in the feature sheet: this is the design system's own
   class, every page's crumbs can carry a name someone typed, and a page-level
   override would be both a namespace collision and a fix that only holds on
   one screen. Each crumb ellipsises at 28ch; the trail never wraps and never
   pushes the head wider than its column. Callers that put a long name in a
   crumb should also set `title` on it, so the full text is one hover away. */
.page-head-crumbs {
  display: flex; align-items: center; gap: 6px;
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 10px;
  min-width: 0;
  flex-wrap: nowrap;
}
.page-head-crumbs .crumb {
  color: var(--text-3); text-decoration: none;
  max-width: 28ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;
}
.page-head-crumbs .crumb-sep { flex: none; }
.page-head-crumbs .crumb:hover { color: var(--text); }
.page-head-crumbs .crumb-current { color: var(--text); }
.page-head-crumbs .crumb-sep { color: var(--text-4); }
.page-head h1 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  letter-spacing: -0.015em;
  font-size: 32px;
  margin: 0 0 4px;
  line-height: 1.15;
  color: var(--text);
}
.page-head h1.display { /* alias for clarity; same styles */ }
.page-head .sub { color: var(--text-2); font-size: 14.5px; }
.page-head .sub b { color: var(--text); font-weight: 600; }
.page-head-meta {
  flex-shrink: 0;
  text-align: right;
  font-size: 12px;
  color: var(--text-3);
  font-family: "JetBrains Mono", monospace;
  letter-spacing: 0.08em;
}

/* SEGMENT TABS */
.segment-tabs {
  display: inline-flex;
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 4px;
  border-radius: 11px;
  gap: 2px;
  margin-bottom: 24px;
}
.segment-tabs a {
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text-2);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: background .12s, color .12s;
}
.segment-tabs a:hover { color: var(--text); background: var(--surface-2); }
.segment-tabs a.active {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 4px 12px -4px rgba(106,76,241,0.5);
}
.segment-tabs a.active:hover { background: var(--accent-deep); }
.segment-tabs a .badge-num {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  background: var(--surface-3);
  color: var(--text-3);
  padding: 1px 7px;
  border-radius: 999px;
  font-weight: 500;
  /* Counts can be 2–3 digits — the pill must never collapse or clip. */
  min-width: 22px;
  text-align: center;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.segment-tabs a.active .badge-num {
  background: rgba(255,255,255,0.2);
  color: #fff;
}

/* CARD BASE */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px;
  gap: 12px;
  border-bottom: 1px solid var(--border-soft);
}
.card-title {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 10px;
}
.card-title .count {
  background: var(--surface-3);
  color: var(--text-2);
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 999px;
}

/* AVATARS — color variants */
.avatar {
  width: 40px; height: 40px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  font-family: "Inter", sans-serif;
  flex: 0 0 40px;
}
.avatar-sm { width: 32px; height: 32px; flex: 0 0 32px; font-size: 11.5px; }
.avatar-lg { width: 48px; height: 48px; flex: 0 0 48px; font-size: 15px; }
.av-1 { background: linear-gradient(135deg, #f17d6e, #e85a8a); }
.av-2 { background: linear-gradient(135deg, #6a4cf1, #b07aff); }
.av-3 { background: linear-gradient(135deg, #1c8e5a, #38b878); }
.av-4 { background: linear-gradient(135deg, #b87410, #d99634); }
.av-5 { background: linear-gradient(135deg, #b15dde, #d27df0); }
.av-6 { background: linear-gradient(135deg, #4a32b8, #6a4cf1); }
.av-7 { background: linear-gradient(135deg, #c0423a, #e85a8a); }
.av-8 { background: linear-gradient(135deg, #38b878, #1c8e5a); }
.av-9 { background: linear-gradient(135deg, #1f5fa9, #3f8ade); }
.av-10 { background: linear-gradient(135deg, #6a4cf1, #4a32b8); }
.av-11 { background: linear-gradient(135deg, #e0a040, #b87410); }
.av-12 { background: linear-gradient(135deg, #d27df0, #8b6dff); }

/* BUTTONS */
.btn {
  border: none;
  border-radius: 10px;
  padding: 10px 16px;
  font-size: 13.5px;
  font-weight: 600;
  transition: transform .1s, background .12s, color .12s;
  display: inline-flex; align-items: center; gap: 8px;
  font-family: "Inter", sans-serif;
}
/* Alex, 2026-08-09: *"give it a blue outline that is the same blue … when you
   hover on it instead of being black text on blue … change the text to white."*
   The outline is the same accent as the fill, so a primary sits in the same 1px
   box as the now-outlined `.btn-secondary` and the two align on a row. `color`
   is restated on :hover because it was being lost to an unscoped rule in
   discover.css; that leak is fixed at source, and pinning it here means a future
   late-loading page style cannot take the text colour off a primary again. */
.btn-primary { background: var(--accent); color: #fff; border: 1px solid var(--accent); }
.btn-primary:hover { background: var(--accent-deep); border-color: var(--accent-deep); color: #fff; }
.btn-secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
.btn-secondary:hover { background: var(--surface-2); }
.btn-dark { background: #15172b; color: #fff; }
.btn-dark:hover { background: #1f2238; }
/* D4 — Alex, twice: *"the design of these buttons is really bad. They're just
   words that when you highlight … Maybe there should at least be an outline …
   That should be a CSS update that updates all these types of buttons at the
   same time."*

   He was describing this rule literally. `.btn` sets `border: none`, so a ghost
   button had no border and no background — it WAS just words, and only became
   a button on hover, once the pointer was already on it.

   The border is not a new decision. `.btn-secondary` directly above already
   defines what a bordered button looks like in this system, so this takes the
   same `1px solid var(--border)` rather than inventing a weight or a colour.
   The transparent background stays, which is what still separates ghost from
   secondary: same outline, no fill, so the hierarchy is unchanged and only the
   invisibility is gone.

   ⚠️ Scope, also read from the code rather than chosen: `.suc-btn-ghost`
   (success-pilot.css) already carries a border, and `.btn-link` is an
   underlined text link — visibly a link, not the silent-words defect. The only
   other surface with this exact fault is `.onb-btn-ghost` in setup.html, which
   is fixed in the same pass. */
.btn-ghost { background: transparent; color: var(--text-2); border: 1px solid var(--border); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text); }

/* STATUS BADGES */
.badge {
  font-size: 11px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  font-family: "Inter", sans-serif;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  letter-spacing: 0.01em;
}
.badge-success { background: var(--good-soft); color: var(--good); }
.badge-fail { background: var(--danger-soft); color: var(--danger); }
.badge-warn { background: var(--warn-soft); color: var(--warn); }
.badge-info { background: var(--accent-soft); color: var(--accent-deep); }
.badge-neutral { background: var(--surface-3); color: var(--text-2); }
.badge-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
}

@media (max-width: 1180px) {
  .search { width: 220px; }
}
@media (max-width: 880px) {
  .app { grid-template-columns: 1fr; }
  aside.sidebar { display: none; }
  main.main { padding: 20px; }
  .search { display: none; }
}

/* ============ COMMUNITY SHELL — 2-column layout (sidebar + subnav + page-wrap) ============ */
main.community-main {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  align-items: stretch;
  padding: 0;
  max-width: none;
  min-width: 0;
}
/* When the secondary subnav is hidden (modules other than outreach /
   community / email — e.g. the website builder via /website → funnels),
   the empty 220px grid track left an ugly gap and squeezed the content
   column. renderSubnav() in sidebar-nav.js toggles .subnav-hidden on
   this element so the grid collapses to a single column on those pages. */
main.community-main.subnav-hidden {
  grid-template-columns: minmax(0, 1fr);
}
.subnav {
  border-right: 1px solid var(--border-soft);
  padding: 28px 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--surface-2);
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
  /* The rail paints ABOVE the content beside it.
     Both this and `main.community-main` are positioned with z-index:auto, so
     they paint in DOM order — and the rail comes first, which put the whole
     rail UNDER the main column. Invisible until something in the rail needs to
     escape it: the collapsed-rail tooltip (`.sub-item::after`, z-index 60) was
     rendered with opacity 1 and correct text and could not be seen, because a
     course card was painted over the top of it. Alex spotted it on the courses
     grid, 2026-08-02, but it was never specific to that page.
     Deliberately low — modals and overlays sit at 9000+ and still win. */
  z-index: 5;
}
.sub-eyebrow {
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: var(--text-4);
  text-transform: uppercase;
  padding: 14px 10px 6px;
}
.sub-eyebrow:first-child { padding-top: 0; }
.sub-item {
  padding: 8px 12px;
  border-radius: 9px;
  color: var(--text-2);
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: background .12s, color .12s;
  cursor: pointer;
  text-decoration: none;
}
.sub-item:hover { background: var(--surface); color: var(--text); }
.sub-item.active {
  background: var(--surface);
  color: var(--accent-deep);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(20,15,40,0.04);
}
.sub-item .ico { width: 16px; height: 16px; flex: 0 0 16px; opacity: 0.85; }
.sub-item.active .ico { color: var(--accent); opacity: 1; }
/* 🚨 WHY THIS RULE EXISTS: A LABEL WAS BEING CUT WITH NOTHING TO SHOW FOR IT.
   "Create your community" rendered as "Create your commur" in the 220px
   subnav — no ellipsis, no wrap, no scrollbar. Alex, 2026-08-25: *"there are
   different states of the menu, I might not be able to see what's written
   there."*

   `.sub-item` is a flex container, so a bare text node became an anonymous
   flex item with `min-width:auto`, which refuses to shrink below its content
   width and overflows the column instead of wrapping. Anonymous items cannot
   be selected, which is why no stylesheet had ever been able to fix this;
   `item()` in sidebar-nav.js now emits a real `<span class="lbl">` — that
   class name and not a new one, because the collapsed-rail rules further down
   this file have been selecting `.sub-item .lbl` and `attr(data-tip)` since
   they were written, against markup that never existed. Both were dead; both
   work now.

   ⚠️ ELLIPSIS, NOT WRAP, AND THE REASON IS 400 LINES BELOW. The first draft of
   this rule wrapped the label to two lines, which is the friendlier answer —
   but `.sub-item .lbl` is ALSO styled by the collapse animation further down
   (`white-space:nowrap; overflow:hidden; max-width:170px`, transitioning
   max-width to 0 as the rail closes). That rule is later in the file and wins,
   so `overflow-wrap` never applied and the label went back to being cut with
   nothing to show for it. Wrapping and the collapse animation cannot both be
   had: the animation needs a single line to slide shut.

   So the guarantee is different and weaker, and worth stating plainly: a label
   too long for the column is CUT, but it is cut with an ellipsis and it keeps
   its full text in `data-tip` for the collapsed tooltip. Truncation you can
   see and recover is survivable. "Create your commur" was not.

   `min-width:0` is what lets it shrink to the column at all — as a flex item
   it otherwise refuses to go below its 170px cap and overflows instead. */
.sub-item .lbl {
  min-width: 0;
}
.sub-item .right-tag {
  margin-left: auto;
  flex: 0 0 auto;   /* the tag keeps its width; the label is what gives way */
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px;
  color: var(--text-4);
}
.sub-item.active .right-tag { color: var(--accent); }
/* ── "Soon" rows on the product shelf (A0ad.1) ──────────────────────────
   Alex wants a coach to SEE what is coming — *"it will get them excited"* —
   so these render rather than being hidden like `comingSoon` items. They are
   `<span>`s with no handler (sidebar-nav.js `item()`), and this makes them
   look the part: readable, plainly not a destination, no hover lift and no
   pointer. A row that looks tappable and is not is the fault this round has
   spent the day removing; a row that looks like a label is honest. */
.sub-item.is-soon {
  cursor: default;
  opacity: .55;
}
.sub-item.is-soon:hover { background: none; color: var(--text-2); }
.sub-item.is-soon .right-tag {
  font-family: inherit;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: 20px;
  background: var(--surface-2, rgba(128,128,128,.12));
  color: var(--text-3);
}
.page-wrap { padding: 28px 36px 80px; min-width: 0; }
@media (max-width: 1100px) {
  .subnav { display: none; }
  main.community-main { grid-template-columns: minmax(0, 1fr); }
  /* T5 — unify the mobile/tablet-portrait nav breakpoint at 1100px: the
     sidebar disappears exactly where the secondary subnav does, and the
     hamburger accordion (shown ≤1100px in app-styles-v2.css) becomes the single
     nav that reaches both top-level modules AND their submenus. This closes the
     881–1100px dead band where neither subnav nor hamburger was reachable.
     >1100px (tablet-landscape + desktop) keeps the sidebar + subnav unchanged. */
  .app { grid-template-columns: 1fr; }
  aside.sidebar { display: none; }
}

/* =============================================================
   UNIFIED SPA — Block 1 (2026-05-26)
   Per-page styles lifted from the standalone module HTMLs so the
   absorbed content (Blocks 2-4) renders inside /app.html unchanged.
   Each section is delimited by its source page. Duplicates of the
   community shell rules above (community-main, subnav, sub-eyebrow,
   sub-item, page-wrap, mobile breakpoint) were NOT lifted — they
   already live in this file.
   ============================================================= */

/* === Source: src/public/community.html — community feed/members/posts === */

.route { display: none; }
.route.active { display: block; }

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  margin-bottom: 18px;
  overflow: hidden;
}
.panel-head {
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--border-soft);
}
.panel-head h2 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 18px;
  margin: 0 0 4px;
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
}
.panel-head .sub {
  color: var(--text-3);
  font-size: 13px;
}
.panel-head .sub b { color: var(--text); font-weight: 600; }
.panel-head .row-end {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.panel-body { padding: 20px 24px; }

.stat-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-bottom: 22px;
}
.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
}
.stat .label { font-size: 12.5px; color: var(--text-3); font-weight: 500; }
.stat .value {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 30px;
  color: var(--text);
  margin-top: 4px;
  letter-spacing: -0.02em;
  display: flex;
  align-items: baseline;
  gap: 5px;
}
.stat .value .unit { font-size: 14px; color: var(--text-3); font-weight: 500; }
.stat .delta {
  margin-top: 8px;
  font-size: 12.5px;
  color: var(--good);
  font-weight: 600;
}
.stat .delta .note { color: var(--text-3); font-weight: 500; margin-left: 4px; }

.ov-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}
.activity-list { padding: 4px 0; }
.activity-row {
  display: grid;
  /* Avatar column sizes to the avatar itself (.avatar-sm is 32px here but 36px
     under outreach-dashboard.css) so it never overflows into the gap and
     crowds the text. Slightly larger gap for breathing room. */
  grid-template-columns: auto 1fr auto;
  gap: 14px;
  padding: 12px 24px;
  align-items: center;
  border-bottom: 1px solid var(--border-soft);
  font-size: 13.5px;
}
.activity-row:last-child { border-bottom: none; }
.activity-row .who { color: var(--text); font-weight: 600; }
.activity-row .what { color: var(--text-3); font-size: 12.5px; margin-top: 1px; }
.activity-row .when {
  color: var(--text-3);
  font-family: "JetBrains Mono", monospace;
  font-size: 11.5px;
}

.public-url {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft);
  color: var(--accent-deep);
  border-radius: 12px;
  padding: 14px 18px;
  font-family: "JetBrains Mono", monospace;
  font-size: 13px;
  margin-top: 14px;
}
.public-url .url { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.public-url .btn { padding: 6px 12px; font-size: 12px; }

.feed-toolbar {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.chip-filter {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-2);
  border-radius: 999px;
  padding: 7px 13px;
  font-size: 12.5px;
  font-weight: 500;
  transition: background .12s, color .12s;
}
.chip-filter:hover { background: var(--surface-2); color: var(--text); }
.chip-filter.active { background: var(--text); color: #fff; border-color: var(--text); }

.post-row {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  gap: 14px;
  padding: 20px 24px;
  border-bottom: 1px solid var(--border-soft);
  align-items: start;
  transition: background .12s;
}
.post-row:last-child { border-bottom: none; }
.post-row:hover { background: var(--surface-2); }
.post-row.pinned { background: linear-gradient(180deg, var(--accent-softer) 0%, transparent 100%); }
.post-row.pinned:hover { background: var(--accent-softer); }

.post-meta {
  color: var(--text-3);
  font-size: 12.5px;
  font-family: "JetBrains Mono", monospace;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.post-meta .who { color: var(--text); font-weight: 600; font-family: "Inter", sans-serif; }
.post-meta .channel { color: var(--accent); }
.post-title {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.005em;
  margin: 0 0 4px;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.post-excerpt {
  color: var(--text-2);
  font-size: 14px;
  margin: 4px 0 12px;
  line-height: 1.55;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-actions {
  display: flex;
  gap: 6px;
  align-items: center;
  /* Round 2 (c1): on a pinned card (Unpin, ▲, ▼, Share to socials, Hide,
     Delete) the row ran past the card and Delete sat outside it. Wrap. */
  flex-wrap: wrap;
  min-width: 0;
}
.post-actions .btn { padding: 6px 12px; font-size: 12.5px; }
.post-actions .count {
  color: var(--text-3);
  font-size: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  padding: 6px 10px;
  border-radius: 8px;
  font-family: "JetBrains Mono", monospace;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.post-right { text-align: right; }

.member-row {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  gap: 14px;
  padding: 16px 24px;
  border-bottom: 1px solid var(--border-soft);
  align-items: center;
  transition: background .12s;
}
.member-row:last-child { border-bottom: none; }
.member-row:hover { background: var(--surface-2); }
.member-row .name {
  font-weight: 600;
  color: var(--text);
  font-size: 14.5px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.member-row .meta {
  color: var(--text-3);
  font-size: 12.5px;
  font-family: "JetBrains Mono", monospace;
  margin-top: 2px;
}
.member-actions { display: flex; gap: 6px; }
.member-actions .btn { padding: 7px 12px; font-size: 12.5px; }
.role-tag {
  font-size: 10px;
  background: var(--surface-3);
  color: var(--text-2);
  padding: 2px 7px;
  border-radius: 4px;
  font-family: "JetBrains Mono", monospace;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.role-power { background: var(--accent-soft); color: var(--accent-deep); }
.role-regular { background: var(--good-soft); color: var(--good); }
.role-new { background: var(--warn-soft); color: var(--warn); }

.msg-row {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  gap: 12px;
  padding: 14px 24px;
  border-bottom: 1px solid var(--border-soft);
  align-items: center;
  transition: background .12s;
  cursor: pointer;
}
.msg-row:last-child { border-bottom: none; }
.msg-row:hover { background: var(--surface-2); }
.msg-row .name { font-weight: 600; font-size: 14px; }
.msg-row .snip { color: var(--text-3); font-size: 12.5px; margin-top: 1px; }
.msg-row .when { color: var(--text-3); font-size: 11.5px; font-family: "JetBrains Mono", monospace; }

.idea-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.idea {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 22px 18px;
  transition: border-color .15s, transform .15s;
}
.idea:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.idea h3 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 16px;
  margin: 0 0 8px;
  letter-spacing: -0.005em;
  color: var(--text);
}
.idea p {
  color: var(--text-2);
  font-size: 13.5px;
  line-height: 1.55;
  margin: 0 0 16px;
}
.idea-actions { display: flex; gap: 8px; }
.idea-actions .btn { padding: 7px 13px; font-size: 12.5px; }
.idea-stats {
  display: flex;
  gap: 14px;
  margin-top: 12px;
  font-size: 11.5px;
  color: var(--text-3);
  font-family: "JetBrains Mono", monospace;
}
.idea-stats span { display: inline-flex; align-items: center; gap: 5px; }

.form-stack { display: flex; flex-direction: column; gap: 14px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field label {
  font-size: 12.5px;
  color: var(--text-2);
  font-weight: 600;
  letter-spacing: 0.01em;
}
.field .hint { font-size: 12px; color: var(--text-3); font-weight: 400; }
.input, .textarea, .select {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 11px 14px;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.input:focus, .textarea:focus, .select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.textarea { min-height: 100px; resize: vertical; line-height: 1.55; }
.field-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: end;
}
/* Courses 2B backlog fold-in (brief 2B §2d): .field-row's second column
   is `auto`-sized, so a <select>/<input> with wide content (e.g. "Level
   — unlocked at a community level") forces that column wide and squeezes
   the `1fr` sibling at narrow widths — the courses editor's Title input
   and per-lesson drip label are two symptoms of this ONE shared root
   cause, not separate bugs. Stack to a single column below 480px, same
   breakpoint this file already uses elsewhere (line ~2705). This is a
   single class definition used by every settings form built on it
   (grepped: one other occurrence in this file, the definition above) —
   fixing it here fixes every one of them, not just courses. */
@media (max-width: 480px) {
  .field-row { grid-template-columns: 1fr; }
}
.panel-foot {
  padding: 14px 24px;
  border-top: 1px solid var(--border-soft);
  background: var(--surface-2);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.panel-foot .meta { color: var(--text-3); font-size: 12.5px; }
.panel-foot .meta b { color: var(--text); font-weight: 600; }

.empty-block {
  text-align: center;
  padding: 32px 24px 24px;
  color: var(--text-3);
}
.empty-block .ico {
  width: 56px; height: 56px;
  border-radius: 16px;
  background: var(--accent-soft);
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 14px;
}
.empty-block h3 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 18px;
  color: var(--text);
  margin: 0 0 6px;
}
.empty-block p { margin: 0 0 18px; font-size: 14px; max-width: 380px; margin-inline: auto; }

/* ============ MEDIA LIBRARY (Settings → Media, P1-1) ============
   Management grid for the shared image/video library. Light-theme
   design-system counterpart to the builder's dark modal. */
.media-folders { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.media-folders:empty { display: none; }
.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 14px;
}
.media-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: box-shadow .12s, border-color .12s;
}
.media-card:hover { border-color: var(--border-strong); box-shadow: 0 6px 18px -8px rgba(21,23,43,0.18); }
.media-card-thumb { height: 120px; background: var(--surface-3); }
.media-card-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.media-card-thumb-empty {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-4); font-size: 26px;
}
.media-card-info { padding: 10px 12px; }
.media-card-name {
  font-size: 12.5px; font-weight: 500; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.media-card-meta { font-size: 11.5px; color: var(--text-3); margin-top: 3px; display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.media-card-delete {
  position: absolute; top: 8px; right: 8px;
  width: 30px; height: 30px;
  border: none; border-radius: 8px; cursor: pointer;
  background: rgba(255,255,255,0.92); color: var(--text-3);
  display: none; align-items: center; justify-content: center;
  font-size: 13px;
}
.media-card:hover .media-card-delete { display: inline-flex; }
.media-card-delete:hover { color: var(--danger); background: #fff; }
.media-dropzone {
  margin-top: 16px;
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius);
  padding: 18px;
  text-align: center;
  color: var(--text-3);
  font-size: 13px;
  transition: border-color .12s, background .12s;
}
.media-dropzone.drag-over { border-color: var(--accent); background: var(--accent-softer); }
.media-progress-label { font-size: 12.5px; color: var(--accent-deep); margin-bottom: 5px; }
.media-progress-track { background: var(--surface-3); border-radius: 6px; overflow: hidden; height: 8px; }
.media-progress-bar { background: var(--accent); height: 100%; width: 0%; transition: width .2s; }
@media (max-width: 700px) {
  .media-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .media-card-delete { display: inline-flex; } /* touch — no hover */
}

/* Composer media attachments (Community → Content, P1-6): image/video
   chips + the inline light video picker. */
.cm-chips { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 10px; }
.cm-chips:empty { display: none; }
.cm-chip { position: relative; width: 110px; }
.cm-chip-thumb {
  width: 110px; height: 78px;
  border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface-3); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-4);
}
.cm-chip-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cm-chip-remove {
  position: absolute; top: -7px; right: -7px;
  width: 22px; height: 22px; padding: 0;
  border: none; border-radius: 50%; cursor: pointer;
  background: var(--text); color: #fff; font-size: 13px; line-height: 1;
}
.cm-chip-alt {
  width: 110px; margin-top: 4px; padding: 4px 6px; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: 6px;
  font-size: 11px; font-family: inherit;
}
.cm-chip-label {
  margin-top: 4px; font-size: 11px; color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cm-video-picker {
  margin-top: 12px; padding: 14px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2);
}
.cm-video-picker-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; margin-bottom: 12px;
  font-size: 13px; color: var(--text-2);
}

.page-title-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 22px;
}
.page-title-row h1 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 28px;
  letter-spacing: -0.015em;
  margin: 0 0 3px;
  color: var(--text);
}
.page-title-row .lead { color: var(--text-2); font-size: 14.5px; }
.page-title-row .lead b { color: var(--text); font-weight: 600; }

@media (max-width: 720px) {
  .stat-strip, .idea-grid, .ov-grid { grid-template-columns: 1fr; }
}

/* === Source: src/public/community-analytics.html — analytics dashboard/tiles/ranked lists === */

.range-tabs {
  display: inline-flex;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 3px;
}
.range-tabs button {
  border: none; background: transparent;
  font-size: 12.5px; padding: 6px 12px; border-radius: 7px;
  color: var(--text-2); font-weight: 500;
}
.range-tabs button.active {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 2px 6px -2px rgba(106,76,241,0.4);
}

.section { margin-bottom: 28px; }
.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 12px;
  gap: 14px;
}
.section-head h2 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.005em;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text);
}
.section-head h2 .hint {
  font-size: 11.5px;
  color: var(--text-3);
  font-weight: 500;
  font-family: "Inter", sans-serif;
  letter-spacing: 0;
}

.tile-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.tile-grid.col-3 { grid-template-columns: repeat(3, 1fr); }
.tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  position: relative;
  overflow: hidden;
}
.tile .label {
  font-size: 12px;
  color: var(--text-3);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.tile .value {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 36px;
  color: var(--text);
  margin-top: 6px;
  line-height: 1;
  letter-spacing: -0.025em;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.tile .value .unit { font-size: 14px; color: var(--text-3); font-weight: 500; }
.tile .delta {
  margin-top: 10px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
}
.delta.up { color: var(--good); }
.delta.down { color: var(--danger); }
.delta.flat { color: var(--text-3); }
.delta .note { color: var(--text-3); font-weight: 500; margin-left: 4px; }
.tile.zero {
  background: var(--surface-2);
  border-style: dashed;
}
.tile.zero .value { color: var(--text-3); }
.tile.zero .delta { color: var(--text-3); }

.tile.funnel {
  background: linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 100%);
}
.tile .funnel-bar {
  height: 4px;
  background: var(--surface-3);
  border-radius: 2px;
  margin-top: 12px;
  overflow: hidden;
}
.tile .funnel-fill {
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
}
.arrow-step {
  color: var(--text-4);
  align-self: center;
  text-align: center;
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.spread-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 24px;
}
.spread-bar {
  display: flex;
  height: 38px;
  border-radius: 10px;
  overflow: hidden;
  margin: 18px 0 12px;
  border: 1px solid var(--border-soft);
}
.spread-seg {
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700;
  font-family: "Bricolage Grotesque", sans-serif;
  font-size: 15px;
  transition: opacity .12s;
}
.spread-seg:hover { opacity: 0.92; }
.seg-light  { background: linear-gradient(90deg, #f3b6a4, #f17d6e); }
.seg-active { background: linear-gradient(90deg, #ee6c80, #e85a8a); }
.seg-power  { background: linear-gradient(90deg, #b15dde, #6a4cf1); }
.spread-legend {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--text-2);
}
.spread-legend .li { display: inline-flex; align-items: center; gap: 7px; }
.spread-legend .li b { color: var(--text); font-weight: 700; }
.spread-legend .sw {
  width: 9px; height: 9px; border-radius: 3px;
}

.ranked {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.ranked-head {
  padding: 18px 22px;
  border-bottom: 1px solid var(--border-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.ranked-head h3 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 15px;
  margin: 0;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
}
.ranked-head .total {
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  color: var(--text-3);
}
.ranked-row {
  display: grid;
  grid-template-columns: 32px 1fr auto auto;
  gap: 14px;
  padding: 12px 22px;
  align-items: center;
  border-bottom: 1px solid var(--border-soft);
  font-size: 13.5px;
  transition: background .12s;
}
.ranked-row:last-child { border-bottom: none; }
.ranked-row:hover { background: var(--surface-2); }
.rank-num {
  font-family: "JetBrains Mono", monospace;
  font-size: 13px;
  color: var(--text-3);
  text-align: center;
  font-weight: 600;
}
.rank-title { font-weight: 500; color: var(--text); }
.rank-author { color: var(--text-3); font-size: 12.5px; margin-top: 1px; }
.rank-bar {
  width: 140px;
  height: 6px;
  background: var(--surface-3);
  border-radius: 3px;
  overflow: hidden;
}
.rank-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  border-radius: 3px;
}
.rank-val {
  font-family: "JetBrains Mono", monospace;
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
  width: 36px;
  text-align: right;
}

.two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

.callout {
  background: linear-gradient(135deg, #15102e 0%, #221a52 60%, #2d2470 100%);
  color: #fff;
  border-radius: var(--radius-xl);
  padding: 24px 28px;
  margin-bottom: 22px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 22px;
  align-items: center;
  position: relative;
  overflow: hidden;
}
.callout::before {
  content: "";
  position: absolute;
  right: -80px; top: -80px;
  width: 240px; height: 240px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(139,109,255,0.35), transparent 65%);
}
.callout-eyebrow {
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px;
  letter-spacing: 0.22em;
  color: rgba(255,255,255,0.62);
  text-transform: uppercase;
  margin-bottom: 6px;
}
.callout h2 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 22px;
  margin: 0 0 4px;
  letter-spacing: -0.015em;
  position: relative;
}
.callout p {
  color: rgba(255,255,255,0.7);
  margin: 0;
  font-size: 14px;
  max-width: 560px;
  position: relative;
}
.callout .btn { position: relative; }

@media (max-width: 720px) {
  .tile-grid, .tile-grid.col-3 { grid-template-columns: 1fr 1fr; }
  .callout { grid-template-columns: 1fr; }
}

/* === Source: src/public/community-settings.html — settings/profile/channels/form fields === */

.settings-layout {
  padding: 28px 36px 80px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 220px;
  gap: 36px;
  min-width: 0;
}
.toc {
  position: sticky;
  top: 28px;
  align-self: start;
  border-left: 1px solid var(--border-soft);
  padding-left: 16px;
}
.toc-label {
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: var(--text-4);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.toc a {
  display: block;
  padding: 6px 0;
  font-size: 13px;
  color: var(--text-3);
  border-left: 2px solid transparent;
  padding-left: 12px;
  margin-left: -14px;
  transition: color .12s, border-color .12s;
}
.toc a:hover { color: var(--text); }
.toc a.active {
  color: var(--accent-deep);
  border-left-color: var(--accent);
  font-weight: 600;
}

/* Mobile: the content + 220px TOC grid squeezes the content into a narrow left
   column on phones. Stack to one column and drop the TOC (the page is short
   enough to scroll). Mirrors the app's 768px mobile breakpoint — see the
   #appShell collapse in 71b8a08f, which fixed the outer grid but not this inner one. */
@media (max-width: 768px) {
  .settings-layout {
    /* minmax(0, 1fr), as on desktop: a plain 1fr column grows to its widest
       unbreakable child (the public address row), which made the whole page
       798px wide on a 390px phone and pushed every card off the right edge. */
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    padding: 20px 16px 64px;
  }
  .settings-layout .toc { display: none; }
  /* The address takes its own line and the buttons sit under it: side by side
     on a phone, the address shrank to nothing beside Copy, Change and Open. */
  .settings-layout .url-row { flex-wrap: wrap; }
  .settings-layout .url-row .url { flex-basis: 100%; }
}

.sec {
  scroll-margin-top: 24px;
  margin-bottom: 28px;
}
.sec-head {
  margin-bottom: 14px;
}
.sec-head h2 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.015em;
  margin: 0 0 4px;
  color: var(--text);
  display: flex; align-items: center; gap: 10px;
}
.sec-head .lead { color: var(--text-3); font-size: 13.5px; }

.card-inner {
  padding: 22px 24px;
  border-bottom: 1px solid var(--border-soft);
}
.card-inner:last-child { border-bottom: none; }
.card-inner h3 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.005em;
  margin: 0 0 4px;
  color: var(--text);
}
.card-inner .desc {
  color: var(--text-3);
  font-size: 13px;
  margin-bottom: 14px;
}
.card-inner .desc:last-child { margin-bottom: 0; }
.card-inner .desc b { color: var(--text); font-weight: 600; }
.card-inner .row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.card-inner .row.tight { margin-bottom: 0; }
.card + .card { margin-top: 14px; }

.field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.field-grid.col-3 { grid-template-columns: 1fr 1fr 1fr; }

.pill-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.choice-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 12px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text-2);
  cursor: pointer;
  transition: all .12s;
}
.choice-pill:hover { background: var(--surface-2); color: var(--text); }
.choice-pill.active {
  background: var(--text);
  color: #fff;
  border-color: var(--text);
}
.choice-pill.active .ico { color: #fff; }
.choice-pill .ico { width: 14px; height: 14px; }
.choice-pill .check {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 1.5px solid var(--border-strong);
  display: inline-flex; align-items: center; justify-content: center;
}
.choice-pill.active .check {
  background: #fff; border-color: #fff;
}
.choice-pill.active .check::after {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--text);
}

.toggle {
  width: 40px; height: 22px;
  background: var(--border-strong);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background .15s;
  flex: 0 0 40px;
}
.toggle::after {
  content: "";
  width: 16px; height: 16px;
  background: #fff;
  border-radius: 50%;
  position: absolute;
  top: 3px; left: 3px;
  transition: transform .15s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
.toggle.on { background: var(--accent); }
.toggle.on::after { transform: translateX(18px); }

.url-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 8px 8px 8px 16px;
}
.url-row .url {
  flex: 1;
  font-family: "JetBrains Mono", monospace;
  font-size: 13px;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;   /* a flex item will not shrink below its text without this, so the ellipsis never showed */
}
.url-row .free-tag {
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px;
  color: var(--good);
  margin-left: 4px;
}
.url-row .actions { display: flex; gap: 6px; }
.url-row .btn { padding: 8px 12px; font-size: 12.5px; }

.profile-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.mini-field {
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 12px 14px;
}
.mini-field .lbl {
  font-family: "JetBrains Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 4px;
}
.mini-field .val {
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
}
.ai-summary {
  background: linear-gradient(135deg, var(--accent-softer), #fff 80%);
  border: 1px solid var(--accent-soft);
  border-radius: 12px;
  padding: 18px 20px;
  margin-top: 14px;
}
.ai-summary-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 10px;
  color: var(--accent-deep);
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 600;
}
.ai-summary-head .ico {
  width: 18px; height: 18px;
}
.ai-summary p {
  color: var(--text-2);
  font-size: 13.5px;
  line-height: 1.6;
  margin: 0 0 10px;
}
.ai-summary p:last-child { margin-bottom: 0; }

.color-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.color-swatches {
  display: flex; gap: 6px;
}
.color-swatch {
  width: 28px; height: 28px;
  border-radius: 8px;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform .1s;
}
.color-swatch:hover { transform: scale(1.06); }
.color-swatch.active {
  border-color: var(--text);
  box-shadow: 0 0 0 2px #fff inset;
}
.color-hex-input {
  width: 110px;
  font-family: "JetBrains Mono", monospace;
  font-size: 13px;
}
.color-preview {
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 1px solid var(--border);
}

.channel-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border-soft);
}
.channel-row:last-of-type { border-bottom: none; }
.channel-row .hash {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: 14px;
  flex: 0 0 32px;
}
.channel-row .info { flex: 1; min-width: 0; }
.channel-row .name { font-weight: 600; color: var(--text); font-size: 14px; }
.channel-row .slug { color: var(--text-3); font-size: 12.5px; font-family: "JetBrains Mono", monospace; margin-top: 1px; }
.channel-row .role-tag {
  font-size: 10px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  padding: 2px 7px;
  border-radius: 4px;
  font-family: "JetBrains Mono", monospace;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.save-bar {
  position: sticky;
  bottom: 18px;
  margin-top: 24px;
  background: var(--text);
  color: #fff;
  border-radius: 14px;
  padding: 14px 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  box-shadow: 0 12px 32px -10px rgba(20,15,40,0.4);
  z-index: 5;
}
.save-bar .info { font-size: 13.5px; opacity: 0.85; }
.save-bar .info b { color: #fff; font-weight: 600; opacity: 1; }
.save-bar .actions { display: flex; gap: 8px; }
.save-bar .btn.btn-secondary { background: rgba(255,255,255,0.1); color: #fff; border-color: rgba(255,255,255,0.15); }
.save-bar .btn.btn-secondary:hover { background: rgba(255,255,255,0.2); }
.save-bar .btn.btn-primary { background: #fff; color: var(--text); }
.save-bar .btn.btn-primary:hover { background: #f1edff; }

.danger-card {
  background: linear-gradient(180deg, var(--danger-soft), var(--surface));
  border: 1px solid #f4c4c0;
}

@media (max-width: 1000px) {
  .field-grid, .field-grid.col-3, .profile-grid { grid-template-columns: 1fr; }
}

/* === Source: src/public/comments.html — comments review/pending/queued/sent list === */

.progress-row {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 22px;
}
.progress-track {
  flex: 1;
  height: 6px;
  background: var(--surface-3);
  border-radius: 4px;
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  border-radius: 4px;
  width: 27%;
}
.progress-label {
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  color: var(--text-3);
}
.progress-label b { color: var(--text); font-weight: 600; }

.focus-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 22px;
  align-items: start;
}

.review-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.review-head {
  padding: 22px 26px;
  display: flex; align-items: center; gap: 14px;
  border-bottom: 1px solid var(--border-soft);
}
.review-author {
  flex: 1;
}
.review-author .name {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 18px;
  color: var(--text);
  letter-spacing: -0.01em;
  display: flex; align-items: center; gap: 10px;
}
.review-author .meta {
  color: var(--text-3);
  font-size: 13px;
  margin-top: 2px;
  display: flex; align-items: center; gap: 8px;
}
.review-author .meta a { color: var(--accent); font-weight: 500; }
.skip-actions { display: flex; gap: 6px; }
.skip-actions .btn {
  padding: 8px 14px;
  font-size: 13px;
}

.post-wrap { padding: 24px 26px; }
.post-label {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--text-3);
  text-transform: uppercase;
  margin-bottom: 10px;
  display: flex; align-items: center; gap: 8px;
}
.post-label .line { flex: 1; height: 1px; background: var(--border-soft); }
.post-bubble {
  background: linear-gradient(180deg, var(--accent-softer) 0%, #faf8ff 100%);
  border: 1px solid var(--accent-soft);
  border-radius: 14px;
  padding: 22px 24px;
  color: var(--text);
  font-size: 14.5px;
  line-height: 1.62;
  position: relative;
}
.post-bubble p { margin: 0 0 14px; }
.post-bubble p:last-child { margin-bottom: 0; }
.post-bubble .hashtags { color: var(--accent); font-weight: 500; }
.post-bubble .post-link {
  color: var(--accent);
  font-weight: 500;
  word-break: break-all;
}
.post-bubble-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  font-size: 12.5px;
  color: var(--text-3);
}
.post-bubble-meta a {
  color: var(--accent);
  font-weight: 500;
  display: inline-flex; align-items: center; gap: 4px;
}
.post-bubble-meta .when {
  font-family: "JetBrains Mono", monospace;
}

.reply-block {
  margin: 24px 26px 26px;
  border: 1px dashed var(--border-strong);
  border-radius: 14px;
  padding: 22px 24px;
  background: var(--surface-2);
}
.reply-block.has-draft {
  border-style: solid;
  background: var(--surface);
}
.reply-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.reply-eyebrow {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--text-3);
  text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 8px;
}
.reply-eyebrow .spark {
  width: 16px; height: 16px;
  color: var(--accent);
}
.reply-empty {
  text-align: center;
  padding: 12px 0 4px;
  color: var(--text-3);
  font-size: 14px;
}
.reply-empty .btn { margin-top: 14px; }

.reply-textarea {
  width: 100%;
  border: none;
  background: transparent;
  outline: none;
  color: var(--text);
  font-family: "Inter", sans-serif;
  font-size: 14.5px;
  line-height: 1.6;
  min-height: 100px;
  resize: vertical;
}
.reply-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--border-soft);
  padding-top: 14px;
  margin-top: 12px;
}
.reply-meta {
  font-size: 12.5px;
  color: var(--text-3);
  display: flex; align-items: center; gap: 12px;
}
.reply-meta .ai-tag {
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 10.5px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 4px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-family: "JetBrains Mono", monospace;
}
.reply-actions { display: flex; gap: 8px; }

.up-next .card-body { padding: 8px 0; }
.up-next-item {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: 11px;
  padding: 12px 22px;
  align-items: center;
  border-bottom: 1px solid var(--border-soft);
  transition: background .12s;
  cursor: pointer;
}
.up-next-item:last-child { border-bottom: none; }
.up-next-item:hover { background: var(--surface-2); }
.up-next-item .name { font-weight: 600; font-size: 13.5px; color: var(--text); }
.up-next-item .snip {
  color: var(--text-3);
  font-size: 12.5px;
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}

.tip-card {
  background: linear-gradient(135deg, #2a1f6e 0%, #1e1646 100%);
  color: #fff;
  border-radius: var(--radius-lg);
  padding: 22px;
  overflow: hidden;
  position: relative;
}
.tip-card::before {
  content: "";
  position: absolute;
  bottom: -60px; right: -60px;
  width: 180px; height: 180px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(139,109,255,0.4), transparent 65%);
}
.tip-card .tip-eyebrow {
  color: rgba(255,255,255,0.65);
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.tip-card h3 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 17px;
  margin: 0 0 6px;
  letter-spacing: -0.01em;
  position: relative;
}
.tip-card p {
  color: rgba(255,255,255,0.72);
  font-size: 13px;
  margin: 0;
  position: relative;
}

.row-list {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.row {
  display: grid;
  grid-template-columns: 48px 1fr auto;
  gap: 16px;
  padding: 20px 24px;
  border-bottom: 1px solid var(--border-soft);
  align-items: start;
  transition: background .12s;
}
.row:last-child { border-bottom: none; }
.row:hover { background: var(--surface-2); }
.row .info { min-width: 0; }
.row .name-line {
  display: flex; align-items: center; gap: 10px;
  font-weight: 600;
  font-size: 14.5px;
  color: var(--text);
}
.row .sub-line {
  color: var(--text-3);
  font-size: 12.5px;
  margin-top: 2px;
  font-family: "JetBrains Mono", monospace;
}
.row .preview {
  color: var(--text-2);
  font-size: 14px;
  line-height: 1.55;
  margin-top: 10px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.row .row-actions {
  display: flex;
  gap: 6px;
  align-items: center;
}
.row .row-actions .btn { padding: 7px 12px; font-size: 12.5px; }
.row .when {
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  color: var(--text-3);
  margin-bottom: 8px;
  text-align: right;
  white-space: nowrap;
}
.row .right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.row-error {
  margin-top: 10px;
  padding: 9px 12px;
  border-radius: 8px;
  background: var(--danger-soft);
  border-left: 3px solid var(--danger);
  color: var(--danger);
  font-size: 12.5px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.row.queued {
  grid-template-columns: 48px 1fr auto;
}
.row.queued .schedule-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  margin-top: 2px;
}

.empty {
  padding: 80px 32px;
  text-align: center;
  color: var(--text-3);
}
.empty .ico {
  width: 56px; height: 56px;
  border-radius: 16px;
  background: var(--surface-3);
  color: var(--text-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
}
.empty h3 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 18px;
  color: var(--text);
  margin: 0 0 6px;
}
.empty p { margin: 0; font-size: 14px; }

@media (max-width: 1180px) {
  .focus-wrap { grid-template-columns: 1fr; }
}

/* === Source: src/public/outreach-pipeline.html — kanban board/contacts/filters === */

.main-inner { padding-right: 36px; min-width: 0; }

.filters-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 22px;
  flex-wrap: wrap;
}
.filter-search {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 9px 14px;
  display: flex;
  align-items: center;
  gap: 9px;
  width: 320px;
  color: var(--text-3);
}
.filter-search input {
  border: none; outline: none; background: transparent;
  flex: 1; font-family: inherit; font-size: 14px; color: var(--text);
}
.chip {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-2);
  border-radius: 999px;
  padding: 7px 13px;
  font-size: 12.5px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  transition: background .12s, color .12s;
}
.chip:hover { background: var(--surface-2); color: var(--text); }
.chip.active {
  background: var(--accent);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 3px 10px -3px rgba(106,76,241,0.5);
}
.chip .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.filters-bar .spacer { flex: 1; }
.filters-bar .right { display: flex; gap: 8px; align-items: center; }

.board {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 28px;
  margin-right: 36px;
  scroll-snap-type: x proximity;
}
.col {
  /* Elastic kanban columns — basis 268px (the original fixed width), grow
     to fill any spare horizontal room evenly across all columns, shrink
     down to a 240px floor below which the .board's overflow-x kicks in.
     Prevents both dead-space-to-the-right on wide monitors and unreadable
     squish on laptops. */
  flex: 1 1 268px;
  min-width: 240px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 240px);
  min-height: 600px;
  scroll-snap-align: start;
}
.col-head {
  padding: 16px 16px 12px;
  border-bottom: 1px solid var(--border-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.col-title {
  display: flex; align-items: center; gap: 9px;
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 15px;
  color: var(--text);
  letter-spacing: -0.005em;
}
.col-swatch {
  width: 9px; height: 9px; border-radius: 3px;
}
.sw-approved { background: #f3b6a4; }
.sw-research { background: #f17d6e; }
.sw-engaging { background: #e85a8a; }
.sw-invited  { background: #b15dde; }
.sw-journey  { background: #6a4cf1; }

.col-count {
  font-family: "JetBrains Mono", monospace;
  font-size: 11.5px;
  color: var(--text-3);
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 2px 8px;
  border-radius: 999px;
}
.col-action {
  background: transparent;
  border: none;
  width: 24px; height: 24px;
  border-radius: 6px;
  color: var(--text-3);
  display: inline-flex; align-items: center; justify-content: center;
}
.col-action:hover { background: var(--surface); color: var(--text); }

.col-body {
  padding: 10px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}
.col-body::-webkit-scrollbar { width: 6px; }
.col-body::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.col-body::-webkit-scrollbar-track { background: transparent; }

.ccard {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 11px;
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 32px 1fr auto;
  gap: 10px;
  align-items: center;
  cursor: pointer; /* not grab: cards cannot be dragged (Alex, 2026-09-24) */
  transition: border-color .12s, transform .12s, box-shadow .12s;
  position: relative;
}
.ccard:hover {
  border-color: var(--border-strong);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px -6px rgba(20,15,40,0.15);
}
.ccard .info { min-width: 0; }
.ccard .name {
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 5px;
}
.ccard .when {
  font-size: 11.5px;
  color: var(--text-3);
  margin-top: 1px;
  font-family: "JetBrains Mono", monospace;
}
.ccard .when.ready {
  color: var(--good);
  font-weight: 600;
  font-family: "Inter", sans-serif;
  font-size: 11.5px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.ccard .when.ready::before {
  content: "";
  display: inline-block;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--good);
}
.ccard .indicator {
  width: 20px; height: 20px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-soft);
  color: var(--accent);
  flex: 0 0 20px;
}
.ccard .indicator.tiny { width: 16px; height: 16px; flex: 0 0 16px; border-radius: 4px; }

.ccard .name .emoji {
  font-size: 11px;
  line-height: 1;
}
.ccard .small-badge {
  font-size: 9.5px;
  font-weight: 700;
  background: var(--surface-3);
  color: var(--text-3);
  padding: 1px 5px;
  border-radius: 4px;
  letter-spacing: 0.04em;
  font-family: "JetBrains Mono", monospace;
}

.ccard .avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  flex: 0 0 32px;
  font-size: 11.5px;
  font-weight: 700;
}

.col-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 36px 18px;
  color: var(--text-3);
  border: 2px dashed var(--border);
  border-radius: 12px;
  margin: 10px;
  background: var(--surface);
}
.col-empty .ico {
  width: 38px; height: 38px;
  border-radius: 10px;
  background: var(--surface-3);
  color: var(--text-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
}
.col-empty h4 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
  margin: 0 0 4px;
}
.col-empty p { margin: 0; font-size: 12.5px; line-height: 1.5; }

.col-more {
  text-align: center;
  color: var(--text-3);
  font-size: 12px;
  padding: 14px 10px;
  border-top: 1px dashed var(--border);
  cursor: pointer;
  transition: color .12s, background .12s;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.col-more:hover {
  color: var(--accent);
  background: var(--surface);
}
.col-more b { color: var(--text); font-weight: 600; }

.stats-strip {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-bottom: 22px;
  overflow: hidden;
  height: 14px;
}
.stats-bar {
  height: 100%;
  border-radius: 4px;
  position: relative;
}
.stats-bar:first-child { border-top-left-radius: 4px; border-bottom-left-radius: 4px; }
.stats-bar:last-child { border-top-right-radius: 4px; border-bottom-right-radius: 4px; }
.stats-legend {
  display: flex;
  gap: 18px;
  margin-bottom: 18px;
  font-size: 12.5px;
  color: var(--text-2);
  flex-wrap: wrap;
}
.stats-legend .item { display: inline-flex; align-items: center; gap: 6px; }
.stats-legend b { color: var(--text); font-weight: 700; }
.stats-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 26px;
  margin-bottom: 22px;
}
.stats-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.stats-head h3 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 15px;
  margin: 0;
  letter-spacing: -0.005em;
  display: flex;
  align-items: center;
  gap: 10px;
}
.stats-head .total {
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  color: var(--text-3);
}
.stats-head .total b { color: var(--text); font-weight: 600; }

@media (max-width: 880px) {
  .board { margin-right: 20px; }
  .filter-search { width: 100%; }
}

/* ═══ Business switcher — new-design restyle ═════════════════════════
   Overrides dashboard.css :937 rules when rendered inside the new
   sidebar. Sits between .brand and the first .nav-group. Matches
   .user-card proportions (padding, radius). Hidden when the user has
   only 1 linked business (see getBusinessSwitcherHtml at ui-core.js:628).
   ──────────────────────────────────────────────────────────────────── */
aside.sidebar .business-switcher {
  position: relative;
  padding: 0;
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 12px;
  padding-bottom: 12px;
  background: transparent;
}
aside.sidebar .business-switcher .biz-current {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-radius: 9px;
  background: var(--surface-2);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .12s;
  min-height: 38px;
  border: 1px solid var(--border-soft);
}
aside.sidebar .business-switcher .biz-current:hover {
  background: var(--surface-3, var(--surface-2));
  border-color: var(--border);
}
aside.sidebar .business-switcher .biz-current i:first-child {
  color: var(--accent);
  opacity: 0.85;
  font-size: 12px;
  width: 14px;
  text-align: center;
}
aside.sidebar .business-switcher .biz-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
aside.sidebar .business-switcher .biz-arrow {
  font-size: 10px;
  color: var(--text-4);
  transition: transform .15s;
}
aside.sidebar .business-switcher .biz-dropdown.open ~ .biz-current .biz-arrow,
aside.sidebar .business-switcher .biz-current:has(+ .biz-dropdown.open) .biz-arrow {
  transform: rotate(180deg);
}
aside.sidebar .business-switcher .biz-dropdown {
  display: none;
  position: absolute;
  top: calc(100% - 8px);
  left: 0;
  right: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px -8px rgba(0,0,0,0.18);
  z-index: 100;
  overflow: hidden;
  padding: 4px;
}
aside.sidebar .business-switcher .biz-dropdown.open { display: block; }
aside.sidebar .business-switcher .biz-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text-2);
  border-radius: 7px;
  transition: background .12s;
}
aside.sidebar .business-switcher .biz-option:hover {
  background: var(--surface-2);
  color: var(--text);
}
aside.sidebar .business-switcher .biz-option.biz-active {
  color: var(--accent-deep);
  font-weight: 600;
  background: var(--accent-soft);
}
aside.sidebar .business-switcher .biz-option.biz-active i { color: var(--accent-deep); font-size: 11px; }

/* ════════════════════════════════════════════════
   COLLAPSIBLE MENUS  (driven by /app-shell.js)
   Lifted from the Replicants design prototype. The mobile off-canvas
   drawer from the prototype is intentionally NOT ported — mobile uses
   the existing #hamburgerMenu / #hamburgerOverlay system owned by
   sidebar-nav.js. These rules cover desktop only (≥ 881px).
   ════════════════════════════════════════════════ */

/* Lift the rail above the content column so its seam toggle is never covered. */
aside.sidebar { z-index: 40; }
main.community-main { position: relative; transition: grid-template-columns .46s cubic-bezier(.33,1.34,.5,1); }

/* Label cascade — primary rail labels collapse in/out with a staggered
   transition. --i is set by app-shell.js (0..n) so labels ripple. */
.nav-item .lbl {
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  /* ⚠️ THIS IS THE RULE THAT ACTUALLY CUT THE TEXT. `overflow:hidden` with a
     max-width and no `text-overflow` clips mid-word and gives no sign it has
     done so — which is how the subnav rendered "Create your commur" and looked
     like that was simply the label. The cap has to stay (the collapse
     animation transitions it to 0), so the ellipsis is the fix. */
  text-overflow: ellipsis;
  max-width: 170px;
  transition: opacity .26s ease calc(var(--i, 0) * 24ms),
              max-width .34s cubic-bezier(.33,1.1,.5,1) calc(var(--i, 0) * 24ms),
              transform .3s ease calc(var(--i, 0) * 24ms);
}
.sub-item .lbl {
  /* Same clip, same fix — see .nav-item .lbl directly above. */
  display: inline-block; white-space: nowrap; overflow: hidden; max-width: 170px;
  text-overflow: ellipsis;
  transition: opacity .26s ease calc(var(--i, 0) * 24ms),
              max-width .34s cubic-bezier(.33,1.1,.5,1) calc(var(--i, 0) * 24ms),
              transform .3s ease calc(var(--i, 0) * 24ms);
}

/* ---- Panel collapse toggles ---- */
/* Quiet rounded-SQUARE panel toggles (not bold circular chips — a circle +
   chevron read as a Back button; a muted square + panel glyph reads as a
   collapse control). No drop-shadow, no accent ring; they recede until hover. */
.nav-toggle, .subnav-toggle {
  position: absolute;
  top: 18px;
  z-index: 45;
  width: 28px; height: 28px;
  border-radius: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-4);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 2px rgba(21,23,43,.05);
  transition: transform .32s cubic-bezier(.34,1.5,.5,1),
              left .46s cubic-bezier(.33,1.34,.5,1),
              color .18s ease, border-color .18s ease, background .18s ease;
}
.nav-toggle { right: -15px; }
/* The subnav toggle straddles the subnav/content seam. It used to be
   position:absolute inside the scrolling content column, so it rode away on
   scroll (Alex, 2026-06-12). Now viewport-FIXED; app-shell.js computes `left`
   from the live seam position (rail/subnav widths change with collapse). The
   static values below are first-paint fallbacks for the default state. */
.subnav-toggle { position: fixed; left: 434px; } /* first-paint fallback: tucked inside the subnav's right edge; app-shell.js recomputes from the live seam */
/* Collapsed the panel is still a 64px rail, so its seam is the rail edge PLUS
   that track. The old fallback here was 233px — the primary toggle's own spot
   — which stacked the two controls and trapped the menu closed. */
.subnav-collapsed .subnav-toggle { left: 297px; }

/* No subnav on this page → nothing for this control to collapse, and at the
   rail's edge it lands on top of the primary toggle and eats its clicks.
   app-shell.js also hides it once it measures; this rule stops it appearing
   for the frame before that runs. Same reasoning as the setup-page rule below,
   generalised to every page without a secondary panel. */
main.community-main.subnav-hidden .subnav-toggle { display: none; }

/* 🚨 REMOVED 2026-08-25 — the premise expired.
   This read:
     main.community-main:has(#page-setup.active) .subnav-toggle{display:none}
   with the reason "Onboarding (setup) has no working secondary panel, so its
   collapse arrow does nothing" (Alex, 2026-06-04). That was true then.

   It is not true now. The setup page keeps its secondary panel and lands with
   it COLLAPSED to the 64px rail, so the arrow is the only way back to the
   panel — and this rule was deleting the way back. Alex, 2026-08-25:
   *"you've removed the collapse button for the submenu. Why is that gone?...
   Can you put that back please?"*

   Kept as a note rather than deleted silently, because the next person to see
   a collapse arrow on the wizard will reasonably wonder whether it belongs
   there. It does: collapsed-but-reopenable is the whole point.
   `main.community-main.subnav-hidden .subnav-toggle` above still hides it on
   pages that genuinely have no secondary panel, which is the case this rule
   was really reaching for. */

.nav-toggle:hover, .subnav-toggle:hover {
  color: var(--accent-deep);
  border-color: #e2dbff;
  background: var(--accent-soft);
}
.nav-toggle:active, .subnav-toggle:active { transform: scale(.9); }
.nav-toggle svg, .subnav-toggle svg { transition: transform .44s cubic-bezier(.34,1.5,.5,1); }
.nav-collapsed .nav-toggle svg,
.subnav-collapsed .subnav-toggle svg { transform: rotate(180deg); }
/* the "R" mark winks on every primary toggle */
.brand-mark.pinged { animation: navMarkWink .58s cubic-bezier(.34,1.56,.5,1); }
@keyframes navMarkWink {
  0%   { transform: scale(1)    rotate(0); }
  35%  { transform: scale(1.18) rotate(-9deg); }
  62%  { transform: scale(.93)  rotate(6deg); }
  100% { transform: scale(1)    rotate(0); }
}

/* ════════ PRIMARY rail — collapsed (desktop only) ════════ */
@media (min-width: 881px) {
  .nav-collapsed aside.sidebar { padding-left: 13px; padding-right: 13px; }
  .nav-collapsed .brand { gap: 0; justify-content: center; padding-left: 0; padding-right: 0; }
  .nav-collapsed .brand-name { opacity: 0; max-width: 0; transform: translateX(-6px); overflow: hidden; }
  .nav-collapsed .nav-group, .nav-collapsed .sidebar-foot { align-items: stretch; }
  .nav-collapsed .nav-item {
    position: relative; justify-content: center; gap: 0; padding: 0;
    width: 48px; height: 44px; margin: 1px auto; border-radius: 13px;
  }
  .nav-collapsed .nav-item .lbl { opacity: 0; max-width: 0; transform: translateX(-8px); }
  .nav-collapsed .nav-item .nav-free-tag { display: none; }
  .nav-collapsed .nav-item .pill {
    position: absolute; top: 6px; right: 9px; margin: 0; padding: 0;
    width: 7px; height: 7px; min-width: 0; font-size: 0;
    border-radius: 50%; border: 1.5px solid var(--surface);
  }
  .nav-collapsed .nav-label { font-size: 0; padding: 12px 0 6px; height: 0; overflow: visible; position: relative; }
  .nav-collapsed .nav-label::before { content: ""; display: block; width: 22px; height: 1px; margin: 0 auto; background: var(--border-strong); }
  /* ⭐ THE PROFILE, WHEN THE RAIL IS COLLAPSED.
     Alex, 2026-09-02: *"When the menus collapse, you can't get at your profile
     names… maybe a little circle with your initials should be there. You can
     just click on that and that will get your profile options up."*

     The avatar was already the only visible part of the card, so the circle
     existed — what did not work was the MENU. `.profile-menu` is
     `left:0; right:0; min-width:220px` (app-styles-v2.css:246), which is fine
     against a 260px card and impossible against a 50px one: it was pinned to
     the rail's width and pushed out of a 76px column. So when collapsed it
     flies out to the RIGHT of the rail instead, the same direction and the same
     offset as the collapsed nav tooltips, which is where the eye already is. */
  .nav-collapsed .user-card {
    justify-content: center; padding: 8px 0; gap: 0;
    width: 48px; height: 48px; margin: 0 auto; border-radius: 50%;
  }
  .nav-collapsed .user-card:hover { background: var(--surface-2); }
  /* Fold the name/plan column away. ⚠️ `:not(.profile-menu)` is load-bearing,
     not tidiness: `> div:not(.user-avatar)` is specificity (0,3,1) — the `div`
     type selector — so it BEATS a `.nav-collapsed .user-card .profile-menu`
     override at (0,3,0) no matter how far down the file that override sits.
     Written without it, the flyout below was pinned at opacity:0 and the
     circle opened onto nothing. Exclude the menu here rather than trying to
     out-specify this rule later. */
  .nav-collapsed .user-card > div:not(.user-avatar):not(.profile-menu) {
    opacity: 0; max-width: 0; overflow: hidden; white-space: nowrap;
    transition: opacity .2s ease, max-width .3s ease;
  }
  .nav-collapsed .user-card > div.profile-menu {
    opacity: 1; max-width: none;
    left: calc(100% + 14px); right: auto; bottom: 0; width: 240px;
  }
  /* The rail must not clip the menu it now hangs outside of. */
  .nav-collapsed aside.sidebar,
  .nav-collapsed .sidebar-foot { overflow: visible; }
  /* Business switcher is text-heavy and 76px is too narrow for it to read
     gracefully — fold it away when collapsed. The switcher is only present
     when the user has > 1 linked business (see ui-core.js:628). */
  .nav-collapsed aside.sidebar .business-switcher {
    display: none;
  }
  /* tooltips on collapsed nav items */
  .nav-collapsed .nav-item::after {
    content: attr(data-tip);
    position: absolute; left: calc(100% + 16px); top: 50%;
    transform: translateY(-50%) translateX(-6px) scale(.96);
    background: #15172b; color: #fff; padding: 6px 11px; border-radius: 8px;
    font-size: 12.5px; font-weight: 500; letter-spacing: .01em; white-space: nowrap;
    opacity: 0; pointer-events: none; box-shadow: 0 8px 24px -6px rgba(21,23,43,.4);
    transition: opacity .15s ease, transform .17s cubic-bezier(.34,1.4,.5,1); z-index: 60;
  }
  .nav-collapsed .nav-item:hover::after { opacity: 1; transform: translateY(-50%) translateX(0) scale(1); }
}

/* ════════ SECONDARY subnav — collapsed (only where the subnav exists) ════════ */
@media (max-width: 1080px) {
  .subnav-toggle { display: none; }
}
@media (min-width: 1081px) {
  .community-main.subnav-collapsed { grid-template-columns: 64px minmax(0, 1fr); }
  .subnav-collapsed .subnav { overflow: visible; padding-left: 10px; padding-right: 10px; }
  .subnav-collapsed .sub-eyebrow { font-size: 0; padding: 12px 0 6px; height: 0; overflow: visible; position: relative; }
  .subnav-collapsed .sub-eyebrow:first-child { padding-top: 0; }
  .subnav-collapsed .sub-eyebrow::before { content: ""; display: block; width: 20px; height: 1px; margin: 0 auto; background: var(--border-strong); }
  .subnav-collapsed .sub-item {
    position: relative; justify-content: center; gap: 0; padding: 0;
    width: 44px; height: 40px; margin: 1px auto; border-radius: 11px;
  }
  .subnav-collapsed .sub-item .lbl { opacity: 0; max-width: 0; transform: translateX(-8px); }
  .subnav-collapsed .sub-item .right-tag {
    position: absolute; top: 5px; right: 7px; margin: 0; padding: 0;
    width: 6px; height: 6px; min-width: 0; font-size: 0;
    background: var(--accent); border-radius: 50%; border: 1.5px solid var(--surface-2);
  }
  .subnav-collapsed .sub-item::after {
    content: attr(data-tip);
    position: absolute; left: calc(100% + 14px); top: 50%;
    transform: translateY(-50%) translateX(-6px) scale(.96);
    background: #15172b; color: #fff; padding: 6px 11px; border-radius: 8px;
    font-size: 12.5px; font-weight: 500; letter-spacing: .01em; white-space: nowrap;
    opacity: 0; pointer-events: none; box-shadow: 0 8px 24px -6px rgba(21,23,43,.4);
    transition: opacity .15s ease, transform .17s cubic-bezier(.34,1.4,.5,1); z-index: 60;
  }
  .subnav-collapsed .sub-item:hover::after { opacity: 1; transform: translateY(-50%) translateX(0) scale(1); }
}

/* Hide the seam toggles on the mobile breakpoint — sidebar is hidden
   entirely under 880px (see existing @media block above), and the
   #hamburgerMenu drawer is used instead. */
@media (max-width: 880px) {
  .nav-toggle, .subnav-toggle { display: none; }
}

/* ── #page-community member-view mobile fixes (Coder B) ───────────────────────
   Scoped to #page-community so the shared .post-row/.member-row/.chip-filter
   styles are untouched elsewhere. The feed/members rows use a `44px 1fr auto`
   grid; a bare 1fr is minmax(min-content,1fr), so a long post title / member
   name kept the content column from shrinking — it grew to ~782px and was
   clipped by .panel{overflow-x:hidden} at every width. minmax(0,1fr) + content
   wrap fixes it (same pattern as .mi-card/.group-card). */
#page-community .post-row,
#page-community .member-row { grid-template-columns: 44px minmax(0, 1fr) auto; }
#page-community .post-title,
#page-community .post-excerpt,
#page-community .member-row .name { overflow-wrap: anywhere; min-width: 0; }
#page-community .member-actions { flex-wrap: wrap; justify-content: flex-end; }
/* Round 2 (c1): the actions column is `auto`, so a pinned card's six buttons
   sized it to one long line and Delete ran outside the card at 1440. The
   text column may shrink to nothing but no further, and the buttons wrap
   inside a bounded column instead. */
#page-community .post-row { grid-template-columns: 44px minmax(0, 1fr) auto; }
#page-community .post-row .post-actions { max-width: 340px; justify-content: flex-end; }
/* Very narrow: drop the actions to their own full-width row so they can never
   push the row past the viewport. */
@media (max-width: 480px) {
  #page-community .post-row,
  #page-community .member-row { grid-template-columns: 44px minmax(0, 1fr); }
  #page-community .post-actions,
  #page-community .member-actions { grid-column: 1 / -1; justify-content: flex-start; }
}
/* Touch tap targets ≥44px on the feed/members route (chips + buttons). */
@media (pointer: coarse) {
  #page-community button,
  #page-community [role="button"],
  #page-community .chip-filter { min-height: 44px; min-width: 44px; }
}

/* Compact link card + media indicator on the coach Feed panel (P3-2). */
.post-linkcard-compact {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 6px 0 8px; padding: 6px 10px; max-width: 100%;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text); text-decoration: none;
  font-size: 12.5px;
}
.post-linkcard-compact:hover { border-color: var(--border-strong); }
.post-linkcard-compact img {
  width: 32px; height: 32px; object-fit: cover; border-radius: 6px; flex: 0 0 32px;
}
.post-linkcard-compact .plc-c-title {
  font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.post-linkcard-compact .plc-c-site { color: var(--text-3); flex: 0 0 auto; }
.post-media-indicator { margin: 4px 0 6px; font-size: 12px; color: var(--text-3); }

/* P1 tidy (Tester obs 1): Settings → Media inline styles → classes.
   The design system bans inline styles on .page-head children. */
.sm-file-input { display: none; }
.sm-images-search { width: 200px; }
.sm-images-sort { width: auto; }
.sm-progress { margin-bottom: 14px; }

/* P5/F4 ride-along tidy (Tester P4 observation) — the coach live-preview
   video. The design system bans inline styles on panel children. */
.live-preview { width: 100%; max-width: 640px; aspect-ratio: 16/9; background: #000; border-radius: 12px; display: block; }

/* The Community dashboard's "platform update waiting" bar. `display` is HERE and
   not inline on the element, because an inline `display:flex` outranks the
   `hidden` attribute (UA `[hidden]{display:none}`) and the bar could never be
   hidden — measured on Alex's screen 2026-09-05 23:38, "Publishing…" for ever
   after a republish that had in fact succeeded. The second rule keeps `hidden`
   meaning hidden. tests/community-shell-republish-bar.test.js renders both. */
[data-shell-republish] { display: flex; }
[data-shell-republish][hidden] { display: none; }

/* ══════════════════════════════════════════════════════════════════════
   THE MENU TIP — the builders OFFER the extra room, they never take it

   Alex, 2026-08-03: "just collapsing without them knowing what's going on
   might be a little bit kind of frightening… it should say 'Would you like us
   to increase your workspace by collapsing the menus?' It has a little arrow…
   It's basically more of a tooltip than an automatic thing."

   So this is a pointer at the control, not a layout change. Positioned in JS
   (fixed, beside the rail's own toggle) because the toggle moves with the
   rail; everything visual is here. Desktop only — the JS gate is 1024px and
   the rail is off-canvas below that, so there is nothing to point at.
   ══════════════════════════════════════════════════════════════════════ */
.rep-nav-tip {
  position: fixed;
  z-index: 1200;            /* above the rail, below modals */
  /* ⚠️ WRAPS SINCE 2026-08-04. It was a single row of [text][button][✕], which
     worked while the second button was a 24px glyph. Alex asked for two named
     buttons — "Don't show me this again" / "Just close it" — and three real
     labels do not fit beside a sentence at any sane width. The text takes its
     own line and the buttons sit under it. */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  max-width: 340px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .16);
  font-size: 13px;
  line-height: 1.45;
  animation: repNavTipIn .18s ease-out both;
}
@keyframes repNavTipIn {
  from { opacity: 0; transform: translateX(-6px); }
  to   { opacity: 1; transform: none; }
}
/* The arrow points back at the toggle the sentence is talking about. Drawn as
   a rotated square straddling the left edge so it inherits the border and the
   surface, and stays right whatever the panel's height turns out to be. */
.rep-nav-tip-arrow {
  position: absolute;
  left: -6px;
  top: 50%;
  width: 11px;
  height: 11px;
  margin-top: -5.5px;
  background: var(--surface);
  border-left: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  transform: rotate(45deg);
}
/* Hung BELOW the toggle (round 5), so the arrow sits on the top edge and
   points up at it. `--tip-arrow-x` is set by place() in app-shell.js. */
.rep-nav-tip.below { max-width: 300px; animation-name: repNavTipDown; }
.rep-nav-tip.below .rep-nav-tip-arrow {
  left: var(--tip-arrow-x, 20px);
  top: -6px;
  margin-top: 0;
  border-left: 1px solid var(--border);
  border-bottom: 0;
  border-top: 1px solid var(--border);
}
@keyframes repNavTipDown {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
.rep-nav-tip-text { flex: 1 1 100%; min-width: 0; }
.rep-nav-tip-go {
  flex: 0 0 auto;
  padding: 6px 10px;
  border: 0;
  border-radius: 8px;
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-weight: 600;
  font-size: 12.5px;
  cursor: pointer;
}
.rep-nav-tip-go:hover { filter: brightness(1.06); }
/* ⚠️ QUIETER THAN THE BUTTON, ON PURPOSE. Alex, 2026-08-04: *"The 'Collapse'
   will be a button and then 'Don't show me again' will be the less obvious text
   next to it."* One does the thing and one is a decision, and the weight is what
   says which is which — so this is deliberately not a second button.

   (There were three controls for a few hours; "Just close it" went when he
   settled the count at two. Its selector is kept in this rule for one release
   in case a cached page still renders it.) */
.rep-nav-tip-x,
.rep-nav-tip-never {
  flex: 0 0 auto;
  padding: 6px 9px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-3);
  font: inherit;
  font-size: 12.5px;
  line-height: 1.2;
  cursor: pointer;
}
.rep-nav-tip-x:hover,
.rep-nav-tip-never:hover { background: var(--surface-2); color: var(--text); text-decoration: underline; }
@media (prefers-reduced-motion: reduce) {
  .rep-nav-tip { animation: none; }
}

/* ── LOCKED NAV ROW (D2, 2026-08-23) ──────────────────────────────────
   A module the tenant does not hold, shown rather than hidden.

   ⚠️ IT MUST STILL LOOK TAPPABLE. The instinct is to style it like a
   disabled control — but this is the shop window, not a dead end, and the
   whole change is that an absent row sells nothing. So it is dimmed enough
   to read as "not yours yet" and brightens on hover like any other nav item.
   `.is-soon` above is the opposite case and stays visually dead, because a
   Soon row genuinely cannot be actioned. */
.nav-item.is-locked { opacity: .62; }
.nav-item.is-locked:hover { opacity: 1; background: var(--accent-soft); color: var(--accent-deep); }
.nav-item.is-locked .nav-lock {
  margin-left: auto;
  width: 13px; height: 13px;
  flex: 0 0 auto;
  color: var(--text-4);
}
.nav-item.is-locked .nav-lock svg { width: 100%; height: 100%; display: block; }
.nav-item.is-locked:hover .nav-lock { color: var(--accent); }

.hamburger-item.is-locked { opacity: .62; }
.hamburger-item.is-locked:hover { opacity: 1; }
.hamburger-item.is-locked .right-tag {
  margin-left: auto;
  font-size: 11px; font-weight: 600;
  color: var(--accent-deep); background: var(--accent-soft);
  border-radius: 999px; padding: 2px 9px;
}

/* ── BETA (Alex, 2026-08-26) ───────────────────────────────────────────────
   *"Put funnels, ads, and social all showing on the list but marked as a beta
   not as locked."*

   ⚠️ A BETA ROW IS NOT A LOCKED ROW AND MUST NOT LOOK LIKE ONE. `.is-locked`
   means "this is yours once you pay" and wears a padlock; a padlock next to
   something we are not willing to sell yet is the wrong promise, and it is
   what sent two customers to a checkout that 503s. So: full opacity, no
   padlock, a plain word. It reads as "coming, and you can put your name down",
   which is what it is.

   Reusing `.right-tag`'s geometry rather than inventing a second pill —
   same size, same radius, same padding — so the two badges are visibly
   siblings. Only the colour differs, and it is deliberately NOT the accent:
   the accent means "actionable" everywhere else in this shell. */
/* ⚠️ `.nav-beta` / a header's `.right-tag` chip also appears WITHOUT `.is-beta`
   on ENTITLED beta rows (B1: Maya's HQ, unlocked but still beta) — there the
   chip rides in the label because the accordion-header path renders no tag
   element. The bare selectors below cover both; `.is-beta` still carries the
   row-level differences (opacity, hover) above. */
.nav-item .nav-beta,
.hamburger-item.is-beta .right-tag,
.hamburger-acc-header .right-tag {
  margin-left: auto;
  font-size: 11px; font-weight: 600; letter-spacing: .02em;
  color: var(--text-3); background: var(--surface-3);
  border-radius: 999px; padding: 2px 9px;
  flex: 0 0 auto;
}
.nav-item:hover .nav-beta,
.hamburger-item.is-beta:hover .right-tag,
.hamburger-acc-header:hover .right-tag { color: var(--text-2); }


/* ── Pipeline board: lead controls (pipeline-board.js, Alex 2026-09-24) ──
   Built to the approved prototype: job title on the tile, photo turns into a
   checkbox, a bar for the selected, a hover quick-look, "Show 20 more", and a
   folded Removed column. */
.pl-card { grid-template-columns: 32px 1fr; text-align: left; }
.pl-card:focus-visible { outline: 2px solid var(--accent, #6a4cf1); outline-offset: 2px; }
.pl-card .pl-role { font-size: 12px; color: var(--text-2, #4d5168); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
.pl-card .when { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pl-av { position: relative; display: inline-flex; align-items: center; justify-content: center; color: #fff; border: none; padding: 0; cursor: pointer; font-family: inherit; }
.pl-av .pl-box { display: none; width: 32px; height: 32px; border-radius: 50%; background: var(--surface, #fff); border: 2px solid var(--accent, #6a4cf1); color: var(--accent, #6a4cf1); align-items: center; justify-content: center; box-sizing: border-box; }
.pl-av .pl-box svg { visibility: hidden; }
.pl-card:hover .pl-av .pl-face, .pl-selmode .pl-av .pl-face, .pl-card.is-sel .pl-av .pl-face, .pl-av:focus-visible .pl-face { display: none; }
.pl-card:hover .pl-av .pl-box, .pl-selmode .pl-av .pl-box, .pl-card.is-sel .pl-av .pl-box, .pl-av:focus-visible .pl-box { display: inline-flex; }
.pl-card.is-sel { border-color: var(--accent, #6a4cf1); box-shadow: 0 0 0 1px var(--accent, #6a4cf1) inset; background: var(--accent-soft, #efeaff); }
.pl-card.is-sel .pl-av .pl-box { background: var(--accent, #6a4cf1); color: #fff; }
.pl-card.is-sel .pl-av .pl-box svg { visibility: visible; }
.pl-card.is-paused { background: var(--surface-2, #faf9f4); }
.pl-card.is-paused .name, .pl-card.is-paused .pl-role { color: var(--text-3, #8a8fa6); }
.pl-card.is-paused .pl-av:not(:hover) .pl-face { filter: grayscale(1); opacity: .55; }
.pl-tag { font-family: "Inter", sans-serif; font-size: 10.5px; font-weight: 600; padding: 1px 7px; border-radius: 999px; background: var(--surface-3, #ebe8df); color: var(--text-2, #4d5168); }
.pl-tag-pend { background: var(--accent-soft, #efeaff); color: var(--accent-deep, #4a32b8); }
.chip .pl-n { font-family: "JetBrains Mono", monospace; font-size: 11px; opacity: .8; }
.chip .pl-n:empty { display: none; }
.pl-note { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; color: var(--text-2, #4d5168); margin: -4px 0 12px; }
.pl-link { background: none; border: none; color: var(--accent-deep, #4a32b8); font-weight: 600; font-size: 12.5px; padding: 6px 2px; text-decoration: underline; cursor: pointer; font-family: inherit; }
.pl-more { width: 100%; border: 1px dashed var(--border-strong, #d9d3c2); background: var(--surface, #fff); border-radius: 10px; padding: 9px 10px; font-size: 12.5px; color: var(--accent-deep, #4a32b8); font-weight: 600; min-height: 44px; cursor: pointer; font-family: inherit; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.pl-more:hover { background: var(--accent-soft, #efeaff); }
.pl-more:disabled { opacity: .6; cursor: default; }
.pl-more .pl-more-sub { font-weight: 400; color: var(--text-3, #8a8fa6); font-size: 11.5px; }
.col-more:has(.pl-more) { padding: 8px 10px 10px; border-top: none; background: transparent; }
.pl-removed { flex: 0 0 52px; align-self: flex-start; }
.pl-removed.is-open { flex: 0 0 260px; min-width: 240px; background: var(--surface-2, #faf9f4); border-style: dashed; }
.pl-removed-fold { width: 52px; min-height: 600px; background: var(--surface-2, #faf9f4); border: 1px dashed var(--border-strong, #d9d3c2); border-radius: var(--radius-lg, 14px); display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 14px 0; color: var(--text-2, #4d5168); cursor: pointer; font-family: inherit; }
.pl-removed-fold:hover { background: var(--surface, #fff); color: var(--text, #15172b); }
.pl-vert { writing-mode: vertical-rl; transform: rotate(180deg); font-family: "Bricolage Grotesque", sans-serif; font-weight: 700; font-size: 14px; }
.pl-removed-card { grid-template-columns: 32px 1fr auto; cursor: default; }
.pl-removed-intro, .pl-removed-empty { font-size: 12px; color: var(--text-2, #4d5168); line-height: 1.45; padding: 2px 2px 6px; }
.pl-removed-empty { text-align: center; padding: 20px 6px; color: var(--text-3, #8a8fa6); }
.pl-bulkbar { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); background: #15172b; color: #fff; border-radius: 14px; padding: 8px 8px 8px 18px; display: flex; align-items: center; gap: 4px; box-shadow: 0 16px 40px -10px rgba(10,10,30,.45); z-index: 9000; font-size: 13.5px; max-width: calc(100vw - 32px); flex-wrap: wrap; }
.pl-bulkbar b { margin-right: 8px; }
.pl-bulkbar button { background: transparent; border: none; color: #fff; padding: 9px 12px; border-radius: 9px; font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; gap: 7px; min-height: 40px; cursor: pointer; font-family: inherit; }
.pl-bulkbar button:hover { background: rgba(255,255,255,.12); }
.pl-bulkbar .rm { color: #ffb4ab; }
.pl-bulkbar .sep { width: 1px; height: 22px; background: rgba(255,255,255,.2); margin: 0 4px; }
.pl-toast { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); background: #15172b; color: #fff; border-radius: 12px; padding: 10px 10px 10px 16px; display: flex; align-items: center; gap: 12px; z-index: 9001; font-size: 13.5px; max-width: calc(100vw - 32px); }
.pl-toast.above-bar { bottom: 86px; }
.pl-toast button { background: none; border: none; color: #b8a8ff; font-weight: 700; font-size: 13px; padding: 8px 10px; min-height: 36px; cursor: pointer; font-family: inherit; }
.pl-hovercard { position: absolute; width: 300px; background: var(--surface, #fff); border: 1px solid var(--border, #e8e4d8); border-radius: 14px; box-shadow: 0 18px 40px -12px rgba(20,15,40,.28); padding: 14px 16px; z-index: 8000; display: flex; flex-direction: column; gap: 3px; font-size: 12.5px; color: var(--text, #15172b); }
.pl-hc-head { display: flex; gap: 12px; align-items: center; margin-bottom: 6px; }
.pl-hc-head .avatar { width: 44px; height: 44px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; font-size: 14px; flex: 0 0 44px; }
.pl-hc-name { font-weight: 700; font-size: 14.5px; }
.pl-hc-role { color: var(--text-2, #4d5168); }
.pl-hc-k { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3, #8a8fa6); margin-top: 7px; }
.pl-hc-v { line-height: 1.4; }
.pl-hc-foot { font-size: 11.5px; color: var(--text-3, #8a8fa6); border-top: 1px solid var(--border-soft, #efece2); padding-top: 8px; margin-top: 8px; }
.pl-colmenu { position: absolute; background: var(--surface, #fff); border: 1px solid var(--border, #e8e4d8); border-radius: 10px; box-shadow: 0 10px 28px rgba(20,18,40,.14); padding: 6px; min-width: 240px; z-index: 9002; display: flex; flex-direction: column; }
.pl-colmenu button { background: none; border: none; text-align: left; padding: 9px 10px; border-radius: 7px; font-size: 13px; color: var(--text, #15172b); min-height: 38px; cursor: pointer; font-family: inherit; }
.pl-colmenu button:hover { background: var(--surface-2, #faf9f4); }
.pl-colmenu .danger { color: var(--danger, #c0423a); }
/* Tall content scrolls instead of falling off-screen. */
.pl-confirm-scrim { position: fixed; inset: 0; background: rgba(20,18,40,.35); z-index: 10050; display: flex; align-items: center; justify-content: center; padding: 16px; overflow-y: auto; }
.pl-confirm { background: var(--surface, #fff); border-radius: 16px; box-shadow: 0 30px 60px -20px rgba(10,10,30,.45); padding: 24px; width: min(460px, 100%); display: flex; flex-direction: column; gap: 10px; margin-top: auto; margin-bottom: auto; }
.pl-confirm h3 { margin: 0; font-family: "Bricolage Grotesque", sans-serif; font-size: 20px; }
.pl-confirm p { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--text-2, #4d5168); }
.pl-confirm-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
.pl-btn-danger { background: #b3372f; border-color: #b3372f; color: #fff; }
.pl-btn-danger:hover { background: #9c2f28; }
