/* =============================================================================
 * Studio — styles.css
 * -----------------------------------------------------------------------------
 * Clean SaaS dashboard styling for the LinkedIn Post Gen Scheduling Studio.
 * Reuses the LPG navy/blue brand (navy #0b3a5c, blue #0a66c2) so the Studio
 * reads as part of the same product family as the popup / results UI.
 *
 * BUILDLESS: pure CSS custom properties (tokens) + plain selectors. No build
 * step, no preprocessor. Consumed directly by studio/web/index.html.
 *
 * CLASS CONTRACT (what index.html / app.js are expected to use) — by section:
 *   Shell      .studio (grid)  .appbar  .main  .content
 *   App bar    .appbar-brand  .appnav  .nav-item[.active]  .acctmenu
 *   Buttons    .btn .btn--primary .btn--secondary .btn--ghost .btn--danger
 *              .btn--sm  (aliases: .primary .secondary .ghost kept for parity)
 *   Cards      .card  .card-head  .card-title  .card-sub  .card-body
 *   Stats      .stat-grid  .stat  .stat-value  .stat-label
 *   Inputs     .field  .field-label  input/select/textarea  .field-row  .hint
 *   Status     .pill  .pill--draft|scheduled|publishing|published|failed|manual
 *   Calendar   .calendar-wrap (+ FullCalendar .fc-* theme overrides)
 *   Modal      .modal-overlay[.open]  .modal  .modal-head  .modal-title
 *              .modal-sub  .modal-body  .modal-foot  .modal-close
 *   Toast      .toast-host  .toast  .toast--ok|err|info
 *   Utils      .hidden  .row  .col  .spacer  .muted  .mono  .spinner
 *
 * Colors come ONLY from the token block below — no hard-coded hex in
 * components, so theming/dark-mode stays a single edit point.
 * ========================================================================== */

/* ----------------------------------------------------------------------------
 * 1. Design tokens (CSS custom properties) — mirrors the LPG brand palette.
 * ------------------------------------------------------------------------- */
:root {
  /* Brand */
  --navy: #0b3a5c;        /* primary brand navy */
  --navy-deep: #082c47;   /* sidebar / darker surfaces */
  --navy-line: #16486e;   /* dividers on navy surfaces */
  --blue: #0a66c2;        /* LinkedIn action blue */
  --blue-dark: #084d92;   /* hover/active blue */
  --blue-tint: #eaf2fc;   /* light blue wash */

  /* Surfaces */
  --bg: #eef1f6;          /* app background */
  --card: #ffffff;        /* card / panel surface */
  --surface-soft: #fbfdff;/* nested panels, table rows */

  /* Ink (text) */
  --ink: #1b2733;         /* primary text */
  --ink-soft: #5b6b7b;    /* secondary text */
  --ink-faint: #5c6873;   /* tertiary / hints */   /* was #8a98a6 — 3.43:1 on a tinted surface; hints are body text, not decoration */
  --ink-invert: #eaf2fb;  /* text on dark surfaces */
  --ink-invert-soft: #9fb6cb;

  /* Lines */
  --line: #e6ebf1;
  --line-soft: #eff2f6;

  /* Status palette (post lifecycle + feedback) */
  --green: #157347;  --green-tint: #e6f5ec;  --green-line: #b6e0c5;
  --amber: #8a6d00;  --amber-tint: #fff6da;  --amber-line: #f1dd9a;
  --red:   #b42318;  --red-tint:   #fdecea;  --red-line:   #f3c4bf;
  --slate: #61707e;  --slate-tint: #eef1f4;  --slate-line: #d8dee5;

  /* Geometry */
  --radius: 14px;         /* cards / modal */
  --radius-sm: 10px;      /* inputs / small panels */
  --radius-pill: 999px;   /* buttons / pills */
  --sidebar-w: 248px;
  /* The height of the sticky bar at the top of the page. That is the APP BAR
     since 2026-09-13 — the 64px page-heading row it used to describe is gone.
     Five sticky section heads in ux-app.css / studio-v2.css offset by this,
     so it has to track the real bar or they float at the wrong height. */
  --topbar-h: 52px;

  /* Elevation */
  --shadow: 0 1px 2px rgba(16,40,70,.04), 0 6px 20px rgba(16,40,70,.06);
  --shadow-lg: 0 18px 60px rgba(8,22,38,.28);

  /* Motion */
  --t-fast: .15s ease;
  --t-med: .25s ease;

  /* Type */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, monospace;

  /* Back-compat token aliases. A number of older rules reference these names
     with a LIGHT literal fallback (e.g. var(--surface,#fff)). Because the names
     were never defined, those rules ALWAYS hit the light literal and so never
     darkened. Defining the aliases here — as references to the real theme tokens
     — makes every such rule follow [data-theme="dark"] automatically (custom
     properties resolve at use-site, so they pick up the dark --card/--line/etc.).
     This is the single-source dark-mode fix for media-gen, topic chips, the
     scroll-stop preview panel, feed-theme chips, the network cards, and more. */
  --surface: var(--card);
  --surface-2: var(--surface-soft);
  --border: var(--line);
  --accent: var(--blue);
  --color-text-tertiary: var(--ink-faint);
}

/* ----------------------------------------------------------------------------
 * 2. Reset / base
 * ------------------------------------------------------------------------- */
* { box-sizing: border-box; margin: 0; padding: 0; }

html, body { height: 100%; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { letter-spacing: -0.01em; }

::selection { background: var(--blue-tint); }

/* Scrollbars (subtle, brand-tinted) */
* { scrollbar-width: thin; scrollbar-color: #c5d2df transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: #cdd9e4; border-radius: 999px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: #b3c3d2; background-clip: content-box; }

/* ----------------------------------------------------------------------------
 * 3. Utilities
 * ------------------------------------------------------------------------- */
.hidden { display: none !important; }
.muted { color: var(--ink-faint); }
.mono { font-family: var(--mono); }
.spacer { flex: 1 1 auto; }
.row { display: flex; align-items: center; gap: 10px; }
.row.wrap { flex-wrap: wrap; }
.col { display: flex; flex-direction: column; gap: 10px; }
.hint { font-size: 12px; color: var(--ink-faint); }
.text-right { text-align: right; }

/* Generic spinner (matches LPG results spinner) */
.spinner {
  width: 15px; height: 15px; border-radius: 50%; flex: 0 0 auto;
  border: 2px solid rgba(0,0,0,.14); border-top-color: currentColor;
  animation: studio-spin .8s linear infinite;
}
@keyframes studio-spin { to { transform: rotate(360deg); } }

/* ----------------------------------------------------------------------------
 * 4. App shell — sidebar + main column
 *    Layout: CSS grid, fixed-width navy sidebar, fluid main pane.
 * ------------------------------------------------------------------------- */
.studio {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;
}

/* ---- Sidebar (navy brand rail) ---- */
.sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, var(--navy) 0%, var(--navy-deep) 100%);
  color: var(--ink-invert);
  padding: 22px 16px;
  box-shadow: 2px 0 18px rgba(11,58,92,.16);
  z-index: 20;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 4px 8px 18px;
  border-bottom: 1px solid var(--navy-line);
  margin-bottom: 16px;
}
.brand .brand-mark {
  flex: 0 0 auto;
  width: 34px; height: 34px; border-radius: 9px;
  display: grid; place-items: center;
  background: var(--blue-fill);
  color: #fff; font-weight: 800; font-size: 16px;
  box-shadow: 0 4px 12px rgba(10,102,194,.4);
}
.brand .brand-name { font-size: 15px; font-weight: 800; color: #fff; line-height: 1.1; }
.brand .brand-sub { font-size: 11px; color: var(--ink-invert-soft); margin-top: 2px; }

/* Nav list */
.nav { display: flex; flex-direction: column; gap: 4px; flex: 1 1 auto; }
.nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  color: var(--ink-invert-soft);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  border: none;
  background: transparent;
  width: 100%;
  text-align: left;
  font-family: inherit;
  transition: background var(--t-fast), color var(--t-fast);
}
.nav-item:hover { background: rgba(255,255,255,.07); color: #fff; text-decoration: none; }
.nav-item.active { background: var(--blue-fill); color: #fff; box-shadow: 0 4px 12px rgba(10,102,194,.32); }
.nav-item .nav-ico { flex: 0 0 auto; width: 18px; height: 18px; opacity: .9; }
.nav-item.active .nav-ico { opacity: 1; }
.nav-item .badge {
  margin-left: auto;
  min-width: 20px; height: 20px; padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: rgba(255,255,255,.16); color: #fff;
  font-size: 11px; font-weight: 700;
}
.nav-item.active .badge { background: rgba(255,255,255,.25); }

.sidebar-foot {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--navy-line);
  font-size: 11.5px;
  color: var(--ink-invert-soft);
}
.sidebar-foot .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #2fbf71; margin-right: 6px; vertical-align: middle; box-shadow: 0 0 0 3px rgba(47,191,113,.2); }

/* ---- Main column ---- */
.main {
  min-width: 0;            /* allow children (calendar) to shrink in grid */
  display: flex;
  flex-direction: column;
}

/* Topbar (sticky page header) */
/* .topbar is gone (2026-09-13): its only content was the page heading, which
   repeated the active app-bar tab. The heading survives as a visually-hidden
   <h1 id="view-title" class="sr-only"> so the document outline is intact. */

/* Page content region */
.content { padding: 24px 28px 40px; }
.view { display: block; }            /* one .view per nav section; toggle .hidden */

/* Section heading inside content */
.section-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.section-head h2 { font-size: 13px; font-weight: 700; color: var(--navy); text-transform: uppercase; letter-spacing: .03em; }
.section-head .spacer { flex: 1; }

/* ----------------------------------------------------------------------------
 * 5. Cards & panels
 * ------------------------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 22px 24px;
  margin-bottom: 18px;
}
.card.flush { padding: 0; overflow: hidden; }   /* for full-bleed contents (calendar/table) */

.card-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 16px;
}
.card-head .spacer { flex: 1; }
.card-title { font-size: 15px; font-weight: 800; color: var(--ink); }
.card-sub { font-size: 12.5px; color: var(--ink-faint); margin-top: 3px; }
.card-body { font-size: 14px; color: var(--ink); }

/* Soft nested panel */
.panel {
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
}

/* ---- Stat cards (dashboard KPIs) ---- */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 18px;
}
.stat {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px;
  position: relative;
  overflow: hidden;
}
.stat::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--blue);
}
.stat.stat--green::before { background: var(--green); }
.stat.stat--amber::before { background: var(--amber); }
.stat.stat--red::before { background: var(--red); }
.stat-value { font-size: 28px; font-weight: 800; color: var(--navy); line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat-label { font-size: 11.5px; font-weight: 700; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .04em; margin-top: 6px; }
.stat-delta { font-size: 11.5px; font-weight: 700; margin-top: 4px; }
.stat-delta.up { color: var(--green); }
.stat-delta.down { color: var(--red); }

/* ----------------------------------------------------------------------------
 * 6. Buttons — pill system from the LPG brand.
 *    Primary class is .btn + modifier; bare .primary/.secondary/.ghost are
 *    kept as aliases so markup matching the popup/results UI also works.
 * ------------------------------------------------------------------------- */
.btn, .primary, .secondary, .ghost {
  cursor: pointer;
  font-family: inherit;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-weight: 700;
  letter-spacing: .01em;
  transition: background var(--t-fast), border-color var(--t-fast),
              color var(--t-fast), box-shadow var(--t-fast);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
}
.btn:disabled, .primary:disabled, .secondary:disabled, .ghost:disabled,
.btn[disabled] { cursor: default; opacity: .65; box-shadow: none; }

/* Primary (filled blue) */
.btn--primary, .primary {
  padding: 11px 24px;
  font-size: 14px;
  /* --blue-fill, not --blue: the dark theme lifts --blue for link legibility,
     which drops white-on-blue to 3.42:1 on a filled button. */
  background: var(--blue-fill, #0a66c2);
  color: #fff;
  border-color: var(--blue-fill, #0a66c2);
}
.btn--primary:hover, .primary:hover {
  background: var(--blue-dark);
  border-color: var(--blue-dark);
  box-shadow: 0 4px 12px rgba(10,102,194,.28);
  text-decoration: none;
}
/* Disabled: white on #aac3dd was 1.82:1 — unreadable even though WCAG exempts
   disabled controls. Darker ink on the same tint reads at 4.60:1. */
.btn--primary:disabled, .primary:disabled {
  background: #aac3dd; border-color: #aac3dd; color: #33506e;
}

/* Secondary (outline blue on white) */
.btn--secondary, .secondary {
  padding: 10px 18px;
  font-size: 13px;
  background: #fff;
  color: var(--blue);
  border-color: #c9d6e3;
  font-weight: 600;
}
.btn--secondary:hover, .secondary:hover {
  background: var(--blue-tint);
  border-color: var(--blue);
  text-decoration: none;
}

/* Ghost (quiet) */
.btn--ghost, .ghost {
  padding: 8px 14px;
  font-size: 12.5px;
  background: #fff;
  color: var(--ink-soft);
  border-color: var(--line);
  font-weight: 600;
}
.btn--ghost:hover, .ghost:hover { border-color: var(--blue); color: var(--blue); text-decoration: none; }

/* Danger (destructive — delete schedule/account) */
.btn--danger {
  padding: 10px 18px;
  font-size: 13px;
  background: #fff;
  color: var(--red);
  border-color: var(--red-line);
}
.btn--danger:hover { background: var(--red-tint); border-color: var(--red); }
.btn--danger.solid { background: var(--red); color: #fff; border-color: var(--red); }
.btn--danger.solid:hover { background: #99231a; border-color: #99231a; }

/* Size + shape modifiers */
.btn--sm { padding: 7px 14px; font-size: 12.5px; }
.btn--lg { padding: 13px 28px; font-size: 15px; }
.btn--block { width: 100%; }
.btn--icon { padding: 9px; width: 38px; height: 38px; border-radius: 50%; }

/* State helper used during async actions (e.g. Publish) */
.btn.is-busy { pointer-events: none; }

/* ----------------------------------------------------------------------------
 * 7. Forms / inputs
 * ------------------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.field-label {
  font-size: 11px; font-weight: 700; color: var(--ink-soft);
  text-transform: uppercase; letter-spacing: .04em;
}
.field-label .req { color: var(--red); margin-left: 2px; }
.field-row { display: flex; gap: 14px; flex-wrap: wrap; }
.field-row > .field { flex: 1 1 200px; }

input[type="text"], input[type="number"], input[type="search"],
input[type="email"], input[type="url"], input[type="password"],
input[type="datetime-local"], input[type="date"], input[type="time"],
select, textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-family: inherit;
  color: var(--ink);
  background: var(--surface-soft);
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
}
textarea { line-height: 1.55; resize: vertical; min-height: 110px; }
select { cursor: pointer; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%235b6b7b' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 13px center;
  padding-right: 34px;
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(10,102,194,.12);
  background: #fff;
}
input::placeholder, textarea::placeholder { color: var(--ink-faint); }
input:disabled, select:disabled, textarea:disabled {
  background: #f0f3f6; color: var(--ink-faint); cursor: not-allowed;
}

/* Char counter / inline meta under a textarea */
.field-foot { display: flex; align-items: center; gap: 10px; margin-top: 7px; }
.field-foot .count { font-size: 12px; color: var(--ink-faint); margin-left: auto; font-variant-numeric: tabular-nums; }

/* Inline validation message */
.field-error { font-size: 12px; color: var(--red); }
/* Non-blocking exact-duplicate notice on a post card (content-management). */
.dup-warning {
  font-size: 12.5px;
  color: #92400e;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: 8px;
  padding: 7px 10px;
  margin: 8px 0 0;
}
/* Feed view (harvested posts + theme analysis) */
.feed-filter { font-size: 13px; color: var(--color-text-secondary, #475569); display: inline-flex; gap: 6px; align-items: center; margin-right: 8px; }
.feed-themes { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 16px; }
.feed-theme-chip { display: inline-flex; gap: 8px; align-items: baseline; padding: 6px 12px; border: 0.5px solid var(--border, #e2e8f0); border-radius: 999px; background: var(--surface, #fff); font-size: 12.5px; }
.feed-theme-name { font-weight: 600; }
.feed-theme-count { font-weight: 700; color: var(--accent, #2563eb); }
.feed-theme-meta { color: var(--color-text-tertiary, #94a3b8); font-size: 11.5px; }
/* Media generation panel (Scheduled view) */
.media-gen { margin: 6px 0 16px; border: 0.5px solid var(--border, #e2e8f0); border-radius: 10px; background: var(--surface, #fff); }
.media-gen > summary { cursor: pointer; padding: 10px 14px; font-weight: 600; font-size: 13px; list-style: none; }
.media-gen > summary::-webkit-details-marker { display: none; }
.media-gen-body { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 0 14px 14px; }
.media-gen-body input[type="text"] { flex: 1; min-width: 220px; padding: 7px 10px; border: 0.5px solid var(--border, #e2e8f0); border-radius: 8px; }
#media-gen-status { width: 100%; }
/* System health + telemetry grid */
.diag-grid { display: grid; grid-template-columns: 1fr; gap: 4px; }
.diag-item { display: flex; align-items: center; gap: 8px; font-size: 12.5px; padding: 4px 0; }
.diag-item .diag-name { font-weight: 600; min-width: 150px; font-family: ui-monospace, monospace; }
.diag-item .diag-detail { color: var(--color-text-tertiary, #94a3b8); }
.diag-dot { width: 8px; height: 8px; border-radius: 50%; background: #cbd5e1; flex: none; }
.diag-ok .diag-dot { background: #16a34a; }
.diag-bad .diag-dot { background: #dc2626; }
.diag-bad .diag-detail { color: #dc2626; }
.field.has-error input, .field.has-error select, .field.has-error textarea {
  border-color: var(--red); background: var(--red-tint);
}
.field.has-error input:focus { box-shadow: 0 0 0 3px rgba(180,35,24,.12); }

/* Checkbox / radio rows (e.g. platform pickers) */
.check {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink); cursor: pointer; user-select: none;
}
.check input { accent-color: var(--blue); margin: 0; cursor: pointer; }

/* Pill multi-select chips (platforms / hashtags) */
.chip-set { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: #fff; color: var(--ink-soft);
  font-size: 12.5px; font-weight: 600; cursor: pointer; user-select: none;
  transition: all var(--t-fast);
}
.chip input { accent-color: var(--blue); margin: 0; }
.chip:hover { border-color: #c4d2df; }
.chip.selected, .chip:has(input:checked) {
  background: var(--blue-tint); border-color: var(--blue); color: var(--blue);
}
.chip .chip-x { color: var(--ink-faint); font-weight: 700; cursor: pointer; }
.chip .chip-x:hover { color: var(--red); }

/* ----------------------------------------------------------------------------
 * 8. Status pills — post lifecycle (matches DB status[] values) + feedback.
 *    Classes: .pill--draft .pill--scheduled .pill--publishing
 *             .pill--published .pill--failed .pill--manual
 * ------------------------------------------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: var(--radius-pill);
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
  border: 1px solid transparent; line-height: 1.4; white-space: nowrap;
}
.pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }

.pill--draft      { background: var(--slate-tint); color: var(--slate); border-color: var(--slate-line); }
.pill--scheduled  { background: var(--blue-tint);  color: var(--blue);  border-color: #bcd7f3; }
.pill--publishing { background: var(--amber-tint); color: var(--amber); border-color: var(--amber-line); }
.pill--published  { background: var(--green-tint); color: var(--green); border-color: var(--green-line); }
.pill--failed     { background: var(--red-tint);   color: var(--red);   border-color: var(--red-line); }
.pill--manual     { background: var(--blue-tint);  color: var(--navy);  border-color: #bcd7f3; }

/* Animated dot while publishing */
.pill--publishing::before { animation: studio-pulse 1.1s ease-in-out infinite; }
@keyframes studio-pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }

/* ----------------------------------------------------------------------------
 * 9. Tables (schedules list / publish log)
 * ------------------------------------------------------------------------- */
.table-wrap { width: 100%; overflow-x: auto; }
table.tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.tbl th {
  text-align: left; font-size: 11px; font-weight: 700; color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: .03em;
  padding: 12px 16px; border-bottom: 1px solid var(--line); background: var(--surface-soft);
  white-space: nowrap;
}
table.tbl td { padding: 13px 16px; border-bottom: 1px solid var(--line-soft); color: var(--ink); vertical-align: middle; }
table.tbl tbody tr { transition: background var(--t-fast); }
table.tbl tbody tr:hover { background: var(--blue-tint); }
table.tbl tbody tr:last-child td { border-bottom: none; }
table.tbl td.col-actions { text-align: right; white-space: nowrap; }
table.tbl td.mono { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); }
.tbl-title { font-weight: 700; color: var(--ink); }
.tbl-meta { font-size: 11.5px; color: var(--ink-faint); margin-top: 2px; }

/* Empty state */
.empty {
  text-align: center; padding: 48px 24px; color: var(--ink-faint);
}
.empty .empty-ico { font-size: 34px; opacity: .5; margin-bottom: 10px; }
.empty .empty-title { font-size: 15px; font-weight: 700; color: var(--ink-soft); margin-bottom: 6px; }
.empty .empty-sub { font-size: 13px; max-width: 360px; margin: 0 auto 16px; }

/* ----------------------------------------------------------------------------
 * 10. Calendar — FullCalendar (CDN) theme overrides, brand-matched.
 *     Wrap the calendar mount in .calendar-wrap.
 * ------------------------------------------------------------------------- */
.calendar-wrap { padding: 8px 4px 4px; }
.calendar-wrap .fc {
  --fc-border-color: var(--line);
  --fc-page-bg-color: var(--card);
  --fc-neutral-bg-color: var(--surface-soft);
  --fc-today-bg-color: var(--blue-tint);
  --fc-event-bg-color: var(--blue);
  --fc-event-border-color: var(--blue);
  --fc-event-text-color: #fff;
  --fc-now-indicator-color: var(--red);
  font-family: var(--font);
  font-size: 13px;
}

/* Toolbar */
.calendar-wrap .fc .fc-toolbar-title { font-size: 18px; font-weight: 800; color: var(--navy); }
.calendar-wrap .fc .fc-toolbar.fc-header-toolbar { margin-bottom: 16px; }
.calendar-wrap .fc .fc-button-primary {
  background: #fff; border: 1px solid #c9d6e3; color: var(--blue);
  font-weight: 600; font-size: 13px; text-transform: capitalize;
  border-radius: var(--radius-pill); padding: 8px 16px; box-shadow: none;
  transition: all var(--t-fast);
}
.calendar-wrap .fc .fc-button-primary:hover { background: var(--blue-tint); border-color: var(--blue); color: var(--blue); }
.calendar-wrap .fc .fc-button-primary:not(:disabled).fc-button-active,
.calendar-wrap .fc .fc-button-primary:not(:disabled):active {
  background: var(--blue-fill); border-color: var(--blue-fill); color: #fff; box-shadow: 0 4px 12px rgba(10,102,194,.22);
}
.calendar-wrap .fc .fc-button-primary:disabled { background: #f0f3f6; border-color: var(--line); color: var(--ink-faint); }
.calendar-wrap .fc .fc-button:focus { outline: none; box-shadow: 0 0 0 3px rgba(10,102,194,.18); }
.calendar-wrap .fc .fc-button .fc-icon { font-size: 15px; }

/* Grid */
.calendar-wrap .fc .fc-col-header-cell-cushion {
  color: var(--ink-faint); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; padding: 10px 4px;
}
.calendar-wrap .fc .fc-daygrid-day-number { color: var(--ink-soft); font-size: 12.5px; font-weight: 600; padding: 6px 8px; }
.calendar-wrap .fc .fc-day-today .fc-daygrid-day-number { color: var(--blue); font-weight: 800; }
.calendar-wrap .fc .fc-day-other .fc-daygrid-day-number { color: var(--ink-faint); opacity: .6; }
.calendar-wrap .fc .fc-scrollgrid { border-radius: var(--radius-sm); overflow: hidden; }

/* Events — colour by post status via FullCalendar classNames.
   app.js should set event.classNames = ['ev--<status>'] */
.calendar-wrap .fc .fc-event {
  border-radius: 7px; border: none; padding: 2px 6px;
  font-size: 11.5px; font-weight: 700; cursor: pointer;
  box-shadow: 0 1px 3px rgba(16,40,70,.16);
}
.calendar-wrap .fc .fc-event:hover { filter: brightness(.95); }
.calendar-wrap .fc .fc-event .fc-event-time { font-weight: 800; opacity: .9; }
.calendar-wrap .fc .fc-event .fc-event-title { font-weight: 600; }

/* ---- the roomy views: Day and 3 days --------------------------------------
 * Owner 2026-09-25: the week view is too congested — 19 posts on his busiest day,
 * five of them in the same minute, seven columns wide. Day and 3-day cut the
 * columns; these rules buy back the HEIGHT, which is the other half of it.
 *
 * Every hour of the clock carries posts here (22 of 24 are in use), so the grid
 * cannot be clipped to working hours. A taller hour is the honest way to make
 * room: the card grows and the page scrolls, rather than the pills shrinking.
 */
.calendar-wrap .fc .fc-timegrid-slot { height: 46px; }
.calendar-wrap .fc .fc-timegrid-slot-label-cushion { font-size: 11px; font-weight: 700; color: var(--ink-faint); }
.calendar-wrap .fc .fc-timegrid-axis-cushion { font-size: 10.5px; color: var(--ink-faint); }
/* A pill with room in it: two lines, and padding that does not eat the text. */
.calendar-wrap .fc .fc-timegrid-event { padding: 4px 8px; box-shadow: 0 1px 4px rgba(16,40,70,.2); }
.calendar-wrap .fc .fc-timegrid-event .fc-event-main-frame { gap: 1px; }
.calendar-wrap .fc .fc-timegrid-event .fc-event-time { font-size: 10.5px; }
.calendar-wrap .fc .fc-timegrid-event .fc-event-title { font-size: 12px; line-height: 1.25; }
/* The line of the post itself, in Day and 3-day only (app.js: SNIPPET_VIEWS). */
.calendar-wrap .fc .fc-ev-snip {
  font-size: 10.5px; font-weight: 500; line-height: 1.3; opacity: .82;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  word-break: break-word;
}
/* Five buttons in the view group now, plus prev/next/today — let them wrap
 * before they push the title off the row. */
.calendar-wrap .fc .fc-toolbar.fc-header-toolbar { flex-wrap: wrap; row-gap: 10px; }
.calendar-wrap .fc .fc-button-group { flex-wrap: wrap; }

.calendar-wrap .fc .ev--draft      { background: var(--slate); color: #fff; }
.calendar-wrap .fc .ev--scheduled  { background: var(--blue);  color: #fff; }
.calendar-wrap .fc .ev--publishing { background: var(--amber); color: #fff; }
.calendar-wrap .fc .ev--published  { background: var(--green); color: #fff; }
.calendar-wrap .fc .ev--failed     { background: var(--red);   color: #fff; }
.calendar-wrap .fc .ev--manual     { background: var(--navy);  color: #fff; }

/* Legend (status key under calendar) */
.cal-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; padding: 14px 8px 4px; }
/* Pushes the world clock to the far end of the filter row it now shares. */
.cal-legend-spacer { flex: 1 1 auto; min-width: 0; }
.cal-legend .leg { display: inline-flex; align-items: center; gap: 7px; font-size: 11.5px; font-weight: 600; color: var(--ink-soft); }
.cal-legend .leg .sw { width: 11px; height: 11px; border-radius: 3px; flex: 0 0 auto; }
.cal-legend .leg.draft .sw      { background: var(--slate); }
.cal-legend .leg.scheduled .sw  { background: var(--blue); }
.cal-legend .leg.publishing .sw { background: var(--amber); }
.cal-legend .leg.published .sw  { background: var(--green); }
.cal-legend .leg.failed .sw     { background: var(--red); }
.cal-legend .leg.manual .sw     { background: var(--navy); }

/* #3 — the legend is now an interactive category filter. Each chip is a button
   carrying `dot <status>` (the coloured ::before dot is defined in studio-v2.css)
   plus this pill affordance; the active chip + the "All" chip get their own look. */
.cal-legend-chip { display: inline-flex; align-items: center; gap: 7px; padding: 4px 12px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--ink-soft); font-size: 11.5px; font-weight: 700; line-height: 1.6; cursor: pointer; transition: border-color .12s, background .12s, color .12s; }
.cal-legend-chip:hover { border-color: var(--blue); color: var(--blue); }
.cal-legend-chip.is-active { background: var(--blue-tint); border-color: var(--blue); color: var(--blue); }
.cal-legend-chip.all::before { content: none; }

/* ----------------------------------------------------------------------------
 * 11. Modal — schedule editor / account add / confirm dialogs.
 *     .modal-overlay toggles .open; trap focus / scroll in app.js.
 * ------------------------------------------------------------------------- */
.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  display: none;
  align-items: flex-start; justify-content: center;
  padding: 48px 20px;
  background: rgba(8,22,38,.55);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  overflow-y: auto;
}
.modal-overlay.open { display: flex; animation: studio-fade .18s ease; }
@keyframes studio-fade { from { opacity: 0; } to { opacity: 1; } }

.modal {
  background: var(--card);
  width: 100%; max-width: 620px;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: studio-rise .2s ease;
}
.modal.modal--sm { max-width: 460px; }
.modal.modal--lg { max-width: 820px; }
@keyframes studio-rise { from { transform: translateY(12px); opacity: .6; } to { transform: translateY(0); opacity: 1; } }

.modal-head {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 20px 24px;
  border-bottom: 1px solid var(--line);
}
.modal-head .spacer { flex: 1; }
.modal-title { font-size: 17px; font-weight: 800; color: var(--navy); }
.modal-sub { font-size: 12.5px; color: var(--ink-faint); margin-top: 4px; }
.modal-close {
  flex: 0 0 auto;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--line); background: #fff; color: var(--ink-soft);
  font-size: 16px; line-height: 1; cursor: pointer;
  display: grid; place-items: center; transition: all var(--t-fast);
}
.modal-close:hover { background: var(--red-tint); border-color: var(--red-line); color: var(--red); }

.modal-body { padding: 22px 24px; max-height: 64vh; overflow-y: auto; }
.modal-foot {
  display: flex; align-items: center; gap: 10px; justify-content: flex-end;
  padding: 16px 24px; border-top: 1px solid var(--line); background: var(--surface-soft);
}
.modal-foot .spacer { flex: 1; }

/* ----------------------------------------------------------------------------
 * 12. Banners / inline alerts (form-level feedback)
 * ------------------------------------------------------------------------- */
.banner {
  border-radius: 12px; padding: 13px 16px; font-size: 13px;
  margin-bottom: 16px; white-space: pre-wrap;
  display: flex; align-items: flex-start; gap: 10px;
  border: 1px solid;
}
.banner.info  { background: var(--blue-tint);  border-color: #bcd7f3;        color: var(--navy); }
.banner.ok    { background: var(--green-tint); border-color: var(--green-line); color: var(--green); }
.banner.warn  { background: var(--amber-tint); border-color: var(--amber-line); color: var(--amber); }
.banner.error { background: var(--red-tint);   border-color: var(--red-line);   color: var(--red); }
.banner a { color: inherit; font-weight: 800; text-decoration: underline; }

/* ----------------------------------------------------------------------------
 * 13. Toasts (transient feedback, top-right stack)
 * ------------------------------------------------------------------------- */
.toast-host {
  position: fixed; top: 18px; right: 18px; z-index: 1100;
  display: flex; flex-direction: column; gap: 10px; max-width: 360px;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: 10px;
  background: var(--card); border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: var(--radius-sm); box-shadow: var(--shadow);
  padding: 12px 14px; font-size: 13px; color: var(--ink);
  animation: studio-toast-in .22s ease;
}
@keyframes studio-toast-in { from { transform: translateX(16px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
.toast--ok   { border-left-color: var(--green); }
.toast--err  { border-left-color: var(--red); }
.toast--info { border-left-color: var(--blue); }
.toast .toast-title { font-weight: 700; }
.toast .toast-msg { color: var(--ink-soft); margin-top: 2px; }

/* ----------------------------------------------------------------------------
 * 14. Media / attachment thumbnails (post media_assets preview)
 * ------------------------------------------------------------------------- */
.media-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.media-thumb {
  position: relative;
  width: 96px; height: 96px; border-radius: var(--radius-sm);
  overflow: hidden; border: 1px solid var(--line); background: var(--surface-soft);
}
.media-thumb img, .media-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.media-thumb .kind {
  position: absolute; left: 6px; bottom: 6px;
  font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
  background: rgba(11,58,92,.82); color: #fff; padding: 2px 6px; border-radius: 999px;
}
.media-thumb .rm {
  position: absolute; right: 5px; top: 5px;
  width: 20px; height: 20px; border-radius: 50%; border: none;
  background: rgba(180,35,24,.92); color: #fff; font-size: 12px; line-height: 1;
  cursor: pointer; display: grid; place-items: center;
}

/* Dropzone */
.dropzone {
  border: 2px dashed #c4d2df; border-radius: var(--radius-sm);
  padding: 24px; text-align: center; color: var(--ink-faint);
  font-size: 13px; cursor: pointer; transition: all var(--t-fast);
  background: var(--surface-soft);
}
.dropzone:hover, .dropzone.drag { border-color: var(--blue); background: var(--blue-tint); color: var(--blue); }

/* ----------------------------------------------------------------------------
 * 15. Accounts list (connected platforms)
 * ------------------------------------------------------------------------- */
.account {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--card); margin-bottom: 10px;
}
.account .acct-avatar {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 10px;
  display: grid; place-items: center; background: var(--navy); color: #fff;
  font-weight: 800; font-size: 15px;
}
.account .acct-name { font-size: 14px; font-weight: 700; color: var(--ink); }
.account .acct-meta { font-size: 12px; color: var(--ink-faint); margin-top: 2px; }
.account .spacer { flex: 1; }

/* ----------------------------------------------------------------------------
 * 15b. Settings view (token connection + user preferences)
 * ------------------------------------------------------------------------- */
.settings-card { max-width: 720px; }            /* keep forms readable on wide screens */
.settings-card .card-head { align-items: center; }
.settings-actions { margin-top: 6px; }

/* Token input + show/hide button on one line */
.token-row { display: flex; align-items: stretch; gap: 8px; }
.token-row input { flex: 1 1 auto; min-width: 0; }
.token-row .btn { flex: 0 0 auto; align-self: stretch; }

/* The sidebar connection pill doubles as a "go to settings" control */
#connection-status { transition: opacity var(--t-fast); }
#connection-status:hover { opacity: .85; }
#connection-status:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* ----------------------------------------------------------------------------
 * 15c. World-clock bar (Calendar + Scheduled) + Edit-form countdown
 * ------------------------------------------------------------------------- */
/* The world clock is a compact dropdown, not a bar. It used to be a full-width
   card ~66px tall (with margin) for a line of times; it is now a ~30px trigger
   that opens a popover, so the calendar starts that much higher up the page. */
.tz-bar {
  position: relative;
  display: inline-flex; align-items: center;
  margin: 0 0 10px;
}
.tz-trigger {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px; border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: var(--card); color: var(--ink-soft);
  font: inherit; font-size: 12.5px; cursor: pointer;
  box-shadow: var(--shadow);
}
.tz-trigger:hover { background: var(--surface-soft); color: var(--ink); }
.tz-trigger-ico { font-size: 13px; line-height: 1; opacity: .75; }
.tz-trigger-time { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.tz-trigger-caret { font-size: 10px; opacity: .6; }
.tz-pop {
  position: absolute; left: 0; top: calc(100% + 6px); z-index: 40;
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  min-width: max-content; max-width: min(92vw, 720px);
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-sm); box-shadow: 0 10px 30px rgba(15,23,42,.16);
  padding: 10px 14px;
}
.tz-pop.hidden { display: none !important; }
.tz-bar-title {
  font-size: 11px; font-weight: 700; color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: .04em;
}
.tz-zones { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.tz-chip {
  display: inline-flex; align-items: baseline; gap: 7px;
  padding: 5px 11px; border-radius: var(--radius-pill);
  background: var(--surface-soft); border: 1px solid var(--line);
}
.tz-chip--local { background: var(--blue-tint); border-color: #bcd7f3; }
.tz-chip-label { font-size: 11.5px; font-weight: 700; color: var(--ink-soft); }
.tz-chip--local .tz-chip-label { color: var(--blue); }
.tz-chip-time { font-size: 12.5px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }

/* Countdown banner inside the Edit-post modal */
.countdown-banner {
  border-radius: 10px; padding: 9px 13px; font-size: 12.5px; font-weight: 700;
  margin-bottom: 14px; background: var(--blue-tint); color: var(--navy);
  border: 1px solid #bcd7f3;
}
.countdown-banner.overdue { background: var(--amber-tint); color: var(--amber); border-color: var(--amber-line); }

/* ----------------------------------------------------------------------------
 * 16. Responsive
 * ------------------------------------------------------------------------- */
/* The sidebar rail became a top app bar on 2026-09-13; the rules that shrank it
   to icons and the ones that restored labels inside the mobile drawer are gone.
   They outranked the app bar's own responsive rules (`.nav-item span.nav-label`
   beats `.appnav .nav-label`) and forced the labels back on at phone widths. */
@media (max-width: 1024px) {
  .stat-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}

@media (max-width: 760px) {
  .studio { grid-template-columns: 1fr; }

  .content { padding: 18px 16px 32px; }
  .card { padding: 18px 16px; }
  .field-row { gap: 0; }
  .field-row > .field { flex: 1 1 100%; }
  .modal-overlay { padding: 16px; align-items: stretch; }
  .modal { max-width: 100%; }
  .modal-body { max-height: none; }
  .calendar-wrap .fc .fc-toolbar.fc-header-toolbar { flex-direction: column; gap: 10px; align-items: stretch; }
  /* Month / Week / 3 days / Day / List has to fit a phone, so the pills shrink
     rather than the row scrolling sideways. */
  .calendar-wrap .fc .fc-button-primary { padding: 7px 11px; font-size: 12px; }
  .calendar-wrap .fc .fc-timegrid-slot { height: 40px; }
}

/* Hamburger button: hidden on desktop, shown on mobile via media query above */
.nav-toggle {
  display: none;
  width: 38px; height: 38px; border-radius: 10px;
  border: 1px solid var(--line); background: #fff; color: var(--navy);
  cursor: pointer; align-items: center; justify-content: center; font-size: 18px;
}
.nav-toggle:hover { background: var(--blue-tint); border-color: var(--blue); }

/* ----------------------------------------------------------------------------
 * 17. Print (clean export of a schedule/log)
 * ------------------------------------------------------------------------- */
@media print {
  .appbar, .toast-host, .modal-overlay, .btn, .nav-toggle { display: none !important; }
  .studio { grid-template-columns: 1fr; }
  body { background: #fff; }
  .card { box-shadow: none; border-color: #ccc; }
}

/* ===== Feed v2: toolbar, clickable themes, PTS badge + actions menu ===== */
.feed-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 4px 0 12px; }
.feed-toolbar .feed-search { flex: 1 1 240px; min-width: 200px; }
.feed-toolbar .feed-regex-label { white-space: nowrap; }
.feed-search.has-error { border-color: var(--red, #c0392b); }
.feed-search-error:empty { display: none; }
.feed-search-error { color: var(--red, #c0392b); }
.feed-themes { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 10px; }
.feed-theme-chip { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border: 1px solid var(--line, #d9e1ec); background: #fff; border-radius: 999px; padding: 4px 12px; font-size: 13px; }
.feed-theme-chip:hover { border-color: var(--blue, #2563eb); }
.feed-theme-chip.is-active { background: var(--blue-tint, #eef4ff); border-color: var(--blue, #2563eb); color: var(--blue, #2563eb); }
.feed-theme-chip .feed-theme-count { font-weight: 800; }
.feed-theme-chip .feed-theme-meta { color: var(--ink-faint, #7a8aa0); font-size: 11.5px; }
.feed-theme-top { border: none; background: transparent; cursor: pointer; color: var(--ink-faint, #7a8aa0); font: inherit; padding: 0 0 0 4px; }
.feed-theme-top:hover { color: var(--blue, #2563eb); text-decoration: underline; }
.feed-active-filters { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.feed-active-filters.hidden { display: none; }
.chip-x { cursor: pointer; border: 1px solid var(--line, #d9e1ec); background: #fff; border-radius: 999px; padding: 3px 10px; font-size: 12px; }
.chip-x:hover { border-color: var(--red, #c0392b); color: var(--red, #c0392b); }
.feed-list-summary { font-size: 12px; color: var(--ink-faint, #7a8aa0); margin: 0 0 10px; }
.feed-list-summary:empty { display: none; }
.feed-card { position: relative; }
.pts-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px; border-radius: 999px;
  font-weight: 800; cursor: pointer; background: var(--green-tint, #e7f7ee); color: var(--green, #16794c);
  border: 1px solid var(--green-line, #b9e6cd); font-size: 12.5px; }
.pts-badge[aria-expanded="true"] { background: var(--green, #16794c); color: #fff; }
.pts-menu { position: absolute; right: 0; top: 44px; z-index: 30; min-width: 220px; max-width: 80vw;
  background: var(--card); border: 1px solid var(--line, #d9e1ec); border-radius: 10px;
  box-shadow: 0 8px 28px rgba(20,40,80,0.18); padding: 6px; display: none; }
.pts-menu.open { display: block; }
.pts-menu-item { display: block; width: 100%; text-align: left; border: none; background: transparent;
  padding: 8px 10px; border-radius: 7px; cursor: pointer; font: inherit; color: var(--ink, #1b2733); text-decoration: none; }
.pts-menu-item:hover { background: var(--blue-tint, #eef4ff); }
.pts-menu-item.danger { color: var(--red, #c0392b); }
.pts-menu-item.danger:hover { background: #fdecea; }
.feed-card--editing .feed-edit-author { width: 100%; margin-bottom: 8px; }
.feed-card--editing .feed-edit-text { width: 100%; resize: vertical; font: inherit; }
.feed-redetect { display: inline-flex; align-items: center; gap: 6px; margin: 8px 0; font-size: 13px; }
.feed-edit-actions { display: flex; gap: 8px; margin-top: 6px; }
.toast-undo { margin-left: 10px; border: 1px solid currentColor; background: transparent; color: inherit;
  border-radius: 6px; padding: 2px 10px; cursor: pointer; font: inherit; font-weight: 700; }

/* ===========================================================================
   Network CRM view (data-view-panel="network") — search → contact detail →
   "Guide me" engagement rail. All np-* classes are emitted by web/network.js.
   =========================================================================== */
.np-searchbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 4px 0 12px; }
.np-searchbar .np-search { flex: 1 1 280px; min-width: 220px; }
.np-results-summary:empty { display: none; }
.np-results { display: flex; flex-direction: column; gap: 10px; }
.np-card { cursor: pointer; transition: border-color .12s ease, box-shadow .12s ease; }
.np-card:hover { border-color: #c4d2df; }
.np-card.is-selected { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(10,102,194,.12); }
.np-card:focus-visible { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(10,102,194,.18); }
.np-card-meta { margin-top: 8px; font-size: 12px; color: var(--ink-faint); }
.np-age { font-variant-numeric: tabular-nums; }
.np-pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; font-size: 11.5px; font-weight: 700; border: 1px solid transparent; background: var(--slate-tint); color: var(--slate); border-color: var(--slate-line); }
.np-pill--champion   { background: var(--green-tint); color: var(--green); border-color: var(--green-line); }
.np-pill--reactivate { background: var(--amber-tint); color: var(--amber); border-color: var(--amber-line); }
.np-pill--pipeline   { background: var(--blue-tint);  color: var(--blue);  border-color: #bcd7f3; }
.np-pill--tier       { background: var(--slate-tint); color: var(--slate); border-color: var(--slate-line); }
.np-pill--t1 { background: var(--green-tint); color: var(--green); border-color: var(--green-line); }
.np-pill--t2 { background: var(--blue-tint);  color: var(--blue);  border-color: #bcd7f3; }
.np-pill--t3 { background: var(--amber-tint); color: var(--amber); border-color: var(--amber-line); }
.np-pill--t4 { background: var(--slate-tint); color: var(--slate); border-color: var(--slate-line); }
.np-pill--score  { background: #fff; color: var(--ink-soft); border-color: var(--line); font-variant-numeric: tabular-nums; }
.np-pill--future { background: var(--blue-tint); color: var(--navy); border-color: #bcd7f3; }
.np-workspace { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 18px; margin-top: 18px; align-items: start; }
@media (max-width: 900px) { .np-workspace { grid-template-columns: 1fr; } }
.np-detail { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 18px 20px; box-shadow: 0 1px 2px rgba(11,58,92,.04); }
.np-detail-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 16px; }
.np-detail-name { font-size: 18px; font-weight: 800; color: var(--ink); }
.np-detail-role { font-size: 13px; color: var(--ink-soft); margin-top: 3px; }
.np-detail-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.np-detail-cols { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 20px; }
@media (max-width: 720px) { .np-detail-cols { grid-template-columns: 1fr; } }
.np-subhead { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--navy); margin: 0 0 10px; }
.np-timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.np-timeline::before { content: ""; position: absolute; left: 13px; top: 4px; bottom: 4px; width: 2px; background: var(--line); }
.np-tl-row { position: relative; display: flex; gap: 12px; padding: 6px 0 14px; }
.np-tl-ico { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; z-index: 1; display: inline-flex; align-items: center; justify-content: center; font-size: 14px; background: #fff; border: 1px solid var(--line); color: var(--ink-soft); }
.np-tl-body { min-width: 0; flex: 1 1 auto; }
.np-tl-sub { font-size: 11.5px; color: var(--ink-faint); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.np-tl-summary { font-size: 13.5px; color: var(--ink); margin-top: 2px; overflow-wrap: anywhere; }
.np-tl-row--inferred { opacity: .6; }
.np-tl-row--inferred .np-tl-ico { border-style: dashed; }
.np-badge { font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 999px; text-transform: uppercase; letter-spacing: .03em; }
.np-badge--inferred { background: var(--slate-tint); color: var(--slate); border: 1px solid var(--slate-line); }
.np-notes-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.np-note { border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; background: var(--line-soft); }
.np-note-body { font-size: 13px; color: var(--ink); overflow-wrap: anywhere; }
.np-note-meta { margin-top: 4px; }
.np-note-add { display: flex; flex-direction: column; gap: 6px; }
.np-note-input { resize: vertical; }
.np-guide { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; box-shadow: 0 1px 2px rgba(11,58,92,.04); position: sticky; top: 18px; }
.np-guide-head { margin-bottom: 12px; }
.np-guide-title { font-size: 14px; font-weight: 800; color: var(--navy); }
.np-guide-hint { margin-top: 8px; }
.np-guide-cached { margin: 10px 0 0; color: var(--ink-faint); }
.np-guide-section { margin-top: 16px; }
.np-guide-text { font-size: 13.5px; color: var(--ink); line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.np-guide-flags { margin-top: 14px; }
.np-openers { margin-top: 18px; }
.np-opener { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin-bottom: 8px; background: #fff; }
.np-opener-text { font-size: 13.5px; color: var(--ink); margin: 0 0 8px; white-space: pre-wrap; overflow-wrap: anywhere; }
.np-opener-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.np-disclaimer { margin-top: 16px; font-size: 11.5px; color: var(--ink-faint); border-top: 1px dashed var(--line); padding-top: 12px; }
.np-empty { padding: 12px 0; }

/* ===================== Newsletter tab ===================== */
.nl-layout { display: grid; grid-template-columns: 320px 1fr; gap: 16px; align-items: start; }
@media (max-width: 880px) { .nl-layout { grid-template-columns: 1fr; } }
/* Tuck under the app bar, not behind it: a bare top:16px pinned the rail into
   the 52px the bar occupies, so its top slid out of sight while scrolling. */
.nl-rail { position: sticky; top: calc(var(--topbar-h) + 16px); max-height: calc(100vh - var(--topbar-h) - 48px); overflow: auto; }
.nl-issue-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.nl-issue-item { text-align: left; width: 100%; cursor: pointer; background: var(--surface-soft); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; transition: border-color var(--t-fast), background var(--t-fast); }
.nl-issue-item:hover { border-color: var(--blue); }
.nl-issue-item.is-active { border-color: var(--navy); background: var(--blue-tint); }
.nl-issue-item-head { display: flex; align-items: center; gap: 8px; justify-content: space-between; }
.nl-issue-item-title { font-weight: 700; font-size: 13.5px; color: var(--ink); }
.nl-issue-item-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-faint); margin-top: 4px; }
.nl-issue-item-sub .nl-dot { opacity: .5; }
.nl-review-flag { color: var(--amber); font-weight: 700; }
.nl-builder.is-loading { opacity: .55; pointer-events: none; }
.nl-builder-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.nl-builder-head-main { display: flex; align-items: center; gap: 10px; }
.nl-builder-period { font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); font-weight: 700; }
.nl-dirty-note { color: var(--amber); }
.nl-section-head { display: flex; align-items: baseline; gap: 10px; margin: 22px 0 10px; border-bottom: 1px solid var(--line); padding-bottom: 6px; }
.nl-section-title { font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); margin: 0; }
.nl-section-meta { font-size: 12px; color: var(--ink-faint); }
.nl-items, .nl-posts { display: flex; flex-direction: column; gap: 10px; }
.nl-item, .nl-post { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; }
.nl-item--unresolved { border-color: var(--amber-line); background: var(--amber-tint); }
.nl-item--editing { border-color: var(--blue); }
.nl-item-head { display: flex; align-items: center; gap: 10px; }
.nl-item-title, .nl-post-title { font-weight: 700; font-size: 15px; color: var(--ink); }
.nl-item-summary { margin: 8px 0 4px; font-size: 14px; color: var(--ink); }
.nl-item-why { margin: 4px 0; font-size: 13.5px; color: var(--ink-soft); }
.nl-item-sources { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.nl-src-link { font-size: 13px; font-weight: 600; text-decoration: none; color: var(--blue); }
.nl-src-link:hover { text-decoration: underline; }
.nl-no-source { color: var(--amber); }
.nl-theme-chip { margin-top: 8px; }
.nl-item-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.spacer { flex: 1; }
.nl-conf { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 2px 8px; border-radius: var(--radius-pill); border: 1px solid transparent; white-space: nowrap; }
.nl-conf--green { color: var(--green); background: var(--green-tint); border-color: var(--green-line); }
.nl-conf--amber { color: var(--amber); background: var(--amber-tint); border-color: var(--amber-line); }
.nl-conf--red   { color: var(--red);   background: var(--red-tint);   border-color: var(--red-line); }
.nl-conf--unknown { color: var(--slate); background: var(--slate-tint); border-color: var(--slate-line); }
.nl-approve-state { font-size: 12px; font-weight: 700; }
.nl-approve-state.is-ok { color: var(--green); }
.nl-approve-state.is-pending { color: var(--amber); }
.nl-reorder { display: inline-flex; gap: 4px; }
.nl-reorder-btn { padding: 4px 9px; line-height: 1; }
.nl-post--best { border-color: var(--green-line); }
.nl-post-head { display: flex; align-items: center; gap: 8px; }
.nl-post-takeaway { margin: 8px 0 4px; font-size: 13.5px; color: var(--ink-soft); }
.nl-post-score { font-size: 12px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.nl-preview { margin-top: 24px; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.nl-preview-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; background: var(--surface-soft); border-bottom: 1px solid var(--line); }
.nl-preview-toggle { display: inline-flex; gap: 6px; }
.nl-fmt-btn.is-active { background: var(--navy); color: #fff; border-color: var(--navy); }
.nl-preview-body { padding: 14px; }
.nl-web-frame { width: 100%; height: 520px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: #fff; }
.nl-article-text { white-space: pre-wrap; word-break: break-word; font: 13px/1.6 var(--mono); background: var(--surface-soft); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px; max-height: 520px; overflow: auto; margin: 0; }
.nl-preview-foot { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.nl-carousel { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; }
.nl-slide { aspect-ratio: 4 / 5; background: var(--navy); color: var(--ink-invert); border-radius: var(--radius-sm); padding: 14px; display: flex; flex-direction: column; gap: 8px; }
.nl-slide-n { font-size: 11px; opacity: .6; }
.nl-slide-title { font-size: 15px; font-weight: 800; }
.nl-slide-body { font-size: 12.5px; color: var(--ink-invert-soft); overflow: hidden; }
.nl-action-bar { display: flex; align-items: center; gap: 10px; margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.nl-dist-summary { font-size: 14px; color: var(--ink); margin: 0 0 14px; }
.nl-dist-h { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); margin: 16px 0 8px; }
.nl-dist-dests { display: flex; flex-direction: column; gap: 8px; }
.nl-dist-dest { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); cursor: pointer; }
.nl-dist-dest-main { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.nl-dist-dest-label { font-weight: 700; font-size: 13.5px; color: var(--ink); }
.nl-dist-dest-sub { font-size: 12px; color: var(--ink-faint); }
.nl-dist-dest-cost { font-size: 12px; font-weight: 700; color: var(--green); }
.nl-cost-table { border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.nl-cost-row { display: flex; justify-content: space-between; gap: 10px; padding: 8px 12px; font-size: 13px; border-bottom: 1px solid var(--line-soft); }
.nl-cost-row:last-child { border-bottom: 0; }
.nl-cost-label { color: var(--ink-soft); }
.nl-cost-value { color: var(--ink); font-variant-numeric: tabular-nums; }

/* --- contact detail "facts" grid (identity + reachability + top-3 signals) --- */
.np-facts { display: grid; grid-template-columns: max-content 1fr; gap: 7px 16px; margin: 14px 0 4px; padding: 14px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.np-fact { display: contents; }
.np-fact-k { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-faint); align-self: center; white-space: nowrap; }
.np-fact-v { font-size: 13.5px; color: var(--ink); overflow-wrap: anywhere; }
.np-fact-link { font-size: 13.5px; color: var(--blue); text-decoration: none; overflow-wrap: anywhere; }
.np-fact-link:hover { text-decoration: underline; }
.np-gender { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.np-gender-sel { width: auto; padding: 3px 8px; font-size: 13px; }
.np-gender-note { font-size: 11.5px; }

/* Network — "Topics discussed" chips (NC-7). Shown in the contact detail, always visible. */
.np-topics { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.np-topics-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft, #5b6b7b); }
.np-topics-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.np-topic-chip { display: inline-flex; align-items: baseline; gap: 6px; padding: 3px 10px; border-radius: 999px;
  background: var(--blue-tint, #eaf2fc); border: 1px solid var(--line, #e6ebf1); font-size: 12px; }
.np-topic-name { font-weight: 700; color: var(--blue, #0a66c2); text-transform: capitalize; }
.np-topic-meta { font-size: 11px; color: var(--ink-faint, #6b7886); }
.np-topics-none { font-style: italic; }

/* ============================================================================
 * Compose view (data-view-panel="compose") — one-stop LinkedIn post package:
 * generate -> curate -> edit (post text, hooks, tags, best time, first comment,
 * image prompts, video prompt, carousel, voiceover) with one-click media render.
 * Reuses the shared tokens / .card / .btn / .field system; all rules are scoped
 * so nothing outside the Compose panel is affected.
 * ========================================================================== */

/* --- Generate control bar (theme + seed + judge + Generate) --------------- */
[data-view-panel="compose"] .cmp-bar { margin-bottom: 18px; }
[data-view-panel="compose"] .cmp-bar-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; }
[data-view-panel="compose"] .cmp-bar-row > .field { flex: 1 1 220px; margin-bottom: 0; }
[data-view-panel="compose"] .cmp-bar-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 14px; }
[data-view-panel="compose"] #cmp-judge { width: auto; margin: 0; }
[data-view-panel="compose"] .cmp-judge-label { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-soft); font-weight: 600; cursor: pointer; }

/* Status + cost line (subtle, tabular figures for the running spend) */
[data-view-panel="compose"] #cmp-status,
[data-view-panel="compose"] #cmp-render-status {
  font-size: 12.5px; color: var(--ink-faint);
  display: inline-flex; align-items: center; gap: 8px;
  font-variant-numeric: tabular-nums;
}
[data-view-panel="compose"] #cmp-status:empty,
[data-view-panel="compose"] #cmp-render-status:empty { display: none; }
[data-view-panel="compose"] #cmp-status.is-busy,
[data-view-panel="compose"] #cmp-render-status.is-busy { color: var(--blue); }
[data-view-panel="compose"] #cmp-status.is-error,
[data-view-panel="compose"] #cmp-render-status.is-error { color: var(--red); }

/* --- Editor (revealed after generate) — stacked, sectioned card ----------- */
[data-view-panel="compose"] .cmp-editor.is-loading { opacity: .55; pointer-events: none; }
[data-view-panel="compose"] .cmp-section { margin-top: 22px; }
[data-view-panel="compose"] .cmp-section:first-child { margin-top: 0; }
[data-view-panel="compose"] .cmp-section-head {
  display: flex; align-items: baseline; gap: 10px;
  margin: 0 0 10px; padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
[data-view-panel="compose"] .cmp-section-title {
  font-size: 13px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-soft); margin: 0; font-weight: 700;
}
[data-view-panel="compose"] .cmp-section-meta { font-size: 12px; color: var(--ink-faint); }

[data-view-panel="compose"] #cmp-post { min-height: 180px; resize: vertical; line-height: 1.55; }
[data-view-panel="compose"] #cmp-firstcomment { min-height: 90px; resize: vertical; }

/* Alt-hooks: a column of editable single-line inputs */
[data-view-panel="compose"] #cmp-hooks { display: flex; flex-direction: column; gap: 8px; }
[data-view-panel="compose"] #cmp-hooks input { width: 100%; }

/* Best-time: compact inline fields */
[data-view-panel="compose"] #cmp-besttime { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
[data-view-panel="compose"] #cmp-besttime > .field { margin-bottom: 0; flex: 0 1 auto; }
[data-view-panel="compose"] #cmp-besttime .cmp-besttime-reason { flex: 1 1 240px; }

/* --- Image prompts: responsive grid of cards with a thumbnail area -------- */
[data-view-panel="compose"] #cmp-images {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}
[data-view-panel="compose"] .cmp-img-card {
  display: flex; flex-direction: column; gap: 10px;
  background: var(--surface-soft); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 14px;
}
[data-view-panel="compose"] .cmp-img-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
[data-view-panel="compose"] .cmp-img-family {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--blue); background: var(--blue-tint);
  border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 2px 10px;
}
/* #6: Tool + Aspect used to each grow to fill the row (flex 1 1 110px), so the two
   selects dwarfed the prompt. Keep them compact + left-aligned at a comfortable fixed
   width; the prompt + negative-prompt then own the full card width below. */
[data-view-panel="compose"] .cmp-img-selects { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
[data-view-panel="compose"] .cmp-img-selects > .field { flex: 0 1 172px; margin-bottom: 0; }
[data-view-panel="compose"] .cmp-img-selects select { width: 100%; }
[data-view-panel="compose"] .cmp-img-card textarea { resize: vertical; font-size: 13px; }
[data-view-panel="compose"] .cmp-img-card .cmp-img-prompt { min-height: 136px; line-height: 1.5; }
[data-view-panel="compose"] .cmp-img-card .cmp-img-negative { min-height: 60px; }
/* #6: the card you're actively editing (expanded) spans the full grid width so the
   prompt gets real room; collapsed summary cards keep tiling in the compact grid. */
[data-view-panel="compose"] .cmp-img-cards > .cmp-img-card:not(.is-collapsed) { grid-column: 1 / -1; }
/* #7: the rendered image used to paint at its intrinsic resolution and overflow the
   panel (and look huge in an expanded full-width card). Constrain it to the card width
   with a sane cap so the most-recent render always fits; the watermark badge overlays
   the now inline-block host that shrink-wraps the image. */
[data-view-panel="compose"] .cmp-img-thumbhost { display: inline-block; max-width: 100%; margin-top: 4px; }
[data-view-panel="compose"] .cmp-img-thumb { display: block; width: auto; max-width: min(100%, 360px); height: auto; border-radius: var(--radius-sm); border: 1px solid var(--line); }
[data-view-panel="compose"] .cmp-img-foot { display: flex; align-items: center; gap: 10px; margin-top: auto; }
[data-view-panel="compose"] .cmp-thumb {
  width: 100%; aspect-ratio: 1 / 1; border-radius: var(--radius-sm);
  background: var(--blue-tint); border: 1px dashed var(--line);
  overflow: hidden; display: grid; place-items: center;
  color: var(--ink-faint); font-size: 12px;
}
[data-view-panel="compose"] .cmp-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* --- Video block: paste-ready prompt + onscreen text + player ------------- */
[data-view-panel="compose"] #cmp-video {
  display: flex; flex-direction: column; gap: 12px;
  background: var(--surface-soft); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 16px;
}
[data-view-panel="compose"] #cmp-video textarea { min-height: 110px; resize: vertical; font-size: 13px; }
[data-view-panel="compose"] #cmp-video .cmp-video-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
[data-view-panel="compose"] #cmp-video video {
  width: 100%; max-height: 420px; border-radius: var(--radius-sm);
  background: var(--navy); border: 1px solid var(--line); display: block;
}

/* --- Carousel: editable slide cards (mirror .nl-carousel/.nl-slide) -------- */
[data-view-panel="compose"] #cmp-carousel { display: flex; flex-direction: column; gap: 12px; }
[data-view-panel="compose"] .cmp-slides {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px;
}
[data-view-panel="compose"] .cmp-slide {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 12px;
}
[data-view-panel="compose"] .cmp-slide-n {
  font-size: 11px; font-weight: 700; color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: .04em;
}
[data-view-panel="compose"] .cmp-slide input,
[data-view-panel="compose"] .cmp-slide textarea { width: 100%; font-size: 13px; }
[data-view-panel="compose"] .cmp-slide textarea { min-height: 80px; resize: vertical; }

/* --- Voiceover script ----------------------------------------------------- */
[data-view-panel="compose"] #cmp-voiceover { display: flex; flex-direction: column; gap: 12px; }
[data-view-panel="compose"] #cmp-voiceover textarea { min-height: 140px; resize: vertical; line-height: 1.55; }

/* --- Footer action bar (Save draft) --------------------------------------- */
[data-view-panel="compose"] .cmp-action-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--line);
}

/* Narrow screens: single-column grids + stacked control bar */
@media (max-width: 720px) {
  [data-view-panel="compose"] #cmp-images,
  [data-view-panel="compose"] .cmp-slides { grid-template-columns: 1fr; }
  [data-view-panel="compose"] .cmp-bar-row > .field { flex-basis: 100%; }
}

/* ── Compose: live generation workflow stepper (driven by /generate/stream) ─── */
.cmp-steps {
  list-style: none; margin: 12px 0 0; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 10px;
  border: 1px solid var(--border, #e2e8f0); border-radius: 10px;
  background: var(--card); animation: studio-fade .2s ease both;
}
.cmp-steps[hidden] { display: none; }
.cmp-step { display: flex; align-items: center; gap: 10px; font-size: 13px; line-height: 1.3; color: var(--color-text-secondary, #64748b); }
.cmp-step-dot { flex: 0 0 auto; width: 16px; height: 16px; border-radius: 50%; box-sizing: border-box; position: relative; border: 2px solid var(--border, #cbd5e1); background: transparent; }
.cmp-step-label { flex: 1 1 auto; }
.cmp-step.is-pending { opacity: .55; }
.cmp-step.is-active { color: var(--accent, #2563eb); font-weight: 600; }
.cmp-step.is-active .cmp-step-dot { border-color: var(--accent, #2563eb); border-top-color: transparent; animation: studio-spin .8s linear infinite; }
.cmp-step.is-done { color: var(--ok, #16a34a); }
.cmp-step.is-done .cmp-step-dot { border-color: var(--ok, #16a34a); background: var(--ok, #16a34a); animation: none; }
.cmp-step.is-done .cmp-step-dot::after { content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }

/* ── Compose: harvested-post seed preview (full text + media) ──────────────── */
.cmp-seed { margin: 8px 0 4px; padding: 12px; border: 1px solid var(--border, #e2e8f0); border-radius: 10px; background: var(--card); animation: studio-fade .2s ease both; }
.cmp-seed[hidden] { display: none; }
.cmp-seed-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; margin-bottom: 8px; }
.cmp-seed-author { font-weight: 600; }
.cmp-seed-stats { font-size: 12px; color: var(--color-text-secondary, #64748b); }
.cmp-seed-link { margin-left: auto; font-size: 12px; color: var(--accent, #2563eb); text-decoration: none; white-space: nowrap; }
.cmp-seed-link:hover { text-decoration: underline; }
.cmp-seed-text { white-space: pre-wrap; word-break: break-word; font-size: 13px; line-height: 1.5; max-height: 220px; overflow-y: auto; padding: 8px 10px; border-radius: 8px; background: var(--bg, #f8fafc); border: 1px solid var(--border, #e2e8f0); }
.cmp-seed-tags { margin-top: 8px; font-size: 12px; color: var(--accent, #2563eb); }
.cmp-seed-media { margin-top: 10px; display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.cmp-seed-mediaitem { position: relative; aspect-ratio: 1 / 1; border-radius: 8px; overflow: hidden; border: 1px solid var(--border, #e2e8f0); background: var(--bg, #f1f5f9); }
.cmp-seed-mediaitem.is-broken { display: none; }
.cmp-seed-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.cmp-seed-thumb--empty { display: flex; align-items: center; justify-content: center; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--color-text-secondary, #64748b); }
.cmp-seed-badge { position: absolute; left: 6px; bottom: 6px; padding: 2px 7px; border-radius: 999px; font-size: 11px; font-weight: 600; color: #fff; background: rgba(15, 23, 42, .78); }
.cmp-seed-note { margin-top: 8px; font-size: 11px; color: var(--color-text-secondary, #64748b); line-height: 1.4; }

/* Experience bank (Compose) — the creator's TRUE stories the AI may draw on. */
/* Seed from a harvested post: collapsed until opened (owner, 2026-10-03). */
.cmp-seedbox { margin-top: 10px; border: 1px solid var(--border, #e2e8f0); border-radius: 8px; padding: 8px 10px; background: var(--bg, #f8fafc); }
.cmp-seedbox > summary { cursor: pointer; font-weight: 600; font-size: 13px; }
.cmp-seedbox[open] > summary { margin-bottom: 8px; }
.cmp-seedbox-status { font-weight: 400; color: var(--ink-soft, #64748b); }
.cmp-seedbox-status:not(:empty)::before { content: "\00B7  "; }
.cmp-exp { margin-top: 10px; border: 1px solid var(--border, #e2e8f0); border-radius: 8px; padding: 8px 10px; background: var(--bg, #f8fafc); }
.cmp-exp > summary { cursor: pointer; font-weight: 600; font-size: 13px; }
.cmp-exp-list { display: flex; flex-direction: column; gap: 10px; margin: 10px 0; }
.cmp-exp-row { padding: 10px; }
.cmp-exp-row-top { display: flex; gap: 10px; flex-wrap: wrap; }
.cmp-exp-row-top .cmp-inline-field { flex: 1 1 auto; }
.cmp-exp-body { width: 100%; resize: vertical; }
.cmp-exp-row-foot { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.cmp-exp-row-status { font-size: 11px; color: var(--color-text-secondary, #64748b); }

/* Image pool (Compose) — rendered + edited images, carousel-selectable. */
.cmp-imagepool { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; }
.cmp-pool-item { position: relative; border: 1px solid var(--border, #e2e8f0); border-radius: 8px; overflow: hidden; background: var(--bg, #f1f5f9); display: flex; flex-direction: column; }
.cmp-pool-item.is-broken { display: none; }
.cmp-pool-thumb { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; }
.cmp-pool-edit { margin: 6px; }

/* In-app image editor (web/image-editor.js) modal. */
.imed-overlay .imed-modal { width: min(960px, 96vw); max-width: 96vw; }
.imed-body { display: flex; flex-direction: column; gap: 10px; }
.imed-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.imed-toolbar .imed-sep { width: 1px; height: 22px; background: var(--border, #e2e8f0); margin: 0 4px; }
.imed-size { width: 120px; }
.imed-color { width: 38px; height: 28px; padding: 0; border: 1px solid var(--border, #e2e8f0); border-radius: 6px; background: none; }
.imed-stage { width: 100%; height: min(60vh, 560px); background: repeating-conic-gradient(#e2e8f0 0% 25%, #f8fafc 0% 50%) 50% / 24px 24px; border: 1px solid var(--border, #e2e8f0); border-radius: 8px; overflow: hidden; }
.imed-canvas { width: 100%; height: 100%; display: block; touch-action: none; cursor: grab; }
.imed-status { font-size: 12px; color: var(--color-text-secondary, #64748b); }

/* Carousel image picker (image-only mode). */
.cmp-carousel-mode { max-width: 210px; }
.cmp-carousel-imglist { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.cmp-carousel-imgitem { display: flex; align-items: center; gap: 8px; border: 1px solid var(--border, #e2e8f0); border-radius: 8px; padding: 6px; background: var(--bg, #f8fafc); }
.cmp-carousel-imgitem .cmp-pool-thumb { width: 56px; height: 56px; aspect-ratio: auto; border-radius: 6px; }
.cmp-carousel-imgpos { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 999px; background: var(--accent, #2563eb); color: #fff; font-size: 12px; font-weight: 600; }

/* Thumbnail picker (seed reference, carousel backgrounds, add-from-pool). */
.cmp-thumbpick { display: flex; flex-wrap: wrap; gap: 8px; }
.cmp-thumbpick-cell { position: relative; width: 72px; height: 72px; padding: 0; border: 2px solid var(--border, #e2e8f0); border-radius: 8px; overflow: hidden; background: var(--bg, #f1f5f9); cursor: pointer; display: flex; align-items: center; justify-content: center; }
.cmp-thumbpick-cell.is-sel { border-color: var(--accent, #2563eb); box-shadow: 0 0 0 2px var(--accent, #2563eb) inset; }
.cmp-thumbpick-cell.is-broken { display: none; }
.cmp-thumbpick-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cmp-thumbpick-none { font-size: 11px; color: var(--color-text-secondary, #64748b); text-align: center; padding: 4px; }

/* Per-asset actions (image pool) + download links. */
.cmp-pool-actions { display: flex; gap: 6px; padding: 6px; }
.cmp-pool-actions .btn { flex: 1 1 auto; }
.cmp-dl-host { display: inline-flex; gap: 6px; }
.cmp-dl { text-decoration: none; }

/* ============================================================================
 * Compose v2 controls (asks #7, #9, #10, #12, #13, #14) — built by web/compose.js.
 * Additive only: image-style (concept-family) picker, collapsible image-prompt /
 * carousel-slide cards, per-slide controls (remove / reorder / add), the
 * best-time → calendar link, ghost copy buttons, and the watermark toggle/badge.
 * Reuses the shared tokens + .btn/.btn--ghost/.btn--sm/.btn--danger system so it
 * reads as one with the rest of Compose; every selector is cmp-* scoped.
 * ========================================================================== */

/* --- #10 Image-style selector: collapsible picker of selectable chips -------
   compose.js builds: <details class="cmp-style-picker"><summary>…</summary>
   <div class="cmp-style-wrap"> N × <button class="cmp-style-chip[ is-selected]">.
   The chosen families persist on the package + drive the image-prompt count. */
.cmp-style-picker {
  margin: 0 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  padding: 0;
}
.cmp-style-picker > summary {
  cursor: pointer;
  list-style: none;
  padding: 10px 14px;
  font-size: 12.5px; font-weight: 700;
  color: var(--ink-soft);
  display: flex; align-items: center; gap: 8px;
}
.cmp-style-picker > summary::-webkit-details-marker { display: none; }
/* Disclosure caret that rotates when the <details> is open. */
.cmp-style-picker > summary::before {
  content: "›"; flex: 0 0 auto;
  font-size: 15px; line-height: 1; color: var(--ink-faint);
  transition: transform var(--t-fast);
}
.cmp-style-picker[open] > summary::before { transform: rotate(90deg); }
.cmp-style-picker > summary .cmp-style-count {
  margin-left: auto;
  font-size: 11px; font-weight: 800;
  color: var(--blue); background: var(--blue-tint);
  border: 1px solid #bcd7f3; border-radius: var(--radius-pill);
  padding: 1px 9px;
}
.cmp-style-wrap {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 4px 14px 14px;
}
/* Unselected chip: quiet outline; selected: filled blue (clear affordance). */
.cmp-style-chip {
  cursor: pointer; user-select: none;
  font-family: inherit; font-size: 11.5px; font-weight: 600;
  letter-spacing: .02em;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: #fff; color: var(--ink-soft);
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.cmp-style-chip:hover { border-color: #c4d2df; color: var(--ink); }
.cmp-style-chip::before {
  content: ""; flex: 0 0 auto;
  width: 13px; height: 13px; border-radius: 50%;
  border: 1.5px solid #c4d2df; background: #fff;
  transition: background var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
}
.cmp-style-chip.is-selected {
  background: var(--blue-fill); border-color: var(--blue-fill); color: #fff;
}
.cmp-style-chip.is-selected:hover { background: var(--blue-dark); border-color: var(--blue-dark); color: #fff; }
.cmp-style-chip.is-selected::before {
  background: #fff; border-color: #fff;
  box-shadow: inset 0 0 0 3px var(--blue);
}
.cmp-style-chip:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(10,102,194,.22); }

/* --- #10/#13 Generic collapse pattern for cmp-img-card + cmp-slide ----------
   compose.js adds a .cmp-collapse-btn caret to a card head and toggles
   .cmp-card-collapsed on the card to hide its body (everything after the head). */
.cmp-collapse-btn {
  flex: 0 0 auto;
  width: 24px; height: 24px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 7px;
  background: #fff; color: var(--ink-soft);
  font-size: 13px; line-height: 1; cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.cmp-collapse-btn:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-tint); }
/* Caret glyph (compose.js leaves it empty / uses ▾); rotate when collapsed. */
.cmp-collapse-btn::before { content: "\25BE"; transition: transform var(--t-fast); }
.cmp-collapse-btn:empty::before,
.cmp-collapse-btn[data-caret]::before { content: "\25BE"; }
.cmp-card-collapsed .cmp-collapse-btn::before { transform: rotate(-90deg); }
/* Hide the card body when collapsed: keep the head row, drop everything after it.
   Works for image-prompt cards (.cmp-img-card) and carousel slides (.cmp-slide). */
.cmp-img-card.cmp-card-collapsed > :not(.cmp-img-head):not(.cmp-slide-controls),
.cmp-slide.cmp-card-collapsed > :not(.cmp-slide-head):not(.cmp-slide-n):not(.cmp-slide-controls) {
  display: none !important;
}
.cmp-img-card.cmp-card-collapsed,
.cmp-slide.cmp-card-collapsed { gap: 0; }

/* --- #12 Per-slide controls (remove ✕ / reorder ↑↓ / add +) ----------------
   compose.js builds: <div class="cmp-slide-controls"> with small icon buttons,
   plus a standalone .cmp-slide-add to append a slide. */
.cmp-slide-head { display: flex; align-items: center; gap: 8px; }
.cmp-slide-head .spacer { flex: 1; }
.cmp-slide-controls {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: auto;
}
.cmp-slide-btn {
  flex: 0 0 auto;
  width: 24px; height: 24px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 7px;
  background: #fff; color: var(--ink-soft);
  font-size: 12.5px; line-height: 1; cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.cmp-slide-btn:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-tint); }
.cmp-slide-btn:disabled { opacity: .4; cursor: default; background: #fff; border-color: var(--line); color: var(--ink-faint); }
.cmp-slide-btn--danger { color: var(--red); }
.cmp-slide-btn--danger:hover { border-color: var(--red); color: var(--red); background: var(--red-tint); }
/* "+ Add slide" — full-width dashed affordance under the slide grid. */
.cmp-slide-add {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; padding: 10px 14px;
  border: 1.5px dashed #c4d2df; border-radius: var(--radius-sm);
  background: var(--surface-soft); color: var(--ink-soft);
  font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.cmp-slide-add:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-tint); }

/* --- #7 Best-time → calendar link --------------------------------------------
   compose.js builds a .cmp-cal-actions row holding a clear .cmp-cal-link plus an
   optional small button (e.g. "Schedule this draft"). */
.cmp-cal-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin-top: 10px;
}
.cmp-cal-link {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700; color: var(--blue);
  text-decoration: none; cursor: pointer;
}
.cmp-cal-link::before { content: "\1F4C5"; font-size: 14px; }
.cmp-cal-link:hover { color: var(--blue-dark); text-decoration: underline; }
.cmp-cal-note { font-size: 12px; color: var(--ink-faint); }

/* --- #9 Copy buttons (quiet ghost; flips to ✓ Copied on success) ------------ */
.cmp-copy-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: #fff; color: var(--ink-soft);
  font-family: inherit; font-size: 12px; font-weight: 600;
  line-height: 1; cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.cmp-copy-btn:hover { border-color: var(--blue); color: var(--blue); }
.cmp-copy-btn.is-copied { border-color: var(--green-line); color: var(--green); background: var(--green-tint); }

/* --- #14 Watermark toggle + badge -------------------------------------------
   compose.js builds a small .cmp-wm-toggle control (checkbox + label) and stamps
   a .cmp-wm-badge ("✓ watermark") onto an image once watermarked. */
.cmp-wm-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 600; color: var(--ink-soft);
  cursor: pointer; user-select: none;
}
.cmp-wm-toggle input { accent-color: var(--blue); margin: 0; cursor: pointer; }
.cmp-wm-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: var(--radius-pill);
  font-size: 10.5px; font-weight: 800; letter-spacing: .02em;
  background: var(--blue-tint); color: var(--blue); border: 1px solid #bcd7f3;
}
/* When overlaid on a thumbnail (image pool / prompt card), pin to a corner. */
.cmp-thumb .cmp-wm-badge,
.cmp-pool-item .cmp-wm-badge {
  position: absolute; left: 6px; top: 6px; z-index: 2;
  background: rgba(10,102,194,.92); color: #fff; border-color: transparent;
}

/* ============================================================================
 * F12 — Scroll-Stop Truncation Linter (live "…see more" fold preview)
 * ----------------------------------------------------------------------------
 * A LIVE, PURE-CLIENT preview rendered under the post textarea (#cmp-post).
 * web JS (fold linter) builds, under the post field:
 *   <div class="cmp-fold-preview">
 *     <div class="cmp-fold-body">              <- mirrors the post, monospaced wrap
 *       <span>above-the-fold text</span>       <- shown normally
 *       <span class="cmp-fold-marker">…see more</span>
 *       <span class="cmp-below-fold">below-the-fold text</span>   <- dimmed
 *     </div>
 *     <div class="cmp-fold-foot">
 *       <span class="cmp-fold-count">N chars before the fold</span>
 *       <span class="cmp-fold-hint">…weak-opener warning…</span>  <- optional
 *     </div>
 *   </div>
 * Reuses the shared tokens; all selectors are cmp-fold-* scoped so nothing else
 * is touched. Degrades gracefully: if JS adds nothing, no rules apply.
 * ========================================================================== */
.cmp-fold-preview {
  margin: 8px 0 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  padding: 12px 14px;
  animation: studio-fade .2s ease both;
}
.cmp-fold-preview[hidden] { display: none; }
/* Small caption row above the mirrored text. */
.cmp-fold-label {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-faint);
  margin-bottom: 8px;
}
/* The mirrored post body — preserve the author's line breaks & spacing so the
   3-line / ~210-char fold lands where LinkedIn would actually cut it. */
.cmp-fold-body {
  font-size: 13px; line-height: 1.55; color: var(--ink);
  white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
}
.cmp-fold-body:empty { display: none; }
/* Above the fold renders in normal ink (default). Below the fold is dimmed so
   the eye stops exactly at the cut. */
.cmp-below-fold { color: var(--ink-faint); opacity: .6; }
/* The "…see more" cut marker LinkedIn shows at the fold. */
.cmp-fold-marker {
  display: inline;
  font-weight: 700; color: var(--blue);
  white-space: nowrap;
}
.cmp-fold-marker::before { content: " "; }
/* Footer: char counter (left) + optional weak-opener hint (right/wraps). */
.cmp-fold-foot {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px;
  margin-top: 10px; padding-top: 8px;
  border-top: 1px solid var(--line);
}
.cmp-fold-count {
  font-size: 11.5px; font-weight: 700;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
/* "N chars before the fold" turns amber when the above-the-fold runs long. */
.cmp-fold-count.is-tight { color: var(--amber); }
/* Weak-opener warning hint (starts with "I", lone "?", no number/strong noun). */
.cmp-fold-hint {
  font-size: 11.5px; color: var(--amber);
  background: var(--amber-tint); border: 1px solid var(--amber-line);
  border-radius: var(--radius-pill);
  padding: 2px 10px;
}
.cmp-fold-hint:empty { display: none; }
.cmp-fold-hint::before { content: "\26A0\FE0F"; margin-right: 5px; }

/* ============================================================================
 * F6 — De-AI Humanizer ("light pass" button + non-destructive flag highlights)
 * ----------------------------------------------------------------------------
 * A "🧹 Humanize" button placed near the post text; on click it runs CONSERVATIVE
 * pure-JS transforms on #cmp-post and offers a one-step Undo. A separate "flag"
 * mode highlights sentences that read AI-written WITHOUT editing them.
 * Reuses the shared .btn/.btn--ghost system; cmp-humanize-* / cmp-ai-flag scoped.
 * ========================================================================== */
/* Button sits with the other post-section actions (matches .btn--ghost feel). */
.cmp-humanize-btn {
  display: inline-flex; align-items: center; gap: 6px;
}
.cmp-humanize-btn .cmp-humanize-ico { font-size: 13px; line-height: 1; }
/* Active "flag" state — the button reads as engaged while highlights are shown. */
.cmp-humanize-btn.is-flagging {
  background: var(--amber-tint); border-color: var(--amber-line); color: var(--amber);
}
/* One-step Undo affordance shown after a humanize pass (quiet, inline). */
.cmp-humanize-undo {
  font-size: 12px; color: var(--ink-faint);
  display: inline-flex; align-items: center; gap: 6px;
}
.cmp-humanize-undo:empty { display: none; }

/* Non-destructive flag overlay — a read-only mirror of the post where sentences
   likely AI-written are highlighted; built as <mark class="cmp-ai-flag"> spans. */
.cmp-ai-flag-overlay {
  margin: 8px 0 4px;
  border: 1px solid var(--amber-line);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  padding: 12px 14px;
  font-size: 13px; line-height: 1.55; color: var(--ink);
  white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
  animation: studio-fade .2s ease both;
}
.cmp-ai-flag-overlay[hidden] { display: none; }
/* A flagged (likely AI-written) sentence — subtle amber highlight, no editing. */
.cmp-ai-flag {
  background: var(--amber-tint);
  color: var(--ink);
  border-bottom: 1.5px solid var(--amber-line);
  border-radius: 3px;
  padding: 0 1px;
}

/* --------------------------------------------------------------------------
   Traction loop (audit §1): post-modal results scorecard.
   -------------------------------------------------------------------------- */
.edit-scorecard {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 4px 0 10px;
  font-size: 13px;
  background: var(--surface);
}
.edit-scorecard .scorecard-head { font-weight: 600; margin-bottom: 6px; }
.edit-scorecard .scorecard-row { display: flex; gap: 10px; padding: 2px 0; align-items: baseline; }
.edit-scorecard .scorecard-label { min-width: 130px; opacity: .72; flex: none; }

/* F101 Win Log — rides the scorecard card; hidden entirely when the flag is off
   (the .winlog node is simply never created). Alias tokens keep dark mode right. */
.edit-scorecard .winlog { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.edit-scorecard .winlog-form { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; align-items: center; }
.edit-scorecard .winlog-form select,
.edit-scorecard .winlog-form input {
  font-size: 12.5px; padding: 4px 8px; border: 1px solid var(--border);
  border-radius: 6px; background: var(--surface); color: var(--text);
}
.edit-scorecard .winlog-form input[type="number"] { width: 150px; }
.edit-scorecard .winlog-form input[type="text"] { flex: 1 1 140px; min-width: 120px; }

/* F103 Voice Reps — calendar-view tap card. Hidden unless the server flag is on
   AND today's pairs exist; alias tokens keep dark mode correct. */
.voice-reps-card { padding: 14px 16px; margin-bottom: 12px; }
.voice-reps-card .vr-head { display: flex; align-items: baseline; gap: 10px; font-weight: 600; }
.voice-reps-card .vr-pct { margin-left: auto; font-size: 12px; font-weight: 500; opacity: .75; }
.voice-reps-card .vr-sub { font-size: 12.5px; opacity: .72; margin: 4px 0 10px; }
.voice-reps-card .vr-option {
  display: block; width: 100%; text-align: left; margin: 6px 0; padding: 10px 12px;
  font-size: 13.5px; line-height: 1.45; cursor: pointer;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text);
}
.voice-reps-card .vr-option:hover { border-color: var(--accent, #0a66c2); }
.voice-reps-card .vr-skip { margin-top: 6px; }

/* F106 Voice DNA card — Settings CTA block. Hidden (and never built) unless the
   server flag features.voiceCard is on; alias tokens keep dark mode correct. */
.voice-dna { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--border); }
.voice-dna .vdna-head { font-weight: 600; }
.voice-dna .vdna-sub { font-size: 12.5px; opacity: .72; margin: 4px 0 8px; }
.voice-dna .vdna-status { font-size: 13px; color: var(--text); min-height: 18px; margin-bottom: 8px; }
.voice-dna .vdna-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.voice-dna .vdna-row a.btn { text-decoration: none; }

/* F109 Data governance settings card (hidden unless features.captureGovernance) */
.gov-card .gov-summary { margin: 8px 0 10px; padding: 8px 10px; border: 1px dashed var(--border); border-radius: 8px; background: var(--surface); }
.gov-card .gov-line { font-size: 12.5px; color: var(--text); opacity: .85; line-height: 1.5; }
.gov-card .gov-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; margin-bottom: 10px; }
.gov-card .gov-grid label { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; }
.gov-card .gov-grid input { border: 1px solid var(--border); background: var(--surface); color: var(--text); border-radius: 8px; padding: 6px 8px; }

/* F104 Snap-to-Post — Compose seed-area control. Never rendered unless the
   server flag features.visionSeed is on; alias tokens keep dark mode correct. */
.cmp-vision { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }
.cmp-vision .cmp-vision-btn {
  font-size: 12.5px; padding: 4px 10px; cursor: pointer;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text);
}
.cmp-vision .cmp-vision-btn:hover:not(:disabled) { border-color: var(--accent, #0a66c2); }
.cmp-vision .cmp-vision-btn:disabled { opacity: .6; cursor: default; }
.cmp-vision .cmp-vision-note { font-size: 11.5px; opacity: .68; color: var(--text); }
.cmp-vision .cmp-vision-file { display: none; }

/* F105 Momentum — Compose "From your week" tray. Never rendered unless the
   server flag features.momentum is on AND this week has signals; alias tokens
   keep dark mode correct. */
.cmp-momentum { margin: 2px 0 10px; }
.cmp-momentum .cmp-momentum-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.cmp-momentum .cmp-momentum-wrap { display: flex; flex-wrap: wrap; gap: 6px; }
.cmp-momentum .cmp-momentum-item { display: inline-flex; align-items: stretch; }
.cmp-momentum .cmp-momentum-chip {
  border: 1px solid var(--border); border-right: 0; border-radius: 999px 0 0 999px;
  background: var(--surface); color: var(--text);
  padding: 3px 8px 3px 10px; font-size: 12px; cursor: pointer; line-height: 1.3;
}
.cmp-momentum .cmp-momentum-chip:hover { border-color: var(--accent, #0a66c2); }
.cmp-momentum .cmp-momentum-chip.is-selected {
  background: var(--accent, #0a66c2); border-color: var(--accent, #0a66c2); color: #fff;
}
.cmp-momentum .cmp-momentum-x {
  border: 1px solid var(--border); border-radius: 0 999px 999px 0;
  background: var(--surface); color: var(--text);
  padding: 3px 8px; font-size: 11px; cursor: pointer; opacity: .65;
}
.cmp-momentum .cmp-momentum-x:hover:not(:disabled) { opacity: 1; border-color: var(--accent, #0a66c2); }
.cmp-momentum .cmp-momentum-x:disabled { opacity: .4; cursor: default; }

/* F110 Profile Studio — flag-gated Profile view (nav hidden while dark; the
   whole view is DOM-built by profile-studio.js). Alias tokens keep dark mode
   correct. Copy-paste-only surface: banner + kind picker + variant cards with
   live LinkedIn char counters. */
.ps-banner { margin-bottom: 12px; }
.ps-controls { padding: 14px 16px; margin-bottom: 14px; }
.ps-controls-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.ps-controls-row .ps-kind-select,
.ps-controls-row .ps-role-hint {
  font-size: 13px; padding: 7px 10px; border: 1px solid var(--border);
  border-radius: 8px; background: var(--surface); color: var(--text);
}
.ps-controls-row .ps-role-hint { flex: 1 1 240px; min-width: 180px; }
.ps-status { display: block; font-size: 12.5px; opacity: .75; margin-top: 8px; min-height: 16px; }
.ps-draft { padding: 14px 16px; margin-bottom: 12px; }
.ps-draft-head { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 8px; }
.ps-draft-head .ps-kind { font-weight: 600; }
.ps-draft-head .ps-hint { font-size: 12px; opacity: .7; }
.ps-draft-head .ps-keep { margin-left: auto; }
.ps-variant {
  margin: 8px 0; padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 8px; background: var(--surface); color: var(--text);
}
.ps-variant-text { font-size: 13.5px; line-height: 1.5; white-space: pre-wrap; }
.ps-variant-foot { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.ps-variant-foot .ps-count { font-size: 12px; opacity: .7; }
.ps-variant-foot .ps-copy { margin-left: auto; }
.ps-empty { font-size: 13px; opacity: .7; }

/* F108 Command Center — operator-only cockpit (nav hidden while dark; the
   whole view is DOM-built by command-center.js). Alias tokens keep dark mode
   correct. Strictly read-only: rollup table + unified scheduled queue. */
.cc-banner { margin-bottom: 12px; }
.cc-card { padding: 14px 16px; margin-bottom: 14px; }
.cc-card .card-head { display: flex; align-items: center; gap: 10px; }
.cc-card .cc-refresh { margin-left: auto; }
.cc-status { display: block; font-size: 12px; opacity: .7; min-height: 16px; margin: 4px 0 8px; }
.cc-table-wrap { overflow-x: auto; }
.cc-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.cc-table th, .cc-table td {
  padding: 7px 10px; border-bottom: 1px solid var(--border);
  text-align: left; white-space: nowrap; color: var(--text);
}
.cc-table th { font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; opacity: .7; }
.cc-table .cc-num { text-align: right; font-variant-numeric: tabular-nums; }
.cc-table .cc-zero { opacity: .35; }
.cc-ws .cc-ws-name { font-weight: 600; display: block; }
.cc-ws .cc-ws-slug { font-size: 11.5px; opacity: .6; display: block; }
.cc-ws .cc-sample { margin-left: 6px; }
.cc-queue-item {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding: 8px 10px; margin: 6px 0; border: 1px solid var(--border);
  border-radius: 8px; background: var(--surface); color: var(--text);
}
.cc-queue-item .cc-queue-when { font-size: 12.5px; font-variant-numeric: tabular-nums; opacity: .8; }
.cc-queue-item .cc-queue-ws { font-size: 12.5px; font-weight: 600; }
.cc-queue-item .cc-queue-title { flex: 1 1 200px; font-size: 13px; min-width: 140px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-queue-item .pill { margin-left: auto; }
.cc-empty { font-size: 13px; opacity: .7; }

/* ============================================================================
   Release-notes version banner — deploy refresh prompt (public GET /version).
   Shown fixed bottom-right when the served version differs from the version
   the SPA booted with. Alias tokens (--surface/--border/--text) follow
   [data-theme="dark"] automatically, so one block covers light + dark.
   ========================================================================== */
.version-banner {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 2000; /* above modals' backdrop-adjacent chrome; it must never be missed */
  width: min(360px, calc(100vw - 32px));
  padding: 14px 16px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
  font-size: 13.5px;
  line-height: 1.45;
}
/* The DraftADay extension's "update me" note sits bottom-left, clear of the release one. */
.version-banner--ext { right: auto; left: 16px; }
.version-banner__text { margin: 6px 0 0; }
.version-banner__cmd {
  display: block;
  margin: 6px 0;
  padding: 6px 8px;
  border-radius: 8px;
  background: var(--surface-2, rgba(127, 127, 127, .12));
  font: 12.5px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  user-select: all;
}
@media (max-width: 760px) {
  .version-banner--ext { bottom: auto; top: 16px; }
}
.version-banner__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.version-banner__title { font-size: 14.5px; }
.version-banner__dismiss {
  background: none;
  border: none;
  color: var(--text);
  opacity: .55;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}
.version-banner__dismiss:hover { opacity: 1; }
.version-banner__label {
  margin-top: 8px;
  font-weight: 600;
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: .04em;
  opacity: .7;
}
.version-banner__list {
  margin: 6px 0 0;
  padding-left: 18px;
}
.version-banner__list li { margin: 4px 0; }
.version-banner__refresh { margin-top: 12px; width: 100%; }

/* LinkedIn token expiry banner (2026-09-06) — rides the version-banner shell so
   it sits in the same corner with the same tokens; the left rule marks it as a
   warning, not a release note. */
.li-expiry-banner { border-left: 4px solid var(--warn, #d97706); }
.li-expiry-banner__body { margin: 8px 0 0; opacity: .85; }

/* Image attach in Compose (owner ask 2026-09-09): a visible drop/click/paste
   zone so Ctrl+V is discoverable, plus the thumbnail strip of what's attached. */
.cmp-image-drop {
  border: 1.5px dashed var(--border, #c8ccd4);
  border-radius: 10px;
  padding: 14px 16px;
  text-align: center;
  cursor: pointer;
  color: var(--muted, #5b6472);
  background: var(--surface-2, rgba(0,0,0,.02));
  transition: border-color .15s, background .15s;
}
.cmp-image-drop:hover, .cmp-image-drop:focus { border-color: var(--accent, #0a66c2); outline: none; }
.cmp-image-drop.is-drag { border-color: var(--accent, #0a66c2); background: rgba(10,102,194,.08); }
.cmp-image-drop-cta { font-size: 13px; }
.cmp-image-strip { margin-top: 6px; }
.cmp-image-strip img { box-shadow: 0 1px 4px rgba(0,0,0,.18); }

/* Focused paste target for image paste (owner report 2026-09-09): a bare div
   can't receive clipboard image data, so this contentEditable catches ⌘V/Ctrl+V. */
.cmp-paste-catcher {
  min-height: 120px; border: 2px dashed var(--accent, #0a66c2); border-radius: 10px;
  padding: 20px; display: flex; align-items: center; justify-content: center;
  text-align: center; color: var(--muted, #5b6472); background: rgba(10,102,194,.05); cursor: text;
}
.cmp-paste-catcher:focus { outline: none; border-color: var(--accent, #0a66c2); background: rgba(10,102,194,.10); }
.cmp-paste-catcher:empty::before { content: '⌘V  /  Ctrl+V  here'; font-size: 15px; font-weight: 700; opacity: .55; }

/* -------------------------------------------------------------------------
 * Compose document tabs (owner ask 2026-09-13)
 * One open post per tab. Opening a post from Content Calendar used to replace
 * whatever was in the editor, with no dirty tracking anywhere — this strip plus
 * per-tab autosave is the fix. 36px tall, and only rendered inside Compose.
 * ------------------------------------------------------------------------- */
.cmp-tabstrip {
  display: flex; align-items: center; gap: 6px;
  min-height: 36px; margin: 0 0 12px;
  border-bottom: 1px solid var(--line, #e2e8f0);
  padding-bottom: 0;
}
.cmp-tabstrip:empty { display: none; }
.cmp-tabstrip-list {
  display: flex; align-items: flex-end; gap: 4px;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: thin;
  flex: 1 1 auto; min-width: 0;
}
.cmp-tabstrip-list::-webkit-scrollbar { height: 4px; }
.cmp-tab {
  display: inline-flex; align-items: center; gap: 6px;
  flex: 0 0 auto; max-width: 210px;
  padding: 7px 8px 7px 10px;
  border: 1px solid transparent; border-bottom: none;
  border-radius: 8px 8px 0 0;
  background: transparent; color: var(--ink-soft, #475569);
  font: inherit; font-size: 13px; cursor: pointer;
  white-space: nowrap;
}
.cmp-tab:hover { background: var(--surface-2, #f1f5f9); }
.cmp-tab.is-active {
  background: var(--surface, #fff);
  border-color: var(--line, #e2e8f0);
  color: var(--ink, #0f172a); font-weight: 600;
  box-shadow: 0 -1px 0 var(--brand, #0a66c2) inset;
}
.cmp-tab-ico { flex: 0 0 auto; opacity: .7; font-size: 12px; }
.cmp-tab-name { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.cmp-tab-dot { flex: 0 0 auto; color: var(--warn, #d97706); font-size: 10px; line-height: 1; }
.cmp-tab-x {
  flex: 0 0 auto; opacity: .45; padding: 0 2px; border-radius: 4px;
  font-size: 15px; line-height: 1;
}
.cmp-tab-x:hover { opacity: 1; background: var(--surface-3, #e2e8f0); }
.cmp-tab-new, .cmp-tab-more {
  flex: 0 0 auto; border: 1px solid var(--line, #e2e8f0);
  background: var(--surface, #fff); color: var(--ink-soft, #475569);
  border-radius: 6px; cursor: pointer; font: inherit; font-size: 13px;
  padding: 5px 9px;
}
.cmp-tab-new:hover, .cmp-tab-more:hover { background: var(--surface-2, #f1f5f9); }
.cmp-tab-more { position: relative; }
.cmp-tab-menu {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 40;
  min-width: 220px; max-height: 60vh; overflow-y: auto;
  background: var(--surface, #fff); border: 1px solid var(--line, #e2e8f0);
  border-radius: 8px; box-shadow: 0 8px 24px rgba(15,23,42,.14);
  padding: 4px;
}
.cmp-tab-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 9px; border: 0; border-radius: 6px; background: transparent;
  font: inherit; font-size: 13px; text-align: left; cursor: pointer;
  color: var(--ink, #0f172a);
}
.cmp-tab-menu-item:hover { background: var(--surface-2, #f1f5f9); }
.cmp-tab-menu-item.is-active { font-weight: 600; }
.cmp-tab-menu-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1 1 auto; }
@media (max-width: 760px) {
  .cmp-tab { max-width: 150px; }
}

/* -------------------------------------------------------------------------
 * App bar — replaces the left sidebar (owner ask 2026-09-13).
 * ONE 52px row: brand, primary nav tabs, status, account menu. Below ~900px the
 * labels drop and the row scrolls, so there is a single layout at every width
 * rather than a separate mobile drawer.
 * ------------------------------------------------------------------------- */
.studio { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }

.appbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 14px;
  min-height: 52px; padding: 0 16px;
  background: linear-gradient(90deg, var(--navy, #0b3a5c) 0%, var(--navy-deep, #072a44) 100%);
  color: var(--ink-invert, #fff);
  box-shadow: 0 2px 14px rgba(11,58,92,.18);
}
.appbar-brand { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.appbar-brand .brand-name { font-weight: 700; letter-spacing: .2px; white-space: nowrap; }

.appnav {
  display: flex; align-items: center; gap: 2px;
  flex: 1 1 auto; min-width: 0;
  overflow-x: auto; scrollbar-width: none;
}
.appnav::-webkit-scrollbar { display: none; }
.appnav .nav-item {
  display: inline-flex; align-items: center; gap: 7px; flex: 0 0 auto;
  /* The base .nav-item is still the old vertical rail's, with width:100% — which
     made the first tab fill the whole row and pushed the rest off-screen. */
  width: auto;
  padding: 8px 12px; border: 0; border-radius: 8px;
  background: transparent; color: rgba(255,255,255,.78);
  font: inherit; font-size: 14px; cursor: pointer; white-space: nowrap;
  text-decoration: none;   /* the tabs are links (Cmd+Click opens a new tab) */
}
.appnav .nav-item:hover { background: rgba(255,255,255,.10); color: #fff; text-decoration: none; }
.appnav .nav-item.active {
  background: rgba(255,255,255,.16); color: #fff; font-weight: 600;
  box-shadow: 0 -2px 0 var(--accent, #7cc4ff) inset;
}
.appnav .nav-ico { font-size: 15px; line-height: 1; }

.appbar-right { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.appbar-right #connection-status { white-space: nowrap; }

/* Account menu — the workspace-level views live here rather than on the row. */
.acctmenu { position: relative; }
.acctmenu-btn {
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.35); background: rgba(255,255,255,.12);
  color: #fff; font: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.acctmenu-btn:hover { background: rgba(255,255,255,.22); }
.acctmenu-panel {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 60;
  /* Never wider than the screen: on a phone the button sits at the very edge and
     a fixed 210px panel hung off the right of the viewport. */
  min-width: 210px; max-width: calc(100vw - 16px); padding: 6px;
  background: var(--surface, #fff); border: 1px solid var(--line, #e2e8f0);
  border-radius: 10px; box-shadow: 0 10px 30px rgba(15,23,42,.18);
  display: flex; flex-direction: column; gap: 2px;
  /* Its own ink. Without it the signed-in name, the workspace line and the switcher
     inherited the top bar's light text: 1.13:1 on this white panel in the light
     theme, so nobody could read who they were signed in as (audit 2026-10-03, V6). */
  color: var(--ink, #0f172a);
}
.acctmenu-panel .nav-item {
  display: flex; align-items: center; gap: 9px; width: 100%; min-width: 0;
  padding: 8px 10px; border: 0; border-radius: 7px; background: transparent;
  color: var(--ink, #0f172a); font: inherit; font-size: 14px;
  text-align: left; cursor: pointer;
}
.acctmenu-panel .nav-item:hover { background: var(--surface-2, #f1f5f9); }
.acctmenu-panel .nav-item.active { background: var(--surface-2, #f1f5f9); font-weight: 600; }
.acctmenu-panel .nav-item.hidden { display: none !important; }

.nav-toggle { display: none !important; }

@media (max-width: 900px) {
  .appnav .nav-label { display: none; }          /* icons only, row still scrolls */
  .appbar-brand .brand-name { display: none; }
  .appnav .nav-item { padding: 8px 10px; }
  .appbar-right #connection-status { display: none; }
}
@media (max-width: 640px) {
  .appbar { gap: 6px; padding: 0 8px; }
  /* "+ New post" becomes just "+": it was eating ~90px and pushing the avatar off
     the right edge. The full label returns as a tooltip. */
  .appbar-right .btn--primary { padding: 8px 11px; font-size: 0; }
  .appbar-right .btn--primary::before { content: "+"; font-size: 16px; font-weight: 700; }
  .appbar-right .btn--icon { padding: 6px 8px; }
  .acctmenu-btn { width: 30px; height: 30px; }
}

/* Visually hidden but read aloud. The avatar button's label had no such rule, so
   "Account menu" rendered as visible text spilling out of the app bar. */
.sr-only {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Tab drag-to-reorder (owner ask 2026-09-13: no arrow buttons — drag them).
   The insertion point is a solid edge on the tab you are hovering, so you can see
   exactly where it will land before letting go. */
.cmp-tab { position: relative; }
.cmp-tab.is-dragging { opacity: .45; }
.cmp-tab.is-drop-before::before,
.cmp-tab.is-drop-after::after {
  content: ""; position: absolute; top: 4px; bottom: 4px; width: 2px;
  background: var(--brand, #0a66c2); border-radius: 2px;
}
.cmp-tab.is-drop-before::before { left: -3px; }
.cmp-tab.is-drop-after::after { right: -3px; }
.cmp-tabstrip-list { min-height: 34px; }

/* The world clock lives on the Calendar's filter row now, not on a row above the
   card. No bottom margin there, and it must not be squeezed by flex-wrap. */
.cal-legend .tz-bar { margin: 0; flex: 0 0 auto; }
.cal-legend .tz-pop { left: auto; right: 0; }

/* ---------------------------------------------------------------------------
   POST PREVIEW — the LinkedIn card (owner ask 2026-09-15).
   Shared by the click-anywhere dialog and Compose's Preview tab, so the card
   looks identical wherever a post is read. Sized to LinkedIn's own feed column
   (~540px) because a preview at a different width misleads about the fold.
   --------------------------------------------------------------------------- */
.preview-panel{background:var(--surface,#fff);border-radius:12px;max-width:640px;width:calc(100vw - 32px);
  max-height:calc(100vh - 64px);display:flex;flex-direction:column;box-shadow:0 12px 40px rgba(15,23,42,.18)}
.preview-body{padding:18px;overflow:auto}
.preview-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:12px 18px;
  border-top:1px solid var(--line,#e2e8f0)}
/* "Remove from Facebook — <Page name>": one per Page (R13), and the Page name is
   what tells two of them apart on a one-way action. .btn never wraps, so a long
   Page name at phone width ran past the panel and scrolled the page sideways
   with the name cut off. Let these wrap inside the panel instead. */
.preview-actions .btn--danger{white-space:normal;text-align:left;line-height:1.3;
  max-width:100%;overflow-wrap:anywhere}
/* Walking the calendar from inside the card. Top of the panel, deliberately far
   from "Remove from LinkedIn" in the footer: these are the buttons pressed over
   and over, and that one cannot be undone. */
.preview-nav{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:10px 18px;border-bottom:1px solid var(--line,#e2e8f0)}
.preview-nav-at{white-space:nowrap}

/* Bulk YouTube Shorts dialog. Three short fields on one row down to phone width,
   then a list that says which Shorts, how they did and when each lands. The rows
   stay legible while the run repaints them one at a time. */
.cmp-shorts-grid{display:flex;gap:12px;flex-wrap:wrap;margin:12px 0}
.cmp-shorts-grid .field{flex:1 1 150px;min-width:0}
.cmp-shorts-list{margin:10px 0;max-height:280px;overflow:auto;border:1px solid var(--line,#e2e8f0);
  border-radius:8px}
.cmp-shorts-row{display:flex;align-items:baseline;gap:10px;padding:7px 10px}
.cmp-shorts-row + .cmp-shorts-row{border-top:1px solid var(--line,#e2e8f0)}
.cmp-shorts-title{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The view count and the slot must not be eaten by the title's ellipsis — the
   same trap the Calendar's duplicate Page chips fell into on 2026-09-21. */
.cmp-shorts-views,.cmp-shorts-slot{flex:0 0 auto;white-space:nowrap}
@media (max-width:560px){
  .cmp-shorts-row{flex-wrap:wrap;gap:4px 10px}
  .cmp-shorts-title{flex:1 1 100%}
}
.li-wrap{max-width:540px;margin:0 auto}
.li-card{border:1px solid var(--line,#e2e8f0);border-radius:10px;background:var(--card,#fff);
  padding:14px;box-shadow:0 1px 2px rgba(15,23,42,.05)}
.li-head{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.li-avatar{flex:0 0 auto;width:44px;height:44px;border-radius:50%;
  background:linear-gradient(135deg,#0a66c2,#378fe9);color:#fff;display:flex;align-items:center;
  justify-content:center;font-size:16px;font-weight:700}
/* A Company Page reads differently at a glance — square-ish, like LinkedIn's own
   page avatars — so posting as the wrong destination is visible immediately. */
.li-avatar.is-page{border-radius:10px;background:linear-gradient(135deg,#1d4ed8,#6366f1)}
.li-avatar-sm{width:30px;height:30px;font-size:12px}
.li-meta{display:flex;flex-direction:column;min-width:0;line-height:1.3}
.li-name{font-size:14px;font-weight:700;color:var(--ink,#0f172a)}
.li-sub{font-size:11.5px;color:var(--ink-faint,#7a8898)}
.li-body{font-size:14px;line-height:1.55;white-space:pre-wrap;word-break:break-word;color:var(--ink,#0f172a)}
.li-body.li-empty{color:var(--ink-faint,#7a8898);font-style:italic}
.li-media{margin-top:12px;display:flex;flex-direction:column;gap:8px}
.li-media-item{width:100%;max-height:420px;border-radius:8px;background:#000;object-fit:contain;display:block}
.li-media-cap{font-size:11px;word-break:break-all}
.li-doc{display:flex;align-items:center;gap:8px;padding:14px;border:1px solid var(--line,#e2e8f0);
  border-radius:8px;background:var(--surface-2,#f8fafc);font-size:13px}
.li-doc-icon{font-size:18px}
/* Media attached but nothing chosen to publish: the post would go out as text
   only, which is almost never intended. Loud on purpose. */
.li-warn{margin-top:12px;padding:10px 12px;border-radius:8px;font-size:13px;
  background:rgba(180,83,9,.08);border:1px solid rgba(180,83,9,.25);color:var(--warn,#b45309)}
.li-warn-sub{font-size:11.5px;opacity:.85;margin-top:2px}
.li-foot{display:flex;align-items:center;gap:6px;margin-top:12px;padding-top:10px;
  border-top:1px solid var(--line,#eef2f6);color:var(--ink-faint,#7a8898);font-size:12px;font-weight:600}
.li-comment{display:flex;gap:9px;margin:10px 0 0;padding:10px 12px;border-radius:10px;
  background:var(--surface-2,#f8fafc)}
.li-comment-who{font-size:12px;font-weight:700;color:var(--ink,#0f172a)}
.li-comment-body{font-size:13px;line-height:1.5;white-space:pre-wrap;color:var(--ink-soft,#475569);margin-top:2px}
@media (max-width:640px){ .preview-body{padding:12px} .li-card{padding:11px} }
.card-title.is-clickable{cursor:pointer}
.card-title.is-clickable:hover{color:var(--blue,#0a66c2);text-decoration:underline}
.cmp-mode{display:inline-flex;gap:2px;border:1px solid var(--line,#e2e8f0);border-radius:8px;padding:2px}
.cmp-mode .btn{border:0;border-radius:6px}
.cmp-mode .btn.is-on{background:var(--blue,#0a66c2);color:#fff}
/* Preview mode hides the editing fields wholesale rather than per-field, so a
   field added later is hidden for free instead of leaking into the preview. */
#cmp-preview-pane{display:none;padding:8px 0 4px}
body.cmp-previewing #cmp-preview-pane{display:block}
body.cmp-previewing .cmp-main{display:none}
/* A post changed underneath you, or is being written right now. Sits above the
   editor because it is about to matter, not after the fact. */
.cmp-conflict{margin:0 0 12px;padding:11px 13px;border-radius:10px;font-size:13px;
  background:rgba(180,83,9,.08);border:1px solid rgba(180,83,9,.3);color:var(--warn,#b45309)}
.cmp-conflict.is-info{background:rgba(10,102,194,.07);border-color:rgba(10,102,194,.28);color:var(--blue,#0a66c2)}
.cmp-conflict-head{font-weight:700;margin-bottom:3px}
.cmp-conflict-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:9px}

/* ---- signed-in identity + the way out, in the account menu ----------------
   The session cookie is httpOnly, so the page asks GET /api/auth/me instead of
   inspecting document.cookie — which it is never allowed to read, and which is
   why the old Sign out button was hidden 100% of the time. */
.acctmenu-who {
  display: flex; flex-direction: column; gap: 2px;
  margin-top: 6px; padding: 10px 12px 8px;
  border-top: 1px solid var(--line);
}
.acctmenu-who-name { font-weight: 600; font-size: .9rem; }
.acctmenu-who-sub { font-size: .78rem; opacity: .85; }
.nav-item--out .nav-label { font-weight: 600; }

/* ---- workspace switcher (account menu) ------------------------------------
   Hidden unless the person is in more than one workspace: a select with a
   single option is a control that lies about having a choice. */
.acctmenu-ws {
  display: flex; flex-direction: column; gap: 5px;
  margin-top: 6px; padding: 10px 12px 4px;
  border-top: 1px solid var(--line);
}
.acctmenu-ws-label {
  font-size: .7rem; letter-spacing: .06em; text-transform: uppercase;
  opacity: .8;
}
.acctmenu-ws-select {
  width: 100%; padding: 7px 9px; border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--card); color: inherit; font: inherit; font-size: .88rem;
}
.acctmenu-ws-select:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

/* ---- account sharing (Accounts view) --------------------------------------
   Two lists in one card: what this workspace can act as, and what it has lent
   out. The distinction between "connected here" and "shared with you" is the
   whole point of the card, so it is a label on every row rather than a legend. */
.sharecard { margin-top: 18px; }
.card-title--sm { font-size: .95rem; margin-bottom: 8px; }
.sharecard-sub { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.sharerow {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 0; border-bottom: 1px solid var(--line);
}
.sharerow:last-child { border-bottom: 0; }
.sharerow-name { font-weight: 600; }
.sharerow-meta { font-size: .8rem; opacity: .85; }
.sharerow .spacer { flex: 1 1 auto; }
.sharetag {
  font-family: var(--mono);
  font-size: .68rem; letter-spacing: .05em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; border: 1px solid;
}
.sharetag--owned   { color: var(--green);    border-color: var(--green); }
.sharetag--granted { color: var(--amber); border-color: var(--amber); }
.sharetag--revoked { opacity: .75; }
.sharerow .btn { flex: 0 0 auto; }

/* ---- disconnecting a Page -------------------------------------------------
   A disconnected Page stays listed on purpose: it is still connected to
   Facebook and one click from being usable again. It is dimmed and labelled so
   it can never be mistaken for a destination. */
.sharerow-tick { flex: 0 0 18px; width: 18px; height: 18px; margin: 0; cursor: pointer; }
.sharerow-tick--none { visibility: hidden; cursor: default; }
.sharerow.is-off .sharerow-name,
.sharerow.is-off .sharerow-meta { opacity: .7; }
.sharerow-name.is-off { text-decoration: line-through; text-decoration-thickness: 1px; }
.sharetag--off {
  color: var(--ink-soft); border-color: var(--border);
  background: var(--surface-2);
}
.sharebulk {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; margin-bottom: 8px;
  border: 1px solid var(--amber); border-radius: 10px;
  background: color-mix(in srgb, var(--amber) 14%, transparent);
}
.sharebulk-n { font-weight: 600; font-size: .88rem; }

/* ---- people in a workspace ------------------------------------------------ */
.peoplerow {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 0; border-bottom: 1px solid var(--line);
}
.peoplerow:last-child { border-bottom: 0; }
.peoplerow-n { font-weight: 600; }
.peoplerow-m { font-size: .8rem; opacity: .85; }
.peoplerow .spacer { flex: 1 1 auto; }
.peoplerole {
  font-family: var(--mono);
  font-size: .68rem; letter-spacing: .05em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; border: 1px solid var(--border);
}
.peoplenew { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.peoplenew-l { font-size: .85rem; opacity: .9; }
.peoplenew-sel {
  flex: 1 1 280px; min-width: 220px; padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--card);
  color: inherit; font: inherit; font-size: .9rem;
}
/* The one moment the plaintext token exists in the interface. */
.invitebox {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding: 12px;
  border: 1px solid var(--amber); border-radius: 10px;
  background: color-mix(in srgb, var(--amber) 14%, transparent);
}
.invitebox-l { flex: 1 1 100%; font-size: .84rem; font-weight: 600; }
.invitebox-i {
  flex: 1 1 320px; min-width: 200px; padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--card);
  color: inherit; font-family: var(--mono); font-size: .8rem;
}

/* ---- sources: multi-URL pull + history search (Compose) -------------------- */
.srctabs { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.srctab {
  padding: 6px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border); background: var(--card);
  color: inherit; font: inherit; font-size: .82rem; max-width: 240px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.srctab.is-on { border-color: var(--amber); background: color-mix(in srgb, var(--amber) 14%, transparent); font-weight: 600; }
.srctab.is-bad { opacity: .75; border-style: dashed; }
.srcpanel {
  margin-top: 10px; padding: 12px 14px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card);
}
.srcpanel-h { font-weight: 600; margin-bottom: 2px; }
.srcpanel-m { font-size: .8rem; opacity: .85; margin-bottom: 8px; }
.srcpanel-t {
  max-height: 260px; overflow: auto; white-space: pre-wrap;
  font-size: .88rem; line-height: 1.55;
}
.srcmedia { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.srcmedia img {
  width: 84px; height: 84px; object-fit: cover; border-radius: 8px;
  border: 1px solid var(--line); cursor: pointer; background: var(--surface-2);
}
.srcmedia img.is-on { outline: 2px solid var(--amber); outline-offset: 1px; }
.srcacts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.srcsearch { margin-top: 12px; }
.srchits { margin-top: 8px; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.srchit {
  display: flex; gap: 10px; align-items: center; padding: 9px 11px; cursor: pointer;
  border-bottom: 1px solid var(--line);
}
.srchit:last-child { border-bottom: 0; }
.srchit:hover { background: var(--surface-2); }
.srchit img { width: 42px; height: 42px; object-fit: cover; border-radius: 6px; flex: 0 0 42px; }
.srchit-t { font-weight: 600; font-size: .9rem; }
.srchit-m { font-size: .76rem; opacity: .85; }
.srchit .spacer { flex: 1 1 auto; }

/* Network · Compare & reach out (2026-09-27: the Profile Comparer merged into Network). */
.np-compare { border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; margin: 12px 0; background: var(--card); }
.np-cmp-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 10px; }
.np-cmp-picker { margin: 0 0 10px; }
.np-cmp-picks { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; max-height: 220px; overflow: auto; }
.np-cmp-pick, .np-cmp-hist { text-align: left; background: none; border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; cursor: pointer; color: var(--ink); font: inherit; font-size: 13px; }
.np-cmp-pick:hover, .np-cmp-hist:hover, .np-cmp-hist.is-active { border-color: var(--blue); }
.np-cmp-status { font-size: 14px; color: var(--ink-soft); }
.np-cmp-meta { margin: 4px 0 8px; }
.np-cmp-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--line); margin-bottom: 10px; flex-wrap: wrap; }
.np-cmp-tab { background: none; border: none; border-bottom: 2px solid transparent; padding: 6px 10px; cursor: pointer; color: var(--ink-soft); font: inherit; font-size: 14px; }
.np-cmp-tab.is-on { color: var(--ink); border-bottom-color: var(--blue); font-weight: 600; }
.np-cmp-summary { font-size: 15px; color: var(--ink); margin: 0 0 10px; }
.np-cmp-h { font-size: 13px; margin: 10px 0 6px; color: var(--ink); }
.np-cmp-list { margin: 0; padding-left: 18px; font-size: 14px; color: var(--ink); }
.np-cmp-list li { margin: 4px 0; display: flex; gap: 8px; align-items: flex-start; justify-content: space-between; }
.np-cmp-two { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.np-cmp-draft { border-top: 1px solid var(--line); padding: 10px 0; }
.np-cmp-dlabel { font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 6px; }
.np-cmp-text { width: 100%; box-sizing: border-box; font-size: 14px; }
.np-cmp-dactions { display: flex; gap: 8px; margin-top: 6px; }
/* a draft held for his form of address (release 319): why, as a held Top Comment says it (.np-cmt-hold) */
.np-cmp-hold { font-size: 12px; font-weight: 600; color: var(--ink); margin: 0 0 6px; border-left: 3px solid var(--amber); padding-left: 8px; overflow-wrap: anywhere; }
.np-cmp-raw { white-space: pre-wrap; font-size: 13px; color: var(--ink-soft); max-height: 240px; overflow: auto; }
.np-cmp-history { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }
/* First-hour boost ("People to tell") — Network strip above the results, below
   "Strike while warm". docs/specs/NETWORK_FIRST_HOUR_BOOST.md */
.np-boost { margin: 0 0 12px; padding: 10px 14px; }
.np-boost-h { font-size: 13px; margin-bottom: 2px; }
.np-boost-sub { font-size: 13px; color: var(--ink-soft); margin: 0 0 8px; }
.np-boost-post { border-top: 1px solid var(--line); padding: 8px 0 4px; }
.np-boost-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-bottom: 4px; }
/* The post header is the open/close control: one line per closed post. */
.np-boost-toggle { display: inline-flex; align-items: baseline; gap: 8px; background: none; border: none; padding: 2px 0; font: inherit; text-align: left; cursor: pointer; color: inherit; }
.np-boost-toggle::before { content: '▸'; color: var(--ink-soft); font-size: 12px; }
.np-boost-post.is-open .np-boost-toggle::before { content: '▾'; }
/* The title is a link to the post itself (the draft in Compose, or the live post). */
a.np-boost-title { text-decoration: none; }
a.np-boost-title:hover, a.np-boost-title:focus-visible { text-decoration: underline; }
.np-boost-toggle:hover .np-boost-count, .np-boost-toggle:focus-visible .np-boost-count { text-decoration: underline; }
.np-boost-count { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.np-boost-title { font-size: 14px; font-weight: 600; color: var(--ink); min-width: 0; overflow-wrap: anywhere; }
.np-boost-when { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.np-boost-when.is-live { color: var(--blue); font-weight: 600; }
.np-boost-status { font-size: 13px; color: var(--ink-soft); margin: 2px 0 6px; }
.np-boost-person { border: 1px solid var(--line); border-radius: 8px; background: var(--card); padding: 8px 10px; margin: 6px 0; }
.np-boost-person.is-sent { background: transparent; }
/* A post's history: what went out, Claude's draft beside his words, who else was proposed. */
.np-boost-day { font-size: 12px; font-weight: 600; color: var(--ink-soft); margin: 10px 0 0; }
.np-boost-daytoggle { display: block; background: none; border: none; padding: 2px 0; font-family: inherit; cursor: pointer; text-align: left; }
.np-boost-daytoggle::before { content: '▸ '; }
.np-boost-daytoggle[aria-expanded="true"]::before { content: '▾ '; }
.np-boost-daytoggle:hover, .np-boost-daytoggle:focus-visible { text-decoration: underline; }
.np-boost-sentline { font-size: 12px; color: var(--ink-soft); margin: 2px 0 4px; }
.np-boost-senttext { font-size: 13px; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; margin: 0 0 4px; padding: 4px 0 4px 8px; border-left: 2px solid var(--line); }
.np-boost-draft, .np-boost-otherbox { margin: 6px 0 2px; }
.np-boost-draft summary, .np-boost-otherbox summary { font-size: 12px; color: var(--ink-soft); cursor: pointer; }
.np-boost-drafttext { font-size: 13px; color: var(--ink-soft); white-space: pre-wrap; overflow-wrap: anywhere; margin: 4px 0; }
.np-boost-others { padding: 4px 0 0; }
.np-boost-other { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; padding: 2px 0; }
.np-boost-otherwhy { font-size: 12px; color: var(--ink-soft); }
.np-boost-who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.np-boost-name { background: none; border: none; padding: 0; cursor: pointer; font: inherit; font-size: 14px; font-weight: 600; color: var(--blue); text-align: left; }
.np-boost-name:hover, .np-boost-name:focus-visible { text-decoration: underline; }
.np-boost-role { font-size: 13px; color: var(--ink-soft); min-width: 0; overflow-wrap: anywhere; }
.np-boost-why { font-size: 12px; color: var(--ink-soft); margin: 2px 0 6px; }
/* The global textarea min-height (110px) made rows="3" meaningless: about 3 lines here. */
.np-boost-note { width: 100%; box-sizing: border-box; font-size: 14px; min-height: 64px; }
.np-boost-err { font-size: 12px; color: var(--ink-soft); margin: 4px 0 0; }
.np-boost-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
/* Sent by itself (lib/network-boost-auto): the switch in the strip's head, how it is
   going, and on each note when it goes and how it went. */
.np-boost-auto { border-top: 1px solid var(--line); padding: 8px 0 6px; margin: 0 0 2px; }
.np-boost-autoswitch { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--ink); cursor: pointer; user-select: none; }
.np-boost-autoswitch input { accent-color: var(--blue); margin: 0; width: 16px; height: 16px; cursor: pointer; }
.np-boost-autostate { font-size: 12px; color: var(--ink-soft); margin: 4px 0 0; }
.np-boost-autostate.is-warn, .np-boost-autoline.is-warn { color: var(--amber); }
.np-boost-autoline { font-size: 12px; color: var(--ink-soft); margin: 4px 0 0; }
.np-boost-autoback { background: none; border: none; padding: 0; font: inherit; font-size: 12px; color: var(--blue); cursor: pointer; text-decoration: underline; }
/* "Never send to" (lib/network-boost-never): companies, names or words whose people get
   no note; one line when closed. */
.np-boost-never { border-top: 1px solid var(--line); padding: 6px 0 4px; margin: 0 0 2px; }
.np-boost-never > summary { cursor: pointer; font-size: 13px; color: var(--ink); display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; list-style: none; }
.np-boost-never > summary::-webkit-details-marker { display: none; }
.np-boost-never > summary::before { content: '▸'; color: var(--ink-soft); font-size: 12px; }
.np-boost-never[open] > summary::before { content: '▾'; }
.np-boost-neverh { font-weight: 600; }
.np-boost-nevernames { font-size: 12px; color: var(--ink-soft); min-width: 0; overflow-wrap: anywhere; }
.np-boost-never > summary:hover .np-boost-neverh, .np-boost-never > summary:focus-visible .np-boost-neverh { text-decoration: underline; }
.np-boost-neverbody { padding: 4px 0 2px 16px; }
.np-boost-neversub, .np-boost-nevertotal, .np-boost-neverpreview { font-size: 12px; color: var(--ink-soft); margin: 4px 0; overflow-wrap: anywhere; }
.np-boost-neverlist { list-style: none; margin: 6px 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.np-boost-neveritem { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); }
.np-boost-neverkind { font-size: 11px; font-weight: 600; color: var(--ink-soft); border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px; white-space: nowrap; }
.np-boost-nevervalue { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.np-boost-nevern { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.np-boost-neverquick { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 8px 0 4px; }
.np-boost-neverqh { font-size: 12px; color: var(--ink-soft); }
.np-boost-neverchip { background: var(--card); border: 1px solid var(--line); border-radius: 999px; padding: 3px 10px; font: inherit; font-size: 12px; color: var(--ink); cursor: pointer; }
.np-boost-neverchip:hover, .np-boost-neverchip:focus-visible { border-color: var(--blue); color: var(--blue); }
.np-boost-neverchip:disabled { opacity: 0.6; cursor: default; }
.np-boost-neveradd { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0 0; }
/* The global form controls are full-width and tall: one compact row here. */
.np-boost-never .np-boost-neverkindsel { width: auto; flex: 0 0 auto; padding: 6px 30px 6px 10px; font-size: 13px;
  background-repeat: no-repeat; background-position: right 10px center; }
.np-boost-never .np-boost-neverinput { width: auto; flex: 1 1 220px; min-width: 0; padding: 6px 10px; font-size: 13px; }
/* "Never send to" on Engagement, Replies, Comments and Touch (release 312, 2026-10-05; docs/specs/EXCLUDE_LISTS.md):
   Boost's card (the rules above, the same classes) with a Person picker, and the "Excluded: Google" chip beside the
   Send / Reply / Post button of someone on a tab's list. Theme tokens only: the dark theme follows on its own. */
.np-never { margin: 4px 0 8px; }
.np-never-found { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.np-never-found:empty { display: none; }
/* One contact a name found: the whole row is the button (his name, their headline under it). */
.np-never .np-never-pick { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; max-width: 100%;
  white-space: normal; text-align: left; line-height: 1.3; border-radius: var(--radius-sm); border-color: var(--line); }
.np-never .np-never-pick:disabled { opacity: 0.6; }
.np-never-pickname { font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.np-never-picksub { font-size: 12px; font-weight: 400; color: var(--ink-soft); overflow-wrap: anywhere; }
.np-excluded { display: inline-flex; align-items: center; align-self: center; max-width: 100%; padding: 2px 9px; border: 1px solid var(--amber-line);
  border-radius: 999px; background: var(--amber-tint); color: var(--ink); font-size: 12px; font-weight: 600; line-height: 1.4; overflow-wrap: anywhere; }
/* On the Engagement page the card sits under the two switches, the whole width of their grid. */
.cm-auto .np-never { grid-column: 1 / -1; margin: 0; }
/* Stay in touch today — Network strip below "Strike while warm", above the
   First-hour boost. Ten compact cards in a grid so the day's list stays short.
   docs/specs/NETWORK_STAY_IN_TOUCH.md */
.np-touch { margin: 0 0 12px; padding: 10px 14px; }
.np-touch-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px; }
.np-touch-h { font-size: 13px; margin-bottom: 2px; }
.np-touch-progress { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.np-touch-bar { height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; margin: 4px 0 6px; }
.np-touch-bar-fill { display: block; height: 100%; background: var(--blue); transition: width 0.2s ease; }
.np-touch-sub { font-size: 13px; color: var(--ink-soft); margin: 0 0 8px; }
.np-touch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; }
.np-touch-card { border: 1px solid var(--line); border-radius: 8px; background: var(--card); padding: 8px 10px; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.np-touch-card.is-done, .np-touch-card.is-snoozed, .np-touch-card.is-skipped { opacity: 0.65; }
.np-touch-who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.np-touch-name { background: none; border: none; padding: 0; cursor: pointer; font: inherit; font-size: 14px; font-weight: 600; color: var(--blue); text-align: left; min-width: 0; overflow-wrap: anywhere; }
.np-touch-name:hover, .np-touch-name:focus-visible { text-decoration: underline; }
.np-touch-tier { font-size: 11px; font-weight: 600; color: var(--ink); border: 1px solid var(--line); border-radius: 999px; padding: 0 6px; }
.np-touch-role { font-size: 13px; color: var(--ink-soft); min-width: 0; overflow-wrap: anywhere; }
.np-touch-last { font-size: 12px; color: var(--ink); }
.np-touch-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.np-touch-chip { font-size: 12px; color: var(--ink-soft); border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px; overflow-wrap: anywhere; }
.np-touch-state { font-size: 12px; font-weight: 600; color: var(--ink-soft); margin-top: 4px; }
.np-touch-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
@media (max-width: 480px) { .np-touch-grid { grid-template-columns: 1fr; } }

/* Network — daily refresh, "Comment first" and the view of one post (owner,
   2026-09-27). docs/specs/NETWORK_DAILY_REFRESH_COMMENT_FIRST.md. Tokens only. */
.np-daily { margin: 0 0 12px; padding: 8px 14px; }
.np-daily-line { font-size: 13px; color: var(--ink); margin: 0; overflow-wrap: anywhere; }
.np-daily-events { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.np-daily-ev { font-size: 13px; color: var(--ink-soft); overflow-wrap: anywhere; }
.np-cmt { margin: 0 0 12px; padding: 10px 14px; }
.np-cmt-item { border: 1px solid var(--line); border-radius: 8px; background: var(--card); padding: 8px 10px; margin: 6px 0; min-width: 0; }
.np-cmt-item.is-done, .np-cmt-item.is-skipped { opacity: 0.65; }
.np-cmt-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.np-cmt-when { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.np-cmt-excerpt { font-size: 13px; color: var(--ink); margin: 4px 0 6px; white-space: pre-line; overflow-wrap: anywhere;
  border-left: 2px solid var(--line); padding-left: 8px; }
.np-cmt-draft { width: 100%; box-sizing: border-box; font-size: 14px; min-height: 72px; }
.np-cmt-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.np-pp { margin: 0 0 12px; padding: 10px 14px; }
.np-pp-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.np-pp-select { max-width: 100%; min-width: 0; flex: 1 1 260px; font-size: 13px; }
.np-pp-search { min-width: 0; flex: 0 1 200px; font-size: 13px; }
.np-pp-hint { font-size: 12px; color: var(--ink-soft); margin: 0 0 6px; }
.np-pp-tag { font-size: 12px; color: var(--ink-soft); }
.np-pp-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 4px 0 8px; }
.np-pp-asktext { font-size: 13px; color: var(--ink-soft); flex: 1 1 240px; min-width: 0; }
.np-pp-body { min-width: 0; }
.np-pp-sec { border-top: 1px solid var(--line); padding: 8px 0 4px; }
.np-pp-h { font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 2px; }
.np-pp-empty { font-size: 13px; color: var(--ink-soft); margin: 2px 0 6px; }
/* each section one line with a count until opened (only one open at a time) */
.np-pp-toggle { display: flex; align-items: baseline; gap: 8px; width: 100%; background: none; border: none; padding: 2px 0; font: inherit;
  font-size: 13px; font-weight: 600; text-align: left; cursor: pointer; color: var(--ink); }
.np-pp-toggle::before { content: '▸'; color: var(--ink-soft); font-size: 12px; }
.np-pp-sec.is-open .np-pp-toggle::before { content: '▾'; }
.np-pp-toggle:hover .np-boost-count, .np-pp-toggle:focus-visible .np-boost-count { text-decoration: underline; }
.np-pp-secbody { min-width: 0; padding-top: 4px; }
.np-cmt-more { margin-top: 4px; }
/* Top 10 to comment on today (release 247): the place, why they are on the list, what waits
   for him, what went wrong, and the switch. Colours from the shared tokens (both themes). */
.np-cmt-rank { font-size: 12px; font-weight: 700; color: var(--ink-soft); min-width: 2ch; }
.np-cmt-why { font-size: 12px; color: var(--ink-soft); margin: 2px 0 4px; overflow-wrap: anywhere; }
.np-cmt-hold { font-size: 12px; font-weight: 600; color: var(--ink); margin: 0 0 6px; border-left: 3px solid var(--amber); padding-left: 8px; }
/* Comments waiting for his OK come first, under their own header (2026-10-02). */
.np-cmt-waiting-h { font-size: 13px; font-weight: 700; color: var(--ink); margin: 14px 0 8px; padding: 6px 10px; border-left: 4px solid var(--amber); background: var(--amber-tint); border-radius: var(--radius-sm); }
.np-cmt-waiting-h.is-rest { border-left-color: var(--line); background: transparent; font-weight: 600; color: var(--ink-soft); }
.np-cmt-err { font-size: 12px; color: var(--red); margin: 0 0 6px; overflow-wrap: anywhere; }
.np-cmt-err.is-unsure { font-weight: 600; }
.np-cmt-sources { font-size: 12px; color: var(--ink-soft); margin: 4px 0 0; overflow-wrap: anywhere; }
.np-cmt-sent { font-size: 13px; color: var(--ink); margin: 2px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.np-cmt-ok { color: var(--ink); }
.np-cmt-next { font-size: 12px; color: var(--ink-soft); margin: 6px 0 0; }
.np-cmt-reaction { width: auto; min-width: 0; padding: 6px 30px 6px 10px; font-size: 12.5px; }
.np-cmt-item.is-sending, .np-cmt-item.is-chrome { border-color: var(--amber-line); }
.np-cmt-item.is-failed { border-color: var(--red-line); }
.np-cmt-auto { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px; margin: 0 0 8px; background: var(--card); min-width: 0; }
.np-cmt-auto.is-on { border-color: var(--accent); }
.np-cmt-auto-switch { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; font-size: 13px; cursor: pointer; }
.np-cmt-auto-switch input { width: auto; margin: 0; }
.np-cmt-auto-status { font-size: 12px; color: var(--ink-soft); flex: 1 1 100%; min-width: 0; }
/* Comment first today (release 282): his pace beside the title ("5 per hour"), and the caution
   above 10 an hour in the page's warning style (amber rule, ink text). Tokens only (both themes). */
.np-cmt-pace { display: inline-flex; align-items: center; min-width: 0; }
.np-cmt .np-cmt-pace-sel { width: auto; min-width: 0; max-width: 100%; padding: 4px 30px 4px 10px; font-size: 12.5px; }
.np-cmt-caution { margin: 2px 0 6px; padding-left: 8px; border-left: 3px solid var(--amber); font-size: 12px; font-weight: 600;
  color: var(--ink); overflow-wrap: anywhere; }
@media (max-width: 480px) { .np-pp-select, .np-pp-search { flex-basis: 100%; } }
/* ---- Waits for their reply (release 317, 2026-10-06; web/waits-reply.js) ----------------------------------------------
   Owner, 2026-10-05: "you have sent messages to same person twice, though she/he has not responded the last message ...
   Before sending the message again, it should check if the person has responded." The chip on a row whose last message
   from him has no reply yet ("Waits for their reply (28 Sep)", the "Excluded" chip's look), and the question before a
   send: over everything (the contact drawer, the person page), Send anyway and Cancel 44 px tall, a 16 px gutter and no
   sideways scroll on a phone. Theme tokens only: the dark theme follows on its own. */
.wr-chip { display: inline-flex; align-items: center; align-self: center; max-width: 100%; min-width: 0; padding: 2px 9px; box-sizing: border-box;
  border: 1px solid var(--amber-line); border-radius: var(--radius-pill); background: var(--amber-tint); color: var(--ink);
  font-size: 12px; font-weight: 600; line-height: 1.4; overflow-wrap: anywhere; }
.np-openers-wait, .pp-wait { margin: 0 0 8px; min-width: 0; }
.pp-wait { margin: 8px 0 0; }
.np-tn-wait { display: inline-flex; min-width: 0; max-width: 100%; }
.np-tn-wait[hidden] { display: none; }
.wr-root { position: fixed; inset: 0; z-index: 1400; display: flex; align-items: center; justify-content: center;
  padding: 16px; box-sizing: border-box; overflow-x: hidden; overflow-y: auto; }
.wr-backdrop { position: absolute; inset: 0; background: var(--navy-deep); opacity: .45; }
:root[data-theme="dark"] .wr-backdrop { opacity: .62; }
.wr-dialog { position: relative; width: 100%; max-width: 440px; min-width: 0; box-sizing: border-box; margin: auto; padding: 20px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); color: var(--ink); box-shadow: var(--shadow-lg); }
.wr-who { margin: 0 0 6px; font-size: 13px; font-weight: 700; color: var(--ink-soft); overflow-wrap: anywhere; }
.wr-msg { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.wr-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; margin-top: 18px; min-width: 0; }
.wr-acts .btn { min-height: 44px; min-width: 44px; padding: 0 18px; max-width: 100%; }
@media (max-width: 480px) { .wr-acts .btn { flex: 1 1 140px; } }
/* A Compare draft's Send, its chip, Copy and Mark sent wrap on a phone's width (the chip made the row too long). */
.np-cmp-dactions { flex-wrap: wrap; align-items: center; }

/* ---- Write with Claude (release 320, 2026-10-11; web/ai-request.js) ---------------------------------------------------
   Owner: "let's install and implement explicit button to do anything automatically by Claude. As this has increased the
   uses of token excessively and you must stop it." A row with no draft: "Write with Claude" (Studio's ghost button, in
   the action blue so it reads as the next step); asked: "Writing…" with a calm dot, and Cancel while Claude has not
   started it; failed: why, in the error red, and Try again. Each list's header: "Write all shown (N)". Tokens only, so
   both themes follow; 44 px targets on a phone (the touch row's own 30 px rule is outranked here). */
.ai-req { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; min-width: 0; max-width: 100%; vertical-align: middle; }
.btn.ai-req-write, .ai-all { border-color: var(--blue); color: var(--blue); }
.btn.ai-req-write:hover, .ai-all:hover { background: var(--blue-tint); }
.ai-all:disabled, .ai-all[disabled] { border-color: var(--line); color: var(--ink-soft); background: transparent; }
/* Dark: studio-v2.css gives every ghost button the card and the ink (:root[data-theme="dark"] .btn--ghost); the accent
   stays, from the same tokens (its lifted blue reads on the dark card). */
:root[data-theme="dark"] .btn.ai-req-write, :root[data-theme="dark"] .ai-all:not(:disabled) { border-color: var(--blue); color: var(--blue); }
.ai-req-busy { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; font-size: 12.5px; font-weight: 700; color: var(--ink-soft); }
.ai-req-busy::before { content: ''; flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--blue); animation: ai-req-pulse 1.4s ease-in-out infinite; }
.ai-req-busy:focus { outline: none; }
.ai-req-busy:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 4px; }
@keyframes ai-req-pulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ai-req-busy::before { animation: none; } }
.ai-req-err { flex: 1 1 14em; min-width: 0; font-size: 12.5px; line-height: 1.4; color: var(--red); overflow-wrap: anywhere; }
.np-boost-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; min-width: 0; margin-bottom: 2px; }
.np-boost-top .np-boost-h { margin-bottom: 0; }
.np-cat-ai { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; }
.eg-ai-all { display: flex; justify-content: flex-end; margin: 0 0 10px; }
.np-rw-write { margin-top: 4px; }
.wr-ai-all { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 0 0 10px; }
/* Compose's queue: a waiting line with Write with Claude wraps (its lines are one nowrap row) and is not faded like the
   others (the button would read grey-on-grey); the panel keeps to the screen's width. */
#cmp-queue-free-panel, #cmp-queue-free-panel .cmp-queue-details { max-width: 100%; min-width: 0; box-sizing: border-box; }
#cmp-queue-free-panel .cmp-queue-body { min-width: 0; }
#cmp-queue-free-panel .cmp-queue-line.has-ai { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; white-space: normal; opacity: 1; }
#cmp-queue-free-panel .cmp-queue-line.has-ai > span:first-child { flex: 1 1 12em; min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 640px), (hover: none) and (pointer: coarse) {
  .ai-req > .btn.btn--sm, .btn.btn--sm.ai-all { min-height: 44px; min-width: 44px; }
  .ai-req-busy { min-height: 44px; }
}
