/* DWOC Social Media — design system.
 * Tokens + primitives follow the handoff spec (Linear/Raycast dark,
 * single indigo accent, Geist typography). Legacy `.sp-*` rules further
 * down inherit the new palette via the aliases in this :root. */

:root {
    /* Surfaces */
    --bg: #0a0a0b;
    --surface: #121214;
    /* --surface-1 is an alias for --surface — kept because ~8 rules in
       this file already write `var(--surface-1)`. Without the alias
       those rules resolve to `transparent`, which silently looks fine
       on the page (transparent + page-bg = same as --surface) but
       breaks any time the parent isn't the page-bg (modal card, lightbox
       panel, etc.). Define once here so the misnomer can't bite us. */
    --surface-1: var(--surface);
    --surface-2: #17171a;
    --surface-3: #1d1d21;
    --surface-4: #242429;
    /* Lines */
    --border: #3a3a42;
    --border-strong: #52525c;
    --border-subtle: #1d1d21;
    /* Text */
    --text: #f5f5f7;
    --text-2: #c9c9d0;
    --text-3: #8a8a93;
    --text-4: #5c5c63;
    /* Accent (indigo) */
    --accent: #6366f1;
    --accent-hover: #7c7ef4;
    --accent-pressed: #5558d9;
    --accent-soft: rgba(99, 102, 241, 0.12);
    --accent-soft-2: rgba(99, 102, 241, 0.2);
    --accent-border: rgba(99, 102, 241, 0.35);
    --accent-text: #a5a6f6;
    /* Semantic — each colour comes as the quad (base / soft fill / border / text)
       so badges, pills, tabs, and verdict accents all read from the same tokens.
       New magic shades go HERE, not inline — `pill-warning`, `sm-verdict-pill-amber`,
       and `sm-tabbar-tab-reviewed.is-active` are all built from this quad. */
    --success: #22c55e;
    --success-soft: rgba(34, 197, 94, 0.12);
    --success-border: rgba(34, 197, 94, 0.35);
    --success-text: #4ade80;
    --warning: #f59e0b;
    --warning-soft: rgba(245, 158, 11, 0.12);
    --warning-border: rgba(245, 158, 11, 0.35);
    --warning-text: #fbbf24;
    --danger: #ef4444;
    --danger-soft: rgba(239, 68, 68, 0.12);
    --danger-border: rgba(239, 68, 68, 0.35);
    --danger-text: #f87171;
    --info: #38bdf8;
    --info-soft: rgba(56, 189, 248, 0.12);
    --info-border: rgba(56, 189, 248, 0.35);
    --info-text: #7dd3fc;
    /* Type */
    --font-sans: "Geist", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
    /* Radii */
    --r-sm: 4px;
    --r-md: 6px;
    --r-lg: 8px;
    --r-xl: 12px;
    /* Shadows (used sparingly) */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.3);

    /* Legacy aliases — old `.sp-*` rules reference these names, so they
       re-theme automatically without touching every rule. Remove when
       the legacy CSS is deleted in later phases. */
    --navy: var(--surface-2);
    --baby-blue: var(--accent);
    --calm-green: var(--success);
    --bg-main: var(--bg);
    --bg-card: var(--surface-2);
    --bg-elevated: var(--surface-3);
    --text-primary: var(--text);
    --text-secondary: var(--text-2);
    --text-muted: var(--text-3);
    --border-light: var(--border);
    --shadow-card: var(--shadow-sm);
    --shadow-hover: var(--shadow-md);
    --radius: var(--r-lg);
    --radius-sm: var(--r-md);
    --status-in-progress: var(--text-3);
    --status-waiting: var(--warning);
    --status-reviewed: var(--info);
    --status-scheduled: #722ed1;
    --status-posted: var(--success);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html {
    /* Firefox: themed thin scrollbar across the whole app (applies inside the
       modal's embedded iframe too, since it loads this same stylesheet). */
    scrollbar-width: thin;
    scrollbar-color: var(--border-light) var(--bg-main);
}
/* WebKit (Chrome/Safari/Edge) themed scrollbar on the page + iframes. */
html::-webkit-scrollbar,
body::-webkit-scrollbar { width: 12px; height: 12px; }
html::-webkit-scrollbar-track,
body::-webkit-scrollbar-track { background: var(--bg-main); }
html::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb {
    background: var(--border-light);
    border-radius: 6px;
    border: 2px solid var(--bg-main);
}
html::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover { background: var(--baby-blue); }
html::-webkit-scrollbar-corner,
body::-webkit-scrollbar-corner { background: var(--bg-main); }

body {
    font-family: var(--font-sans);
    background: var(--bg);
    color: var(--text);
    font-size: 16px;
    line-height: 1.45;
    -webkit-font-smoothing: antialiased;
    font-feature-settings: "cv11", "ss01";
}

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

/* === FLASH MESSAGES === */

.sp-flash-container { margin-bottom: 1rem; }
.sp-flash {
    padding: 0.75rem 1rem;
    border-radius: var(--radius-sm);
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
    font-size: 1.125rem;
}
.sp-flash-success { background: #132b1a; color: #6ee77a; border: 1px solid #234d2c; }
.sp-flash-error { background: #2d1215; color: #ff8a8a; border: 1px solid #4d2327; }
.sp-flash-close { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: inherit; opacity: 0.6; }

/* === LOGIN === */

.sp-login-container { width: 100%; max-width: 400px; }
.sp-login-card {
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    padding: 2.5rem;
}
.sp-login-header { text-align: center; margin-bottom: 2rem; }
.sp-login-header h1 { font-size: 1.875rem; color: #ffffff; margin-top: 0.5rem; }
.sp-login-header p { color: var(--text-secondary); font-size: 1.125rem; }
.sp-logo-icon-large {
    width: 144px;
    height: 144px;
    display: block;
    margin: 0 auto;
}

/* === FORMS === */

.sp-form-group { margin-bottom: 1rem; }
.sp-form-group label {
    display: block;
    font-size: 1.062rem;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: 0.3rem;
}
.sp-form-group input,
.sp-form-group textarea,
.sp-form-group select {
    width: 100%;
    padding: 0.6rem 0.8rem;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
    font-size: 1.188rem;
    font-family: inherit;
    transition: border-color 0.2s;
    background: var(--bg-elevated);
    color: var(--text-primary);
}
.sp-form-group input:focus,
.sp-form-group textarea:focus,
.sp-form-group select:focus {
    outline: none;
    border-color: var(--baby-blue);
    box-shadow: 0 0 0 3px rgba(0,180,255,0.15);
}


/* === BUTTONS === */

.sp-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.6rem 1.2rem;
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: 1.125rem;
    font-weight: 500;
    border: none;
    cursor: pointer;
    transition: all 0.2s;
    text-decoration: none;
}
.sp-btn:hover { text-decoration: none; }

.sp-btn-primary { background: var(--baby-blue); color: white; }
.sp-btn-primary:hover { background: #0090d4; color: white; }

.sp-btn-secondary { background: var(--bg-elevated); color: var(--text-primary); border: 1px solid var(--border-light); }
.sp-btn-secondary:hover { background: var(--border-light); color: var(--text-primary); }

.sp-btn-danger { background: #ff4d4f; color: white; }
.sp-btn-danger:hover { background: #cf1322; }

.sp-btn-full { width: 100%; justify-content: center; }
.sp-btn-large { padding: 0.8rem 2rem; font-size: 1.25rem; }
.sp-btn-small { padding: 0.4rem 0.8rem; font-size: 1.0rem; }

.sp-btn-icon {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.3rem;
    border-radius: 4px;
    color: var(--text-muted);
    transition: all 0.2s;
}
.sp-btn-icon:hover { background: rgba(0,0,0,0.05); }
.sp-btn-icon.sp-btn-danger { color: #ff4d4f; }
.sp-btn-icon.sp-btn-danger:hover { background: #fff1f0; }

/* === STORYBOARD === */

/* .sp-storyboard is now a plain wrapper — its enclosing
   .sm-composer-section already provides surface + padding + radius +
   vertical gap, and the h2 uses .t-label like every other section title. */
.sp-storyboard-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}
.sp-storyboard-status {
    font-size: 0.938rem;
    color: var(--text-muted);
    min-height: 1em;
    transition: color 0.2s;
}
.sp-storyboard-status.saving { color: var(--baby-blue); }
.sp-storyboard-status.saved { color: var(--calm-green); }
.sp-storyboard-status.error { color: #ff7a7a; }

.sp-storyboard-strip {
    display: flex;
    gap: 0.75rem;
    overflow-x: auto;
    padding: 0.25rem 0 0.75rem;
    align-items: stretch;
    scrollbar-width: thin;
    scrollbar-color: var(--border-light) var(--bg-elevated);
}
.sp-storyboard-strip::-webkit-scrollbar { height: 10px; }
.sp-storyboard-strip::-webkit-scrollbar-track { background: var(--bg-elevated); border-radius: 5px; }
.sp-storyboard-strip::-webkit-scrollbar-thumb { background: var(--border-light); border-radius: 5px; }
.sp-storyboard-strip::-webkit-scrollbar-thumb:hover { background: var(--baby-blue); }

.sp-sb-frame {
    flex: 0 0 200px;
    width: 200px;
    background: var(--bg-elevated);
    border-radius: var(--radius-sm);
    display: flex;
    flex-direction: column;
    transition: box-shadow 0.15s, transform 0.15s;
    position: relative;
}
.sp-sb-frame[draggable="true"] { cursor: grab; }
/* Reviewer mode renders an extra per-frame note block. No fixed min-height —
   captions + notes grow with their content; frames align at the top. */
.sp-sb-frame[draggable="true"]:hover { box-shadow: var(--shadow-hover); }
.sp-sb-frame.dragging { opacity: 0.5; }
.sp-sb-frame.drop-target { outline: 2px dashed var(--baby-blue); outline-offset: -2px; }

.sp-sb-frame-head {
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    padding: 0.3rem 0.5rem;
    font-size: 1.172rem;
    font-weight: 600;
    color: var(--text-muted);
}
.sp-sb-order { letter-spacing: 0.5px; }
/* Delete button is absolutely positioned so the Frame label stays
   centered even when the delete affordance is rendered. */
.sp-sb-frame-head .sp-sb-delete {
    position: absolute;
    right: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
}
.sp-sb-delete {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.15rem 0.3rem;
    font-size: 0.938rem;
    border-radius: 3px;
    transition: color 0.15s, background 0.15s;
}
.sp-sb-delete:hover { color: #ff7a7a; background: rgba(255, 77, 79, 0.1); }

.sp-sb-thumb {
    width: 100%;
    aspect-ratio: 9 / 16;
    background: var(--bg-main);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.sp-sb-thumb img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    display: block;
}

.sp-sb-caption {
    width: 100%;
    padding: 8px 10px;
    font-size: 13px;
    line-height: 1.35;
    color: var(--text-primary);
    background: var(--bg-card);
    border: none;
    border-top: 1px solid var(--border-light);
    font-family: inherit;
    /* Producer-mode textarea only. Starts at 84px; the corner grip lets
       the producer enlarge it if a caption runs long. */
    height: 84px;
    overflow-y: auto;
    resize: vertical;
}
.sp-sb-caption:focus { outline: none; background: var(--bg-elevated); }
.sp-sb-caption-readonly {
    white-space: pre-wrap;
    color: var(--text-secondary);
    /* Review mode: let the caption grow with content — no scrollbars. */
    height: auto;
    overflow: visible;
}


.sp-sb-drop-zone {
    flex: 0 0 200px;
    width: 200px;
    border: 2px dashed var(--border-light);
    border-radius: var(--radius-sm);
    padding: 1rem 0.75rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    text-align: center;
    color: var(--text-muted);
    cursor: pointer;
    transition: all 0.2s;
    outline: none;
}
.sp-sb-drop-zone:hover,
.sp-sb-drop-zone:focus,
.sp-sb-drop-zone.drag-active {
    border-color: var(--baby-blue);
    background: rgba(0, 180, 255, 0.05);
    color: var(--text-secondary);
}
.sp-sb-drop-zone i { font-size: 1.875rem; color: var(--baby-blue); }
.sp-sb-drop-title { font-size: 1.062rem; font-weight: 600; color: var(--text-primary); }
.sp-sb-drop-hint { font-size: 0.875rem; line-height: 1.4; }
.sp-sb-drop-hint kbd {
    background: var(--bg-elevated);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    border: 1px solid var(--border-light);
    font-size: 0.812rem;
    font-family: ui-monospace, Menlo, monospace;
}
.sp-sb-browse-btn {
    font-size: 0.875rem;
    padding: 0.25rem 0.75rem;
    border: 1px solid var(--border-light);
    background: var(--bg-elevated);
    color: var(--text-secondary);
    border-radius: 4px;
    cursor: pointer;
    margin-top: 0.25rem;
}
.sp-sb-browse-btn:hover { border-color: var(--baby-blue); color: var(--text-primary); }

/* === RESPONSIVE === */

@media (max-width: 1024px) {
    .sp-detail-layout { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
    .sp-column { flex: 0 0 280px; width: 280px; }
    .sp-nav-center { display: none; }
    .sp-board-filters { flex-wrap: wrap; }
    .sp-filter-row { flex-direction: column; }
    .sp-image-select-grid { grid-template-columns: repeat(2, 1fr); }
}

/* =========================================================
 * DESIGN SYSTEM PRIMITIVES (ported from handoff/dark.css)
 * New `.sm-*` screens use these directly. Legacy `.sp-*`
 * rules above reference the aliased tokens and will be
 * replaced in later phases.
 * ========================================================= */

/* ---- Typography utilities ---- */
.t-h1 { font-size: 28px; font-weight: 600; letter-spacing: -0.02em; color: var(--text); }
.t-h2 { font-size: 20px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); }
.t-h3 { font-size: 16px; font-weight: 600; color: var(--text); }
.t-body { font-size: 16px; color: var(--text-2); }
.t-sm { font-size: 15px; color: var(--text-3); }
.t-xs { font-size: 14px; color: var(--text-3); }
.t-label { font-size: 14px; font-weight: 500; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.04em; }
h2.t-label { font-size: 16px; font-weight: 700; color: var(--text); text-transform: none; letter-spacing: 0; }
.t-mono { font-family: var(--font-mono); font-size: 14px; }
.t-num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

/* ---- Card ---- */
.card {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
}
.card-pad { padding: 16px; }
.card-pad-lg { padding: 20px; }
.card-pad-sm { padding: 12px; }

/* ---- Button ---- */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 10px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    color: var(--text-2);
    font-family: inherit;
    font-size: 15px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.1s, border-color 0.1s, color 0.1s;
    white-space: nowrap;
    text-decoration: none;
}
.btn:hover { background: var(--surface-4); color: var(--text); border-color: var(--border-strong); text-decoration: none; }
.btn svg, .btn i { flex-shrink: 0; }
.btn-sm { height: 24px; padding: 0 8px; font-size: 14px; }
.btn-lg { height: 32px; padding: 0 14px; font-size: 16px; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: white; }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: white; }
/* Darker indigo than btn-primary — used for "Duplicate" so it reads as
   a sibling action to Edit without competing for the eye. */
.btn-duplicate { background: #3b3da8; border-color: #3b3da8; color: white; }
.btn-duplicate:hover { background: #2f3196; border-color: #2f3196; color: white; }
/* Darker than the --success token (#22c55e) so the white label has
   stronger contrast — the bright variant felt washed-out behind a
   white "Save". --success is still used for pills/text where the
   colour is the foreground, so leaving the token alone keeps that
   bright accent intact. */
.btn-success { background: #16a34a; border-color: #16a34a; color: white; }
.btn-success:hover { background: #15803d; border-color: #15803d; color: white; }
.btn-danger-solid { background: var(--danger); border-color: var(--danger); color: white; }
.btn-danger-solid:hover { background: #dc2626; border-color: #dc2626; color: white; }
.btn-ghost { background: transparent; border-color: transparent; }
.btn-ghost:hover { background: var(--surface-3); border-color: transparent; }
.btn-danger { color: var(--danger-text); }
.btn-danger:hover { background: var(--danger-soft); border-color: var(--danger-border); color: var(--danger-text); }
.btn-icon { width: 28px; padding: 0; justify-content: center; }

/* ---- Pill / Badge ---- */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-2);
    line-height: 1.5;
    white-space: nowrap;
}
.pill-accent { background: var(--accent-soft); border-color: var(--accent-border); color: var(--accent-text); }
.pill-success { background: var(--success-soft); border-color: var(--success-border); color: var(--success-text); }
.pill-warning { background: var(--warning-soft); border-color: var(--warning-border); color: var(--warning-text); }
.pill-danger { background: var(--danger-soft); border-color: var(--danger-border); color: var(--danger-text); }
.pill-info { background: var(--info-soft); border-color: var(--info-border); color: var(--info-text); }
.pill-solid { background: var(--accent); border-color: var(--accent); color: white; }
.dot {
    display: inline-block;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

/* ---- Input / Textarea ---- */
.input {
    display: block;
    width: 100%;
    height: 28px;
    padding: 0 10px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    color: var(--text);
    font-family: inherit;
    font-size: 15px;
}
.input:focus { outline: none; border-color: var(--accent); background: var(--surface-2); }
.input::placeholder { color: var(--text-4); }
.textarea {
    display: block;
    width: 100%;
    padding: 10px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    color: var(--text);
    font-family: inherit;
    font-size: 16px;
    line-height: 1.5;
    resize: vertical;
    min-height: 60px;
}
.textarea:focus { outline: none; border-color: var(--accent); }

/* ---- Avatar ---- */
.av {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--surface-4);
    color: var(--text-2);
    font-size: 13px;
    font-weight: 600;
    flex-shrink: 0;
    letter-spacing: 0.02em;
}
.av-sm { width: 18px; height: 18px; font-size: 8px; }
.av-lg { width: 32px; height: 32px; font-size: 15px; }
.av-i { background: linear-gradient(135deg, #ec4899, #8b5cf6); color: white; }
.av-t { background: linear-gradient(135deg, #06b6d4, #3b82f6); color: white; }
.av-a { background: linear-gradient(135deg, #f59e0b, #ef4444); color: white; }
.av-m { background: linear-gradient(135deg, #10b981, #06b6d4); color: white; }
.av-j { background: linear-gradient(135deg, #a855f7, #6366f1); color: white; }
.av-l { background: linear-gradient(135deg, #f472b6, #a78bfa); color: white; }

/* ---- Platform chip ---- */
.plat {
    display: inline-flex;
    width: 33px; height: 33px;
    border-radius: 7.5px;
    flex-shrink: 0;
    position: relative;
    /* Hide the inline letter codes ("IG", "FB", "X", …) that templates
       still emit for accessibility. text-indent: 200% leaks inside
       inline-flex on some browsers (the X icon was showing a clipped
       second "X" to the right of the brand glyph), so collapse the
       inline font instead. The per-platform ::before re-establishes
       its own font-size below. */
    overflow: hidden;
    font-size: 0;
    line-height: 0;
}
.plat::before {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    text-indent: 0;
    font-family: "Font Awesome 6 Brands";
    font-weight: 400;
    color: white;
    line-height: 1;
    font-size: 18px;
}
.plat-lg { width: 48px; height: 48px; border-radius: 10.5px; }
.plat-lg::before { font-size: 26px; }
.plat-sm { width: 24px; height: 24px; border-radius: 4.5px; }
.plat-sm::before { font-size: 13px; }

/* Per-platform: brand glyph + chip background. Codepoints from FA 6.4. */
.plat-IG  { background: linear-gradient(135deg, #f58529 0%, #dd2a7b 50%, #515bd4 100%); }
.plat-IG::before  { content: "\f16d"; }
.plat-FB  { background: #1877f2; }
.plat-FB::before  { content: "\f39e"; }
.plat-YT  { background: #ff0033; }
.plat-YT::before  { content: "\f167"; }
.plat-PN  { background: #bd081c; }
.plat-PN::before  { content: "\f231"; }
.plat-TT  { background: #09090b; border: 1px solid #27272a; }
.plat-TT::before  { content: "\e07b"; }
.plat-X   { background: #09090b; border: 1px solid #27272a; }
/* FA 6.4.0 doesn't reliably ship the x-twitter brand glyph, so render a
   plain bold "X" — matches the rebrand without depending on a glyph. */
.plat-X::before   {
    content: "X";
    font-family: -apple-system, "Segoe UI", system-ui, sans-serif;
    font-weight: 900;
}
.plat-SUB { background: #ff6719; }
.plat-SUB::before {
    content: "\f1ea";
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
}

/* ---- Kbd ---- */
.kbd {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-bottom-width: 1.5px;
    border-radius: 4px;
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text-3);
}

/* ---- Nav item (sidebar) ---- */
.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px;
    border-radius: var(--r-md);
    color: var(--text-3);
    font-size: 16px;
    cursor: pointer;
    font-weight: 500;
    transition: background 0.1s, color 0.1s;
    text-decoration: none;
}
.nav-item:hover { background: var(--surface-3); color: var(--text-2); text-decoration: none; }
.nav-item.active { background: var(--surface-3); color: var(--text); }
.nav-item.active .nav-icon { color: var(--accent); }
.nav-icon { width: 14px; height: 14px; flex-shrink: 0; color: var(--text-4); font-size: 16px; }
.nav-count { margin-left: auto; font-size: 14px; color: var(--text-4); font-variant-numeric: tabular-nums; }

/* ---- Tabs ---- */
.tabs { display: flex; gap: 0; border-bottom: 1px solid var(--border); }
.tab {
    padding: 8px 14px;
    font-size: 15px;
    font-weight: 500;
    color: var(--text-3);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    text-decoration: none;
}
.tab:hover { color: var(--text-2); text-decoration: none; }
.tab.active { color: var(--text); border-bottom-color: var(--accent); }

/* ---- Table ---- */
.t-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 15px;
}
.t-table th {
    text-align: left;
    font-weight: 500;
    color: var(--text-3);
    font-size: 14px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--border);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.t-table td {
    padding: 10px;
    border-bottom: 1px solid var(--border-subtle);
    color: var(--text-2);
}
.t-table tr:hover td { background: var(--surface-3); }
.t-table tr:last-child td { border-bottom: none; }

/* ---- Placeholder (media) ---- */
.ph {
    background:
        linear-gradient(var(--surface-3), var(--surface-3)),
        repeating-linear-gradient(135deg, transparent 0 10px, rgba(255, 255, 255, 0.02) 10px 11px);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-4);
    font-family: var(--font-mono);
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    position: relative;
    overflow: hidden;
}
.ph::before {
    content: "";
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(135deg, transparent 0 14px, rgba(255, 255, 255, 0.015) 14px 15px);
    pointer-events: none;
}

/* ---- Separators ---- */
.sep { height: 1px; background: var(--border); border: none; margin: 0; }
.sep-v { width: 1px; background: var(--border); align-self: stretch; }

/* ---- Layout helpers ---- */
.row { display: flex; gap: 12px; }
.col { display: flex; flex-direction: column; gap: 12px; }
.ai-c { align-items: center; }
.jc-sb { justify-content: space-between; }
.jc-c { justify-content: center; }
.f1 { flex: 1; min-width: 0; }
.gap-xs { gap: 4px; }
.gap-sm { gap: 6px; }
.gap-md { gap: 12px; }
.gap-lg { gap: 20px; }

/* =========================================================
 * APP SHELL (sidebar + topbar + content)
 * ========================================================= */

.sm-app {
    display: flex;
    height: 100vh;
    overflow: hidden;
    background: var(--surface);
    color: var(--text);
}

.sm-sidebar {
    width: 216px;
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    height: 100vh;
    position: sticky;
    top: 0;
}

.sm-sidebar-header {
    padding: 18px 14px 14px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 10px;
    /* Anchor element — kill default link chrome so the sidebar header
       still reads as a header, not a hyperlink. */
    color: inherit;
    text-decoration: none;
    transition: background 0.1s;
}
.sm-sidebar-header:hover { background: var(--surface-3); text-decoration: none; }
.sm-sidebar-logo {
    width: 50px;
    height: 50px;
    display: block;
    flex-shrink: 0;
}
.sm-sidebar-title {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.2;
    min-width: 0;
}
.sm-sidebar-title-main {
    font-size: 15px;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.01em;
}
.sm-sidebar-title-sub {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-3);
    letter-spacing: 0.01em;
    margin-top: 2px;
}

.sm-sidebar-section {
    padding: 12px 10px;
    border-bottom: 1px solid var(--border);
}
.sm-sidebar-section:last-of-type { border-bottom: none; }
.sm-sidebar-section-label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-4);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 4px 10px 8px;
}

.sm-sidebar-footer {
    margin-top: auto;
    padding: 12px 14px;
    border-top: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 10px;
}
.sm-sidebar-user-meta { flex: 1; min-width: 0; line-height: 1.2; }
.sm-sidebar-user-name { font-size: 15px; font-weight: 500; color: var(--text); }
.sm-sidebar-user-role { font-size: 13px; color: var(--text-4); text-transform: uppercase; letter-spacing: 0.04em; }

.sm-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--surface);
}

.sm-topbar {
    min-height: 36px;
    padding: 4px 16px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 14px;
    flex-shrink: 0;
}
.sm-topbar-title {
    display: flex;
    min-width: 0;
}
.sm-topbar-h1 {
    font-size: 18px;
    font-weight: 600;
    line-height: 1.25;
    color: var(--text);
    letter-spacing: -0.01em;
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}
/* Inline meta sitting next to the H1 — every page that previously
   used a third stacked subtitle line now puts its counts/greeting
   here so the topbar stays one tight row. */
.sm-topbar-inline-meta {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-3);
    letter-spacing: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sm-topbar-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Outer: full-width scroll container. The scrollbar lands at the
   viewport right edge so the wheel works anywhere on the page —
   not at a centered max-width's edge. */
.sm-content {
    flex: 1;
    min-height: 0;
    overflow: auto;
}
/* Inner: visual padding + max-width centering. Default for content
   pages that flow vertically (archive, dashboard, post forms, etc.) */
.sm-content-inner {
    padding: 24px 28px;
    max-width: 1320px;
    width: 100%;
    margin: 0 auto;
    box-sizing: border-box;
}
/* Flush pages (kanban board, review queue, bin, /favorites) have
   internal flex/grid layouts that need to fill the full area
   edge-to-edge. Explicit `height: 100%` so child layouts that
   declare `height: 100%` (`.sm-review`, `.sm-board-wrap`, `.sm-favs`)
   resolve against a real height instead of `auto`. */
.sm-content-flush > .sm-content-inner {
    padding: 0;
    max-width: none;
    height: 100%;
    display: flex;
    flex-direction: column;
}

/* Coming-soon placeholder */
.sm-stub {
    height: 100%;
    min-height: 60vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    color: var(--text-3);
    text-align: center;
}
.sm-stub-icon {
    width: 56px; height: 56px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 14px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    color: var(--accent-text);
    font-size: 28px;
    margin-bottom: 6px;
}
.sm-stub-title { font-size: 22px; font-weight: 600; color: var(--text); }
.sm-stub-body { font-size: 16px; max-width: 520px; line-height: 1.5; }

/* Flash messages adopt the new palette */
.sp-flash {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-left: 2px solid var(--accent);
    color: var(--text);
}
.sp-flash-success { border-left-color: var(--success); }
.sp-flash-error { border-left-color: var(--danger); }
.sp-flash-warning { border-left-color: var(--warning); }

/* =========================================================
 * REVIEW QUEUE (Phase 1)
 * Two-column flush layout: 360px list on left + detail pane
 * on right, both living inside the sm-content-flush container.
 * ========================================================= */

.sm-review {
    display: grid;
    grid-template-columns: 432px 1fr;
    height: 100%;
    min-height: 0;
    background: var(--surface);
}

/* ---- Left list column ---- */

.sm-review-list {
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--surface);
}

.sm-review-list-head {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.sm-review-search {
    position: relative;
}
.sm-review-search i {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-4);
    font-size: 14px;
    pointer-events: none;
}
.sm-review-search .input { padding-left: 28px; }

/* === Review Queue status tabs ===
   Two large color-coded tabs above the left/right split — clicking one
   filters the list to Pending or Reviewed. The colors match the
   existing status badges (amber/green) so Max sees the same colour on
   the tab and on each row. Default-active is Pending. */
.sm-review-tabbar {
    display: flex;
    gap: 10px;
    width: 100%;
    padding: 4px 16px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.sm-tabbar-tab {
    flex: 1;
    appearance: none;
    background: var(--surface-1);
    border: 2px solid var(--border);
    border-radius: 10px;
    padding: 6px 24px;
    font: inherit;
    font-size: 18px;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    color: var(--text-3);
    transition: background 140ms ease, border-color 140ms ease, color 140ms ease, transform 80ms ease;
}
.sm-tabbar-tab:hover { transform: translateY(-1px); color: var(--text); }
.sm-tabbar-count {
    font-size: 15px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    padding: 2px 12px;
    border-radius: 999px;
    background: var(--surface-3);
    color: var(--text-3);
    line-height: 1.2;
}
/* Pending — neutral gray. Pending posts are just "not yet reviewed",
   so the tab stays neutral; the green "Reviewed" tab is the only
   coloured one (work done). */
.sm-tabbar-tab-pending { border-color: var(--border-strong); color: var(--text-2); }
.sm-tabbar-tab-pending:hover { border-color: var(--border-strong); color: var(--text); }
.sm-tabbar-tab-pending.is-active {
    background: var(--surface-3);
    border-color: var(--border-strong);
    color: var(--text);
}
.sm-tabbar-tab-pending.is-active .sm-tabbar-count {
    background: var(--text-3);
    color: var(--surface);  /* dark on gray for legible contrast */
}
/* Reviewed — green. Mirrors the success/* tokens used by the
   "Reviewed" pill and the green-verdict pill. */
.sm-tabbar-tab-reviewed { border-color: var(--success-border); color: var(--success-text); }
.sm-tabbar-tab-reviewed:hover { border-color: var(--success); color: var(--success-text); }
.sm-tabbar-tab-reviewed.is-active {
    background: var(--success-soft);
    border-color: var(--success);
    color: var(--success-text);
}
.sm-tabbar-tab-reviewed.is-active .sm-tabbar-count {
    background: var(--success);
    color: #052e16;  /* dark on green for legible contrast — no token */
}

.sm-sort-btns {
    display: inline-flex;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 2px;
    gap: 2px;
}
.sm-sort-btn {
    padding: 2px 8px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-3);
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
    user-select: none;
}
.sm-sort-btn:hover { color: var(--text-2); }
.sm-sort-btn.is-active { background: var(--surface-4); color: var(--text); }

.sm-review-list-body {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
}

.sm-review-list-foot {
    padding: 8px 14px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 14px;
    color: var(--text-3);
}
.sm-kbd-hint { display: flex; gap: 4px; align-items: center; }

/* ---- Bin (soft-deleted posts) ---- */

.sm-bin-head {
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
    padding: 12px 14px;
}
.sm-bin-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.sm-bin-selectall {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    user-select: none;
}
.sm-bin-selected-count { color: var(--text-3); }
.sm-bin-actions {
    display: flex;
    gap: 8px;
}
.sm-bin-actions .btn { flex: 1; justify-content: center; }

/* Bin row: leading checkbox + button-styled body. The button is a
   reset of native button chrome so it inherits the .sm-review-row
   layout below. */
.sm-bin-row { gap: 10px; padding-left: 12px; }
.sm-bin-row-check {
    display: flex;
    align-items: center;
    padding: 0 4px;
    cursor: pointer;
}
.sm-bin-row-check input { width: 16px; height: 16px; cursor: pointer; }
.sm-bin-row-body {
    flex: 1;
    display: flex;
    gap: 14px;
    align-items: center;
    background: transparent;
    border: 0;
    padding: 0;
    color: inherit;
    text-align: left;
    cursor: pointer;
    font: inherit;
    min-width: 0;
}
.sm-bin-row-body:hover { background: transparent; }
.sm-bin .sm-review-pane.is-loading { opacity: 0.55; pointer-events: none; }

/* ---- Review row ---- */

.sm-review-row {
    display: flex;
    gap: 14px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-subtle);
    border-left: 2px solid transparent;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.1s, border-color 0.1s;
    align-items: center;
}
.sm-review-row:hover {
    background: var(--surface-3);
    text-decoration: none;
    color: inherit;
}
.sm-review-row.is-selected {
    background: var(--surface-3);
    border-left-color: var(--accent);
}

.sm-review-row-thumb {
    width: 96px;
    height: 96px;
    flex-shrink: 0;
    border-radius: var(--r-md);
    overflow: hidden;
    background: var(--surface-3);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
}
.sm-review-row-thumb img {
    /* Show the whole image — portraits letterbox instead of being cropped
       mid-subject. Looks nicer for 9:16 reels/verticals in a square box. */
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
}
.sm-review-row-thumb .ph { border: none; border-radius: 0; width: 100%; height: 100%; }

.sm-review-row-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.sm-review-row-top {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}
.sm-review-row-id {
    color: var(--text-4);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
    min-width: 0;
}
.sm-review-row-top-right {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}
.sm-review-row-title {
    font-size: 16px;
    font-weight: 500;
    color: var(--text);
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.sm-review-row-bottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 6px;
}
.sm-review-row-date { color: var(--text-4); }

/* ---- Right pane ---- */

.sm-review-pane {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    background: var(--surface);
    overflow: hidden;
    position: relative;
}
.sm-review-pane.loading { opacity: 0.6; pointer-events: none; }

.sm-review-empty {
    margin: auto;
    padding: 40px;
    text-align: center;
    color: var(--text-3);
    max-width: 420px;
}
.sm-review-empty .sm-stub-icon { margin: 0 auto 14px; }

/* Pane inner */
.sm-pane {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

.sm-pane-head {
    /* One-line header: Title — (status pill) — date — [push] — actions.
       Tight vertical padding so the header doesn't dominate the modal. */
    padding: 10px 18px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-shrink: 0;
    background: var(--surface);
    border-radius: var(--r-lg);
}
.sm-pane-head .t-h1.sm-pane-title {
    margin: 0;
    font-size: 22px;
    line-height: 1.2;
    /* Truncate long titles with ellipsis so the status pill + date +
       actions never get pushed off-screen. */
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sm-pane-status-pill { flex-shrink: 0; }
.sm-pane-date {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text);
    font-size: 14px;
}
.sm-pane-date i { color: var(--text-3); font-size: 13px; }
/* Push the action cluster to the right edge. */
.sm-pane-actions {
    margin-left: auto;
    display: flex;
    gap: 6px;
    align-items: center;
    flex-shrink: 0;
}
/* Post-level .sm-favorite-btn / .sm-btn-request-changes were retired
   in v3 (image-level favorites + traffic-light verdict replaced
   them). Image stars live in `.sm-fav-star` further down. */

.sm-pane-body {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
    padding: 20px 24px 24px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.sm-pane-section {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.sm-pane-section-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

/* Calm inline note at the top of the board pane (e.g. "posted without
   completing checklist"). Same palette as .pill-info, but full-width
   so it reads as context rather than a status badge. */
.sm-pane-note {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border-radius: var(--r-md);
    font-size: 13px;
}
.sm-pane-note-info {
    background: var(--info-soft);
    border: 1px solid var(--info-border);
    color: var(--info-text);
}

/* ---- Carousel (preferred image picker) ---- */

.sm-carousel {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 4px 2px 10px;
    user-select: none;
    scrollbar-width: thin;
    /* Center the option tiles when the row fits; "safe" makes the
       browser fall back to start alignment when the row overflows so
       horizontal scroll still reaches the leading tiles. */
    justify-content: safe center;
}
.sm-carousel-tile {
    flex: 0 0 auto;
    width: 255px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 8px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.sm-carousel-tile.is-selected {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-soft);
}
.sm-carousel-label {
    text-align: center;
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text-2);
    letter-spacing: 0.04em;
    padding: 2px 0;
}
.sm-carousel-photo {
    width: 100%;
    background: var(--surface-3);
    border-radius: var(--r-md);
    overflow: hidden;
}
.sm-carousel-photo img {
    width: 100%;
    height: auto;
    object-fit: contain;
    pointer-events: none;
    display: block;
}
.sm-carousel-btn {
    flex: 0 0 auto;
    min-width: 0;
    width: 100%;
    justify-content: center;
}
.sm-carousel-tile.is-selected .sm-carousel-btn {
    background: var(--accent);
    border-color: var(--accent);
    color: white;
}
.sm-carousel-tile.is-selected .sm-carousel-btn:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
    color: white;
}

/* ---- Video grid ---- */

.sm-video-grid {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.sm-video-card {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
}
/* No forced aspect ratio — let the video render at its native shape so a
   9:16 reel isn't squashed into a 16:9 box. Capped to 70vh so vertical
   videos don't dominate the entire viewport. */
.sm-video-card video {
    max-width: 100%;
    max-height: 70vh;
    background: #000;
    display: block;
}
.sm-video-filename {
    padding: 6px 10px;
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- Content field grid ---- */

.sm-field-grid {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.sm-field {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 10px 14px;
}
.sm-field-label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-4);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 4px;
}
.sm-field-value {
    font-size: 16px;
    color: var(--text-2);
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}
.sm-field-value a { color: var(--accent-text); }
.sm-field-hashtags { font-family: var(--font-mono); color: var(--accent-text); }
.sm-field-pre {
    margin: 0;
    font-family: var(--font-mono);
    font-size: 15px;
    color: var(--text-2);
    white-space: pre-wrap;
    word-break: break-word;
}

/* ---- Notes (plain text; newlines preserved) ---- */

.sm-notes-body {
    background: var(--surface-2);
    border-radius: var(--r-md);
    padding: 14px 18px;
    font-size: 16px;
    color: var(--text-2);
    line-height: 1.6;
    max-height: 420px;
    overflow-y: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
}
.sm-notes-body strong, .sm-notes-body b { color: var(--text); font-weight: 600; }
.sm-notes-body em, .sm-notes-body i { font-style: italic; }
.sm-notes-body a { color: var(--accent-text); text-decoration: underline; }
.sm-notes-body code {
    background: var(--surface-3);
    padding: 0.1em 0.35em;
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 0.9em;
}
.sm-notes-body pre {
    background: var(--surface-3);
    padding: 10px;
    border-radius: var(--r-md);
    overflow-x: auto;
    margin: 0.6em 0;
}
.sm-notes-body blockquote {
    border-left: 2px solid var(--border-strong);
    padding-left: 12px;
    margin: 0.5em 0;
    color: var(--text-3);
}
.sm-notes-body table {
    border-collapse: collapse;
    margin: 0.75em 0;
    width: 100%;
    font-size: 15px;
}
.sm-notes-body th, .sm-notes-body td {
    border: 1px solid var(--border);
    padding: 6px 10px;
    text-align: left;
    vertical-align: top;
}
.sm-notes-body th { background: var(--surface-3); font-weight: 600; color: var(--text); }
.sm-notes-body .error { color: var(--danger-text); background: var(--danger-soft); padding: 0 3px; border-radius: 3px; }
.sm-notes-body hr { border: none; border-top: 1px solid var(--border); margin: 0.8em 0; }

/* ---- Comments ---- */

.sm-comments {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.sm-comment {
    display: flex;
    gap: 10px;
    padding: 10px 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.sm-comment-body { flex: 1; min-width: 0; }
.sm-comment-head {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    align-items: baseline;
    margin-bottom: 4px;
}
.sm-comment-head strong { font-size: 15px; color: var(--text); font-weight: 600; }
.sm-comment p { font-size: 16px; color: var(--text-2); line-height: 1.5; margin: 0; }

.sm-comment-form {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 4px;
}
.sm-comment-submit { align-self: flex-end; }
.sm-comment-form-hint {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-4);
}

/* =========================================================
 * BOARD + KANBAN (Phase 2)
 * Producer-only kanban screen, flush layout inside sm-content-flush.
 * ========================================================= */

.sm-board-wrap {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

.sm-board-toolbar {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 10px 24px;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
    flex-shrink: 0;
    overflow-x: auto;
}
.sm-board-filter-group {
    display: flex;
    align-items: center;
    gap: 8px;
}
/* Pushes Sort Posted to the far right of the toolbar so it sits
   visually above the board's right-hand half (the Posted columns).
   Status sort stays anchored on the left. */
.sm-board-filter-group-end { margin-left: auto; }

.sm-plat-filters {
    display: inline-flex;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 2px;
    gap: 2px;
}
.sm-plat-filter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px; height: 22px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.1s;
}
.sm-plat-filter:hover { background: var(--surface-4); }
.sm-plat-filter.is-active { background: var(--surface-4); }
.sm-plat-filter:not(.is-active) .plat { opacity: 0.55; }
.sm-plat-filter-clear {
    margin-left: 4px;
    padding: 2px 8px;
    background: transparent;
    border: none;
    color: var(--text-3);
    font-size: 14px;
    cursor: pointer;
    border-radius: 4px;
}
.sm-plat-filter-clear:hover { color: var(--text); background: var(--surface-3); }

/* Kanban.
   ONE scrollbar for the whole board — both axes live on .sm-board. No
   per-column vertical scroll. Each column fills at least the board's
   viewport height (so short columns still look grounded) but grows
   freely downward; the tallest column dictates the scrollable height.
   Column headers stick to the top of the board's scroll so you always
   know what column you're reading as you scroll past tall columns. */
.sm-board {
    flex: 1;
    min-height: 0;
    display: flex;
    gap: 12px;
    overflow: auto;
    padding: 16px 24px;
    align-items: flex-start;
}
.sm-board.is-panning * { pointer-events: none; }
.sm-column {
    flex: 0 0 280px;
    width: 280px;
    background: var(--surface-2);
    border-radius: var(--r-lg);
    display: flex;
    flex-direction: column;
    min-height: 100%;
}
.sm-column-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    flex-shrink: 0;
    background: var(--surface-2);
    /* Sticky against the board's scroll container so the title stays
       pinned to the top while the user scrolls vertically past a tall
       column. */
    position: sticky;
    top: 0;
    z-index: 2;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    /* Drag handle for column reorder (initBoardColumnReorder). */
    cursor: grab;
    user-select: none;
}
.sm-column-head:active { cursor: grabbing; }
.sm-column.is-col-dragging { opacity: 0.55; }
/* Divider between the pre-posted "status" columns and the per-bucket
   "Posted" columns. The first column with a posted_bucket gets a
   thick light-gray stripe on its left and breathing room so the two
   halves of the board read as distinct zones. */
.sm-column-first-posted {
    margin-left: 24px;
    position: relative;
}
.sm-column-first-posted::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -16px;
    width: 4px;
    background: var(--border, #d1d5db);
    border-radius: 2px;
}
.sm-column-head-left {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
.sm-column-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.sm-column-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}
.sm-column-count {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-3);
    background: var(--surface-3);
    padding: 1px 6px;
    border-radius: 999px;
    font-variant-numeric: tabular-nums;
}
.sm-column-body {
    flex: 1;
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.sm-column-body.drag-over { background: var(--accent-soft); }
.sm-column-empty {
    color: var(--text-4);
    text-align: center;
    padding: 16px 8px;
    border: 1px dashed var(--border);
    border-radius: var(--r-md);
}

/* Card — single outer border; thumb and body share --surface-4 so no
   internal seam appears between the image and the details strip. */
.sm-card {
    display: flex;
    flex-direction: column;
    background: var(--surface-4);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    text-decoration: none;
    color: inherit;
    cursor: grab;
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: box-shadow 0.1s, border-color 0.1s, transform 0.05s;
    /* Don't let the column-body's flex layout shrink cards to fit; they
       keep their natural height and the body scrolls when overflowing. */
    flex-shrink: 0;
}
.sm-card:hover {
    border-color: var(--border-strong);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
    text-decoration: none;
    color: inherit;
}
.sm-card.dragging { opacity: 0.5; transform: rotate(1deg); }
/* Verdict accent — an inset top strip in red/amber/green when Max has
   cast a verdict. Visible in the "Reviewed by Max" column (and
   anywhere else the card surfaces) so Jane sees the colour at a
   glance. */
.sm-card.is-verdict-red    { box-shadow: inset 0 2px 0 var(--danger),  0 1px 2px rgba(0, 0, 0, 0.25); }
.sm-card.is-verdict-amber  { box-shadow: inset 0 2px 0 var(--warning), 0 1px 2px rgba(0, 0, 0, 0.25); }
.sm-card.is-verdict-green  { box-shadow: inset 0 2px 0 var(--success), 0 1px 2px rgba(0, 0, 0, 0.25); }
.sm-card-verdict {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 50%;
    margin-right: 4px;
}
.sm-card-verdict-red    { background: var(--danger);  }
.sm-card-verdict-amber  { background: var(--warning); }
.sm-card-verdict-green  { background: var(--success); }
.sm-verdict-pill                 { background: var(--surface-2); }
.sm-verdict-pill-red    .dot     { background: var(--danger); }
.sm-verdict-pill-amber  .dot     { background: var(--warning); }
.sm-verdict-pill-green  .dot     { background: var(--success); }
.sm-verdict-pill-red             { color: var(--danger-text);  border-color: var(--danger-border);  background: var(--danger-soft); }
.sm-verdict-pill-amber           { color: var(--warning-text); border-color: var(--warning-border); background: var(--warning-soft); }
.sm-verdict-pill-green           { color: var(--success-text); border-color: var(--success-border); background: var(--success-soft); }

.sm-card-thumb {
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--surface-3);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.sm-card-thumb img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
}
.sm-card-thumb-text {
    padding: 12px;
    font-size: 14px;
    color: var(--text-3);
    line-height: 1.4;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}
.sm-card-thumb-text p {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 5;
    -webkit-box-orient: vertical;
}

.sm-card-body {
    padding: 8px 10px 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sm-card-meta {
    display: flex;
    align-items: center;
    gap: 6px;
}
.sm-card-meta-label {
    color: var(--text-3);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    flex-shrink: 1;
    min-width: 0;
}
.sm-card-meta-spacer { flex: 1; }
.sm-card-title {
    font-size: 16px;
    font-weight: 500;
    line-height: 1.3;
    color: var(--text);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.sm-card-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 6px;
    color: var(--text-3);
}
.sm-card-foot i { margin-right: 2px; }
.sm-card-date-empty { color: var(--text-4); }


/* =========================================================
 * COMPOSER (Phase 2)
 * Two-column: editor on the left + sticky preview on the right.
 * ========================================================= */

/* Composer body */
.sm-composer-editor {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}
.sm-composer-preview {
    position: sticky;
    top: 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.sm-composer-section {
    background: var(--surface-2);
    border-radius: var(--r-lg);
    padding: 10px 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.sm-section-head {
    display: flex;
    justify-content: space-between;
    align-items: end;
    gap: 12px;
}

/* Form fields (composer) */
.sm-form-row {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 12px;
    align-items: end;
}
.sm-form-row .sm-form-wide { grid-column: 1; }
.sm-form-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}
.sm-form-label {
    font-size: 11px;
    font-weight: 500;
    color: var(--text-4);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.sm-form-hint { color: var(--text-4); margin-top: 2px; display: block; font-size: 14px; }

.sm-char-counter {
    display: block;
    margin-top: 4px;
    font-size: 14px;
    color: var(--text-4);
    text-align: right;
}
.sm-char-counter.is-warn { color: var(--warning-text); }
.sm-char-counter.is-over { color: var(--danger-text); font-weight: 600; }

/* Upload zone (inside the upload modal) */
.sm-upload-zone {
    position: relative;
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-md);
    padding: 40px 16px;
    text-align: center;
    color: var(--text-3);
    background: var(--surface-3);
    transition: border-color 0.1s, background 0.1s;
}
.sm-upload-zone i {
    font-size: 30px;
    color: var(--text-4);
    margin-bottom: 6px;
}
.sm-upload-zone p { font-size: 15px; margin-bottom: 4px; color: var(--text-2); }
.sm-upload-zone small { font-size: 14px; color: var(--text-4); }
.sm-upload-zone.drag-active {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent-text);
}
.sm-upload-click-overlay {
    position: absolute;
    inset: 0;
    cursor: pointer;
}

/* Upload modal */
.sm-upload-modal-body {
    max-width: 640px;
}
.sm-upload-modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 4px;
}

/* Inline gallery (below the body textarea, replacing the old Media section) */
.sm-gallery-inline {
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.sm-gallery-inline:empty { display: none; }

/* Gallery (images + videos) */
.sm-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 10px;
}
.sm-gallery-videos {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.sm-gallery-item {
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
}
.sm-gallery-item.is-preferred { outline: 2px solid var(--success); }
/* `contain` + black background — never crop the producer's media,
   per CLAUDE.md. Letterboxes against black instead of cropping a
   non-4:5 image to fit. */
.sm-gallery-item img { width: 100%; aspect-ratio: 4/5; object-fit: contain; background: #000; display: block; }
.sm-gallery-video video { width: 100%; aspect-ratio: 16/9; background: #000; display: block; }
.sm-gallery-item-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
}
.sm-gallery-filename {
    color: var(--text-3);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    flex: 1;
    min-width: 0;
}

/* Upload progress (used by media_upload.js) */
.sp-upload-progress {
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 8px 10px;
    margin-top: 6px;
    font-size: 15px;
    color: var(--text-2);
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sp-upload-progress-bar {
    background: var(--surface);
    height: 4px;
    border-radius: 2px;
    overflow: hidden;
}
.sp-upload-progress-fill {
    background: var(--accent);
    height: 100%;
    transition: width 0.15s;
}

/* Preview chrome — Metricool-style top bar with platform-icon switcher
   on the left and view tools (eye, phone/desktop) on the right. */
.sm-preview-chrome {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 2px;
    color: var(--text-3);
}
.sm-preview-card-wrap { display: block; }

.sm-preview-chrome-tools {
    display: flex;
    align-items: center;
    gap: 4px;
}
.sm-preview-tool {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px; height: 28px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    color: var(--text-3);
    cursor: pointer;
    padding: 0;
    font-size: 13px;
    transition: color 0.1s, background 0.1s, border-color 0.1s;
}
.sm-preview-tool:hover { color: var(--text); background: var(--surface-3); }
.sm-preview-tool.is-active {
    background: var(--accent-soft);
    border-color: var(--accent-border);
    color: var(--accent-text);
}
.sm-preview-device-toggle {
    display: inline-flex;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    padding: 2px;
    gap: 2px;
    margin-left: 4px;
}
.sm-preview-device-toggle .sm-preview-tool {
    width: 26px; height: 22px;
    border: none;
}
.sm-preview-device-toggle .sm-preview-tool.is-active {
    background: var(--surface);
    border-color: transparent;
    color: var(--text);
}

/* Eye-hidden state — collapses the preview card, switcher, and
   constraints. The chrome label row stays visible so the user can
   re-enable the preview. */
.sm-composer-preview.is-hidden .sm-preview-card-wrap,
.sm-composer-preview.is-hidden .sm-preview-switcher,
.sm-composer-preview.is-hidden .sm-preview-constraints {
    display: none;
}

/* Device toggle — phone is a flat full-width render of the mock (no
   simulated phone bezel; the mock takes the full pane width and
   whatever vertical room it needs, so the constraints card flows
   directly underneath). Desktop wraps it in a wider browser-chrome
   frame (title bar with traffic-light dots). */
.pv-device-phone .sm-preview-card-wrap {
    width: 100%;
    padding: 0;
    background: transparent;
    border: 0;
}
.pv-device-phone .sm-preview-card-wrap > .pv {
    border-radius: 10px;
    overflow: hidden;
}

.pv-device-desktop .sm-preview-card-wrap {
    max-width: 100%;
    background: #16171a;
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 32px 20px 20px;
    position: relative;
}
.pv-device-desktop .sm-preview-card-wrap::before {
    content: '';
    position: absolute;
    top: 12px;
    left: 16px;
    width: 46px;
    height: 10px;
    background:
        radial-gradient(circle at 5px 5px, #ff5f56 4px, transparent 4.5px),
        radial-gradient(circle at 21px 5px, #ffbd2e 4px, transparent 4.5px),
        radial-gradient(circle at 37px 5px, #27c93f 4px, transparent 4.5px);
}
/* Card-style renderers breathe when the browser frame widens. */
.pv-device-desktop .pv-x-tweet,
.pv-device-desktop .pv-x-thread,
.pv-device-desktop .pv-fb-feed,
.pv-device-desktop .pv-yt-long,
.pv-device-desktop .pv-sub-essay,
.pv-device-desktop .pv-sub-email,
.pv-device-desktop .pv-ig-feed,
.pv-device-desktop .pv-pn-pin {
    max-width: 520px;
    margin-left: auto;
    margin-right: auto;
}
/* Vertical renderers (Reels / Shorts / TikTok / video pins) render as
   a centered small player on a desktop page — not full-width. */
.pv-device-desktop .pv-ig-reel,
.pv-device-desktop .pv-fb-reel,
.pv-device-desktop .pv-yt-short,
.pv-device-desktop .pv-tt-video,
.pv-device-desktop .pv-tt-photo,
.pv-device-desktop .pv-pn-video {
    max-width: 320px;
    margin-left: auto;
    margin-right: auto;
}

@media (max-width: 1024px) {
    .sm-composer-preview { position: static; }
}

/* =========================================================
 * ARCHIVE (refresh for new palette)
 * ========================================================= */
.sm-archive-filters {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 20px;
}
.sm-archive-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}
.sm-archive-card {
    display: flex;
    flex-direction: column;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.1s, box-shadow 0.1s;
}
.sm-archive-card:hover {
    border-color: var(--border-strong);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    text-decoration: none;
    color: inherit;
}
.sm-archive-thumb {
    width: 100%;
    aspect-ratio: 4 / 5;
    background: #000;  /* black so contain letterboxing reads cleanly */
    overflow: hidden;
}
.sm-archive-thumb img {
    width: 100%;
    height: 100%;
    /* `contain` — never crop the producer's media. Letterboxes
       against the wrapper's background instead of cropping. */
    object-fit: contain;
    display: block;
}
.sm-archive-body { padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
.sm-archive-meta { display: flex; align-items: center; gap: 6px; }
.sm-archive-title { font-size: 16px; font-weight: 500; color: var(--text); line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sm-pagination { display: flex; justify-content: center; align-items: center; gap: 12px; margin-top: 24px; color: var(--text-3); }

/* =========================================================
 * DASHBOARD (Phase 3)
 * Real numbers only. Placeholder panels clearly marked
 * "Coming soon" until each platform's API is connected.
 * ========================================================= */

.sm-dashboard {
    display: flex;
    flex-direction: column;
    gap: 20px;
    max-width: 1320px;
}

/* KPI tiles */
.sm-kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 12px;
}
.sm-kpi {
    display: block;
    padding: 14px 16px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-left: 2px solid var(--border-strong);
    border-radius: var(--r-lg);
    color: inherit;
    text-decoration: none;
    transition: background 0.1s, border-color 0.1s;
}
.sm-kpi:hover {
    background: var(--surface-3);
    border-color: var(--border-strong);
    text-decoration: none;
    color: inherit;
}
.sm-kpi-label {
    font-size: 14px;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 500;
}
.sm-kpi-value {
    font-size: 32px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--text);
    margin: 4px 0 2px;
}
.sm-kpi-sub { font-size: 14px; color: var(--text-3); }
.sm-kpi-warning { border-left-color: var(--warning); }
.sm-kpi-warning .sm-kpi-value { color: var(--warning-text); }
.sm-kpi-danger { border-left-color: var(--danger); }
.sm-kpi-danger .sm-kpi-value { color: var(--danger-text); }
.sm-kpi-muted { opacity: 0.7; }
.sm-kpi-muted .sm-kpi-value { color: var(--text-2); }

/* Two-column row: activity chart + attention panel */
.sm-dashboard-row {
    display: grid;
    grid-template-columns: 1fr 340px;
    gap: 16px;
    align-items: start;
}

/* Activity bar chart — bars grow UP from bottom, labels sit under. */
.sm-activity-chart {
    display: flex;
    align-items: stretch;
    gap: 6px;
    height: 240px;
    padding-top: 12px;
    padding-bottom: 52px;
    margin-top: 4px;
}
.sm-activity-col {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    gap: 6px;
    min-width: 0;
    position: relative;
}
.sm-activity-bar {
    width: 100%;
    max-width: 36px;
    background: var(--accent-soft);
    border: 1px solid var(--accent-border);
    border-radius: 3px 3px 0 0;
    min-height: 2px;
    transition: background 0.1s;
}
.sm-activity-bar:hover { background: var(--accent-soft-2); }
.sm-activity-bar[data-n="0"] { background: var(--surface-3); border-color: var(--border); }
.sm-activity-xlabel {
    font-size: 13px;
    color: var(--text-4);
    white-space: nowrap;
    position: absolute;
    top: calc(100% + 6px);   /* just under the bar baseline */
    right: 50%;              /* right edge at the bar's vertical center */
    transform: rotate(-35deg);
    transform-origin: top right;
}

/* Needs-attention panel */
.sm-attention-group { margin-top: 12px; display: flex; flex-direction: column; gap: 4px; }
.sm-attention-group .t-label { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.sm-attention-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--r-sm);
    color: var(--text-2);
    text-decoration: none;
    transition: background 0.1s;
}
.sm-attention-item:hover { background: var(--surface-3); color: var(--text); text-decoration: none; }
.sm-attention-title {
    flex: 1;
    min-width: 0;
    font-size: 15px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Platform table */
.sm-plat-table .sm-t-num {
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* Engagement placeholder grid */
.sm-dashboard-placeholder-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 10px;
    margin-top: 14px;
}
.sm-dashboard-placeholder {
    padding: 12px 14px;
    background: var(--surface);
    border: 1px dashed var(--border);
    border-radius: var(--r-md);
    color: var(--text-3);
}
.sm-dashboard-placeholder-num {
    font-size: 28px;
    font-weight: 600;
    color: var(--text-4);
    margin-bottom: 2px;
}

@media (max-width: 1024px) {
    .sm-dashboard-row { grid-template-columns: 1fr; }
}

/* =========================================================
 * BOARD DETAIL MODAL
 * Clicking a card opens the post's details in a centered modal
 * overlay. Content is fetched from /board/_pane.
 * ========================================================= */

.sm-detail-modal { padding: 40px 24px; }
.sm-detail-modal[hidden] { display: none !important; }
/* Compound selector needed to win over .sm-modal (which sets 520px cap
   and appears later in the cascade). The board detail pane needs real
   estate — aim for near-viewport width on big monitors. */
.sm-modal.sm-detail-modal-body {
    width: 100%;
    max-width: min(92vw, 1400px);
    max-height: calc(100vh - 80px);
    padding: 0;
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 0;
}
/* Close button lives inline with the Edit action inside the pane header
   (see _board_pane.html) — no absolute positioning needed. */
.sm-detail-modal-content {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 24px 28px;
}
.sm-detail-modal-content.loading { opacity: 0.55; pointer-events: none; }
.sm-detail-modal-content:empty::before {
    content: "Loading…";
    color: var(--text-3);
    display: block;
    text-align: center;
    padding: 32px;
}

.sm-detail-modal-foot {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 12px 20px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    flex-shrink: 0;
}
.sm-detail-modal-foot[hidden] { display: none; }
.sm-detail-modal-delete {
    background: #dc143c;
    border-color: #dc143c;
    color: white;
    font-size: 16px;
    width: 44px;
}
.sm-detail-modal-delete:hover {
    background: #b01030;
    border-color: #b01030;
    color: white;
}

/* Pane gallery (read-only, no carousel) */
.sm-pane-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 10px;
}
.sm-pane-gallery-item {
    position: relative;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
}
.sm-pane-gallery-item img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    display: block;
}
.sm-pane-gallery-item.is-preferred {
    border-color: var(--success);
    box-shadow: 0 0 0 2px var(--success-soft);
}
.sm-preferred-tag {
    position: absolute;
    top: 6px;
    left: 6px;
    padding: 2px 8px;
    background: var(--success);
    color: white;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.sm-preferred-tag i { font-size: 10px; }

/* Selected card outline (mirrors review row) */
.sm-card.is-selected {
    box-shadow: 0 0 0 2px var(--accent), 0 4px 12px rgba(0, 0, 0, 0.4);
    background: var(--surface-4);
}

/* =========================================================
 * AUTH SHELL (login page — no sidebar, no topbar)
 * Full-viewport centered container for pre-login screens.
 * ========================================================= */
.sm-auth-shell {
    min-height: 100vh;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: var(--bg);
}
.sm-auth-shell .sp-login-container {
    margin: 0 auto;
}

/* Embedded-iframe shell (for the few places we still embed partials
   without the full app chrome). */
.sm-embed-shell { padding: 16px 20px; }

/* =========================================================
 * COMPOSER v2 — universal fields + variant tabs + preview
 * ========================================================= */

.sm-composer-v2 {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 1320px;
    margin: 0 auto;
}

/* Variant tabs (one per platform×template + add button) */
.sm-variant-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    padding: 8px 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
}
.sm-variant-tab {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px 6px 8px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    color: var(--text-2);
    font-family: inherit;
    font-size: 14px;
    cursor: pointer;
    transition: background 0.1s, border-color 0.1s, color 0.1s;
    position: relative;
}
.sm-variant-tab:hover { background: var(--surface-4); color: var(--text); }
.sm-variant-tab.is-active {
    background: var(--accent-soft);
    border-color: var(--accent-border);
    color: var(--accent-text);
}
.sm-variant-tab-label { font-weight: 500; color: var(--text); }
.sm-variant-tab.is-active .sm-variant-tab-label { color: var(--text); }
.sm-variant-tab-template {
    color: var(--text-3);
    padding-left: 6px;
    border-left: 1px solid var(--border-strong);
    margin-left: 2px;
}
.sm-variant-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px; height: 20px;
    background: transparent;
    border: none;
    color: var(--text-4);
    cursor: pointer;
    border-radius: 4px;
    padding: 0;
    margin-left: 4px;
    font-size: 11px;
}
.sm-variant-remove:hover { background: var(--danger-soft); color: var(--danger-text); }
.sm-variant-add {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    background: transparent;
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-md);
    color: var(--text-3);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
}
.sm-variant-add:hover { color: var(--accent-text); border-color: var(--accent-border); background: var(--accent-soft); }

/* =========================================================
 * PLATFORM-ICON STRIP (Composer, Metricool-style)
 * Row of platform chips; active ones show a template badge +
 * caret, inactive ones are greyed and click-to-add.
 * ========================================================= */

.sm-plat-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    padding: 8px 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
}
.sm-plat-strip-empty .sm-plat-strip-hint { margin-right: 6px; color: var(--text-3); display: inline-flex; gap: 6px; align-items: center; }
.sm-plat-strip-empty .sm-plat-strip-hint i { color: var(--text-4); }

.sm-plat-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 6px 2px 4px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--text-3);
    cursor: pointer;
    position: relative;
    transition: background 0.1s, border-color 0.1s, opacity 0.1s;
}
.sm-plat-chip:not(.is-active) { opacity: 0.5; }
.sm-plat-chip:not(.is-active):hover { opacity: 1; background: var(--surface-3); }
.sm-plat-chip.is-active {
    background: var(--surface-3);
    border-color: var(--border);
    color: var(--text-2);
}
.sm-plat-chip.is-current {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--text);
}
.sm-plat-chip-main {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 4px;
    background: transparent;
    border: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
}
.sm-plat-chip-main .plat { width: 26px; height: 26px; font-size: 12px; }
.sm-plat-chip-tpl {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-3);
    white-space: nowrap;
}
.sm-plat-chip.is-current .sm-plat-chip-tpl { color: var(--text); }
/* Caret + remove share the same box geometry so the gap inside the chip
   is uniform: icon — label — caret — X, with the chip's flex gap as the
   single source of truth for spacing between them. */
.sm-plat-chip-caret,
.sm-plat-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 50%;
    color: var(--text-4);
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
}
.sm-plat-chip-caret { font-size: 14px; }
.sm-plat-chip-remove { font-size: 10px; }
.sm-plat-chip-caret:hover { color: var(--text); background: var(--surface-4); }
.sm-plat-chip-remove:hover { background: var(--danger-soft); color: var(--danger-text); }

.sm-plat-chip-add {
    width: 34px;
    height: 34px;
    padding: 0;
    justify-content: center;
    border: 1px dashed var(--border-strong);
    color: var(--text-3);
    opacity: 0.9;
}
.sm-plat-chip-add:hover {
    color: var(--accent-text);
    border-color: var(--accent-border);
    background: var(--accent-soft);
    opacity: 1;
}

/* Template-switch popover (opens from the chip caret) */
.sm-tpl-popover {
    position: fixed;
    z-index: 50;
    min-width: 200px;
    max-width: 280px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.sm-tpl-popover-head {
    padding: 6px 10px 4px;
    color: var(--text-4);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 500;
}
.sm-tpl-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    background: transparent;
    border: none;
    color: var(--text-2);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
    border-radius: var(--r-sm);
}
.sm-tpl-option i:first-child { color: var(--text-3); width: 14px; }
.sm-tpl-option:hover { background: var(--surface-4); color: var(--text); }
.sm-tpl-option.is-current { background: var(--accent-soft); color: var(--text); }
.sm-tpl-option span { flex: 1; }
.sm-tpl-option-check { color: var(--accent-text); font-size: 12px; }

/* Composer grid: editor (left) + preview (right, sticky) */
.sm-composer-grid {
    display: grid;
    grid-template-columns: 1fr 360px;
    gap: 24px;
    align-items: flex-start;
}
.sm-composer-grid .sm-composer-editor {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
}
.sm-composer-grid .sm-composer-preview {
    position: sticky;
    top: 16px;
    /* Cap to viewport so a long mock (Pinterest pin, IG feed with long
       caption + hashtags) scrolls inside this pane instead of forcing
       the producer to scroll the whole page. The icon chrome below is
       sticky-pinned to the pane's top so it never disappears. */
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    overflow-x: hidden;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sm-composer-grid .sm-composer-preview .sm-preview-chrome {
    position: sticky;
    top: 0;
    /* Match .sm-main's surface so the pinned chrome reads as part of
       the page, not a darker overlay strip. */
    background: var(--surface);
    z-index: 2;
}

/* Field dimming when the active template doesn't use this field */
.sm-form-field { transition: opacity 0.15s; }
.sm-form-field.is-dimmed { opacity: 0.35; }
.sm-form-field.is-dimmed:focus-within { opacity: 1; }
.sm-field-note { color: var(--text-4); font-weight: 400; margin-left: 6px; }

/* Constraint hints below the preview card */
.sm-preview-constraints {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: 10px 14px;
}
.sm-preview-constraints .t-label { margin-bottom: 6px; }
.sm-constraints-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.sm-constraints-list li {
    font-size: 12px;
    color: var(--text-3);
    padding-left: 14px;
    position: relative;
}
.sm-constraints-list li::before {
    content: "·";
    position: absolute;
    left: 4px;
    color: var(--text-4);
}

/* Review-image lightbox — opens on click of any sm-carousel-photo
   image. Takes the entire viewport (no padding so the picture has all
   the horizontal space it can get). Layout is a vertical flex column:
   counter on top, image flanked by arrow buttons in the middle row,
   big Select button at the bottom. Nothing overlaps the image — every
   chrome element lives in its own row. The image is letterboxed
   (object-fit: contain) — per CLAUDE.md, the producer's content is
   never cropped. */
/* Two-class selector deliberately — `.sm-modal-overlay` (defined later
   in this file) sets a semi-transparent backdrop with equal specificity,
   which would otherwise win on source order and let the page bleed
   through. `.sm-modal-overlay.sm-lightbox` beats it on specificity. */
.sm-modal-overlay.sm-lightbox {
    padding: 24px;
    background: #0a0d14;
    z-index: 1000;
}
.sm-lightbox-frame {
    /* Bordered panel that wraps tightly around the content (counter +
       image-with-arrows + Select). Width/height are driven by the
       image's max constraints below — the panel collapses to fit. */
    width: max-content;
    max-width: calc(100vw - 48px);
    max-height: calc(100vh - 48px);
    margin: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 20px 24px 24px;
    background: var(--surface-1);
    border: 1px solid var(--border-strong);
    border-radius: 12px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6);
}
.sm-lightbox-counter {
    color: rgba(255, 255, 255, 0.85);
    background: rgba(0, 0, 0, 0.45);
    padding: 8px 18px;
    border-radius: 999px;
    /* 2× the previous t-xs sizing — readable from across the room. */
    font-size: 22px;
    font-weight: 600;
    line-height: 1;
    backdrop-filter: blur(4px);
}
.sm-lightbox-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
}
.sm-lightbox-img {
    /* Viewport-relative caps so the frame can shrink-wrap. Reserves room
       for: 2 arrows (64×2) + 2×20px gap + 2×24px frame padding (~216px
       wide), counter (~30) + Select btn (~50) + 2×16 gaps + 20+24 frame
       padding (~156px tall). The Select button only renders for picker
       galleries, so 156 is the tight upper bound. */
    max-width: calc(100vw - 216px);
    max-height: calc(100vh - 156px);
    width: auto;
    height: auto;
    object-fit: contain;
    user-select: none;
    border-radius: 6px;
    box-shadow: 0 12px 48px rgba(0, 0, 0, 0.6);
    /* Better resampling on the aggressive downscales that happen when
       the source is much larger than the viewport — default bilinear
       softens text-heavy graphics noticeably. */
    image-rendering: -webkit-optimize-contrast;
    image-rendering: high-quality;
}
.sm-lightbox-select-btn {
    /* ~3× the standard btn — bigger font, more padding, wide hit area
       so the action is unmistakable from the bottom of the modal. */
    min-width: 240px;
    padding: 18px 36px;
    font-size: 18px;
    font-weight: 600;
    gap: 10px;
    justify-content: center;
}
.sm-lightbox-select-btn i { font-size: 18px; }
.sm-lightbox-select-btn.is-selected {
    background: var(--success-soft);
    color: var(--success-text);
    border-color: var(--success);
}
.sm-lightbox-arrow {
    flex: 0 0 auto;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.5);
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: rgba(255, 255, 255, 0.85);
    font-size: 24px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 120ms ease, color 120ms ease;
}
.sm-lightbox-arrow:hover:not(:disabled) { background: rgba(0, 0, 0, 0.75); color: #fff; }
.sm-lightbox-arrow:disabled { opacity: 0.25; cursor: default; pointer-events: none; }
/* The arrows and Select button declare explicit `display`, which beats
   the UA's [hidden] { display: none } rule on specificity. Restore the
   hide behaviour so element.hidden = true actually hides them. */
.sm-lightbox-arrow[hidden],
.sm-lightbox-select-btn[hidden] { display: none; }
.sm-lightbox-close {
    position: absolute;
    top: 16px;
    right: 16px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.5);
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: rgba(255, 255, 255, 0.85);
    font-size: 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
}
.sm-lightbox-close:hover { background: rgba(0, 0, 0, 0.75); color: #fff; }
/* The carousel photo wrapper is the click target (any pixel of the
   image area opens the lightbox) — give it the zoom cursor so the
   affordance is obvious at rest. */
.sm-carousel-photo { cursor: zoom-in; }

/* Add-platform modal */
.sm-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
    padding: 24px;
}
.sm-modal-overlay[hidden] { display: none; }
.sm-modal {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
    width: 100%;
    max-width: 520px;
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.sm-modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
/* Two-column Add Platform modal: platforms on the left, the selected
   platform's templates on the right, full-width Add button below. */
.sm-add-modal {
    max-width: 720px;
    padding: 0;
    gap: 0;
}
.sm-add-modal .sm-modal-head {
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}
.sm-add-cols {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 0;
    max-height: 60vh;
    min-height: 340px;
}
.sm-add-col {
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    overflow-y: auto;
}
.sm-add-col-plats {
    border-right: 1px solid var(--border);
    background: var(--surface);
}
.sm-add-col-tpls { background: var(--surface-2); }

.sm-add-plat {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--r-md);
    color: var(--text-2);
    cursor: pointer;
    font-family: inherit;
    font-size: 14px;
    text-align: left;
}
.sm-add-plat-label { flex: 1; }
.sm-add-chev { color: var(--text-4); font-size: 12px; }
.sm-add-plat:hover { background: var(--surface-3); color: var(--text); }
.sm-add-plat.is-selected {
    background: var(--accent-soft);
    border-color: var(--accent-border);
    color: var(--text);
}
.sm-add-plat.is-selected .sm-add-chev { color: var(--accent-text); }

.sm-add-tpl {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 12px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    color: var(--text-2);
    cursor: pointer;
    font-family: inherit;
    font-size: 14px;
    text-align: left;
}
.sm-add-tpl:hover { background: var(--surface-4); border-color: var(--border-strong); color: var(--text); }
.sm-add-tpl.is-selected {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--text);
}
.sm-add-tpl-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 500;
}
.sm-add-tpl-head i:first-child { color: var(--text-3); width: 16px; text-align: center; }
.sm-add-tpl-label { flex: 1; }
.sm-add-tpl-check {
    color: var(--accent-text);
    font-size: 13px;
    opacity: 0;
    transition: opacity 0.1s;
}
.sm-add-tpl.is-selected .sm-add-tpl-check { opacity: 1; }
.sm-add-tpl-details { color: var(--text-3); }
.sm-add-empty {
    color: var(--text-4);
    text-align: center;
    padding: 40px 12px;
}

.sm-add-foot {
    padding: 14px 20px;
    border-top: 1px solid var(--border);
    display: flex;
}
.sm-add-foot .sm-add-confirm {
    width: 100%;
    justify-content: center;
    font-size: 15px;
    padding: 10px 16px;
}

/* Platform-icon switcher — sits inside .sm-preview-chrome at the top.
   Click an icon to swap which variant the mock renders. The active
   icon is fully opaque + ringed; inactive icons fade so the active one
   reads at a glance. */
.sm-preview-switcher {
    display: flex;
    align-items: center;
    gap: 6px;
}
.sm-preview-switcher-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    cursor: pointer;
    padding: 2px;
    border-radius: 50%;
    transition: transform 0.1s, box-shadow 0.1s;
}
.sm-preview-switcher-btn .plat {
    /* Slightly larger than the standard chip so the icon row reads as
       primary navigation, not decorative. */
    width: 36px;
    height: 36px;
    border-radius: 50%;
    opacity: 0.45;
    transition: opacity 0.1s, transform 0.1s;
}
.sm-preview-switcher-btn:hover .plat { opacity: 1; }
.sm-preview-switcher-btn.is-active .plat {
    opacity: 1;
    box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);
}

@media (max-width: 1024px) {
    .sm-composer-grid { grid-template-columns: 1fr; }
    .sm-composer-grid .sm-composer-preview { position: static; }
}

/* Review-pane verdict bar — per-variant approve/request-changes action row */
.sm-verdict-bar {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: 12px 14px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}
.sm-verdict-info { color: var(--text-3); }
.sm-verdict-actions { display: flex; gap: 6px; }

.sm-variant-tab-pill {
    padding: 0 4px;
    font-size: 0;
    line-height: 0;
}
.sm-variant-tab-pill .dot { width: 6px; height: 6px; }

.sm-field-override {
    border-left: 2px solid var(--accent-border);
}
.sm-variant-tabs-review {
    margin-bottom: 0;
    border-radius: var(--r-md);
}

/* Variant-scoped comment — subtle left border in the active accent */
.sm-comment-variant { border-left: 2px solid var(--accent); }

/* Notes field (Composer — inline at bottom of editor) */
.sm-notes-textarea {
    resize: vertical;
    min-height: 120px;
}
.sm-notes-status {
    color: var(--text-4);
}
.sm-notes-status.is-error { color: var(--danger-text); }

/* Content toolbar (Composer body textarea) */
.sm-content-toolbar {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 4px 2px 0;
}
.sm-ct-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px; height: 28px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    color: var(--text-3);
    cursor: pointer;
    padding: 0;
    font-size: 14px;
    transition: color 0.1s, background 0.1s, border-color 0.1s;
}
.sm-ct-btn:hover { color: var(--text); background: var(--surface-3); border-color: var(--border); }
.sm-ct-spacer { flex: 1; }

/* Emoji picker popover */
.sm-emoji-popover {
    position: fixed;
    z-index: 60;
    width: 260px;
    max-height: 320px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sm-emoji-search { font-size: 13px; padding: 6px 8px; }
.sm-emoji-grid {
    flex: 1;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sm-emoji-group-label {
    color: var(--text-4);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 500;
    padding: 2px 4px;
}
.sm-emoji-row {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
}
.sm-emoji-btn {
    width: 28px; height: 28px;
    background: transparent;
    border: none;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    border-radius: var(--r-sm);
    padding: 0;
}
.sm-emoji-btn:hover { background: var(--surface-4); }

/* =========================================================
 * COMPOSER STICKY BOTTOM BAR
 * Cancel / Delete · schedule date · Save + overflow menu.
 * Stays pinned to the bottom of the composer viewport as Jane
 * scrolls through presets / media / storyboard.
 * ========================================================= */

.sm-composer-bar {
    position: sticky;
    /* The bar's `margin-bottom: -24px` (below) bleeds into .sm-content-inner's
       bottom padding so the bar sits flush with the scrollport edge. Sticky
       pins to the scroll container's bottom — `bottom: 0` keeps the whole
       bar inside the viewport. */
    bottom: 0;
    z-index: 20;
    /* Flex with space-between distributes slack equally between the
       three groups, so the *visible* gap from Delete (left) to the
       capsule and the gap from the date to Cancel (right) match —
       which the prior grid (1fr auto 1fr) couldn't, since the right
       button cluster is wider than the left and would push the visual
       gutter inward on that side. */
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
    margin: 16px -28px -24px;   /* bleed to the edges of sm-content padding */
    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.25);
}
.sm-composer-bar-left { display: flex; align-items: center; gap: 8px; }
/* The bar center holds the SOP checklist capsule + the schedule
   picker. The pair sits packed together with gap: 24px between them;
   centering on the bar comes from the outer 1fr auto 1fr grid (the
   1fr columns absorb equal slack on each side regardless of how wide
   the left/right buttons are), so the capsule + date combination is
   geometrically centred between Delete on the left and Cancel/Save
   on the right. */
.sm-composer-bar-center {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 24px;
}
.sm-composer-bar-right { display: flex; justify-content: flex-end; align-items: center; gap: 8px; }

/* Producer SOP checklist — capsule + drop-up popover. Capsule lives
   in the composer bar; popover anchors to the capsule and opens
   upward (drop-up) so it stays within the viewport even when the bar
   is at the bottom of the scroll container. */
.sm-checklist { position: relative; }
.sm-checklist[hidden] { display: none; }
.sm-checklist-capsule {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface-3);
    color: var(--text);
    /* Match the rest of the composer bar — same family/size as the
       surrounding .btn elements (15px, body font-family). */
    font-family: inherit;
    font-size: 15px;
    font-weight: 500;
    cursor: pointer;
    transition: background 120ms ease, border-color 120ms ease;
}
.sm-checklist-capsule:hover { background: var(--surface-4); }
.sm-checklist-capsule.is-incomplete {
    border-color: var(--warning-text);
    color: var(--warning-text);
}
.sm-checklist-capsule.is-complete {
    border-color: var(--success-text);
    color: var(--success-text);
}
.sm-checklist-pop {
    position: absolute;
    bottom: calc(100% + 8px);
    left: 0;
    min-width: 280px;
    /* No max-width — the popover grows to fit the longest row so long
       platform / item labels don't wrap mid-cell. */
    width: max-content;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.35);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    z-index: 30;
}
.sm-checklist-pop[hidden] { display: none; }
.sm-checklist-pop-head {
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 11px;
}
.sm-checklist-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}
.sm-checklist-table tr + tr th,
.sm-checklist-table tr + tr td {
    border-top: 1px solid var(--border);
}
.sm-checklist-table th,
.sm-checklist-table td {
    padding: 6px 8px;
    text-align: left;
    vertical-align: middle;
    /* Both columns stay on one line — the popover grows wider rather
       than wrapping a label mid-cell. */
    white-space: nowrap;
}
.sm-checklist-platform {
    color: var(--text-3);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    width: 1%;            /* shrink to content; right cell gets the rest */
}
.sm-checklist-item {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    color: var(--text);
}
.sm-checklist-checkbox {
    width: 16px;
    height: 16px;
    accent-color: var(--success-text);
    cursor: pointer;
}

/* Board card: warning triangle when the post still has unchecked
   checklist items. Sits in the meta row beside the favorite star. */
.sm-card-checklist-warn {
    color: var(--warning-text);
    font-size: 14px;
}


/* Delete is a destructive terminal action — give it the visual weight of
   one. Crimson rest state, brighter crimson on hover, double-wide hitbox,
   and a noticeably larger icon so it reads from across the bar. */
.sm-composer-bar-delete {
    background: #dc143c;
    border-color: #dc143c;
    color: white;
    font-size: 18px;
    width: 56px;
}
.sm-composer-bar-delete:hover {
    background: #b01030;
    border-color: #b01030;
    color: white;
}

.sm-schedule-field {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    color: var(--text-2);
    font-size: 16px;
}
.sm-schedule-field:hover,
.sm-schedule-field:focus-within { border-color: var(--border-strong); color: var(--text); }
.sm-schedule-field i { color: var(--text-3); }

/* Calendar trigger: an <input type="date"> overlaid on the icon at
   opacity:0 so clicking the icon opens the browser's native picker.
   Hidden from tab order — the segmented inputs are the keyboard path. */
.sm-dt-cal-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.sm-dt-cal-input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    border: 0;
    padding: 0;
    background: transparent;
    color: transparent;
}
.sm-dt-cal-input::-webkit-calendar-picker-indicator {
    width: 100%; height: 100%;
    cursor: pointer;
    margin: 0; padding: 0;
}

/* Segmented date/time inputs. Each segment is a tiny numeric input
   sized to fit its placeholder; auto-advance is wired in JS. */
.sm-dt-inputs {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.sm-dt-seg {
    background: transparent;
    border: 0;
    padding: 0 2px;
    color: var(--text);
    font: inherit;
    text-align: center;
    outline: none;
    /* Wide enough that "mm"/"dd"/"hh" placeholders and the actual two
       typed digits never clip — m is the widest glyph in the set. */
    width: 30px;
    caret-color: var(--accent);
}
.sm-dt-seg-year { width: 56px; }
.sm-dt-seg::placeholder { color: var(--text-4); }
.sm-dt-seg:focus { background: var(--surface-4); border-radius: 3px; }
.sm-dt-sep {
    color: var(--text-3);
    user-select: none;
}

/* Save + overflow split button */
.sm-composer-save-group {
    position: relative;
    display: inline-flex;
    align-items: stretch;
    gap: 1px;
    background: var(--border);  /* the 1px gap between buttons */
    border-radius: var(--r-md);
    overflow: hidden;
}
.sm-composer-save-group > .btn {
    border-radius: 0;
    margin: 0;
}
.sm-composer-save-group > .btn:first-child {
    border-top-left-radius: var(--r-md);
    border-bottom-left-radius: var(--r-md);
}
.sm-composer-save-group .sm-save-more {
    border-top-right-radius: var(--r-md);
    border-bottom-right-radius: var(--r-md);
    padding: 6px 10px;
    min-width: 0;
}
.sm-save-menu {
    position: absolute;
    bottom: calc(100% + 4px);
    right: 0;
    min-width: 200px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
    padding: 4px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 30;
}
.sm-save-menu[hidden] { display: none; }
.sm-save-menu button {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    background: transparent;
    border: none;
    color: var(--text-2);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
    border-radius: var(--r-sm);
}
.sm-save-menu button:hover { background: var(--surface-4); color: var(--text); }
.sm-save-menu button i { color: var(--text-3); width: 14px; }

/* Tighten the internal-title row now that the date field moved out */
.sm-form-row-2 { grid-template-columns: 1fr auto; }
/* Title + Card status + Posted-on picker — three side-by-side fields. */
.sm-form-row-3 { grid-template-columns: 1fr auto auto; }
.sm-form-row-3 .input[disabled] { opacity: 0.55; cursor: not-allowed; }

/* =========================================================
 * PRESETS CARDS (Composer "show-only-what's-needed" pattern)
 * One collapsible <details> per active variant. Renders only
 * the override fields that apply to the platform × template.
 * ========================================================= */

.sm-presets-section { gap: 10px; }
.sm-presets-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.sm-preset-card {
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
}
.sm-preset-card-global { background: var(--surface-2); border-color: var(--border-strong); }
.sm-preset-global-icon { color: var(--text-3); font-size: 14px; width: 16px; text-align: center; }
.sm-switch-inline {
    /* Compact switch — vertical alignment + gap-to-label is handled by
       the parent .sm-preset-meta's inline-flex layout. */
    width: 28px;
    height: 16px;
}
.sm-switch-inline .sm-switch-thumb { width: 10px; height: 10px; }
.sm-switch-inline input:checked ~ .sm-switch-track .sm-switch-thumb { transform: translateX(12px); }
.sm-preset-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    cursor: pointer;
    list-style: none;
    user-select: none;
    color: var(--text);
    font-weight: 500;
    font-size: 14px;
}
.sm-preset-head::-webkit-details-marker { display: none; }
/* Bigger platform badge + bolder title on each preset card header. */
.sm-preset-head .plat { width: 32px; height: 32px; border-radius: 7px; }
/* Scale the FA glyph for the preset-head size. The previous rule put
   font-size on the .plat parent, which re-enabled the hidden inline
   letter codes ("IG", "FB", …) and showed them as ghost text behind
   the brand glyph. Targeting ::before keeps the parent at font-size
   0 so the text stays collapsed. */
.sm-preset-head .plat::before { font-size: 13px; }
.sm-preset-title { flex: 1; font-size: 17px; font-weight: 700; color: var(--text); }
.sm-preset-meta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--text-2);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 500;
    font-size: 12px;
}
.sm-preset-chev {
    color: var(--text-2);
    font-size: 12px;
    transition: transform 0.15s;
}
.sm-preset-card[open] .sm-preset-chev { transform: rotate(180deg); }
.sm-preset-card:hover { border-color: var(--border-strong); }

/* Brand-tinted header strip per platform — the logo+title band picks up
   the platform's signature color so each preset card is recognisable at
   a glance. Body stays on neutral --surface-2 for legibility. */
.sm-preset-card[data-platform="ig_post"]    .sm-preset-head { background: color-mix(in srgb, #dd2a7b 28%, var(--surface-3)); }
.sm-preset-card[data-platform="tiktok"]     .sm-preset-head { background: color-mix(in srgb, #25f4ee 22%, var(--surface-3)); }
.sm-preset-card[data-platform="x_twitter"]  .sm-preset-head { background: color-mix(in srgb, #000000 55%, var(--surface-3)); }
.sm-preset-card[data-platform="fb_post"]    .sm-preset-head { background: color-mix(in srgb, #1877f2 28%, var(--surface-3)); }
.sm-preset-card[data-platform="youtube"]    .sm-preset-head { background: color-mix(in srgb, #ff0033 26%, var(--surface-3)); }
.sm-preset-card[data-platform="pinterest"]  .sm-preset-head { background: color-mix(in srgb, #bd081c 28%, var(--surface-3)); }
.sm-preset-card[data-platform="substack"]   .sm-preset-head { background: color-mix(in srgb, #ff6719 26%, var(--surface-3)); }

.sm-preset-body {
    padding: 12px 14px 14px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.sm-preset-empty {
    color: var(--text-4);
    margin: 0;
}
.sm-preset-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.sm-preset-label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-3);
}
.sm-preset-hint {
    color: var(--text-4);
    line-height: 1.35;
}
.sm-preset-counter { text-align: right; }

.sm-preset-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.sm-preset-toggle-row .sm-preset-label { color: var(--text-2); font-weight: 400; font-size: 14px; }

.sm-preset-status {
    align-self: flex-end;
    color: var(--text-4);
    font-size: 11px;
    min-height: 14px;
}
.sm-preset-status.is-error { color: var(--danger-text); }

/* Toggle switch (iOS-style) */
.sm-switch {
    position: relative;
    display: inline-block;
    width: 36px;
    height: 20px;
    flex-shrink: 0;
}
.sm-switch input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
    z-index: 1;
}
.sm-switch-track {
    position: absolute;
    inset: 0;
    background: var(--surface-4);
    border: 1px solid var(--border);
    border-radius: 999px;
    transition: background 0.15s, border-color 0.15s;
}
.sm-switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    background: var(--text-2);
    border-radius: 50%;
    transition: transform 0.15s, background 0.15s;
}
.sm-switch input:checked ~ .sm-switch-track {
    background: var(--accent);
    border-color: var(--accent);
}
.sm-switch input:checked ~ .sm-switch-track .sm-switch-thumb {
    transform: translateX(16px);
    background: #fff;
}

/* Empty-state hint in the variant tab strip when a draft has 0 variants */
.sm-variant-tabs-empty { align-items: center; }
.sm-variant-tabs-hint {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--text-3);
    padding: 4px 8px;
}
.sm-variant-tabs-hint i { color: var(--text-4); }
.sm-variant-add-primary {
    background: var(--accent-soft);
    border-color: var(--accent-border);
    color: var(--accent-text);
}
.sm-variant-add-primary:hover { background: var(--accent-soft-2); }

/* Empty preview when no variant selected yet */
.sm-preview-empty {
    background: var(--surface-2);
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-lg);
    padding: 32px 20px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    color: var(--text-3);
}
.sm-preview-empty i { font-size: 28px; color: var(--text-4); }
.sm-preview-empty-title {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-2);
}


/* =========================================================
 * COMPOSER PREVIEW RENDERERS (.pv-*)
 *
 * One look per platform+template. Each preview card has an outer
 * `.pv` wrapper plus a platform modifier (.pv-ig, .pv-tt, …) and a
 * template modifier (.pv-ig-feed, .pv-ig-reel, …). Drop-in swap —
 * composer_previews.js re-renders the whole #preview-card innerHTML
 * on input or variant change.
 * ========================================================= */

.pv {
    background: #ffffff;
    color: #111;
    border-radius: var(--r-lg);
    overflow: hidden;
    font-size: 13px;
    line-height: 1.4;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    box-shadow: 0 0 0 1px var(--border);
}
/* Vertical templates render at a phone-shaped width so they don't dominate
   the right rail. Feed-shape templates fill the column. */
.pv-ig-reel,
.pv-tt,
.pv-fb-reel,
.pv-yt-short,
.pv-pn-video {
    max-width: 280px;
    margin-left: auto;
    margin-right: auto;
}
.pv-pn-pin {
    max-width: 320px;
    margin-left: auto;
    margin-right: auto;
}

/* Shared avatar styles (platform-tinted circles) */
.pv-av {
    display: inline-block;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    flex-shrink: 0;
    background: linear-gradient(135deg, #6366f1, #8b5cf6);
}
.pv-av-sm { width: 22px; height: 22px; }
.pv-av-grad-ig { background: linear-gradient(135deg, #f58529 0%, #dd2a7b 50%, #515bd4 100%); }
.pv-av-x  { background: #0f1419; }
.pv-av-fb { background: #1877f2; }
.pv-av-yt { background: #ff0033; }
.pv-av-pn { background: #bd081c; }
.pv-av-tt { background: linear-gradient(135deg, #25f4ee 0%, #000 50%, #fe2c55 100%); }
.pv-av-sub { background: #ff6719; }

/* Shared media block (non-vertical) */
.pv-media {
    background: #f1f1f3;
    overflow: hidden;
    width: 100%;
    position: relative;
    display: block;
}
/* Feed-style natural-flow media — image / video render at their actual
   aspect ratio, no forcing, no cropping. The wrapper sizes to the
   media. See CLAUDE.md "Never crop the producer's content." */
.pv-media .pv-feed-img,
.pv-media .pv-feed-video {
    width: 100%;
    height: auto;
    display: block;
}
.pv-media-video { position: relative; }

/* Carousel: first slide is in normal flow (drives the wrapper height),
   the rest stack on top via absolute positioning. Switching is just
   an opacity flip on `.is-active`. */
.pv-feed-carousel { position: relative; }
.pv-feed-slide {
    width: 100%;
    height: auto;
    display: block;
    opacity: 0;
    transition: opacity 0.18s ease;
    pointer-events: none;
}
.pv-feed-slide:not(.is-active) {
    position: absolute;
    inset: 0;
    height: 100%;
    object-fit: contain;
}
.pv-feed-slide.is-active {
    position: relative;
    opacity: 1;
    pointer-events: auto;
}
.pv-media-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #9a9aa3;
    font-size: 12px;
    background: repeating-linear-gradient(45deg, #f5f5f7, #f5f5f7 10px, #eceef2 10px, #eceef2 20px);
}
.pv-play {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 40px;
    height: 40px;
    font-size: 18px;
    color: #fff;
    background: rgba(0, 0, 0, 0.55);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    padding: 0;
    cursor: pointer;
    z-index: 3;
    transition: opacity 0.15s ease, background 0.15s ease;
}
.pv-play:hover { background: rgba(0, 0, 0, 0.78); }
.pv-play-big { width: 56px; height: 56px; font-size: 22px; }
/* Hide the play overlay while the sibling video is playing. The JS
   adds `.is-playing` to the immediate parent on `play` and removes it on
   `pause`/`ended`. */
.is-playing > .pv-play { opacity: 0; pointer-events: none; }

/* Carousel chevrons — interactive buttons shown on any preview whose
   media contains 2+ images. Click flips the active slide via the
   delegated handler in composer_previews.js. */
.pv-carousel-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    z-index: 2;
    border: 0;
    padding: 0;
    cursor: pointer;
}
.pv-carousel-nav:hover { background: rgba(0, 0, 0, 0.78); }
.pv-carousel-prev { left: 8px; }
.pv-carousel-next { right: 8px; }

/* Stacked slides: only .is-active is visible. Track fills the parent
   media container (which already sets aspect-ratio + overflow:hidden). */
.pv-carousel-track {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}
.pv-carousel-slide {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    transition: opacity 0.18s ease;
    pointer-events: none;
}
.pv-carousel-slide.is-active {
    opacity: 1;
    pointer-events: auto;
}

/* Vertical full-bleed container for reels / shorts / tiktok */
.pv-vertical {
    position: relative;
    width: 100%;
    background: #000;
    overflow: hidden;
    color: #fff;
}
.pv-vert-media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* Never crop content — both images and videos in vertical 9:16
       mocks letterbox if their aspect ratio doesn't match. The 9:16
       frame stays for overlay UI (right rail, top bar, bottom nav);
       the producer's media inside is always shown in full.
       See CLAUDE.md "Never crop the producer's content." */
    object-fit: contain;
    background: #000;
}
.pv-vert-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(255,255,255,0.55);
    background: repeating-linear-gradient(45deg, #18181b, #18181b 10px, #1f1f22 10px, #1f1f22 20px);
    font-size: 12px;
}
.pv-vert-topbar {
    position: absolute;
    top: 0; left: 0; right: 0;
    padding: 10px 14px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #fff;
    font-weight: 600;
    font-size: 13px;
    text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}
.pv-vert-rightcol {
    position: absolute;
    bottom: 80px;
    right: 10px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    color: #fff;
    font-size: 10px;
    text-align: center;
    text-shadow: 0 1px 2px rgba(0,0,0,0.6);
}
.pv-vert-rightcol > div {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}
.pv-vert-rightcol i { font-size: 22px; }
.pv-vert-bottom {
    position: absolute;
    bottom: 0; left: 0; right: 56px;
    padding: 12px 14px 14px;
    color: #fff;
    background: linear-gradient(to top, rgba(0,0,0,0.65), transparent);
    font-size: 12px;
    text-shadow: 0 1px 2px rgba(0,0,0,0.5);
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.pv-vert-user {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
}
.pv-vert-handle { font-weight: 600; }
.pv-vert-follow {
    border: 1px solid rgba(255,255,255,0.8);
    padding: 2px 10px;
    border-radius: 4px;
    font-size: 11px;
    margin-left: 4px;
}
.pv-vert-caption {
    font-weight: 400;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    max-height: 3em;
    overflow: hidden;
}
.pv-vert-tags {
    font-size: 11px;
    color: #c5c8ff;
    font-family: var(--font-mono);
    word-break: break-word;
}
.pv-vert-audio {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    opacity: 0.9;
}
.pv-vert-audio-thumb { margin-left: auto; }
.pv-av-xs { width: 16px; height: 16px; }

/* Decorative paused-state scrubber rails — left/right step icons that
   flank the central interactive .pv-play button. Hidden once playback
   starts (the .is-playing class on the parent fades them out, same as
   the play button). pointer-events:none so clicks fall through to the
   real play button at the same z-level. */
.pv-scrubber-sides {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 96px;
    pointer-events: none;
    z-index: 2;
    transition: opacity 0.15s ease;
}
.pv-scrubber-sides i {
    color: rgba(255, 255, 255, 0.92);
    font-size: 22px;
    text-shadow: 0 1px 4px rgba(0,0,0,0.5);
}
.is-playing > .pv-scrubber-sides { opacity: 0; }

/* --- Instagram Feed -------------------------------------------------- */
.pv-ig-feed .pv-ig-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
}
.pv-ig-head-text { line-height: 1.2; flex: 1; min-width: 0; }
.pv-ig-handle { font-weight: 600; font-size: 13px; }
.pv-ig-location { font-size: 11px; color: #8a8a93; }
.pv-ig-more { color: #111; }
.pv-ig-actions {
    display: flex;
    gap: 14px;
    align-items: center;
    padding: 10px 12px 0;
    font-size: 22px;
    color: #111;
}
.pv-ig-bookmark { margin-left: auto; }
.pv-ig-body { padding: 6px 12px 12px; }
.pv-ig-likes { display: block; font-weight: 600; font-size: 13px; margin-bottom: 4px; }
.pv-ig-caption { font-size: 13px; word-break: break-word; }
.pv-ig-handle-inline { font-weight: 600; margin-right: 4px; }
.pv-ig-tags {
    margin-top: 4px;
    color: #00376b;
    font-size: 12px;
    word-break: break-word;
}

/* --- Instagram Reel (also used as base for other vertical variants) --- */
.pv-ig-reel { background: #000; border-radius: var(--r-lg); overflow: hidden; }

/* --- TikTok ---------------------------------------------------------- */
.pv-tt { background: #000; border-radius: var(--r-lg); overflow: hidden; }
.pv-tt-topbar { justify-content: center; gap: 18px; font-weight: 500; }
.pv-tt-topbar .pv-tt-active {
    position: relative;
    padding-bottom: 4px;
}
.pv-tt-topbar .pv-tt-active::after {
    content: "";
    position: absolute;
    left: 50%; bottom: -2px;
    transform: translateX(-50%);
    width: 18px; height: 2px; background: #fff; border-radius: 1px;
}
.pv-tt-rightcol .pv-tt-avatar {
    position: relative;
    margin-bottom: 4px;
}
.pv-tt-rightcol .pv-tt-avatar .pv-av { border: 2px solid #fff; }
.pv-tt-plus {
    position: absolute;
    bottom: -6px;
    left: 50%;
    transform: translateX(-50%);
    width: 16px; height: 16px;
    background: #fe2c55;
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}
.pv-tt-handle { font-weight: 600; font-size: 13px; }
.pv-tt-audio { display: flex; align-items: center; gap: 6px; font-size: 11px; opacity: 0.9; }

/* TikTok rail in paused-state: handle avatar (no follow plus), heart 0,
   comment 0, then a small profile chip ("share" target) at the bottom. */
.pv-tt-rail-avatar,
.pv-tt-rail-share {
    width: 38px; height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0,0,0,0.45);
    border-radius: 50%;
}
.pv-tt-rail-avatar .pv-av,
.pv-tt-rail-share .pv-av { width: 30px; height: 30px; }

/* TikTok bottom-bottom: caption sits above the nav, so reserve room. */
.pv-tt-bottom { bottom: 56px; right: 60px; }

/* TikTok bottom navigation bar (Home / Friends / [+] / Inbox / Profile) */
.pv-tt-nav {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    display: flex;
    justify-content: space-around;
    align-items: center;
    padding: 6px 4px 8px;
    background: #000;
    color: #fff;
    font-size: 10px;
    border-top: 1px solid rgba(255,255,255,0.08);
}
.pv-tt-nav span {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    line-height: 1.1;
}
.pv-tt-nav i { font-size: 18px; }
.pv-tt-nav .pv-tt-nav-plus {
    width: 38px; height: 24px;
    border-radius: 6px;
    background: linear-gradient(90deg, #25f4ee 0 30%, #fff 30% 70%, #fe2c55 70% 100%);
    display: flex;
    align-items: center;
    justify-content: center;
}
.pv-tt-nav .pv-tt-nav-plus i { color: #000; font-size: 14px; }
.pv-tt-photo-count {
    position: absolute;
    top: 52px; right: 12px;
    padding: 3px 8px;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 11px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    gap: 4px;
}

/* --- X / Twitter ----------------------------------------------------- */
.pv-x { padding: 12px 14px; background: #fff; color: #0f1419; }
.pv-x-row { display: flex; gap: 10px; }
.pv-x-main { flex: 1; min-width: 0; }
.pv-x-head {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 13px;
    margin-bottom: 2px;
    flex-wrap: wrap;
}
.pv-x-name { font-weight: 700; }
.pv-x-verified { color: #1d9bf0; font-size: 12px; }
.pv-x-handle { color: #536471; }
.pv-x-more { color: #536471; margin-left: auto; }
.pv-x-body {
    font-size: 14px;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    color: #0f1419;
}
.pv-x-tags {
    margin-top: 4px;
    color: #1d9bf0;
    font-size: 12px;
    font-family: var(--font-mono);
    word-break: break-word;
}
.pv-x-media {
    margin-top: 8px;
    border-radius: 14px;
    overflow: hidden;
    border: 1px solid #cfd9de;
}
.pv-x-media .pv-media { border-radius: 14px; }
.pv-x-actions {
    display: flex;
    justify-content: space-between;
    gap: 6px;
    color: #536471;
    margin-top: 8px;
    font-size: 12px;
}
.pv-x-actions span { display: flex; align-items: center; gap: 4px; }

/* Thread variant */
.pv-x-thread { padding: 12px 14px 4px; }
.pv-x-thread-row { margin-bottom: 10px; }
.pv-x-thread-rail {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}
.pv-x-thread-line {
    flex: 1;
    width: 2px;
    background: #e1e8ed;
    min-height: 24px;
    margin-top: 2px;
}
.pv-x-thread-more {
    text-align: center;
    color: #536471;
    padding: 8px 0 12px;
    font-size: 12px;
    border-top: 1px solid #e1e8ed;
}

/* --- Facebook Feed --------------------------------------------------- */
.pv-fb { background: #fff; color: #050505; }
.pv-fb-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px 6px;
}
.pv-fb-head-text { flex: 1; line-height: 1.2; min-width: 0; }
.pv-fb-name { font-weight: 600; font-size: 13px; }
.pv-fb-meta {
    color: #65676b;
    font-size: 11px;
    display: flex;
    align-items: center;
    gap: 4px;
}
.pv-fb-more { color: #65676b; margin-left: auto; }
.pv-fb-body {
    padding: 4px 12px 8px;
    font-size: 14px;
    white-space: pre-wrap;
    overflow-wrap: break-word;
}
.pv-fb-tags {
    padding: 0 12px 8px;
    color: #1877f2;
    font-size: 12px;
    font-family: var(--font-mono);
    word-break: break-word;
}
.pv-fb-counts {
    display: flex;
    justify-content: space-between;
    padding: 8px 12px;
    color: #65676b;
    font-size: 12px;
    border-top: 1px solid #e4e6eb;
    margin-top: 4px;
}
.pv-fb-counts span { display: flex; align-items: center; gap: 4px; }
.pv-fb-actions {
    display: flex;
    justify-content: space-around;
    padding: 6px 0;
    color: #606770;
    font-size: 13px;
    border-top: 1px solid #e4e6eb;
}
.pv-fb-actions span { display: flex; align-items: center; gap: 6px; padding: 6px 10px; }

/* Facebook Reel */
.pv-fb-reel { background: #000; border-radius: var(--r-lg); overflow: hidden; }
.pv-fb-topbar { color: #fff; font-size: 14px; font-weight: 600; }
.pv-fb-follow { background: #1877f2; border-color: #1877f2; color: #fff; }

/* FB Reel rail: tall stack of Send / Like / Comment / Share / More.
   The "More" lives at the very bottom of the rail, not inline. */
.pv-fb-rightcol { bottom: 64px; gap: 12px; }
.pv-fb-rightcol .pv-fb-more {
    width: 38px; height: 38px;
    background: rgba(0,0,0,0.55);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto;
}
.pv-fb-rightcol .pv-fb-more i { font-size: 14px; color: #fff; }
.pv-fb-bottom { right: 60px; bottom: 50px; }

/* FB Reel audio strip — pinned to the very bottom, full-width pill. */
.pv-fb-audio {
    position: absolute;
    left: 14px; right: 14px; bottom: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background: rgba(0,0,0,0.55);
    color: #fff;
    border-radius: 18px;
    font-size: 12px;
}
.pv-fb-audio i { font-size: 13px; }

/* IG Reel rail: avatar at the bottom replaces the "Follow" affordance. */
.pv-ig-rail-avatar {
    width: 32px; height: 32px;
    border-radius: 8px;
    border: 1px solid rgba(255,255,255,0.6);
    display: flex;
    align-items: center;
    justify-content: center;
}
.pv-ig-rail-avatar .pv-av { width: 24px; height: 24px; border-radius: 6px; }

/* --- YouTube Long-form ---------------------------------------------- */
.pv-yt-long { background: #0f0f0f; color: #f1f1f1; }
.pv-yt-thumb {
    position: relative;
    background: #202020;
    overflow: hidden;
}
.pv-yt-thumb .pv-vert-media,
.pv-yt-thumb .pv-yt-thumb-media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* Same contract as .pv-vert-media — letterbox, don't crop. */
    object-fit: contain;
    background: #000;
}
.pv-yt-duration {
    position: absolute;
    bottom: 6px;
    right: 6px;
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    font-size: 11px;
    padding: 1px 5px;
    border-radius: 3px;
    font-weight: 500;
}
.pv-yt-meta {
    display: flex;
    gap: 10px;
    padding: 10px 12px 12px;
}
.pv-yt-meta-text { flex: 1; min-width: 0; }
.pv-yt-title {
    font-size: 14px;
    font-weight: 600;
    color: #f1f1f1;
    line-height: 1.25;
    margin-bottom: 4px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.pv-yt-channel {
    font-size: 12px;
    color: #aaa;
    display: flex;
    align-items: center;
    gap: 4px;
}
.pv-yt-channel i { font-size: 11px; color: #aaa; }
.pv-yt-stats { font-size: 12px; color: #aaa; }

/* YouTube Short */
.pv-yt-short { background: #000; border-radius: var(--r-lg); overflow: hidden; }
.pv-yt-bottom { right: 72px; }
.pv-yt-short-title {
    font-weight: 600;
    font-size: 13px;
}
.pv-yt-subscribe {
    background: #ff0033;
    color: #fff;
    padding: 2px 10px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    margin-left: 6px;
}
.pv-yt-rightcol > div i { font-size: 20px; }

/* --- Pinterest ------------------------------------------------------- */
.pv-pn { background: #fff; color: #111; border-radius: 16px; overflow: hidden; }
.pv-pn-media {
    position: relative;
    background: #f1f1f3;
    overflow: hidden;
}
.pv-pn-media-inner {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.pv-pn-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px 6px;
    gap: 12px;
}
.pv-pn-actions-left {
    display: flex;
    align-items: center;
    gap: 18px;
    color: #111;
    font-size: 18px;
}
.pv-pn-save {
    background: #e60023;
    color: #fff;
    padding: 8px 16px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 700;
}
.pv-pn-videomark {
    position: absolute;
    top: 8px;
    left: 8px;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
}
.pv-pn-body {
    padding: 4px 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.pv-pn-title {
    font-weight: 700;
    font-size: 15px;
    color: #111;
    line-height: 1.3;
}
.pv-pn-desc {
    font-size: 13px;
    color: #555;
    line-height: 1.4;
}
.pv-pn-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: #111;
}

/* --- Substack -------------------------------------------------------- */
.pv-sub {
    background: #fff;
    color: #1a1a1a;
    font-family: "Charter", "Georgia", serif;
}
.pv-sub-hero {
    position: relative;
    aspect-ratio: 2 / 1;
    overflow: hidden;
    background: #f1f1f3;
}
.pv-sub-hero-media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.pv-sub-body { padding: 14px 16px 16px; }
.pv-sub-pub {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: #888;
    font-family: var(--font-sans);
    margin-bottom: 8px;
}
.pv-sub-title {
    font-size: 20px;
    font-weight: 700;
    line-height: 1.2;
    color: #111;
    margin-bottom: 6px;
}
.pv-sub-lede {
    font-size: 14px;
    color: #444;
    line-height: 1.45;
    margin-bottom: 10px;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.pv-sub-byline {
    font-size: 12px;
    color: #888;
    font-family: var(--font-sans);
    margin-bottom: 10px;
}
.pv-sub-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
    color: #666;
    font-family: var(--font-sans);
    border-top: 1px solid #eee;
    padding-top: 10px;
}
.pv-sub-subscribe {
    background: #ff6719;
    color: #fff;
    padding: 4px 12px;
    border-radius: 4px;
    font-weight: 600;
    margin-right: auto;
}

/* Substack email */
.pv-sub-email {
    border-radius: var(--r-lg);
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0,0,0,0.05), 0 0 0 1px var(--border);
}
.pv-email-head {
    background: #f6f6f4;
    padding: 10px 14px;
    border-bottom: 1px solid #e4e4e0;
    font-family: var(--font-sans);
    font-size: 12px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    color: #555;
}
.pv-email-row { display: flex; gap: 8px; align-items: baseline; }
.pv-email-label {
    width: 52px;
    color: #999;
    text-transform: uppercase;
    font-size: 10px;
    letter-spacing: 0.05em;
}
.pv-email-subject { color: #111; font-weight: 600; }
.pv-email-hero {
    position: relative;
    aspect-ratio: 2 / 1;
    overflow: hidden;
    background: #f1f1f3;
}
.pv-email-hero-media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.pv-email-body {
    padding: 14px 16px;
    color: #222;
    line-height: 1.55;
    font-size: 14px;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    display: -webkit-box;
    -webkit-line-clamp: 8;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.pv-email-foot {
    font-size: 11px;
    color: #999;
    padding: 10px 16px 14px;
    font-family: var(--font-sans);
    border-top: 1px solid #eee;
}

/* Substack Note (small inline-style card) */
.pv-sub-note { padding: 12px 14px; font-family: var(--font-sans); }
.pv-note-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}
.pv-note-head-text { line-height: 1.2; flex: 1; min-width: 0; }
.pv-note-name { font-weight: 600; font-size: 13px; }
.pv-note-meta { font-size: 11px; color: #888; }
.pv-note-body {
    font-size: 13px;
    color: #111;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    margin-bottom: 8px;
}
.pv-note-tags {
    color: #ff6719;
    font-size: 12px;
    font-family: var(--font-mono);
    margin-bottom: 8px;
    word-break: break-word;
}
.pv-note-actions {
    display: flex;
    gap: 14px;
    font-size: 12px;
    color: #888;
    border-top: 1px solid #eee;
    padding-top: 8px;
}
.pv-note-actions span { display: flex; align-items: center; gap: 4px; }

/* Generic fallback (unknown preview_key) */
.pv-generic { background: var(--surface-2); color: var(--text); box-shadow: 0 0 0 1px var(--border); }
.pv-generic-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
}
.pv-generic-platform { color: var(--text); font-weight: 500; font-size: 13px; }
.pv-generic-tpl { color: var(--text-3); font-size: 11px; }
.pv-generic-body { padding: 10px 12px; }
.pv-generic-subject { font-weight: 500; color: var(--text); margin-bottom: 4px; }
.pv-generic-text { color: var(--text-2); font-size: 13px; white-space: pre-wrap; }
.pv-generic-tags {
    color: var(--accent-text);
    font-size: 12px;
    font-family: var(--font-mono);
    margin-top: 6px;
    word-break: break-word;
}


/* ==================================================================
 * REVIEW PANE v3 — two-column anchored-comment layout (.sm-rev)
 * Templates: _review_pane.html + _rev_row.html + _rev_comment.html
 * JS: initReviewPaneActions in static/js/sm/review.js
 * ================================================================== */

.sm-rev {
    --rev-split: 65%;
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

.sm-rev-head {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 6px 20px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
    flex-wrap: wrap;
}
.sm-rev-title { min-width: 0; }
.sm-rev-head-meta {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
}

.sm-rev-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    /* Bottom padding leaves room for the sticky verdict bar so the last
       row is reachable above it. */
    padding-bottom: 120px;
    position: relative;
}

.sm-rev-grid {
    display: grid;
    grid-template-columns: var(--rev-split) 1fr;
    column-gap: 20px;
    /* `stretch` lets the right-column comment slot grow to the row's
       natural height (driven by the left card). With the textarea
       set to `flex: 1` further down, this means the textarea's bottom
       lines up with the card's bottom — Save Comment sits just below
       and the next row starts after it. */
    align-items: stretch;
    padding: 8px 16px;
    position: relative;
}

/* Each row's two children flow into columns 1 and 2 of the grid via
   display: contents. The row itself is invisible — it exists only as
   a semantic grouping for delegated event handlers. */
.sm-rev-row { display: contents; }

.sm-rev-content {
    grid-column: 1;
    padding: 6px 12px 8px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    border-radius: var(--r-md);
    min-width: 0;
    margin-bottom: 6px;
    transition: background 0.12s, border-color 0.12s;
}
/* Borderless comment slot — the surrounding card was visual noise.
   Top padding is 0 so the textarea's visible top edge sits flush
   with the left card's top edge; horizontal padding stays so the
   row-hover region feels generous. */
.sm-rev-comment {
    grid-column: 2;
    padding: 0 12px 6px;
    min-width: 0;
    margin-bottom: 6px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    border-radius: var(--r-md);
    transition: background 0.12s;
}

/* Hovering anywhere on a row's left or right side lights both up
   together — the row exists in the DOM but is `display: contents` so
   `:hover` still fires from its visible children. */
.sm-rev-row:hover > .sm-rev-content {
    background: var(--surface-3);
    border-color: var(--border-strong);
}
.sm-rev-row:hover > .sm-rev-comment {
    background: var(--surface-2);
}

.sm-rev-label {
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 11px;
    margin-bottom: 2px;
}
.sm-rev-value {
    color: var(--text);
    /* +25% over the previous 14px — Max wanted post content easier
       to read at a glance. */
    font-size: 18px;
    line-height: 1.45;
    word-wrap: break-word;
}
.sm-rev-long { white-space: pre-wrap; }
.sm-rev-empty {
    color: var(--text-4);
    font-style: italic;
    font-size: 16px;
}

.sm-rev-gallery {
    display: grid;
    /* ~2× the previous min — Max needs a real preview to pick between
       similar Pinterest renders, not a thumbnail strip. */
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 14px;
    margin-top: 8px;
}
.sm-rev-gallery-item {
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    overflow: hidden;
    background: var(--surface-1);
    cursor: zoom-in;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.sm-rev-gallery-item img {
    width: 100%;
    height: auto;
    display: block;
    object-fit: contain;  /* Never crop the producer's media (CLAUDE.md rule). */
}
.sm-rev-gallery-cap {
    padding: 8px 10px;
    color: var(--text-3);
    border-top: 1px solid var(--border);
    text-align: center;
    word-break: break-all;
}

/* Multi-image picker. Click the image to lightbox; click the Select
   button (or the modal's Select button) to mark this image as the one
   Jane should publish. Single-select — one preferred per post. */
.sm-rev-gallery-picker .sm-rev-gallery-item:hover {
    border-color: var(--accent);
}
.sm-rev-gallery-picker .sm-rev-gallery-item.is-selected {
    border-color: var(--success);
    box-shadow: 0 0 0 2px var(--success) inset;
}
.sm-rev-gallery-select-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: calc(100% - 20px);
    margin: 10px;
    padding: 11px 14px;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    background: var(--surface-2);
    color: var(--text-2);
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.sm-rev-gallery-select-btn i { font-size: 14px; }
.sm-rev-gallery-select-btn:hover {
    background: var(--surface-3);
    color: var(--text-1);
}
.sm-rev-gallery-item.is-selected .sm-rev-gallery-select-btn {
    background: var(--success);
    border-color: var(--success);
    color: #fff;
}

.sm-rev-frame img {
    max-width: 100%;
    height: auto;
    display: block;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    object-fit: contain;
}
.sm-rev-frame-caption { margin-top: 6px; color: var(--text-2); }

/* Storyboard strip — horizontal scroll, one anchor row for the
   whole thing. Each frame keeps its own star overlay so per-frame
   favorites still work. The comment slot on the right matches the
   row's height (via the grid's align-items: stretch + textarea
   flex:1) so Max gets a tall comment area for the whole storyboard. */
.sm-rev-storyboard {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 4px 2px 8px;
    scroll-snap-type: x proximity;
}
.sm-rev-storyboard-frame {
    flex: 0 0 auto;
    width: 180px;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.sm-rev-storyboard-num {
    color: var(--text-3);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-align: center;
}
.sm-rev-storyboard-img {
    position: relative;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    overflow: hidden;
    background: var(--surface-1);
    aspect-ratio: 1 / 1;
    cursor: zoom-in;
}
.sm-rev-storyboard-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;  /* Never crop the producer's media. */
    display: block;
}
.sm-rev-storyboard-caption {
    color: var(--text-2);
    line-height: 1.3;
    word-break: break-word;
}

.sm-rev-row-variant .sm-rev-content {
    border-left: 2px solid var(--accent);
}
.sm-rev-variant-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
}
.sm-rev-variant-tpl { color: var(--text-3); }
.sm-rev-overrides .sm-field { margin-top: 6px; }

/* --- Comment slot internals ---
   Layout per slot is just the textarea, plus an optional foot
   (byline + delete) when a primary comment exists. Saving is bulk:
   one "Save Comments" button on the verdict bar flushes every dirty
   textarea, so each slot gets its full height back.

   rows="1" + no min-height so short fields (e.g. Title) don't push
   the grid row taller than the left card's content. The textarea's
   own resize handle still works for ad-hoc taller slots. */
.sm-rev-comment-text {
    width: 100%;
    flex: 1 0 auto;
    min-width: 0;
    resize: vertical;
    /* +50% over the previous 13px — Max reads these comments at a
       glance and 13px was too tight. */
    font-size: 20px;
    line-height: 1.4;
    background: var(--surface-1);
}
.sm-rev-comment-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}
.sm-rev-comment-byline {
    color: var(--text-3);
    flex: 1;
    min-width: 0;
}
.sm-rev-comment-resolved-tag {
    margin-left: 6px;
    padding: 1px 6px;
    background: var(--success-soft);
    color: var(--success-text);
    border-radius: 6px;
    font-size: 10px;
    text-transform: uppercase;
}
.sm-rev-comment-extra {
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    padding: 6px 8px;
    font-size: 13px;
}
.sm-rev-comment-extra.is-resolved { opacity: 0.6; }
.sm-rev-comment-meta {
    display: flex;
    justify-content: space-between;
    margin-bottom: 4px;
    color: var(--text-3);
}
.sm-rev-comment-del {
    background: none;
    border: 0;
    cursor: pointer;
    color: var(--text-3);
    padding: 0;
}
.sm-rev-comment-del:hover { color: var(--danger-text); }

/* --- Splitter — vertical handle drawn over the column boundary. --- */
.sm-rev-splitter {
    /* Position is calculated from --rev-split on the grid; the handle
       sits 12px wide centered on the boundary. Pointer-events stay
       on so dragging works. */
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(var(--rev-split) + 12px);  /* +12px ≈ half of column-gap so it lands in the gap */
    width: 12px;
    margin-left: -6px;
    cursor: col-resize;
    z-index: 2;
}
.sm-rev-splitter::before {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    left: 50%;
    width: 1px;
    transform: translateX(-50%);
    background: var(--border);
}
.sm-rev-splitter:hover::before,
body.sm-rev-resizing .sm-rev-splitter::before {
    background: var(--accent);
    width: 2px;
}
body.sm-rev-resizing { user-select: none; cursor: col-resize; }

/* --- Sticky verdict bar ---
   Three-column grid keeps the verdict trio truly centered regardless
   of what sits in the side cells (the right cell holds the bulk
   "Save Comments" button). The locked variant collapses back to a
   single centered cell via `.sm-rev-bar-locked`. */
.sm-rev-bar {
    position: sticky;
    bottom: 0;
    left: 0;
    right: 0;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
    padding: 6px 20px;
    background: var(--surface-1);
    border-top: 1px solid var(--border-strong);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.25);
    z-index: 5;
}
.sm-rev-bar-locked { display: flex; justify-content: center; }
.sm-rev-bar-side { display: flex; align-items: center; }
/* Left cell: Revert sits near (but not touching) the verdict trio —
   `flex-end` plus a deliberate margin so there's a half-button gap.
   Right cell: Save Comments parks at the far right of the bar. */
.sm-rev-bar-side-start { justify-content: flex-end; }
.sm-rev-bar-side-end { justify-content: flex-end; position: relative; }
.sm-rev-bar-revert { margin-right: 60px; }
.sm-rev-bar-verdicts {
    display: flex;
    gap: 12px;
    flex-shrink: 0;
}
.sm-rev-bar-save {
    appearance: none;
    cursor: pointer;
    /* Dark blue — distinct from the indigo accent and the
       red/amber/green verdict palette so Save Comments reads as a
       separate, neutral action. */
    background: #1e3a8a;
    color: white;
    border: 1px solid #1e3a8a;
    border-radius: var(--r-md);
    padding: 4px 12px;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 120ms ease, border-color 120ms ease, transform 80ms ease;
}
.sm-rev-bar-save:hover { background: #1e40af; border-color: #2563eb; transform: translateY(-1px); }
.sm-rev-bar-save:active { transform: translateY(0); }
.sm-rev-bar-save:disabled { opacity: 0.6; cursor: progress; }

/* Revert — ghost style. Disabled (grey, low contrast) when no
   verdict is set, lit up when one is. Sits at the right edge of the
   left cell so it hugs the verdict trio. */
.sm-rev-bar-revert {
    appearance: none;
    cursor: pointer;
    background: transparent;
    color: var(--text-2);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-md);
    padding: 4px 12px;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 120ms ease, border-color 120ms ease, color 120ms ease, transform 80ms ease;
}
.sm-rev-bar-revert:hover:not(:disabled) {
    background: var(--surface-3);
    border-color: var(--accent);
    color: var(--text);
    transform: translateY(-1px);
}
.sm-rev-bar-revert:active:not(:disabled) { transform: translateY(0); }
.sm-rev-bar-revert:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    color: var(--text-4);
    border-color: var(--border);
}

/* Confirmation toast — always present in the bar's right cell, faded
   out by default. JS toggles `.is-visible` for 2s after a successful
   save. The right cell is `position: relative` so the toast can pop
   up clear of the bar via `bottom: calc(100% + 12px)`. */
.sm-rev-bar-side-end { position: relative; }
.sm-rev-bar-toast {
    position: absolute;
    bottom: calc(100% + 12px);
    right: 0;
    white-space: nowrap;
    background: var(--success);
    color: #052e16;
    font-weight: 700;
    font-size: 13px;
    padding: 6px 12px;
    border-radius: var(--r-md);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
    pointer-events: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 180ms ease, transform 180ms ease;
}
.sm-rev-bar-toast.is-visible { opacity: 1; transform: translateY(0); }
/* Locked variant — replaces the verdict buttons on posted posts. */
.sm-rev-bar-locked-msg {
    color: var(--text-3);
    font-size: 14px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.sm-rev-bar-locked-msg i { color: var(--text-4); }

/* Locked comment slot — textarea is readonly, foot is gone. Show a
   subtle visual cue so it's clear the field is intentional, not dead. */
.sm-rev-comment.is-locked .sm-rev-comment-text {
    background: transparent;
    border-color: var(--border);
    color: var(--text-2);
    cursor: text;
}
.sm-rev-comment.is-locked .sm-rev-comment-byline {
    margin-top: 4px;
}
/* Three solid, coloured buttons — read like a real traffic light at
   rest, no decoration needed. font-family: inherit so the button
   doesn't fall back to the UA serif. */
.sm-rev-verdict {
    display: inline-flex;
    align-items: center;
    padding: 4px 18px;
    border-radius: var(--r-md);
    border: 1px solid transparent;
    color: white;
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.01em;
    cursor: pointer;
    transition: opacity 0.15s, filter 0.15s, transform 0.1s, box-shadow 0.15s;
}
.sm-rev-verdict-red    { background: var(--danger);  }   /* #ef4444 */
.sm-rev-verdict-amber  { background: #d97706;        }   /* a sliver darker than --warning so white text stays legible */
.sm-rev-verdict-green  { background: #16a34a;        }   /* the .btn-success shade — white text reads cleanly */

.sm-rev-verdict:hover  { filter: brightness(1.1); transform: translateY(-1px); }
.sm-rev-verdict:active { transform: translateY(0); }

/* Cast state — every button except the chosen one drains to grey.
   The chosen one stays full-colour and grows a thick ring in its own
   colour so you can pick it out without thinking. */
.sm-rev-bar[data-current-verdict]:not([data-current-verdict=""]) .sm-rev-verdict:not(.is-on) {
    opacity: 0.28;
    filter: grayscale(0.85);
}
.sm-rev-verdict.is-on {
    transform: scale(1.04);
}
.sm-rev-verdict-red.is-on   { box-shadow: 0 0 0 3px var(--surface-1), 0 0 0 6px var(--danger);  }
.sm-rev-verdict-amber.is-on { box-shadow: 0 0 0 3px var(--surface-1), 0 0 0 6px #d97706;        }
.sm-rev-verdict-green.is-on { box-shadow: 0 0 0 3px var(--surface-1), 0 0 0 6px #16a34a;        }

@media (max-width: 1100px) {
    /* Below 1100px the per-row split gets cramped — collapse to a
       single column and stack each comment under its content. */
    .sm-rev-grid { grid-template-columns: 1fr; column-gap: 0; }
    .sm-rev-content, .sm-rev-comment { grid-column: 1; }
    .sm-rev-splitter { display: none; }
}


/* ==================================================================
 * COMPOSER — review summary banner + inline field annotations (.sm-fc)
 * Templates: post_form.html (banner) + _field_comments.html (annotations)
 * JS: initComposerComments in static/js/sm/composer.js
 * ================================================================== */

/* Top-of-composer summary — verdict colour as the left border so Jane
   can't miss it on page load. */
.sm-rev-summary {
    margin: 0 24px 14px;
    padding: 12px 16px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-left: 4px solid var(--border);
    border-radius: var(--r-md);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.sm-rev-summary-red    { border-left-color: var(--danger);  background: linear-gradient(to right, var(--danger-soft) 0%, var(--surface-2) 30%); }
.sm-rev-summary-amber  { border-left-color: var(--warning); background: linear-gradient(to right, var(--warning-soft) 0%, var(--surface-2) 30%); }
.sm-rev-summary-green  { border-left-color: var(--success); background: linear-gradient(to right, var(--success-soft) 0%, var(--surface-2) 30%); }
.sm-rev-summary-main {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}
.sm-rev-summary-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 12px;
    border-radius: var(--r-sm);
    font-size: 13px;
    font-weight: 500;
}
.sm-rev-summary-badge-red    { background: var(--danger-soft);  color: var(--danger-text);  }
.sm-rev-summary-badge-amber  { background: var(--warning-soft); color: var(--warning-text); }
.sm-rev-summary-badge-green  { background: var(--success-soft); color: var(--success-text); }
.sm-rev-summary-count {
    color: var(--text-2);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.sm-rev-summary-count i { color: var(--warning); }
.sm-rev-summary-count.is-clear i { color: var(--success); }
.sm-rev-summary-author { color: var(--text-3); margin-left: auto; }
.sm-rev-summary-final { margin-top: 6px; }


/* Inline annotation — sits directly under the field it's commenting
   on. Red bar on the left while unresolved; green when resolved. */
.sm-fc {
    margin-top: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sm-fc-item {
    border: 1px solid var(--border);
    border-left: 3px solid var(--danger);
    background: var(--danger-soft);
    border-radius: var(--r-sm);
    padding: 8px 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: border-color 0.15s, background 0.15s, opacity 0.15s;
}
.sm-fc-item.is-resolved {
    border-left-color: var(--success);
    background: var(--success-soft);
    opacity: 0.85;
}
.sm-fc-head {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-3);
    font-size: 11px;
}
.sm-fc-head i { color: var(--danger-text); }
.sm-fc-item.is-resolved .sm-fc-head i { color: var(--success-text); }
.sm-fc-author { font-weight: 600; color: var(--text-2); }
.sm-fc-body {
    font-size: 13px;
    line-height: 1.5;
    color: var(--text);
    white-space: pre-wrap;
}
.sm-fc-resolve {
    align-self: flex-end;
    padding: 4px 10px;
    font-size: 12px;
}

/* Field-level outline — paints the container of the field so Jane's
   eye lands on it as she scrolls. Combine with .sm-fc-item's left
   bar for redundant signal (colour + position). */
[data-field].has-unresolved-comment > .input,
[data-field].has-unresolved-comment > .textarea,
[data-field].has-unresolved-comment > #image-gallery,
[data-field].has-unresolved-comment > .sm-storyboard {
    box-shadow: 0 0 0 2px var(--danger);
}
[data-field].has-resolved-comment > .input,
[data-field].has-resolved-comment > .textarea,
[data-field].has-resolved-comment > #image-gallery,
[data-field].has-resolved-comment > .sm-storyboard {
    box-shadow: 0 0 0 1px var(--success);
}
.sm-preset-card.has-unresolved-comment { box-shadow: inset 3px 0 0 var(--danger); }
.sm-preset-card.has-resolved-comment   { box-shadow: inset 3px 0 0 var(--success); }
.sm-composer-section.has-unresolved-comment { box-shadow: inset 3px 0 0 var(--danger); }
.sm-composer-section.has-resolved-comment   { box-shadow: inset 3px 0 0 var(--success); }


/* ==================================================================
 * MEDIA GROUPING — dropdown that lives opposite the Universal-content
 * heading. Reuses the standard `.sm-form-field` + `.input` styling so
 * it matches Card status / Posted on. Disabled when none of the
 * post's variants are FB or IG (the only platforms it affects).
 * Carousel mode (`.is-carousel` / `.sm-rev-gallery-carousel`) hides
 * every per-image Select affordance because the post ships as a group.
 * ================================================================== */
.sm-section-head-field {
    width: 200px;
    flex: 0 0 auto;
}

.sm-rev-gallery.is-carousel .sm-rev-gallery-select-btn,
.sm-rev-gallery-carousel .sm-rev-gallery-select-btn {
    display: none;
}


/* ==================================================================
 * MEDIA FAVORITES — star overlay (.sm-fav-star) on every tile +
 * the shared add/edit modal (.sm-fav-modal).
 * Templates: _fav_star.html, _fav_modal.html
 * JS: initMediaFavorites in static/js/sm/favorites.js
 * ================================================================== */

/* Each tile (.sm-rev-gallery-item, .sm-video-card, .sm-rev-frame,
   .sm-gallery-item) needs `position: relative` for the absolute star
   overlay. The existing tile rules already set most of these — we
   re-state to defend against any that don't. */
.sm-rev-gallery-item, .sm-video-card, .sm-rev-frame, .sm-gallery-item {
    position: relative;
}

/* Composer gallery — when a teammate (Max) has favorited the tile,
   paint a thin gold edge so Jane spots his picks at a glance even
   before reading the notes. */
.sm-gallery-item.has-team-fav {
    box-shadow: 0 0 0 2px var(--warning);
}

/* Team-favs callout under the tile — small inline note from anyone
   else who saved this asset. Read-only on the producer's side. */
.sm-team-favs {
    position: absolute;
    left: 6px; right: 6px; bottom: 38px;  /* above the gallery foot */
    display: flex;
    flex-direction: column;
    gap: 4px;
    pointer-events: none;
    z-index: 1;
}
.sm-team-fav {
    background: rgba(245, 158, 11, 0.92);
    color: #1f1300;
    padding: 4px 8px;
    border-radius: var(--r-sm);
    font-size: 11px;
    line-height: 1.3;
    box-shadow: 0 1px 4px rgba(0,0,0,0.3);
}
.sm-team-fav-icon { color: #1f1300; margin-right: 4px; }
.sm-team-fav-author { font-weight: 600; }
.sm-team-fav-note { display: block; margin-top: 2px; word-break: break-word; }
.sm-fav-star {
    position: absolute;
    top: 6px; right: 6px;
    width: 28px; height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: rgba(255, 255, 255, 0.85);
    font-size: 14px;
    cursor: pointer;
    z-index: 2;
    transition: background 0.12s, color 0.12s, transform 0.08s;
}
.sm-fav-star:hover {
    background: rgba(0, 0, 0, 0.75);
    color: white;
    transform: scale(1.06);
}
.sm-fav-star.is-on {
    background: var(--warning);
    color: white;
}
.sm-fav-star.is-on:hover {
    background: #e08e00;
}

/* Text-field star — sits inline next to the field label (not as a
   tile overlay), so it's smaller and uses border instead of a heavy
   filled bg. is-on still flips the icon to solid amber. */
.sm-fav-star-text {
    position: static;
    width: 24px;
    height: 24px;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-3);
    font-size: 12px;
}
.sm-fav-star-text:hover {
    background: var(--surface-3);
    border-color: var(--border-strong);
    color: var(--warning-text);
    transform: none;
}
.sm-fav-star-text.is-on {
    background: transparent;
    border-color: var(--warning-border);
    color: var(--warning-text);
}
.sm-fav-star-text.is-on:hover {
    background: var(--warning-soft);
    color: var(--warning-text);
}

/* Field-row label gains a small flex layout so the star sits to the
   right of the label without disturbing the existing single-line
   label rendering. */
.sm-rev-label-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.sm-rev-label-row .sm-rev-label,
.sm-rev-label-row .sm-field-label {
    flex: 1;
    min-width: 0;
}

/* Quote block in the favorite modal preview when kind=text. Same
   #000 backdrop the media kinds get; centred text card on top. */
.sm-fav-modal-text {
    margin: 0;
    max-width: 100%;
    max-height: 80vh;
    overflow: auto;
    padding: 18px 22px;
    background: var(--surface-2);
    border-left: 3px solid var(--warning);
    border-radius: var(--r-sm);
    color: var(--text);
    font-size: 16px;
    line-height: 1.6;
    white-space: pre-wrap;
}

/* Text-favorite tile in /favorites: the thumbnail block becomes a
   quote card with a snippet. Mirrors the media tile height so the
   grid stays even. */
.sm-favs-tile-text .sm-favs-tile-thumb {
    background: var(--surface-2);
    align-items: flex-start;
    padding: 12px 14px;
}
.sm-favs-tile-quote {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    color: var(--text-2);
    font-size: 14px;
    line-height: 1.45;
    overflow: hidden;
}
.sm-favs-tile-quote-icon {
    color: var(--warning);
    flex-shrink: 0;
    margin-top: 2px;
}
.sm-favs-tile-snippet {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 6;
    -webkit-box-orient: vertical;
}
/* Bin row uses the same quote inside a fixed-size thumb slot. */
.sm-favs-tile-quote-row {
    width: 100%;
    height: 100%;
    padding: 8px 10px;
    box-sizing: border-box;
    background: var(--surface-2);
    border-radius: var(--r-sm);
    font-size: 13px;
}

/* Detail-pane treatment for a text favorite. The wrap stacks the
   "from <Platform>" source line above the snapshot blockquote and
   centers both inside the black preview box (set on .is-text below).
   The blockquote keeps its amber accent + soft surface background. */
.sm-favs-detail-text-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    width: 100%;
    max-width: 720px;
}
.sm-favs-detail-source {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--text-3);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.02em;
}
.sm-favs-detail-source i { font-size: 16px; color: var(--text-2); }
.sm-favs-detail-text {
    margin: 0;
    padding: 18px 22px;
    background: var(--surface-2);
    border-left: 3px solid var(--warning);
    border-radius: var(--r-sm);
    color: var(--text);
    font-size: 17px;
    line-height: 1.6;
    white-space: pre-wrap;
    width: 100%;
    box-sizing: border-box;
}

/* Modal — image preview on the left, note + actions on the right.
   Self-sufficient on dim/positioning so it doesn't depend on the
   shared .sm-modal-overlay rule (load-order specificity bit us). */
.sm-fav-modal {
    position: fixed;
    inset: 0;
    /* Solid backdrop — page content behind must not bleed through.
       Matches the lightbox treatment. */
    background: #0a0d14;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
    padding: 24px;
}
.sm-fav-modal[hidden] { display: none; }
.sm-fav-modal-card {
    display: grid;
    grid-template-columns: minmax(280px, 1.2fr) minmax(280px, 1fr);
    gap: 0;
    /* Was `var(--surface-1)` which is UNDEFINED — there's no --surface-1
       token in :root (the ladder is --surface / --surface-2 / -3 / -4).
       The undefined var resolved to transparent, which is why the form
       half of the card showed the page through. Use --surface-2 so the
       card sits a step lighter than the body background. */
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-lg);
    overflow: hidden;
    width: min(90vw, 940px);
    max-height: 85vh;
}
.sm-fav-modal-preview {
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 320px;
    overflow: hidden;
}
.sm-fav-modal-preview img,
.sm-fav-modal-preview video {
    max-width: 100%;
    max-height: 80vh;
    object-fit: contain;  /* Never crop the producer's media (CLAUDE.md rule). */
}
.sm-fav-modal-form {
    padding: 22px 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
}
.sm-fav-modal-note { flex: 1; min-height: 140px; }
.sm-fav-modal-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    align-items: center;
    margin-top: auto;
}

@media (max-width: 800px) {
    .sm-fav-modal-card { grid-template-columns: 1fr; max-height: 95vh; }
    .sm-fav-modal-preview { min-height: 220px; max-height: 40vh; }
}

/* --- /favorites page --- */
.sm-favs {
    display: grid;
    grid-template-columns: minmax(360px, 1.1fr) 1.5fr;
    height: 100%;
    min-height: 0;
}
.sm-favs-list {
    border-right: 1px solid var(--border);
    overflow-y: auto;
    padding: 16px;
}
.sm-favs-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 12px;
}
.sm-favs-tile {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--surface-2);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.1s, transform 0.05s;
}
.sm-favs-tile:hover { border-color: var(--border-strong); transform: translateY(-1px); text-decoration: none; color: inherit; }
.sm-favs-tile.is-selected { border-color: var(--accent); }
.sm-favs-tile-thumb {
    aspect-ratio: 1 / 1;
    background: #000;  /* black so the contain letterbox reads cleanly */
    position: relative;
    overflow: hidden;
}
.sm-favs-tile-thumb img,
.sm-favs-tile-thumb video {
    width: 100%; height: 100%;
    /* `contain` — never crop the producer's media. Tiles letterbox
       against the black wrapper instead of cropping to fit a square. */
    object-fit: contain;
    display: block;
}
/* Shared "no media" placeholder for every thumbnail surface (archive,
   board card, queue/bin rows, favorites tile, favorites bin row).
   Icon + label so the user reads "no image" — not a missing thumbnail.
   The label hides on tiny rows where it'd wrap (handled per-context). */
.sm-thumb-empty {
    width: 100%; height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    color: var(--text-4);
    text-align: center;
    padding: 6px;
    box-sizing: border-box;
}
.sm-thumb-empty i { font-size: 28px; }
.sm-thumb-empty span {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}
/* Detail-pane placeholder shown when the source media is gone (R2
   404). Keeps the favorite usable — note + source-post link still
   work — instead of leaving a broken-image icon in the preview. */
.sm-favs-detail-missing {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 40px 24px;
    color: var(--text-3);
    text-align: center;
    background: var(--surface-2);
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-md);
    min-height: 200px;
}
.sm-favs-detail-missing i { font-size: 42px; color: var(--text-4); }
.sm-favs-tile-kind {
    position: absolute;
    bottom: 6px; left: 6px;
    padding: 2px 8px;
    background: rgba(0,0,0,0.65);
    color: white;
    border-radius: 4px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.sm-favs-tile-body { padding: 8px 10px 10px; min-width: 0; }
.sm-favs-tile-note { color: var(--text); margin-bottom: 4px; word-break: break-word; }
.sm-favs-tile-no-note { color: var(--text-4); font-style: italic; }
.sm-favs-tile-post { color: var(--text-3); }

.sm-favs-pane {
    overflow-y: auto;
    padding: 24px;
    min-height: 0;
}
.sm-favs-empty {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--text-3);
}
.sm-favs-detail-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}
.sm-favs-detail-meta { color: var(--text-3); display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.sm-favs-detail-meta > div { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.sm-favs-detail-meta a { color: var(--text-2); }
.sm-favs-detail-post { color: var(--text-2); font-weight: 500; }
.sm-favs-detail-uuid {
    font-family: var(--font-mono);
    color: var(--text-4);
    background: var(--surface-2);
    padding: 2px 6px;
    border-radius: var(--r-sm);
    cursor: pointer;
    align-self: flex-start;
    user-select: all;
    word-break: break-all;
}
.sm-favs-detail-uuid:hover { color: var(--text-2); background: var(--surface-3); }
.sm-favs-detail-actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }
.sm-favs-detail-note-readonly {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 12px;
    color: var(--text-2);
    line-height: 1.5;
    white-space: pre-wrap;
}
.sm-favs-detail-preview {
    max-height: 60vh;
    background: #000;
    border-radius: var(--r-md);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 14px;
}
.sm-favs-detail-preview.is-text {
    /* Breathing room around the centered snapshot card; min-height so
       a one-line snapshot doesn't collapse the box flush against the
       header above. */
    padding: 32px 28px;
    min-height: 240px;
    overflow: auto;
}
.sm-favs-detail-preview img,
.sm-favs-detail-preview video {
    max-width: 100%;
    max-height: 60vh;
    object-fit: contain;  /* Never crop the producer's media. */
}
.sm-favs-detail-note {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.sm-favs-detail-note-text { min-height: 100px; }
.sm-favs-detail-note .btn { align-self: flex-start; }

