/* ============================================================
   Tassels Design System — Component Classes
   Consumes CSS custom properties from tokens.css.
   Import AFTER tokens.css in base.html.

   Scope: compound component styling (cards, rows, tables,
   banners, pills, buttons, nav internals, calendar cells).
   Contrast with tokens.css, which defines the underlying
   values (colors, type scale, spacing, radius).

   See ADR-0012 and docs/design-system-rollout-plan.md.
   ============================================================ */

/* ── Page shell ─────────────────────────────────────────────── */
/* Standard page wrapper.  Owns max-width, horizontal centering,    */
/* and outer padding for every authenticated surface — applied      */
/* once on the <main> element in base.html so individual templates  */
/* never need to set max-w-* / mx-auto themselves.  This is the     */
/* one knob that keeps page heading alignment consistent across     */
/* every top-level nav destination.                                 */
/*                                                                  */
/* There is intentionally only one width.  If a page needs more     */
/* horizontal room (calendar grid, analytics charts), it constrains */
/* itself internally — never by widening the shell — because the    */
/* shell width is what guarantees the heading lines up across       */
/* every nav target.  Templates with content that genuinely needs   */
/* to escape the shell (currently: the media editor SPA) opt in to  */
/* the bleed variant via the `page_shell_modifier` block.           */
.page-shell {
    /* 108rem ≈ 1728px.  Wide enough to feel spacious on a 1440-1920
       laptop/monitor (where it just takes the available viewport minus
       padding) and to leave only modest gutters on a 4K display.
       Below this width the shell is effectively 100vw - padding, so
       phones/tablets are unaffected — they keep behaving as a fluid
       width with the single 24px outer pad.  Inner `max-w-*` wrappers
       on individual templates (forms, prose) keep reading widths
       comfortable inside the wider shell. */
    max-width: 108rem;
    margin-left: auto;
    margin-right: auto;
    padding: var(--space-6);
}

/* Full-bleed variant for surfaces that own their own chrome and    */
/* must not be centered or capped (currently: the media editor      */
/* SPA shell).                                                      */
.page-shell--bleed {
    max-width: none;
    padding: 0;
}

/* ── Section + card titles ──────────────────────────────────── */
/* Drop these on <h2> / <h3> headings inside page sections and cards.
   They pick up the per-theme display font + treatment tokens so the
   feel changes with the workspace theme — Executive serif italic,
   Athlete condensed UPPERCASE, etc.  Template-level retrofitting onto
   existing inline-styled headings is a Phase 2 sweep.                */
.text-section-title {
    font-family: var(--font-display);
    font-size: var(--text-section);
    font-weight: var(--disp-weight);
    letter-spacing: var(--disp-spacing);
    text-transform: var(--disp-transform);
    line-height: var(--disp-line);
    color: var(--color-text-primary);
}

/* .text-card-title is intentionally body-sized: card layouts across
   the dashboard, cadence, voice, and onboarding surfaces assume a
   13px inline H2.  Bumping to section-size would reflow tight cards.
   The per-theme display treatment (Executive serif italic, Athlete
   condensed UPPERCASE) still shines through at body size — that's
   the point. */
.text-card-title {
    font-family: var(--font-display);
    font-size: var(--text-body);
    font-weight: var(--disp-weight);
    letter-spacing: var(--disp-spacing);
    text-transform: var(--disp-transform);
    line-height: var(--disp-line);
    color: var(--color-text-primary);
    margin-bottom: var(--space-2);
}

/* ── Card layout internals ──────────────────────────────────── */
.card + .card { margin-top: var(--space-3); }

.card--compact {
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-lg);
}

.card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-3);
}
.card__body > * + * { margin-top: var(--space-3); }

/* ── Links ──────────────────────────────────────────────────── */
.link-muted {
    font-size: var(--text-label);
    color: var(--color-text-muted);
    text-decoration: none;
}

.link-accent {
    color: var(--color-text-accent);
    text-decoration: none;
}
.link-accent:hover {
    color: var(--color-text-accent-hover);
    text-decoration: underline;
}

/* ── Draft / list row ───────────────────────────────────────── */
.draft-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    padding: 10px 0;
    gap: var(--space-3);
    border-bottom: 0.5px solid var(--color-border-subtle);
}
.draft-row:last-child { border-bottom: none; }
.draft-row__title {
    font-size: var(--text-body);
    color: var(--color-text-secondary);
}
.draft-row__sub {
    font-size: var(--text-label);
    color: var(--color-text-muted);
    margin-top: 2px;
}
.draft-row__action {
    font-size: 12px;
    color: var(--color-text-accent);
    text-decoration: none;
    white-space: nowrap;
}

/* ── Signal / activity row ──────────────────────────────────── */
.signal-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 0.5px solid var(--color-border-subtle);
}
.signal-row:last-child { border-bottom: none; }
.signal-row__text {
    font-size: var(--text-body);
    color: var(--color-text-secondary);
    flex: 1;
}
.signal-row__date {
    font-size: var(--text-label);
    color: var(--color-text-muted);
    font-family: var(--font-mono);
}

/* ── Sidebar internals ──────────────────────────────────────── */
.sidebar-row {
    display: flex;
    justify-content: space-between;
    font-size: var(--text-body);
    padding: 4px 0;
}
.sidebar-row__key { color: var(--color-text-muted); }
.sidebar-row__val {
    color: var(--color-text-primary);
    font-weight: var(--weight-medium);
}

/* ── Data table ─────────────────────────────────────────────── */
.data-table {
    width: 100%;
    border-collapse: collapse;
}
.data-table thead th {
    text-align: left;
    font-size: var(--text-label);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.8px;
    padding: 8px 12px;
    border-bottom: 0.5px solid var(--color-border-default);
}
.data-table tbody td {
    padding: 10px 12px;
    color: var(--color-text-secondary);
    font-size: var(--text-body);
    border-bottom: 0.5px solid var(--color-border-subtle);
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--color-bg-card-hover); }
.data-table .cell-link {
    color: var(--color-text-accent);
    cursor: pointer;
}

/* Generic hover row for list items outside tables.  Background is a
   per-theme var() — never transition it (paint freezes on theme swap). */
.hover-row:hover { background: var(--color-bg-card-hover); }

/* ── Section sub-nav (segmented pill bar under a page heading) ───
   Each child link is a visible pill so the row reads as nav, not
   inline labels.  Inactive pills have a translucent surface + border
   that deepens on hover; the active pill uses the accent fill from
   the .pill-accent family. */
.subnav {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 4px;
    background: var(--color-bg-card);
    border: 0.5px solid var(--color-border-default);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-5);
}
.subnav__link {
    color: var(--color-text-secondary);
    text-decoration: none;
    font-size: var(--text-body);
    padding: 6px 14px;
    border-radius: calc(var(--radius-md) - 2px);
    border: 0.5px solid transparent;
    /* No transition on background/color/border-color: their computed
       values are per-theme var()s and transitioning them would freeze
       paint on theme swap.  Hover is an immediate swap. */
}
.subnav__link:hover {
    color: var(--color-text-primary);
    background: var(--color-bg-card-hover);
    border-color: var(--color-border-subtle);
}
.subnav__link[aria-current="page"] {
    color: var(--color-accent-indigo);
    background: var(--color-accent-indigo-bg);
    border-color: var(--color-accent-indigo-border);
    font-weight: var(--weight-medium);
}

/* ── Sidebar collapsible (variant edit page) ──────────────────
   `<details class="sidebar-collapsible">` with a summary that
   looks like a compact card header.  When closed, only the summary
   renders; when open, the inner card slides in below.  Native
   `<details>` toggles, so no JS. */
.sidebar-collapsible {
    background: var(--color-bg-card);
    border: 0.5px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    padding: 0;
}
.sidebar-collapsible > summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
}
.sidebar-collapsible > summary::-webkit-details-marker {
    display: none;
}
.sidebar-collapsible[open] > summary {
    border-bottom: 0.5px solid var(--color-border-subtle);
}
.sidebar-collapsible__chevron {
    margin-left: auto;
    transition: transform 0.15s ease;
}
.sidebar-collapsible[open] .sidebar-collapsible__chevron {
    transform: rotate(180deg);
}
/* The inner card (from the includes) shouldn't double-border —
   zero its outer border and let the details wrapper own the
   elevation. */
.sidebar-collapsible > .card,
.sidebar-collapsible > #optimization-panel {
    border: none;
    background: transparent;
    border-radius: 0;
}

/* ── Inline row / stack helpers ─────────────────────────────── */
.inline-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
}

.section-stack > * + * { margin-top: var(--space-5); }

/* ── Dashboard page glow ────────────────────────────────────── */
.page-glow {
    position: absolute;
    top: -80px;
    left: 30%;
    width: 320px;
    height: 180px;
    /* --glow-color is `transparent` in executive + smb, so the radial
       gradient renders nothing visible.  Creative gets a warm coral
       glow; athlete a volt glow.  No per-theme display:none override
       needed — the gradient itself goes invisible. */
    background: radial-gradient(ellipse, var(--glow-color) 0%, transparent 70%);
    pointer-events: none;
    z-index: 0;
}

/* ── Theme toggle ───────────────────────────────────────────── */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    background: var(--color-bg-card);
    border: 0.5px solid var(--color-border-default);
    border-radius: var(--radius-md);
    padding: 6px 12px;
    font-size: var(--text-label);
    color: var(--color-text-secondary);
    cursor: pointer;
    font-family: var(--font-body);
    width: 100%;
    justify-content: flex-start;
}
.theme-toggle:hover { background: var(--color-bg-card-hover); }
.theme-toggle__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-accent-indigo);
}

/* ── Notice / informational banner (subtle) ─────────────────── */
.notice {
    border: 0.5px solid var(--color-border-default);
    background: var(--color-bg-card);
    backdrop-filter: var(--card-backdrop);
    -webkit-backdrop-filter: var(--card-backdrop);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
    font-size: 12px;
    color: var(--color-text-secondary);
    margin-bottom: var(--space-5);
}
.notice strong {
    color: var(--color-text-primary);
    font-weight: var(--weight-medium);
}

/* ── Pill family — round out the trio from tokens.css ───────── */
.pill-danger {
    background: var(--color-status-danger-bg);
    color: var(--color-status-danger);
    border: 0.5px solid var(--color-status-danger-border);
}
.pill-info {
    background: var(--color-status-info-bg);
    color: var(--color-status-info);
    border: 0.5px solid var(--color-status-info-border);
}

/* ── Button family — round out from tokens.css ──────────────── */
.btn-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--color-status-danger-bg);
    color: var(--color-status-danger);
    border: 0.5px solid var(--color-status-danger-border);
    padding: 6px 14px;
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--text-label);
    font-weight: var(--weight-medium);
    cursor: pointer;
    /* background is a per-theme accent — see motion rule in tokens.css. */
    letter-spacing: 0.2px;
}
.btn-danger:hover {
    background: rgba(248, 113, 113, 0.18);
}

/* ── Banners (full-width inline alerts) ─────────────────────── */
.banner {
    border-radius: var(--radius-md);
    border: 0.5px solid var(--color-border-default);
    background: var(--color-bg-card);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-body);
    color: var(--color-text-secondary);
}
.banner--info {
    background: var(--color-status-info-bg);
    border-color: var(--color-status-info-border);
    color: var(--color-status-info);
}
.banner--success {
    background: var(--color-status-success-bg);
    border-color: var(--color-status-success-border);
    color: var(--color-status-success);
}
.banner--warning {
    background: var(--color-status-warning-bg);
    border-color: var(--color-status-warning-border);
    color: var(--color-status-warning);
}
.banner--danger {
    background: var(--color-status-danger-bg);
    border-color: var(--color-status-danger-border);
    color: var(--color-status-danger);
}

/* ── Progress bar modifiers (quota states) ──────────────────── */
.progress-bar__fill--warning {
    background: var(--color-status-warning);
}
.progress-bar__fill--danger {
    background: var(--color-status-danger);
}

/* ── Focus ring utility ─────────────────────────────────────── */
.focus-ring:focus,
.focus-ring:focus-visible {
    outline: 2px solid var(--color-accent-indigo);
    outline-offset: 2px;
}

/* ── Keyboard-shortcut hint ─────────────────────────────────── */
.kbd-hint {
    font-size: 11px;
    color: var(--color-text-muted);
    font-family: var(--font-mono);
}

/* ── Textarea (complements .input / .select in tokens.css) ──── */
.textarea {
    background: var(--color-bg-input);
    border: 0.5px solid var(--color-border-default);
    border-radius: var(--radius-md);
    color: var(--color-text-primary);
    font-family: var(--font-body);
    font-size: var(--text-body);
    padding: 8px 12px;
    outline: none;
    transition: border-color 0.15s ease;
    width: 100%;
    resize: vertical;
    line-height: 1.5;
    color-scheme: inherit;
}
.textarea:focus { border-color: var(--color-accent-indigo); }
.textarea::placeholder { color: var(--color-text-disabled); }
.textarea--mono {
    font-family: var(--font-mono);
    font-size: var(--text-mono);
}

/* ── Form validation ────────────────────────────────────────── */
.form-field-error {
    font-size: var(--text-label);
    color: var(--color-status-danger);
    margin-top: 4px;
}
.form-non-field-errors {
    border-radius: var(--radius-md);
    background: var(--color-status-danger-bg);
    border: 0.5px solid var(--color-status-danger-border);
    color: var(--color-status-danger);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-body);
    margin-bottom: var(--space-3);
}

/* ── Nav chrome (matches styleguide nav) ────────────────────── */
.nav-shell {
    background: var(--color-bg-nav);
    /* --color-border-nav per theme already encodes the right weight:
       executive uses a strong navy line (#172338); the others use a
       subtle tone.  No per-theme override needed. */
    border-bottom: 0.5px solid var(--color-border-nav);
}

.nav-logo {
    /* Full per-theme display treatment: Executive reads serif italic,
       Athlete reads condensed UPPERCASE, etc.  font-weight is read from
       --disp-weight so the wordmark feels right in each skin. */
    font-family: var(--font-display);
    font-size: 14px;
    font-weight: var(--disp-weight);
    letter-spacing: var(--disp-spacing);
    text-transform: var(--disp-transform);
    line-height: var(--disp-line);
    color: var(--color-text-primary);
}
.nav-sep {
    color: var(--color-text-muted);
}
.nav-workspace {
    font-size: var(--text-body);
    color: var(--color-text-muted);
}
.nav-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--color-accent-indigo-bg);
    border: 0.5px solid var(--color-accent-indigo-border);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    color: var(--color-accent-indigo);
    font-weight: var(--weight-medium);
}

/* Redesign Phase 2: Identity slot-1 tint + hairline divider + pill active.
   Active state keys off aria-current (no inline styles needed). */
.nav-link[aria-current="page"] {
    color: var(--color-nav-active);
    border-bottom-color: var(--color-nav-active-border);
    font-weight: var(--weight-medium);
}
.nav-link--identity {
    /* Identity is the input/foundation — tinted with accent-2 and set
       off from the workflow group by .nav-divider. */
    color: var(--color-accent-cyan);
    font-weight: var(--weight-medium);
}
.nav-link--identity[aria-current="page"] {
    color: var(--color-accent-cyan);
    border-bottom-color: var(--color-accent-cyan);
}
.nav-divider {
    display: inline-block;
    width: 1px;
    height: 20px;
    margin: 0 10px;
    background: var(--color-border-default);
    vertical-align: middle;
}

/* Top-bar bell — the notifications inbox entry point (the redesign
   pulls the inbox out of the avatar menu into a dedicated icon). */
.nav-bell {
    position: relative;
    width: 34px;
    height: 34px;
    border-radius: var(--radius-sm);
    border: 0.5px solid var(--color-border-default);
    background: var(--color-bg-card);
    color: var(--color-text-secondary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
}
.nav-bell:hover {
    background: var(--color-bg-card-hover);
    color: var(--color-text-primary);
}
.nav-bell__badge {
    position: absolute;
    top: -5px;
    right: -5px;
    min-width: 17px;
    height: 17px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--color-status-warning);
    color: #fff;
    font-size: 10px;
    line-height: 17px;
    text-align: center;
    font-weight: 600;
}

/* Identity "Story spine" rail (Phase 4) — narrated beats on a timeline.
   Each beat is a node on the rail; .sp-lab / .sp-line / .st-refine atoms
   render the content. */
.spine {
    position: relative;
    padding-left: 28px;
    display: flex;
    flex-direction: column;
}
.spine::before {
    content: "";
    position: absolute;
    left: 9px;
    top: 10px;
    bottom: 10px;
    width: 2px;
    background: var(--color-border-default);
}
.spine__beat {
    position: relative;
    padding: 18px 0;
    border-bottom: 1px solid var(--color-border-subtle);
}
.spine__beat:last-child {
    border-bottom: none;
}
.spine__beat::before {
    content: "";
    position: absolute;
    left: -23px;
    top: 24px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--color-accent-cyan);
    box-shadow: 0 0 0 4px var(--color-bg-base);
}

/* Settings hub cards (Phase 3) — grouped Personal / Workspace links. */
.settings-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
    gap: var(--space-3);
}
.settings-card {
    display: block;
    padding: 16px 18px;
    text-decoration: none;
}
.settings-card:hover {
    background: var(--color-bg-card-hover);
}
.settings-card__title {
    font-size: var(--text-body);
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
}
.settings-card__hint {
    font-size: var(--text-meta);
    color: var(--color-text-secondary);
    margin-top: 4px;
    line-height: 1.45;
}

/* Profile / org-switcher dropdown panel */
.nav-dropdown {
    background: var(--color-bg-dropdown);
    border: 0.5px solid var(--color-border-default);
    border-radius: var(--radius-md);
    padding: 4px 0;
}
.nav-dropdown__label {
    padding: 6px 14px;
    font-size: 11px;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 1px;
    border-bottom: 0.5px solid var(--color-border-subtle);
}
.nav-dropdown__item {
    display: block;
    padding: 8px 14px;
    font-size: var(--text-body);
    color: var(--color-text-secondary);
    text-decoration: none;
    background: transparent;
    border: none;
    width: 100%;
    text-align: left;
    cursor: pointer;
    font-family: var(--font-body);
}
.nav-dropdown__item:hover {
    background: var(--color-bg-card-hover);
    color: var(--color-text-primary);
}
.nav-dropdown__item--active {
    color: var(--color-text-accent);
}
.nav-dropdown__item--danger {
    color: var(--color-status-danger);
}
.nav-dropdown__divider {
    height: 0.5px;
    background: var(--color-border-subtle);
    margin: 4px 0;
    border: none;
}

/* Mobile nav drawer */
.mobile-drawer {
    background: var(--color-bg-nav);
    border-right: 0.5px solid var(--color-border-default);
}
.mobile-drawer__link {
    display: block;
    padding: 12px 16px;
    font-size: var(--text-body);
    color: var(--color-text-secondary);
    text-decoration: none;
}
.mobile-drawer__link:hover,
.mobile-drawer__link:active {
    background: var(--color-bg-card-hover);
    color: var(--color-text-primary);
}
/* Collapsible section in the mobile drawer.  `<details>` handles the
   open/close toggle natively.  The ::marker triangle is replaced with
   a rotated ▾ chevron so the hit area reads like a button, not a list. */
.mobile-drawer__group {
    display: block;
}
.mobile-drawer__group > summary {
    list-style: none;
    cursor: pointer;
    position: relative;
}
.mobile-drawer__group > summary::-webkit-details-marker {
    display: none;
}
.mobile-drawer__link--group::after {
    content: "▾";
    position: absolute;
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--color-text-muted);
    transition: transform 0.15s ease;
}
.mobile-drawer__group[open] > .mobile-drawer__link--group::after {
    transform: translateY(-50%) rotate(180deg);
}
.mobile-drawer__link--nested {
    padding-left: 32px;
    font-size: var(--text-label);
    color: var(--color-text-secondary);
}
.mobile-drawer__footer {
    border-top: 0.5px solid var(--color-border-subtle);
    padding: 12px 16px;
    font-size: var(--text-label);
    color: var(--color-text-muted);
}

/* ── Pagination ─────────────────────────────────────────────── */
.page-nav {
    border-top: 0.5px solid var(--color-border-subtle);
    padding-top: var(--space-4);
}
.page-nav__link {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    font-size: var(--text-label);
    color: var(--color-text-secondary);
    background: transparent;
    border: 0.5px solid var(--color-border-default);
    border-radius: var(--radius-md);
    text-decoration: none;
    /* Hover background is a per-theme var() — see motion rule. */
}
.page-nav__link:hover {
    background: var(--color-bg-card-hover);
    color: var(--color-text-primary);
}
.page-nav__current {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    font-size: var(--text-label);
    color: #ffffff;
    background: var(--color-accent-gradient);
    border-radius: var(--radius-md);
    font-weight: var(--weight-medium);
}

/* ── HTMX spinner top bar ───────────────────────────────────── */
.htmx-progress-bar {
    height: 2px;
    background: var(--color-accent-gradient);
    animation: htmx-progress 1.2s infinite ease-in-out;
}

/* ── Calendar cells (used by core/calendar.html + calendar.js) ─ */
.calendar-cell {
    min-height: 96px;
    background: var(--color-bg-card);
    border: 0.5px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-2);
}
.calendar-cell--other-month { opacity: 0.5; }
.calendar-cell--today {
    outline: 1px solid var(--color-accent-indigo);
    outline-offset: -1px;
}
.calendar-cell.is-drop-target {
    outline: 2px solid var(--color-accent-indigo);
    outline-offset: -2px;
}

.calendar-post {
    display: block;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
    font-size: 11px;
    color: var(--color-text-secondary);
    background: var(--color-bg-card-hover);
    border: 0.5px solid var(--color-border-subtle);
    text-decoration: none;
}
.calendar-post[data-status="PENDING"] {
    color: var(--color-status-info);
    background: var(--color-status-info-bg);
    border-color: var(--color-status-info-border);
}
.calendar-post[data-status="IN_FLIGHT"] {
    color: var(--color-status-warning);
    background: var(--color-status-warning-bg);
    border-color: var(--color-status-warning-border);
}
.calendar-post[data-status="SUCCEEDED"] {
    color: var(--color-status-success);
    background: var(--color-status-success-bg);
    border-color: var(--color-status-success-border);
}
.calendar-post[data-status="FAILED"] {
    color: var(--color-status-danger);
    background: var(--color-status-danger-bg);
    border-color: var(--color-status-danger-border);
}
.calendar-post[data-status="CANCELED"] {
    color: var(--color-text-muted);
    background: var(--color-bg-card);
    border-color: var(--color-border-subtle);
}

/* Hashtag / chip suggestion (content/variant_form.html) */
.chip-suggestion {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    font-size: var(--text-label);
    color: var(--color-text-secondary);
    background: var(--color-bg-card);
    border: 0.5px solid var(--color-border-default);
    border-radius: 20px;
    cursor: pointer;
    font-family: var(--font-body);
    /* Hover swaps to per-theme accent backgrounds — never transition. */
}
.chip-suggestion:hover {
    background: var(--color-accent-indigo-bg);
    border-color: var(--color-accent-indigo-border);
    color: var(--color-text-accent);
}

/* ── Tabs ─────────────────────────────────────────────────────
   Generic tab pattern wired up by app/static/js/tabs.js via
   ``data-tab-root`` / ``data-tab-target``.  Buttons look like
   subnav pills but with an underline accent when active, so the
   pattern reads as "in-surface tabs" distinct from sub-nav pills. */
.tabs {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.tabs__list {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 0.5px solid var(--color-border-subtle);
}
.tabs__button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    color: var(--color-text-muted);
    font-family: inherit;
    font-size: var(--text-label);
    font-weight: var(--weight-medium);
    cursor: pointer;
    /* color + border-color are per-theme — see motion rule. */
}
.tabs__button:hover {
    color: var(--color-text-primary);
}
.tabs__button--active {
    color: var(--color-text-primary);
    border-bottom-color: var(--color-accent-indigo);
}
.tabs__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    font-family: var(--font-mono);
    font-size: 11px;
    border-radius: 9px;
    background: var(--color-bg-card-hover);
    color: var(--color-text-muted);
    border: 0.5px solid var(--color-border-subtle);
}
.tabs__button--active .tabs__count {
    background: var(--color-accent-indigo-bg);
    color: var(--color-text-accent);
    border-color: var(--color-accent-indigo-border);
}
.tabs__panel {
    display: none;
}
.tabs__panel--active {
    display: block;
}

/* ── Modals / overlays ────────────────────────────────────────
   Per docs/conventions.md § "Modals and overlays".  Built on the
   native <dialog> element — showModal()/close() + focus trap +
   Escape handling come from the browser; app/static/js/modal.js
   adds openModal() and backdrop-click dismissal.

   Desktop: centered card, ~520px wide.
   Mobile (≤640px): bottom sheet, full width, rounded top only,
   height capped by dvh so iOS address bar doesn't clip it. */
.modal {
    padding: 0;
    border: none;
    background: transparent;
    max-width: 540px;
    width: calc(100% - 32px);
    max-height: calc(100dvh - 64px);
    border-radius: var(--radius-lg);
    color: var(--color-text-primary);
    /* Explicit centering: some global styles (Tailwind preflight,
       our own resets) can clobber the UA's default margin:auto on
       <dialog>, leaving the modal parked at the top-left. Pin it
       ourselves so the behaviour is stable regardless. */
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    margin: 0;
}
.modal::backdrop {
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(2px);
}
.modal__content {
    display: flex;
    flex-direction: column;
    max-height: calc(100dvh - 64px);
    background: var(--color-bg-card);
    border: 0.5px solid var(--color-border-default);
    border-radius: var(--radius-lg);
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.45);
    overflow: hidden;
}
.modal__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px 12px 20px;
    border-bottom: 0.5px solid var(--color-border-subtle);
}
.modal__title {
    font-size: var(--text-section-title);
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
    margin: 0;
}
.modal__subtitle {
    margin: 4px 0 0 0;
    font-size: var(--text-label);
    color: var(--color-text-muted);
}
.modal__close {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    min-width: 32px;
    min-height: 32px;
    border: 0.5px solid transparent;
    background: transparent;
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    /* All three properties are per-theme — see motion rule. */
}
.modal__close:hover {
    background: var(--color-bg-card-hover);
    border-color: var(--color-border-subtle);
    color: var(--color-text-primary);
}
.modal__body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 12px 20px;
}
.modal__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 20px 16px 20px;
    border-top: 0.5px solid var(--color-border-subtle);
}

/* Mobile: bottom sheet.  Reset the desktop centering transform so
   the dialog pins to the bottom edge instead of floating mid-screen. */
@media (max-width: 640px) {
    .modal {
        position: fixed;
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        transform: none;
        margin: 0;
        width: 100%;
        max-width: 100%;
        max-height: 90dvh;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    }
    .modal__content {
        max-height: 90dvh;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        border-bottom: none;
    }
    .modal__close {
        width: 44px;
        height: 44px;
        min-width: 44px;
        min-height: 44px;
        font-size: 26px;
    }
}

/* ── Trend picker — concrete modal body used by
   create/_trend_picker_modal.html ──────────────────────────── */
.trend-picker__list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.trend-picker__row {
    margin: 0;
}
.trend-picker__form {
    margin: 0;
}
.trend-picker__button {
    width: 100%;
    min-height: 56px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
    background: transparent;
    border: 0.5px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    color: var(--color-text-primary);
    text-align: left;
    cursor: pointer;
    font-family: inherit;
    /* Per-theme background + border-color — see motion rule. */
}
.trend-picker__button:hover {
    background: var(--color-bg-card-hover);
    border-color: var(--color-border-default);
}
.trend-picker__main {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    flex: 1 1 auto;
}
.trend-picker__title {
    font-size: var(--text-body);
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
    line-height: 1.35;
}
.trend-picker__summary {
    font-size: var(--text-label);
    color: var(--color-text-muted);
    line-height: 1.4;
}
.trend-picker__meta {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}
.trend-picker__momentum {
    font-family: var(--font-mono);
    font-size: var(--text-label);
    color: var(--color-text-muted);
}
.trend-picker__empty {
    padding: 24px 8px;
    text-align: center;
}
@media (max-width: 640px) {
    .trend-picker__button {
        min-height: 64px;
        padding: 14px 12px;
    }
}

/* ── Workspaces grid — the "doors" on the Creation Studio hub.
   Four visual anchors into Posts / Library / Editor / Campaigns,
   distinct from the compact subnav pills (which are persistent
   navigation on every Create-section page).  Tile cards read as
   a welcome mat on the hub specifically. */
.workspaces {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
}
@media (max-width: 900px) {
    .workspaces {
        grid-template-columns: repeat(2, 1fr);
    }
}
.workspace-tile {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-height: 96px;
    padding: 16px 18px;
    background: var(--color-bg-card);
    border: 0.5px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    color: var(--color-text-primary);
    text-decoration: none;
    /* transform is theme-invariant; background + border-color are per-theme
       and would freeze paint on theme swap if transitioned. */
    transition: transform 0.1s ease;
}
.workspace-tile:hover {
    background: var(--color-bg-card-hover);
    border-color: var(--color-border-default);
}
.workspace-tile:active {
    transform: scale(0.99);
}
.workspace-tile--current {
    border-color: var(--color-accent-indigo-border);
    background: var(--color-accent-indigo-bg);
}
.workspace-tile__label {
    font-size: var(--text-section-title);
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
}
.workspace-tile__hint {
    font-size: var(--text-label);
    color: var(--color-text-muted);
    margin-top: 6px;
}
.workspace-tile--current .workspace-tile__label {
    color: var(--color-text-accent);
}

/* Editor subnav wrapper — re-introduces the bounded width + side
   padding that the `page-shell--bleed` modifier drops, so the
   Creation Studio pill bar renders in the same place it does on
   the hub instead of hard against the viewport edge. */
.editor-subnav-wrap {
    max-width: 108rem;
    margin: 0 auto;
    padding: var(--space-6) var(--space-6) 0 var(--space-6);
}

/* ── Editor page header (Django shell around the SPA) ────────
   The media editor's `.page-shell--bleed` drops the standard
   outer padding so the SPA canvas can go edge-to-edge; this
   header lives above that bleed region and re-introduces a
   bounded max-width + padding so the breadcrumb and title line
   up with the rest of the app's page headings. */
.editor-page-header {
    max-width: 108rem;
    margin: 0 auto;
    padding: var(--space-6) var(--space-6) var(--space-4) var(--space-6);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.editor-page-header__left {
    min-width: 0;
    flex: 1 1 auto;
}
.editor-page-header__right {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
}

/* ── Composer (variant edit page) ────────────────────────────
   Mirrors a Facebook/LinkedIn-style feed composer.  The outer
   `.composer` sits inside a `.card`.  Zones from top to bottom:
     author strip → textarea → media strip → hashtags → meta → actions. */
.composer {
    display: flex;
    flex-direction: column;
    gap: 18px;
}
.composer__author {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-bottom: 14px;
    border-bottom: 0.5px solid var(--color-border-subtle);
}
.composer__author-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
}
.composer__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: #ffffff;
    font-weight: var(--weight-medium);
    font-size: 16px;
    flex: 0 0 auto;
}
.composer__avatar--sm {
    width: 32px;
    height: 32px;
    font-size: 14px;
}
.composer__author-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.composer__name {
    font-size: var(--text-body);
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
}
.composer__chip {
    display: inline-block;
    align-self: flex-start;
    padding: 2px 8px;
    font-size: 11px;
    color: var(--color-text-muted);
    background: var(--color-bg-card-hover);
    border: 0.5px solid var(--color-border-subtle);
    border-radius: 20px;
}
.composer__body {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.composer__textarea {
    width: 100%;
    padding: 12px 14px;
    background: var(--color-bg-input);
    border: 0.5px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    outline: none;
    resize: vertical;
    font-family: var(--font-body);
    font-size: 17px;
    line-height: 1.5;
    color: var(--color-text-primary);
    min-height: 180px;
    /* border-color transitioned for the focus ring (same theme, state
       change only — safe).  background is a per-theme var(): never
       transition it. */
    transition: border-color 0.15s ease;
}
.composer__textarea::placeholder {
    color: var(--color-text-muted);
    font-weight: var(--weight-regular);
}
.composer__textarea:hover {
    border-color: var(--color-border-default);
}
.composer__textarea:focus {
    border-color: var(--color-accent-indigo);
    background: var(--color-bg-card);
}
.composer__counter-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-size: var(--text-label);
}
.composer__media {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.composer__media-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.composer__media-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.composer__media-tile {
    position: relative;
    width: 88px;
    height: 88px;
    border-radius: var(--radius-md);
    overflow: hidden;
    border: 0.5px solid var(--color-border-subtle);
    background: var(--color-bg-card-hover);
    flex: 0 0 auto;
}
.composer__media-thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.composer__media-thumb--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-muted);
}
.composer__media-remove {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 20px;
    height: 20px;
    padding: 0;
    background: rgba(0, 0, 0, 0.55);
    color: #ffffff;
    border: none;
    border-radius: 50%;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.composer__media-remove:hover {
    background: rgba(0, 0, 0, 0.75);
}
.composer__media-add {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    width: 88px;
    height: 88px;
    border: 0.5px dashed var(--color-border-default);
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-text-muted);
    text-decoration: none;
    text-align: center;
    font-size: 10px;
    /* All three properties are per-theme — see motion rule. */
    flex: 0 0 auto;
}
.composer__media-add:hover {
    border-color: var(--color-accent-indigo-border);
    color: var(--color-text-accent);
    background: var(--color-accent-indigo-bg);
}
/* ADR-0020 — AI generate variant of the media-add tile.  Purple/indigo
   tint + gradient hover so it reads as "AI" rather than "upload". */
.composer__media-add--ai {
    border-style: solid;
    border-color: var(--color-accent-indigo-border);
    color: var(--color-text-accent);
    background: var(--color-accent-indigo-bg);
    font-family: inherit;
    cursor: pointer;
}
.composer__media-add--ai:hover {
    background: var(--color-accent-cyan-bg);
    border-color: var(--color-accent-cyan-border);
    color: var(--color-accent-cyan-text);
}

/* ADR-0020 — small "AI" corner ribbon for generated MediaAssets.  Used
   on the media library, the variant composer's inline thumbnails, and
   the editor SPA's asset picker.  Placed absolutely so it sits over
   the thumbnail corner; the parent must be position:relative. */
.ai-ribbon {
    position: absolute;
    top: 6px;
    right: 6px;
    padding: 1px 7px;
    background: var(--color-accent-indigo);
    color: #ffffff;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    border-radius: 999px;
    line-height: 1.4;
    pointer-events: none;
    z-index: 2;
}
.composer__media-add-plus {
    font-size: 22px;
    line-height: 1;
}
.composer__media-add-label {
    padding: 0 6px;
    line-height: 1.2;
}
.composer__hashtags {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.composer__meta {
    border-top: 0.5px solid var(--color-border-subtle);
    padding-top: 12px;
}
.composer__meta-summary {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    list-style: none;
    padding: 4px 0;
}
.composer__meta-summary::-webkit-details-marker {
    display: none;
}
.composer__meta-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding-top: 10px;
}
.composer__actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-top: 14px;
    border-top: 0.5px solid var(--color-border-subtle);
}

/* ── Post preview card (sidebar) ─────────────────────────────
   Live preview that mirrors a Facebook feed card.  Wired by
   inline JS in `variant_form.html` which updates `#preview-body`
   + `#preview-hashtags` on every keystroke. */
.post-preview {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.post-preview__frame {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.post-preview__meta {
    display: flex;
    justify-content: flex-end;
}
.post-preview__platform {
    font-size: 11px;
    color: var(--color-text-muted);
    letter-spacing: 0.4px;
    text-transform: uppercase;
}
.post-preview__card {
    background: var(--color-bg-card);
    border: 0.5px solid var(--color-border-default);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
.post-preview__header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px 8px 14px;
}
.post-preview__header-meta {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.post-preview__name {
    font-size: var(--text-body);
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
}
.post-preview__time {
    font-size: 11px;
    color: var(--color-text-muted);
}
.post-preview__body-wrap {
    padding: 0 14px 10px 14px;
}
.post-preview__placeholder {
    font-size: var(--text-label);
    color: var(--color-text-muted);
    font-style: italic;
    margin: 0;
}
.post-preview__body {
    font-size: var(--text-body);
    line-height: 1.45;
    color: var(--color-text-primary);
    white-space: pre-wrap;
    word-break: break-word;
    margin: 0;
}
.post-preview__more {
    color: var(--color-text-muted);
    cursor: pointer;
}
.post-preview__hashtags {
    font-size: var(--text-label);
    color: var(--color-accent-cyan-text);
    margin: 6px 0 0 0;
    word-break: break-word;
}
.post-preview__media {
    position: relative;
    border-top: 0.5px solid var(--color-border-subtle);
    border-bottom: 0.5px solid var(--color-border-subtle);
    background: var(--color-bg-card-hover);
}
.post-preview__media-img {
    width: 100%;
    max-height: 260px;
    object-fit: cover;
    display: block;
}
.post-preview__media-img--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 140px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--color-text-muted);
}
.post-preview__media-more {
    position: absolute;
    right: 8px;
    bottom: 8px;
    padding: 2px 8px;
    background: rgba(0, 0, 0, 0.55);
    color: #ffffff;
    border-radius: 12px;
    font-size: 11px;
}
.post-preview__engagement {
    display: flex;
    align-items: center;
    justify-content: space-around;
    padding: 8px 10px;
    font-size: var(--text-label);
    color: var(--color-text-muted);
}

/* ── Per-platform preview skins (#195 §1) ─────────────────────── */
/* One component, four platform finishes.  Everything routes through  */
/* design tokens except each platform's one brand-colour literal      */
/* (the whole point is to *feel* like the platform).                  */

/* LinkedIn — white card, "· 1st" degree pill, professional rail. */
.post-preview--linkedin .post-preview__degree {
    color: var(--color-text-muted);
    font-weight: 400;
}
.post-preview--linkedin .post-preview__hashtags {
    color: #0a66c2;
}
.post-preview__engagement--linkedin {
    border-top: 0.5px solid var(--color-border-subtle);
}
.post-preview--linkedin .post-preview__media-img {
    aspect-ratio: 1.91 / 1;
    max-height: none;
}

/* Facebook — slightly tinted feed surround. */
.post-preview--facebook .post-preview__card {
    background: var(--color-bg-base);
}
.post-preview--facebook .post-preview__media-img {
    aspect-ratio: 1.91 / 1;
    max-height: none;
}

/* Instagram — image-first square, caption below, blue hashtags. */
.post-preview__header--ig {
    justify-content: flex-start;
}
.post-preview__header--ig .post-preview__name {
    flex: 1;
    font-weight: var(--weight-medium);
}
.post-preview__avatar--ring {
    box-shadow: 0 0 0 2px var(--color-bg-card), 0 0 0 3.5px #c13584;
}
.post-preview__ig-dots {
    color: var(--color-text-muted);
    letter-spacing: 1px;
}
.post-preview--instagram .post-preview__media-img,
.post-preview__media--ig-empty {
    aspect-ratio: 1 / 1;
    max-height: none;
    width: 100%;
}
.post-preview__media--ig-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 16px;
    font-size: var(--text-label);
    color: var(--color-text-muted);
    background: var(--color-bg-card-hover);
}
.post-preview__ig-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 8px 14px 2px 14px;
    font-size: 18px;
    color: var(--color-text-primary);
}
.post-preview__ig-actions-spacer {
    flex: 1;
}
.post-preview__caption {
    display: block;
}
.post-preview__ig-user,
.post-preview__tt-user {
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
    margin-right: 6px;
}
.post-preview--instagram .post-preview__hashtags {
    color: #1d4ed8;
}

/* TikTok — vertical 9:16 frame, overlay caption, side rail. */
.post-preview__tt-frame {
    position: relative;
    aspect-ratio: 9 / 16;
    max-height: 420px;
    background: #000000;
    display: flex;
}
.post-preview--tiktok .post-preview__media,
.post-preview__media--tt-empty {
    position: absolute;
    inset: 0;
    border: 0;
    background: #0b0b0b;
}
.post-preview--tiktok .post-preview__media-img {
    width: 100%;
    height: 100%;
    max-height: none;
    aspect-ratio: 9 / 16;
    object-fit: cover;
}
.post-preview__media--tt-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #d4d4d4;
    font-size: var(--text-label);
}
.post-preview__tt-rail {
    position: absolute;
    right: 8px;
    bottom: 64px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    font-size: 20px;
    color: #ffffff;
    z-index: 2;
}
.post-preview__tt-overlay {
    position: absolute;
    left: 0;
    right: 44px;
    bottom: 0;
    padding: 12px 14px;
    z-index: 2;
    background: linear-gradient(transparent, rgba(0, 0, 0, 0.55));
}
.post-preview__tt-user {
    color: #ffffff;
    margin-bottom: 4px;
}
.post-preview__tt-caption .post-preview__body,
.post-preview__tt-caption .post-preview__placeholder {
    color: #f5f5f5;
}
.post-preview__tt-caption .post-preview__hashtags {
    color: #7dd3fc;
}

/* ── Impersonation banner (ADR-0030 PR 3) ─────────────────────── */
/* Loud red chrome that signals "you are right now writing as a    */
/* tenant".  Deliberately bypasses the design-token system so it   */
/* doesn't visually blend into a customer's brand palette — this   */
/* banner is operator chrome, not tenant chrome.  Undismissable.   */
.impersonation-banner {
    background: #b91c1c;
    color: #ffffff;
    padding: 0.6rem 1rem;
    display: flex;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    font-size: var(--text-meta);
    font-weight: 600;
    border-bottom: 2px solid #7f1d1d;
}
.impersonation-banner__exit {
    background: #ffffff;
    color: #b91c1c;
    border: none;
    padding: 0.35rem 0.85rem;
    border-radius: 4px;
    font-weight: 600;
    cursor: pointer;
    font-size: var(--text-meta);
}
.impersonation-banner__exit:hover {
    background: #fee2e2;
}

/* ============================================================
   REDESIGN ATOMS — warm "Story-spine" shared components
   ------------------------------------------------------------
   Ported from design/design_handoff_social_upkeep_app/su-app.css
   per docs/roadmap/redesign-social-upkeep.md Phase 0.  Reads only
   tokens (short aliases defined in tokens.css REDESIGN SHIM).
   Guardrail: NO transitions on theme-swapped background/color/
   border-color — only transform/filter/opacity (and the
   explicitly-allowed .sp-input:focus border-color, mirroring
   .input/.select).
   ============================================================ */

/* ── Display type + in-voice prose ──────────────────────────── */
.st-eyebrow {
  font-size: 11.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent);
}
[data-theme="executive"] .st-eyebrow { color: var(--accent-2); letter-spacing: .16em; }
.st-display {
  font-family: var(--font-display); font-weight: var(--disp-weight);
  letter-spacing: var(--disp-spacing); text-transform: var(--disp-transform);
  line-height: 1.06; color: var(--ink); font-size: 38px; max-width: 20ch;
}
.st-display.sm { font-size: 32px; max-width: 24ch; }
[data-theme="athlete"] .st-display.sm { font-size: 36px; }
[data-theme="executive"] .st-display { font-size: 40px; line-height: 1.1; }
.st-quote { font-style: italic; }
[data-theme="executive"] .st-quote { font-family: var(--font-display); }
.st-muted { font-size: 12px; color: var(--ink-3); }
/* Small uppercase section label (referenced by the settings hub + the
   composer "Also publish to" row).  Ported from the prototype atoms —
   missed in the initial Phase-0 pass. */
.side-label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.st-refine {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 700; color: var(--accent); cursor: pointer;
  white-space: nowrap; border: none; background: transparent;
  font-family: var(--font-body); padding: 0;
}
[data-theme="executive"] .st-refine { color: var(--accent-2); }
.st-refine svg { opacity: .8; }

/* ── Drafted-post card (the "in your voice" sample) ─────────── */
.st-post {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 18px 20px;
}
.st-post-h { display: flex; align-items: center; gap: 11px; margin-bottom: 12px; }
.st-post-h b { display: block; font-size: 14px; color: var(--ink); }
.st-post p { font-size: 15px; color: var(--ink); line-height: 1.6; }
.st-post-f {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--border);
}
.st-flourish {
  margin-left: auto; display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  color: var(--accent-2); background: var(--accent-2-soft); padding: 5px 10px; border-radius: 999px;
}
.st-cta {
  display: inline-flex; align-items: center; gap: 8px; border: none;
  background: var(--accent); color: var(--accent-ink); font-family: var(--font-body);
  font-size: 13px; font-weight: 700; padding: 10px 16px; border-radius: var(--radius-sm);
  cursor: pointer; transition: filter .15s, transform .1s;
}
.st-cta:hover { filter: brightness(1.05); }
.st-cta:active { transform: scale(.98); }
[data-theme="athlete"] .st-cta { text-transform: uppercase; letter-spacing: .03em; box-shadow: 0 0 22px -8px var(--accent); }

/* ── Nudge (progress as a human sentence, never a percentage) ─ */
.st-nudge {
  display: flex; align-items: center; gap: 11px; margin-top: 26px;
  padding: 15px 18px; border-radius: var(--radius); background: var(--accent-2-soft);
  color: var(--ink); font-size: 13.5px; font-weight: 500; line-height: 1.4;
}
.st-nudge-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--accent-2);
  flex-shrink: 0; box-shadow: 0 0 0 4px var(--accent-2-soft);
}

/* ── Spoke head (shared across Identity spokes) ─────────────── */
.sp { display: flex; flex-direction: column; padding: 34px 56px 52px; }
.sp-head { margin-bottom: 30px; }
.sp-back {
  display: inline-flex; align-items: center; gap: 6px; border: none; background: transparent;
  cursor: pointer; font-family: var(--font-body); font-size: 12px; font-weight: 600;
  color: var(--ink-2); padding: 0; margin-bottom: 16px;
}
.sp-back:hover { color: var(--accent); }
.sp-back svg { opacity: .7; }
.sp-head .st-eyebrow { display: block; }
.sp-head .st-display { margin-top: 10px; }
.sp-lede {
  font-size: 15px; color: var(--ink-2); line-height: 1.55; margin-top: 13px;
  max-width: 58ch; text-wrap: pretty;
}

/* ── Edit-in-place block (view + edit are the same surface) ─── */
.sp-beats { display: flex; flex-direction: column; gap: 4px; }
.sp-beat { padding: 18px 0; border-bottom: 1px solid var(--border); }
.sp-beat:first-child { padding-top: 4px; }
.sp-beat.editing { padding-bottom: 20px; }
.sp-lab {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  white-space: nowrap; font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 9px;
}
.sp-line {
  font-size: 21px; color: var(--ink); line-height: 1.4; font-family: var(--font-display);
  font-weight: var(--disp-weight); letter-spacing: var(--disp-spacing);
  text-wrap: pretty; max-width: 52ch;
}
[data-theme="athlete"] .sp-line { font-size: 23px; }
.sp-line.st-quote { font-weight: 400; }
.sp-body { font-size: 16px; color: var(--ink); line-height: 1.6; text-wrap: pretty; max-width: 58ch; }
.sp-hint { font-size: 12.5px; color: var(--ink-3); line-height: 1.5; margin-top: 9px; max-width: 56ch; }
.sp-edit { display: flex; flex-direction: column; gap: 11px; }
.sp-input {
  width: 100%; font-family: var(--font-body); font-size: 16px; line-height: 1.55;
  color: var(--ink); background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: var(--radius-sm); padding: 12px 14px; resize: vertical;
  transition: border-color .15s, box-shadow .15s; outline: none;
}
.sp-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.sp-edit-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.sp-edit-hint { font-size: 12.5px; color: var(--ink-3); line-height: 1.45; flex: 1; min-width: 200px; }
.sp-edit-actions { display: flex; gap: 8px; flex-shrink: 0; }
.sp-btn {
  font-family: var(--font-body); font-size: 12.5px; font-weight: 700; padding: 8px 16px;
  border-radius: var(--radius-sm); border: none; cursor: pointer;
  background: var(--accent); color: var(--accent-ink); transition: filter .15s, transform .1s;
}
.sp-btn:hover { filter: brightness(1.05); }
.sp-btn:active { transform: scale(.97); }
[data-theme="athlete"] .sp-btn { text-transform: uppercase; letter-spacing: .03em; }
.sp-btn.ghost { background: var(--surface); color: var(--ink); border: 1px solid var(--border-2); }
.sp-btn.ghost:hover { background: var(--surface-2); filter: none; }
.sp-btn.sm { padding: 7px 13px; font-size: 11.5px; }

/* ── Tie-back card (how a setting shapes real output) ───────── */
.sp-tieback {
  margin-top: 30px; padding: 20px 22px; border-radius: var(--radius-lg);
  background: var(--surface-2); border: 1px solid var(--border);
}
.sp-tieback-lab {
  display: inline-flex; align-items: center; gap: 7px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent-2); margin-bottom: 11px;
}
.sp-tieback-body { font-size: 15px; color: var(--ink); line-height: 1.6; text-wrap: pretty; }
.sp-tieback-lab2 { font-size: 13px; font-weight: 600; color: var(--ink-2); margin-bottom: 13px; }
.sp-split { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.sp-split-c {
  font-size: 14px; color: var(--ink); line-height: 1.55; padding: 14px 16px;
  border-radius: var(--radius); background: var(--surface); border: 1px solid var(--border);
}
.sp-split-name {
  display: block; font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 6px;
}
@media (max-width: 680px) { .sp-split { grid-template-columns: 1fr; } }

/* ── Removable chips ────────────────────────────────────────── */
.sp-tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 18px; }
.sp-tag {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font-family: var(--font-body); font-size: 12px; font-weight: 600; color: var(--ink-2);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px;
  padding: 5px 11px; cursor: pointer;
}
.sp-tag:hover { border-color: var(--accent); color: var(--accent); }
.sp-tag-x { font-size: 13px; opacity: .6; line-height: 1; }
.sp-tag.add { color: var(--accent); border-style: dashed; border-color: var(--border-2); }
.sp-tag.add:hover { border-color: var(--accent); background: var(--accent-soft); }
.sp-tag.add svg { width: 12px; height: 12px; }

/* ── Add-row + coming-next ──────────────────────────────────── */
.sp-add {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left; cursor: pointer;
  background: var(--surface-2); border: 1.5px dashed var(--border-2); border-radius: var(--radius-lg);
  padding: 18px 22px; font-family: var(--font-body);
}
.sp-add:hover { border-color: var(--accent); background: var(--accent-soft); }
.sp-add-icon {
  width: 40px; height: 40px; border-radius: 50%; background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center; flex-shrink: 0;
}
.sp-add b { display: block; font-size: 15px; color: var(--ink); }
.sp-add-note { font-size: 12.5px; color: var(--ink-2); }
.sp-next {
  display: flex; align-items: center; gap: 11px; padding: 18px 20px; border-radius: var(--radius-lg);
  background: var(--surface-2); border: 1px dashed var(--border-2); font-size: 14px; color: var(--ink-2);
}
.sp-next b { color: var(--ink); }
.sp-next-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent-2); flex-shrink: 0; }

/* ════════════════════════════════════════════════════════════════════
   DASHBOARD (Home) — the warm "weekly pulse" landing page.
   Ported verbatim from design_handoff_with_dashboard (the `.dash-*`
   block) with three local adjustments noted inline.  Reads only design
   tokens, so it reskins across all four themes with no per-theme forks.
   ════════════════════════════════════════════════════════════════════ */

/* `.dash` drops the prototype's own padding (`.page-shell` already pads)
   and caps a narrower reading column than the wide app shell — the pulse
   reads better centred than full-bleed. */
.dash { display: flex; flex-direction: column; max-width: 1180px; margin: 0 auto; }
.dash-head { display: flex; align-items: center; gap: 22px; margin-bottom: 28px; }
.dash-portrait { flex-shrink: 0; box-shadow: 0 10px 26px -12px rgba(0,0,0,.45); }
[data-theme="athlete"] .dash-portrait { box-shadow: 0 0 0 2px var(--accent), 0 10px 26px -12px rgba(0,0,0,.5); }
.dash-head-txt { min-width: 0; }
.dash-head-txt .st-display { margin-top: 9px; }
.dash-head-txt .sp-lede { margin-top: 10px; }

/* hero — suggestion feature card (accent-2 wash, like the section pages) */
.dash-hero { background: var(--accent-2-soft); border: 1px solid transparent; border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 28px 30px; margin-bottom: 18px; position: relative; overflow: hidden; }
.dash-hero::after { content: ""; position: absolute; top: 0; right: 0; width: 300px; height: 100%; background: radial-gradient(circle at 100% 0, var(--accent-soft), transparent 70%); pointer-events: none; }
.dash-hero-top { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 15px; position: relative; z-index: 1; }
.dash-kicker { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-2); }
.dash-hero-title { font-family: var(--font-display); font-weight: var(--disp-weight); font-size: 25px; letter-spacing: var(--disp-spacing); text-transform: var(--disp-transform); color: var(--ink); line-height: 1.2; max-width: 28ch; position: relative; z-index: 1; text-wrap: pretty; margin-bottom: 2px; }
[data-theme="athlete"] .dash-hero-title { font-size: 29px; }
.dash-hero-body { font-size: 14.5px; color: var(--ink-2); line-height: 1.55; margin: 11px 0 0; max-width: 58ch; position: relative; z-index: 1; text-wrap: pretty; }
.dash-angle { margin: 16px 0 18px; background: var(--surface); border-radius: var(--radius); padding: 15px 18px; position: relative; z-index: 1; box-shadow: var(--shadow); }
.dash-angle-lab { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
[data-theme="executive"] .dash-angle-lab { color: var(--accent-2); }
.dash-angle p { font-size: 14.5px; color: var(--ink); line-height: 1.6; text-wrap: pretty; max-width: 62ch; }
/* async-load state: a soft pulsing skeleton while the LLM angle fills.
   Animates opacity only (never a per-theme token property) so a
   data-theme swap mid-pulse can't freeze a half-painted colour. */
.dash-angle--loading { min-height: 52px; }
.dash-angle__skel { height: 11px; border-radius: 999px; background: var(--border-2); animation: dash-angle-pulse 1.1s ease-in-out infinite; }
.dash-angle__skel + .dash-angle__skel { margin-top: 8px; }
.dash-angle__skel.short { width: 62%; }
@keyframes dash-angle-pulse { 0%, 100% { opacity: .45; } 50% { opacity: .85; } }
.dash-hero-actions { display: flex; align-items: center; gap: 18px; position: relative; z-index: 1; }
.dash-skip { font-family: var(--font-body); font-size: 12.5px; font-weight: 600; color: var(--ink-3); background: none; border: none; cursor: pointer; transition: color .15s; }
.dash-skip:hover { color: var(--ink-2); }
.dash-deep { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 700; color: var(--ink-3); cursor: pointer; white-space: nowrap; transition: color .15s; text-decoration: none; }
.dash-deep:hover { color: var(--accent); }
.dash-deep svg { width: 13px; height: 13px; opacity: .8; }

.dash-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; align-items: start; }
.dash-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 22px 24px; }
.dash-card-h { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 17px; }
.dash-card-lab { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); white-space: nowrap; }
.dash-list { display: flex; flex-direction: column; gap: 15px; }
.dash-empty { font-size: 13.5px; color: var(--ink-3); line-height: 1.5; }

.dash-draft { display: flex; gap: 14px; padding-bottom: 15px; border-bottom: 1px solid var(--border); text-decoration: none; }
.dash-draft:last-child { padding-bottom: 0; border-bottom: none; }
.dash-draft-rail { width: 3px; border-radius: 3px; flex-shrink: 0; background: var(--border-2); }
.dash-draft.ready .dash-draft-rail { background: var(--ok); }
.dash-draft.draft .dash-draft-rail { background: var(--accent-2); }
.dash-draft-main { min-width: 0; flex: 1; }
.dash-draft-t { font-family: var(--font-display); font-weight: var(--disp-weight); letter-spacing: var(--disp-spacing); font-size: 16px; color: var(--ink); line-height: 1.35; margin-bottom: 10px; text-wrap: pretty; }
[data-theme="athlete"] .dash-draft-t { font-size: 18px; }
.dash-draft-m { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 12px; color: var(--ink-3); }

.dash-signal { display: flex; gap: 13px; align-items: flex-start; padding-bottom: 15px; border-bottom: 1px solid var(--border); }
.dash-signal:last-child { padding-bottom: 0; border-bottom: none; }
/* base dot carries a neutral fill so kinds beyond competitor/keyword
   (news, topic, hashtag…) still render a visible marker. */
.dash-sigdot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 7px; background: var(--ink-3); }
.dash-sigdot.competitor { background: var(--accent-2); box-shadow: 0 0 0 4px var(--accent-2-soft); }
.dash-sigdot.keyword { background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.dash-signal-main { min-width: 0; flex: 1; }
.dash-signal-t { font-size: 14px; color: var(--ink); line-height: 1.5; text-wrap: pretty; margin-bottom: 7px; text-decoration: none; }
.dash-signal-foot { display: flex; align-items: center; gap: 10px; }
.dash-signal-tag { font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-3); }
.dash-signal-when { font-size: 11px; color: var(--ink-3); }
.dash-signal-when::before { content: "·"; margin-right: 10px; }

.dash-quota { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 22px 24px; }
.dash-quota-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.dash-quota-note { font-size: 12.5px; color: var(--ok); font-weight: 600; }
.dash-quota-line { font-size: 14.5px; color: var(--ink-2); margin-bottom: 14px; }
.dash-quota-line b { color: var(--ink); font-weight: 700; }
.dash-bar { height: 7px; border-radius: 999px; background: var(--bg-2); overflow: hidden; }
.dash-bar > span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); }

.dash-foot { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-top: 18px; padding: 20px 24px; border-radius: var(--radius-lg); background: var(--surface-2); border: 1px solid var(--border); flex-wrap: wrap; }
.dash-foot-txt { min-width: 0; }
.dash-foot-lab { display: inline-flex; align-items: center; gap: 7px; font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-2); margin-bottom: 8px; }
.dash-foot-txt p { font-size: 14px; color: var(--ink); line-height: 1.5; text-wrap: pretty; max-width: 54ch; }
.dash-foot .sp-btn { flex-shrink: 0; display: inline-flex; align-items: center; gap: 7px; }

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