/* !important is deliberate: confirmed with a real browser measurement
   that plenty of elements this toggles (.user-chip, .rail-btn, etc.) set
   their own `display` too - same specificity (one class each) means
   whichever rule is declared LATER in this file wins on a tie, so without
   this, "hidden" silently didn't hide anything on any element whose own
   base class happened to be declared after this one. A utility named
   "hidden" must always actually hide, full stop. */
.hidden { display: none !important; }

/* ============================================================
   THEME TOKENS
   Six themes total: light/dark, each with 3 selectable color
   variants (Mint/Ocean/Sunset) - picked from the theme button in
   the rail (and the login page's corner button). Every theme is
   glass: translucent surfaces + backdrop-filter blur (see "GLASS"
   further down) over a softly glowing gradient painted on <body>,
   in both light and dark. Everything downstream reads only these
   variables, so a card, button or badge never needs its own
   theme-specific rule. `--accent-rgb`/`--info-rgb`/`--danger-rgb`
   are the same colors as --amber/--cyan/--red as bare "r, g, b"
   triplets, for spots that need a translucent tint of them
   (rgba(var(--accent-rgb), 0.15) etc.) rather than the solid color.
   `data-theme` + `data-variant` are set on <html> by an inline
   script in <head> (before first paint, so there's no flash) and
   again on pick by wireThemePicker() in app.js/login.js - see the
   theme button's popover menu.
   ============================================================ */

/* Bare fallback (no attributes yet, or JS disabled + light OS pref):
   light + Mint. */
:root {
  --bg: #F3F3F0;
  --surface: rgba(255,255,255,0.55);
  --surface-alt: rgba(255,255,255,0.75);
  --border: rgba(15,15,20,0.10);
  --text: #16171B;
  --text-muted: #5B5D68;
  --amber: #0E8F6E;
  --cyan: #2F80ED;
  --red: #E5484D;
  --on-accent: #FFFFFF;
  --shadow-rgb: 30, 30, 40;
  --accent-rgb: 14, 143, 110;
  --info-rgb: 47, 128, 237;
  --danger-rgb: 229, 72, 77;
  --glow1: rgba(14,143,110,0.16);
  --glow2: rgba(47,128,237,0.12);
  --glow3: rgba(168,92,246,0.10);

  --c-facebook: #4267B2;
  --c-instagram: #E1306C;
  --c-linkedin: #0A66C2;
  --c-reddit: #FF4500;
  --c-telegram: #29A9EA;
  --c-pinterest: #E60023;
  --c-tiktok: #69C9D0;
  --c-snapchat: #D8CC00;
  --c-messenger: #00B2FF;

  --mono: 'JetBrains Mono', monospace;
  --sans: 'Inter', -apple-system, sans-serif;

  color-scheme: light;
}

/* No-JS fallback: honor system preference when the inline theme
   script hasn't run (JS disabled) - dark + Mint, since variant choice
   itself needs JS. Once the script runs it always sets explicit
   data-theme/data-variant, and the six combo blocks below win over this. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #121316;
    --surface: rgba(255,255,255,0.06);
    --surface-alt: rgba(255,255,255,0.10);
    --border: rgba(255,255,255,0.14);
    --text: #F1F1F3;
    --text-muted: #ABABB6;
    --amber: #1FD68F;
    --cyan: #5B9DF9;
    --red: #F2555A;
    --on-accent: #06251A;
    --shadow-rgb: 0, 0, 0;
    --accent-rgb: 31, 214, 143;
    --info-rgb: 91, 157, 249;
    --danger-rgb: 242, 85, 90;
    --glow1: rgba(31,214,143,0.22);
    --glow2: rgba(91,157,249,0.16);
    --glow3: rgba(168,92,246,0.14);
    color-scheme: dark;
  }
}

/* ---- Light · Mint (default) ---- */
:root[data-theme="light"][data-variant="mint"] {
  --bg: #F3F3F0; --surface: rgba(255,255,255,0.55); --surface-alt: rgba(255,255,255,0.75);
  --border: rgba(15,15,20,0.10); --text: #16171B; --text-muted: #5B5D68;
  --amber: #0E8F6E; --cyan: #2F80ED; --red: #E5484D; --on-accent: #FFFFFF;
  --shadow-rgb: 30, 30, 40; --accent-rgb: 14, 143, 110; --info-rgb: 47, 128, 237; --danger-rgb: 229, 72, 77;
  --glow1: rgba(14,143,110,0.16); --glow2: rgba(47,128,237,0.12); --glow3: rgba(168,92,246,0.10);
  color-scheme: light;
}
/* ---- Light · Ocean ---- */
:root[data-theme="light"][data-variant="ocean"] {
  --bg: #F0F4F9; --surface: rgba(255,255,255,0.55); --surface-alt: rgba(255,255,255,0.75);
  --border: rgba(15,20,35,0.10); --text: #101825; --text-muted: #57607A;
  --amber: #2166D6; --cyan: #0E8F6E; --red: #E5484D; --on-accent: #FFFFFF;
  --shadow-rgb: 15, 30, 55; --accent-rgb: 33, 102, 214; --info-rgb: 14, 143, 110; --danger-rgb: 229, 72, 77;
  --glow1: rgba(33,102,214,0.20); --glow2: rgba(14,143,110,0.12); --glow3: rgba(120,90,255,0.14);
  color-scheme: light;
}
/* ---- Light · Sunset ---- */
:root[data-theme="light"][data-variant="sunset"] {
  --bg: #FBF3EE; --surface: rgba(255,255,255,0.55); --surface-alt: rgba(255,255,255,0.78);
  --border: rgba(50,25,10,0.10); --text: #241A14; --text-muted: #7A6A5E;
  --amber: #C05A3A; --cyan: #2F8F86; --red: #D0453F; --on-accent: #FFFFFF;
  --shadow-rgb: 60, 32, 20; --accent-rgb: 192, 90, 58; --info-rgb: 47, 143, 134; --danger-rgb: 208, 69, 63;
  --glow1: rgba(192,90,58,0.20); --glow2: rgba(255,130,150,0.13); --glow3: rgba(255,190,90,0.16);
  color-scheme: light;
}

/* ---- Dark · Mint (default) ---- */
:root[data-theme="dark"][data-variant="mint"] {
  --bg: #121316; --surface: rgba(255,255,255,0.06); --surface-alt: rgba(255,255,255,0.10);
  --border: rgba(255,255,255,0.14); --text: #F1F1F3; --text-muted: #ABABB6;
  --amber: #1FD68F; --cyan: #5B9DF9; --red: #F2555A; --on-accent: #06251A;
  --shadow-rgb: 0, 0, 0; --accent-rgb: 31, 214, 143; --info-rgb: 91, 157, 249; --danger-rgb: 242, 85, 90;
  --glow1: rgba(31,214,143,0.22); --glow2: rgba(91,157,249,0.16); --glow3: rgba(168,92,246,0.14);
  color-scheme: dark;
}
/* ---- Dark · Ocean ---- */
:root[data-theme="dark"][data-variant="ocean"] {
  --bg: #0E1420; --surface: rgba(255,255,255,0.06); --surface-alt: rgba(255,255,255,0.10);
  --border: rgba(255,255,255,0.14); --text: #EAF0FA; --text-muted: #9FB0C8;
  --amber: #5B9DF9; --cyan: #3FD6C8; --red: #F2555A; --on-accent: #031224;
  --shadow-rgb: 0, 0, 0; --accent-rgb: 91, 157, 249; --info-rgb: 63, 214, 200; --danger-rgb: 242, 85, 90;
  --glow1: rgba(91,157,249,0.24); --glow2: rgba(63,214,200,0.16); --glow3: rgba(120,90,255,0.16);
  color-scheme: dark;
}
/* ---- Dark · Sunset ---- */
:root[data-theme="dark"][data-variant="sunset"] {
  --bg: #1A1210; --surface: rgba(255,255,255,0.07); --surface-alt: rgba(255,255,255,0.11);
  --border: rgba(255,255,255,0.15); --text: #F7ECE6; --text-muted: #C2A99B;
  --amber: #FF9466; --cyan: #5B9DF9; --red: #F2555A; --on-accent: #2B1006;
  --shadow-rgb: 0, 0, 0; --accent-rgb: 255, 148, 102; --info-rgb: 91, 157, 249; --danger-rgb: 242, 85, 90;
  --glow1: rgba(255,148,102,0.26); --glow2: rgba(255,110,140,0.16); --glow3: rgba(255,200,90,0.14);
  color-scheme: dark;
}

/* The glow this glass blurs: fixed, soft color blobs behind everything,
   in both light and dark - flat color behind frosted glass has nothing
   to blur and just looks like plain boxes; this is what actually makes
   the blur visible, in whichever theme/variant is active. */
:root[data-theme="light"] body,
:root[data-theme="dark"] body {
  background:
    radial-gradient(ellipse 900px 600px at 12% -10%, var(--glow1), transparent 60%),
    radial-gradient(ellipse 800px 700px at 105% 5%, var(--glow2), transparent 60%),
    radial-gradient(ellipse 900px 700px at 40% 115%, var(--glow3), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}

* { box-sizing: border-box; }

/* Low-specificity safety net - any more specific sizing elsewhere (the
   many explicit img/video rules throughout this file) still wins, this
   only catches whatever wasn't given its own size and would otherwise
   overflow its container on a narrow screen. */
img, video { max-width: 100%; }

/* The page itself must never scroll sideways - a wide table/canvas/
   code block should scroll within its own box (most already do via
   .table-wrap) rather than blowing out the whole layout on mobile. */
/* overflow-y is set explicitly alongside overflow-x here on purpose: per
   the CSS overflow spec, setting only ONE axis to non-"visible" forces
   the OTHER axis's computed value from "visible" to "auto" too - without
   this, body silently became its own scroll container (instead of the
   real viewport), which broke .rail's `position: sticky` on desktop (it
   scrolled away with the page instead of staying pinned). Explicitly
   "visible" here keeps the viewport itself as the one scroller. */
html, body { max-width: 100%; overflow-x: clip; }

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 5000;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.modal-overlay.hidden { display: none; }
.modal-card { max-width: 440px; width: 100%; margin-bottom: 0; }

.intro-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background:
    radial-gradient(ellipse 900px 600px at 15% -10%, var(--glow1), transparent 60%),
    radial-gradient(ellipse 900px 700px at 105% 10%, var(--glow2), transparent 60%),
    radial-gradient(ellipse 900px 700px at 45% 115%, var(--glow3), transparent 60%),
    var(--bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  animation: introEnter 0.5s ease both;
}
.intro-overlay.fade-out { animation: introFadeOut 0.5s ease forwards; }
@keyframes introEnter { from { opacity: 0; } }
@keyframes introFadeOut { to { opacity: 0; visibility: hidden; } }

/* The mark's own gentle breathing scale reads as "quietly alive" rather
   than a static box, without anything distracting or slow to load. */
.intro-mark-wrap { position: relative; width: 108px; height: 108px; display: flex; align-items: center; justify-content: center; }

.intro-mark {
  position: relative;
  font-family: var(--sans);
  font-weight: 800;
  font-size: 42px;
  letter-spacing: 2px;
  color: var(--amber);
  background: var(--bg);
  border: 2px solid var(--amber);
  border-radius: 16px;
  width: 88px;
  height: 88px;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: introPulse 1.6s ease-in-out infinite;
  box-shadow: 0 0 0 rgba(var(--accent-rgb), 0.4);
}
@keyframes introPulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.35); }
  50% { transform: scale(1.06); box-shadow: 0 0 0 14px rgba(var(--accent-rgb), 0); }
}

/* The wordmark reveal: a wipe sweeps left-to-right like the classic
   "logo drawn on by a line" intro, but the wipe's leading edge is a
   wave - built as a clip-path polygon whose front-edge points ripple
   (travel down the letterforms) as the whole front also sweeps right,
   instead of one rigid straight/diagonal edge translating across. */
.intro-wordmark { position: relative; }
.intro-wordmark-text {
  display: inline-block;
  font-family: var(--sans);
  font-weight: 800;
  font-size: clamp(40px, 9vw, 60px);
  letter-spacing: 0.5px;
  line-height: 1;
  background: linear-gradient(90deg, var(--amber), var(--cyan));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-clip-path: polygon(0% 0%, -28% 0%, -23.8% 8.3%, -20.6% 16.7%, -19.1% 25%, -19.6% 33.3%, -22% 41.7%, -25.8% 50%, -30.2% 58.3%, -34% 66.7%, -36.4% 75%, -36.9% 83.3%, -35.4% 91.7%, -32.2% 100%, 0% 100%);
  clip-path: polygon(0% 0%, -28% 0%, -23.8% 8.3%, -20.6% 16.7%, -19.1% 25%, -19.6% 33.3%, -22% 41.7%, -25.8% 50%, -30.2% 58.3%, -34% 66.7%, -36.4% 75%, -36.9% 83.3%, -35.4% 91.7%, -32.2% 100%, 0% 100%);
  animation: introWordReveal 1.4s cubic-bezier(0.65, 0, 0.35, 1) 0.25s both;
}
@keyframes introWordReveal {
  0%   { clip-path: polygon(0% 0%, -28% 0%, -23.8% 8.3%, -20.6% 16.7%, -19.1% 25%, -19.6% 33.3%, -22% 41.7%, -25.8% 50%, -30.2% 58.3%, -34% 66.7%, -36.4% 75%, -36.9% 83.3%, -35.4% 91.7%, -32.2% 100%, 0% 100%); }
  20%  { clip-path: polygon(0% 0%, 12.6% 0%, 12.9% 8.3%, 11.2% 16.7%, 7.8% 25%, 3.6% 33.3%, -0.6% 41.7%, -3.6% 50%, -5% 58.3%, -4.3% 66.7%, -1.6% 75%, 2.3% 83.3%, 6.6% 91.7%, 10.3% 100%, 0% 100%); }
  40%  { clip-path: polygon(0% 0%, 41.3% 0%, 37.3% 8.3%, 33% 16.7%, 29.4% 25%, 27.3% 33.3%, 27.2% 41.7%, 29.1% 50%, 32.6% 58.3%, 36.9% 66.7%, 40.9% 75%, 43.9% 83.3%, 45% 91.7%, 44.1% 100%, 0% 100%); }
  60%  { clip-path: polygon(0% 0%, 62.7% 0%, 59.9% 8.3%, 59% 16.7%, 60.1% 25%, 63.1% 33.3%, 67.1% 41.7%, 71.4% 50%, 74.9% 58.3%, 76.8% 66.7%, 76.7% 75%, 74.6% 83.3%, 71% 91.7%, 66.7% 100%, 0% 100%); }
  80%  { clip-path: polygon(0% 0%, 91.4% 0%, 93.7% 8.3%, 97.4% 16.7%, 101.7% 25%, 105.6% 33.3%, 108.3% 41.7%, 109% 50%, 107.6% 58.3%, 104.6% 66.7%, 100.4% 75%, 96.2% 83.3%, 92.8% 91.7%, 91.1% 100%, 0% 100%); }
  100% { clip-path: polygon(0% 0%, 132% 0%, 136.2% 8.3%, 139.4% 16.7%, 140.9% 25%, 140.4% 33.3%, 138% 41.7%, 134.2% 50%, 129.8% 58.3%, 126% 66.7%, 123.6% 75%, 123.1% 83.3%, 124.6% 91.7%, 127.8% 100%, 0% 100%); }
}

.intro-bar {
  width: 160px;
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
}
.intro-bar-fill {
  height: 100%;
  width: 40%;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--amber), var(--cyan), transparent);
  animation: introBarSweep 1.1s ease-in-out infinite;
}
@keyframes introBarSweep {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

*, *::before, *::after { transition: background-color 0.2s cubic-bezier(0.4,0,0.2,1), border-color 0.2s cubic-bezier(0.4,0,0.2,1), color 0.2s cubic-bezier(0.4,0,0.2,1), transform 0.25s cubic-bezier(0.34,1.56,0.64,1), opacity 0.2s ease, box-shadow 0.25s ease; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
}

@keyframes fadeSlideIn {
  from { opacity: 0; transform: translateY(10px) scale(0.995); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.view:not(.hidden) { animation: fadeSlideIn 0.4s cubic-bezier(0.16, 1, 0.3, 1); }
.view { position: relative; }

/* A tier-gated (or, logged-out, everything-but-Assistant) page: the real
   content stays in the DOM underneath but this covers it entirely - see
   renderLockedView()/isViewLocked() in app.js. */
.locked-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.locked-card {
  max-width: 420px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 32px 28px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
}
.locked-chain { font-size: 34px; line-height: 1; }
.locked-card h2 { margin: 0; font-size: 18px; color: var(--text); }
.locked-card p { margin: 0; font-size: 13px; color: var(--text-muted); line-height: 1.5; }

/* Small lock badge on a rail button whose page is currently locked - a
   dimmer icon plus a tiny 🔒 in the corner, so it's obvious before you
   even click which tabs are reachable right now. */
.rail-btn.locked .rail-icon { opacity: 0.45; }
.rail-btn.locked { position: relative; }
.rail-btn.locked::after {
  content: '🔒';
  position: absolute;
  left: 22px;
  top: 6px;
  font-size: 9px;
  line-height: 1;
}

.deck {
  display: grid;
  grid-template-columns: 68px 1fr;
  min-height: 100vh;
  transition: grid-template-columns 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}

/* .rail-open (added on load by wireMobileNav() in app.js, so the rail
   starts pinned open rather than requiring a first hover) makes the
   desktop rail expand exactly like :hover already does - removed again
   the moment the mouse actually leaves it, handing off to plain :hover
   from then on. */
.deck:has(.rail:hover), .deck:has(.rail.rail-open) { grid-template-columns: 224px 1fr; }

/* --- Rail (sidebar) --- */
.rail {
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 20px 10px;
  position: sticky;
  top: 0;
  height: 100vh;
  width: 68px;
  overflow: hidden;
  transition: width 0.28s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 10;
}

.rail:hover, .rail.rail-open { width: 224px; }

.rail-brand {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 6px 24px;
  white-space: nowrap;
}

.rail-brand-mark {
  font-family: var(--sans);
  font-weight: 700;
  color: var(--amber);
  font-size: 16px;
  letter-spacing: 1px;
}

.rail-brand-text {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--text-muted);
  opacity: 0;
  transition: opacity 0.2s ease 0.05s;
}
.rail:hover .rail-brand-text, .rail.rail-open .rail-brand-text { opacity: 1; }

.rail-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  /* The nav list keeps growing as tabs get added - without its own
     scroll, .rail's overflow:hidden (needed for the width-collapse
     animation) just clips whatever doesn't fit off the bottom on a
     shorter viewport, silently hiding Settings/Theme/the status dot
     with no way to reach them. This keeps those pinned and reachable
     no matter how tall the nav list gets. */
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  scrollbar-width: thin;
}

.rail-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  text-align: left;
  background: none;
  border: none;
  color: var(--text-muted);
  padding: 10px;
  border-radius: 10px;
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  width: 100%;
}

.rail-icon { width: 19px; height: 19px; flex-shrink: 0; }

.rail-label {
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.rail:hover .rail-label, .rail.rail-open .rail-label { opacity: 1; transform: translateX(0); }

.rail-btn:hover { background: var(--surface-alt); color: var(--text); }

.rail-btn.active {
  background: rgba(var(--accent-rgb), 0.10);
  color: var(--amber);
  font-weight: 600;
}
:root[data-theme="dark"] .rail-btn.active { background: rgba(var(--accent-rgb), 0.16); }
.rail-btn.active .rail-icon { color: var(--amber); }

.rail-settings {
  margin-top: auto;
  border-top: 1px solid var(--border);
  padding-top: 14px;
  margin-bottom: 8px;
}

/* Theme button - a plain rail-btn with two swappable icons; only the
   one matching the current data-theme is shown. Clicking it opens
   .theme-picker-menu (6 swatches: light/dark × Mint/Ocean/Sunset) -
   see wireThemePicker() in app.js/login.js and the no-flash inline
   script in <head>. */
.rail-theme-toggle .icon-sun { display: none; }
.rail-theme-toggle .icon-moon { display: inline-flex; }
:root[data-theme="dark"] .rail-theme-toggle .icon-sun { display: inline-flex; }
:root[data-theme="dark"] .rail-theme-toggle .icon-moon { display: none; }

.theme-picker { position: relative; }

/* Positioned via JS (fixed, coordinates from the button's own
   getBoundingClientRect) rather than plain absolute - the rail has
   overflow:hidden for its collapse/expand animation and would
   otherwise clip a popover trying to open from inside it. */
.theme-picker-menu {
  position: fixed;
  z-index: 6000;
  width: 220px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 10px;
  display: flex;
  gap: 10px;
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.35), 0 16px 40px rgba(var(--shadow-rgb), 0.30);
}
.theme-picker-menu.hidden { display: none; }

.theme-picker-group { flex: 1; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.theme-picker-group-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  padding: 4px 8px 2px;
}

.theme-swatch {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 7px 8px;
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.theme-swatch:hover { background: var(--surface-alt); }
.theme-swatch.active { border-color: var(--amber); background: rgba(var(--accent-rgb), 0.10); font-weight: 600; }

.theme-swatch-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.15);
}

.rail-status {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--sans);
  font-size: 10.5px;
  color: var(--text-muted);
  padding: 8px 10px 4px;
  white-space: nowrap;
}
.rail-status .rail-label { font-size: 10px; }

.pulse-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 0 0 rgba(var(--info-rgb), 0.6);
  animation: pulse 2s infinite;
  flex-shrink: 0;
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(var(--info-rgb), 0.5); }
  70% { box-shadow: 0 0 0 6px rgba(var(--info-rgb), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--info-rgb), 0); }
}

/* --- Main --- */
.main {
  padding: 0 36px 60px;
  max-width: 1100px;
  /* .main is the grid's second (1fr) column, next to the rail - without
     this it just sits flush against the rail with all the leftover space
     on a wide screen piling up on the right, instead of the content
     column sitting centered in the middle of that space. */
  margin: 0 auto;
}

.topbar {
  padding: 20px 0 4px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: relative;
}

/* Right-side stack: login/account chip on top, the platform-strip legend
   underneath it, then the Post Now quick-launch button underneath that -
   replaces the old lone-absolutely-positioned .user-chip; the stack
   itself now owns that same top-right slot. */
.topbar-stack {
  position: absolute;
  top: 20px;
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  max-width: min(340px, 60vw);
}

.user-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 24px;
  padding: 5px 6px 5px 5px;
}

.user-chip-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--amber);
  color: var(--on-accent);
  font-family: var(--sans);
  font-weight: 700;
  font-size: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-transform: uppercase;
  flex-shrink: 0;
}

.user-chip-email {
  font-size: 12.5px;
  color: var(--text-muted);
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-chip-logout {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  padding: 5px 10px;
  border-radius: 16px;
  cursor: pointer;
}
.user-chip-logout:hover { color: var(--red); border-color: var(--red); }

@media (max-width: 800px) {
  .topbar-stack { position: static; margin-top: 8px; align-items: flex-start; max-width: 100%; }
  .user-chip { width: fit-content; }
  .user-chip-email { max-width: 120px; }
}

.guest-chip { padding: 6px 8px 6px 14px; gap: 10px; }
.guest-chip .hint-text { white-space: nowrap; }
.guest-chip .btn-primary { white-space: nowrap; text-decoration: none; }
@media (max-width: 720px) {
  .guest-chip { width: fit-content; flex-wrap: wrap; }
}
@media (max-width: 480px) {
  .guest-chip .hint-text { display: none; }
}

.category-strip {
  display: inline-flex;
  gap: 3px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 24px;
  padding: 3px;
  width: fit-content;
}

.cat-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  padding: 6px 16px;
  border-radius: 20px;
  cursor: pointer;
}

.cat-btn:hover { color: var(--text); }

.cat-btn.active {
  background: var(--amber);
  color: var(--on-accent);
}

.platform-strip {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
/* Inside .topbar-stack (below the login chip) the strip is right-aligned
   and narrower, so it reads as one column with the chip/button above and
   below it rather than a wide row. */
.topbar-stack .platform-strip { justify-content: flex-end; }

.post-now-topbtn {
  white-space: nowrap;
}

.platform-chip {
  font-family: var(--sans);
  font-size: 11px;
  padding: 5px 10px;
  border-radius: 20px;
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-muted);
}

.platform-chip:hover { border-color: var(--platform-color, var(--border)); transform: translateY(-1px); }

.platform-chip .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
}

.platform-chip.unsupported { opacity: 0.55; border-style: dashed; }

.view-head {
  padding: 28px 0 20px;
}

.view-head h1 {
  font-size: 22px;
  margin: 0 0 6px;
  letter-spacing: -0.3px;
}

.view-head p {
  color: var(--text-muted);
  margin: 0;
  max-width: 640px;
  line-height: 1.5;
}

.view.hidden { display: none; }

/* --- Cards --- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 2px 10px rgba(var(--shadow-rgb),0.06);
}

.form-card { display: flex; flex-direction: column; gap: 14px; }

.form-row { display: flex; gap: 14px; flex-wrap: wrap; }

.form-row label {
  flex: 1;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  color: var(--text-muted);
  font-weight: 500;
}

.checkbox-label {
  flex-direction: row !important;
  align-items: center;
  gap: 8px !important;
  align-self: flex-end;
  padding-bottom: 9px;
  cursor: pointer;
}
.checkbox-label input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--amber); cursor: pointer; }

.hint-text {
  font-size: 11.5px;
  color: var(--text-muted);
  margin: -4px 0 0;
  font-family: var(--sans);
}

input, select, textarea {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 9px 10px;
  color: var(--text);
  font-family: var(--sans);
  font-size: 13.5px;
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--amber);
  box-shadow: 0 0 0 3px rgba(var(--shadow-rgb), 0.06);
}

/* A native <select>'s own CLOSED box already picks up --surface-alt/--text
   above (and color-scheme: dark, set per theme further up, handles native
   checkboxes/scrollbars correctly) - but the OPEN dropdown list's
   individual <option> rows are a separate thing Chromium/Firefox render
   from THEIR OWN background/color rather than color-scheme alone, so
   without this they silently fell back to the OS's plain light list
   (black text - unreadable - on a bright white row) even in dark mode.
   Confirmed with a real headless-browser screenshot, not a guess. */
select option, select optgroup {
  /* --bg, not --surface/--surface-alt: those are deliberately translucent
     (glass-over-the-page-background), fine for anything painted inside
     this page, but a native <select> popup has its OWN opaque backdrop -
     not this page's --bg - so a near-transparent white tint on top of
     THAT just read as plain white with near-white (--text) text on it,
     unreadable. --bg is the one fully opaque color in the theme. */
  background: var(--bg);
  color: var(--text);
}

.btn-primary {
  align-self: flex-start;
  background: var(--amber);
  color: var(--on-accent);
  border: none;
  padding: 10px 18px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
}

.btn-primary:hover { filter: brightness(1.08); transform: translateY(-1px); box-shadow: 0 4px 14px rgba(var(--accent-rgb), 0.25); }
.btn-primary:active { transform: translateY(0); }
.btn-primary:disabled { opacity: 0.6; cursor: default; transform: none; box-shadow: none; }

.btn-ghost {
  align-self: flex-start;
  background: none;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 14px;
  border-radius: 10px;
  font-size: 12.5px;
  cursor: pointer;
}

.btn-ghost:hover { border-color: var(--amber); color: var(--amber); transform: translateY(-1px); }

.btn-small { padding: 6px 12px; font-size: 12px; }

.btn-danger {
  align-self: flex-start;
  background: none;
  border: 1px solid var(--red);
  color: var(--red);
  padding: 8px 14px;
  border-radius: 10px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.btn-danger:hover { background: rgba(var(--danger-rgb), 0.1); }
.btn-danger:disabled { opacity: 0.6; cursor: default; }

.danger-zone { border-color: rgba(var(--danger-rgb), 0.4) !important; }

.form-msg { font-family: var(--sans); font-size: 12px; }
.form-msg.error { color: var(--red); }
.form-msg.ok { color: var(--cyan); }

/* --- Grids / entity cards --- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}

.entity-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--platform-color, var(--amber));
  border-radius: 8px;
  padding: 14px 16px;
}

.entity-card:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(var(--shadow-rgb),0.16); border-color: var(--platform-color, var(--border)); }

.entity-card .ec-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}

.entity-card .ec-platform {
  font-family: var(--sans);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--platform-color, var(--amber));
}

.entity-card .ec-label { font-weight: 600; font-size: 14px; margin-bottom: 4px; }
.entity-card .ec-sub { font-family: var(--sans); font-size: 11.5px; color: var(--text-muted); }

.ec-actions { display: flex; gap: 12px; align-items: center; }

.ec-delete, .ec-edit {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 12px;
}
.ec-delete:hover { color: var(--red); }
.ec-edit:hover { color: var(--amber); }

/* --- Accounts: platform overview / drill-down --- */
.platform-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--platform-color, var(--amber));
  border-radius: 8px;
  padding: 16px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.platform-tile:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(var(--shadow-rgb),0.16); border-color: var(--platform-color, var(--border)); }
.platform-tile .pt-name { font-weight: 700; font-size: 15px; color: var(--platform-color, var(--text)); }
.platform-tile .pt-count { font-family: var(--sans); font-size: 11.5px; color: var(--text-muted); }

.entity-card.compact { padding: 10px 14px; cursor: pointer; }
.entity-card.compact .ec-label { margin-bottom: 2px; }
.entity-card.compact.selectable { position: relative; padding-left: 38px; }
.entity-card.compact.selectable .ec-select-checkbox {
  position: absolute;
  left: 12px;
  top: 14px;
  width: 16px;
  height: 16px;
  cursor: pointer;
}

#accountsBulkBar:not(:empty) {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: -6px 0 14px;
  font-size: 12.5px;
  color: var(--text-muted);
}
.entity-card.compact .ec-json {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.accounts-breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -6px 0 14px;
  font-size: 12.5px;
  color: var(--text-muted);
}
.accounts-breadcrumb .bc-back {
  background: none;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
}
.accounts-breadcrumb .bc-back:hover { border-color: var(--amber); color: var(--amber); }

.account-detail-card { border-left-width: 4px; }
.account-detail-card .adc-row { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; border-bottom: 1px dashed var(--border); font-size: 13px; }
.account-detail-card .adc-row:last-of-type { border-bottom: none; }
.account-detail-card .adc-row span:first-child { color: var(--text-muted); }
.account-detail-card .adc-json {
  font-family: var(--mono);
  font-size: 12px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px;
  margin-top: 8px;
  white-space: pre-wrap;
  word-break: break-all;
}
.account-detail-card .ec-actions { margin-top: 14px; gap: 16px; }

/* --- Account containers (grouped, same-platform, max 4, shared proxy
   identity) - see renderContainers() in app.js. --- */
.container-modal-card { max-width: 640px; }

#containersPanel:not(:empty) { margin-bottom: 18px; }
.containers-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.containers-head h3 { font-size: 13px; margin: 0; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; }

.containers-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px;
  margin-bottom: 4px;
}

.container-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--platform-color, var(--cyan));
  border-radius: 8px;
  padding: 14px 16px;
}

.container-card .cc-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 8px; }
.container-card .cc-name { font-weight: 700; font-size: 14px; }
.container-card .cc-actions { display: flex; gap: 10px; flex-shrink: 0; }

.cc-identity {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-family: var(--sans);
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px dashed var(--border);
}
.cc-identity b { color: var(--text); font-weight: 600; }
.cc-identity .cc-ip-unverified { color: var(--amber); }
.cc-identity .cc-no-proxy { font-style: italic; }

.cc-slots { display: flex; flex-direction: column; gap: 6px; }
.cc-slot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  font-size: 12.5px;
}
.cc-slot.empty { color: var(--text-muted); font-style: italic; border-style: dashed; }
.cc-slot-remove { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 12px; flex-shrink: 0; }
.cc-slot-remove:hover { color: var(--red); }

.cc-slots-count { font-family: var(--sans); font-size: 10.5px; color: var(--text-muted); margin-top: 8px; text-align: right; }

/* Container health / bandwidth / shadowban-safety indicators. */
.health-badge {
  display: inline-block;
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 3px 8px;
  border-radius: 4px;
}
.health-badge.health-healthy { background: rgba(var(--info-rgb), 0.15); color: var(--cyan); }
.health-badge.health-no-proxy { background: rgba(136,146,160,0.15); color: var(--text-muted); }
.health-badge.health-bad { background: rgba(var(--danger-rgb), 0.15); color: var(--red); }

.cc-bandwidth { display: flex; align-items: center; gap: 8px; margin: 8px 0; font-family: var(--sans); font-size: 10.5px; color: var(--text-muted); }
.cc-bandwidth-bar { flex: 1; height: 6px; background: var(--surface-alt); border: 1px solid var(--border); border-radius: 3px; overflow: hidden; }
.cc-bandwidth-fill { height: 100%; background: var(--cyan); }
.cc-bandwidth-fill.over { background: var(--red); }
.cc-rotate-warning { color: var(--red); margin: 6px 0; }

.origin-badge .ob-rotation, .origin-badge .ob-pacing { color: var(--amber); }

/* Origin badge (Content page log table + account slot rows) - which
   container/IP/region a post actually went out on. */
.origin-badge { display: flex; flex-direction: column; gap: 2px; font-family: var(--sans); font-size: 11px; }
.origin-badge .ob-container { color: var(--cyan); }
.origin-badge .ob-ip { color: var(--text); }
.origin-badge .ob-region { color: var(--text-muted); }
.origin-badge.none { color: var(--text-muted); font-style: italic; }

/* Unassigned account cards get a small dropdown to join a container. */
.ec-container-picker { margin-top: 8px; }
.ec-container-picker select { width: 100%; font-size: 11.5px; padding: 6px 8px; }

/* --- Profile tab: bio + profile picture per account (see
   loadProfilePage()/saveProfileCard() in app.js). --- */
.profile-account-card { display: flex; flex-direction: column; gap: 10px; }

.profile-pic-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.profile-pic-preview {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
}
.profile-pic-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profile-pic-placeholder {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 18px;
  color: var(--platform-color, var(--amber));
}

.profile-pic-browse {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

/* --- Accounts: "Connect an account" (OAuth) card --- */
#oauthConnectCard { border-color: rgba(var(--accent-rgb), 0.35); }

.card-title:has(.card-title-tag) { display: flex; align-items: center; }
.card-title-tag {
  margin-left: auto;
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--on-accent);
  background: var(--cyan);
  padding: 3px 9px;
  border-radius: 20px;
}

.connect-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
}

.connect-tile {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
  font-size: 13px;
}
.connect-tile::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--platform-color, var(--amber));
  flex-shrink: 0;
}
.connect-tile:hover {
  border-color: var(--platform-color, var(--amber));
  color: var(--platform-color, var(--text));
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(var(--shadow-rgb),0.16);
}
.connect-tile:active { transform: translateY(0); }

/* --- Integrations gallery --- */
.integration-tile {
  border-left: 3px solid var(--platform-color, var(--amber));
  margin-bottom: 0;
}
.integration-tile-own {
  border: 1px solid var(--platform-color, var(--amber));
  border-left-width: 3px;
  box-shadow: 0 2px 14px rgba(var(--shadow-rgb),0.1);
}
.integration-connected-row {
  border-top: 1px solid var(--border);
  margin-top: 10px;
  padding-top: 10px;
}
.integration-action-panel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.integration-action-panel select,
.integration-action-panel textarea {
  width: 100%;
  font-family: var(--mono, monospace);
  font-size: 12px;
}
.integration-apikey-form { display: flex; flex-direction: column; gap: 6px; }

/* A plain divider between the two ways to add an account, so it reads as
   "pick one path" instead of two unrelated forms stacked on the page. */
.or-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: -8px 0 4px;
  color: var(--text-muted);
  font-family: var(--sans);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
}
.or-divider::before, .or-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }

/* --- Accounts: manual-add card, collapsed by default. Native <details>
   markers are replaced with a chevron that matches the rest of the UI. --- */
.manual-account-details > summary,
.advanced-details > summary {
  cursor: pointer;
  list-style: none;
}
.manual-account-details > summary::-webkit-details-marker,
.advanced-details > summary::-webkit-details-marker { display: none; }

.manual-account-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 14px;
  user-select: none;
}
.manual-account-summary::after {
  content: '▸';
  margin-left: auto;
  color: var(--text-muted);
  font-size: 12px;
  transition: transform 0.2s ease;
}
.manual-account-details[open] .manual-account-summary::after { transform: rotate(90deg); }

/* Nested "bulk add" disclosure inside the manual form - visually a step
   down from the card-level ones above, so the hierarchy stays obvious. */
.advanced-details {
  display: flex;
  flex-direction: column;
  gap: 10px;
  border: 1px dashed var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  background: var(--surface-alt);
}
.advanced-details summary {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-muted);
  font-weight: 600;
}
.advanced-details summary::before {
  content: '▸';
  display: inline-block;
  font-size: 10px;
  transition: transform 0.2s ease;
}
.advanced-details[open] summary::before { transform: rotate(90deg); }
.advanced-details[open] summary { margin-bottom: 2px; }

.slots-builder { display: flex; flex-direction: column; gap: 8px; }
.slot-row { display: flex; gap: 8px; align-items: center; }
.slot-row select, .slot-row input[type="time"] {
  padding: 7px 8px; font-size: 13px;
}
.slot-remove { background: none; border: none; color: var(--red); cursor: pointer; font-size: 16px; }

.card-title {
  font-weight: 700;
  font-size: 14px;
  margin: -4px 0 2px;
  color: var(--text);
}

.image-list-builder { display: flex; flex-direction: column; gap: 8px; }
.image-row { display: flex; gap: 8px; align-items: center; }
.image-row input { flex: 1; }

/* --- Insights --- */
.chart-card { padding: 20px 24px; }

/* Small, scannable cards in a responsive grid (same shape as the
   Accounts/Schedules grids) instead of one full-width stacked list -
   each card's collapsed head already carries the at-a-glance numbers
   (posted/failed/last synced), not just platform+followers, so the
   overview alone is useful before ever clicking to expand. */
.insight-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 14px; align-items: start; }

.insight-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--platform-color, var(--amber));
  border-radius: 12px;
  overflow: hidden;
}

.insight-card-head {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  cursor: pointer;
}

.insight-card-head .ich-top { display: flex; align-items: center; gap: 8px; }
.insight-card-head .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--platform-color); flex-shrink: 0; }
.insight-card-head .ich-platform { font-family: var(--sans); font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.4px; }
.insight-card-head .ich-caret { margin-left: auto; color: var(--text-muted); font-size: 11px; transition: transform 0.2s ease; }
.insight-card.expanded .ich-caret { transform: rotate(180deg); }
.insight-card-head .ich-label { font-weight: 600; font-size: 14.5px; }
.insight-card-head .ich-followers { font-family: var(--sans); font-size: 15px; font-weight: 700; color: var(--platform-color); }

.insight-card-head .ich-quickstats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: 11px;
  color: var(--text-muted);
  border-top: 1px dashed var(--border);
  padding-top: 8px;
}

.insight-card-body {
  border-top: 1px solid var(--border);
  padding: 14px 16px 16px;
  display: none;
}
.insight-card.expanded .insight-card-body { display: block; }

/* One clean grid of labeled tiles instead of a loose flex-wrap row of
   bare numbers with nothing separating one stat from the next. */
.insight-stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; }
.insight-stat {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 9px 10px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.insight-stat .is-label { font-size: 10.5px; color: var(--text-muted); line-height: 1.3; }
.insight-stat b { color: var(--text); font-size: 17px; line-height: 1.1; }

/* --- Table --- */
.table-wrap { overflow-x: auto; }
.log-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.log-table th {
  text-align: left;
  font-family: var(--sans);
  font-size: 10.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}
.log-table td {
  padding: 10px 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.post-insights-row td { background: var(--surface-alt); }
.post-insight-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.post-insight-chip {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 10px;
  font-size: 12px;
  color: var(--text-muted);
}
.post-insight-chip b { color: var(--text); font-family: var(--sans); }
.status-pill {
  font-family: var(--sans);
  font-size: 10.5px;
  padding: 2px 8px;
  border-radius: 20px;
  text-transform: uppercase;
}
.status-posted { background: rgba(var(--info-rgb), 0.12); color: var(--cyan); }
.status-pending { background: rgba(var(--accent-rgb), 0.12); color: var(--amber); }
.status-failed { background: rgba(var(--danger-rgb), 0.12); color: var(--red); }

.cat-badge {
  font-family: var(--sans);
  font-size: 9.5px;
  text-transform: uppercase;
  padding: 1px 7px;
  border-radius: 10px;
  letter-spacing: 0.5px;
  vertical-align: middle;
}
.cat-badge.cat-funny { background: rgba(var(--accent-rgb), 0.15); color: var(--amber); }
.cat-badge.cat-official { background: rgba(var(--info-rgb), 0.15); color: var(--cyan); }

.insights-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; }

.suggest-block {
  width: 100%;
  border-top: 1px solid var(--border);
  margin-top: 10px;
  padding-top: 10px;
}
.suggest-controls { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.auto-apply-toggle { padding-bottom: 0; align-self: center; font-size: 11px; }
.suggest-result:not(:empty) { margin-top: 10px; }

.suggestion-box {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 420px;
}
.suggestion-slots { font-family: var(--sans); font-size: 12.5px; color: var(--text); }
.suggestion-reason { font-size: 12px; color: var(--text-muted); line-height: 1.4; }

/* Mobile-only hamburger toggle (opens the rail drawer below) and its
   backdrop - both hidden entirely on desktop where the rail is always
   visible and hover-expands instead. See wireMobileNav() in app.js. */
.mobile-nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}
.mobile-nav-toggle svg { width: 19px; height: 19px; }
.rail-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 45;
  background: rgba(0, 0, 0, 0.45);
}
.rail-backdrop.hidden { display: none !important; }

/* Chat-history toggle sits in the same spot the hamburger does, but
   (unlike the hamburger, mobile-only) works at every width - chat history
   is useful on desktop too. */
.chat-drawer-toggle { display: flex !important; }
.chat-drawer-toggle.active { color: var(--amber); border-color: var(--amber); }

/* --- Post Now quick-launch drawer: unfolds in from the LEFT edge --- */
.post-now-backdrop {
  position: fixed;
  inset: 0;
  z-index: 3900;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.post-now-backdrop.open { opacity: 1; pointer-events: auto; }

.post-now-drawer {
  position: fixed;
  left: 0;
  top: 0;
  height: 100vh;
  width: min(460px, 92vw);
  z-index: 3901;
  background: var(--bg);
  border-right: 1px solid var(--border);
  box-shadow: 16px 0 48px rgba(var(--shadow-rgb), 0.30);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* "Unfold from the left": the panel both slides in AND grows from a
     sliver (scaleX from a left-anchored origin), rather than a plain
     translate - reads like a card unfolding open, not just sliding over. */
  transform: translateX(-100%) scaleX(0.85);
  transform-origin: left center;
  opacity: 0;
  transition: transform 0.32s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.24s ease;
  pointer-events: none;
}
.post-now-drawer.open {
  transform: translateX(0) scaleX(1);
  opacity: 1;
  pointer-events: auto;
}
.post-now-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.post-now-drawer-title { font-family: var(--sans); font-weight: 700; font-size: 15px; }
.post-now-drawer-close {
  background: none; border: none; color: var(--text-muted); font-size: 22px;
  line-height: 1; cursor: pointer; padding: 2px 6px; border-radius: 8px;
}
.post-now-drawer-close:hover { background: var(--surface-alt); color: var(--text); }
.post-now-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 18px;
}
/* The form itself moves in here (see wirePostNowDrawer() in app.js) - it
   already has its own .card styling, so drop the drawer's own inherited
   spacing/border where it'd double up. */
.post-now-drawer-body .form-card { border: none; box-shadow: none; padding: 0; margin: 0; }

@media (max-width: 520px) {
  .post-now-drawer { width: 100vw; }
}

/* --- Assistant chat-history drawer: slides in from the RIGHT --- */
.chat-drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 3900;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.chat-drawer-backdrop.open { opacity: 1; pointer-events: auto; }

.chat-drawer {
  position: fixed;
  right: 0;
  top: 0;
  height: 100vh;
  width: min(340px, 88vw);
  z-index: 3901;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -16px 0 48px rgba(var(--shadow-rgb), 0.30);
  display: flex;
  flex-direction: column;
  padding: 16px;
  gap: 10px;
  transform: translateX(100%);
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}
.chat-drawer.open { transform: translateX(0); pointer-events: auto; }
.chat-drawer-head { display: flex; align-items: center; justify-content: space-between; }
.chat-drawer-title { font-family: var(--sans); font-weight: 700; font-size: 15px; }
.chat-drawer-close {
  background: none; border: none; color: var(--text-muted); font-size: 22px;
  line-height: 1; cursor: pointer; padding: 2px 6px; border-radius: 8px;
}
.chat-drawer-close:hover { background: var(--surface-alt); color: var(--text); }
.chat-drawer-new { width: 100%; }
.chat-drawer-search {
  width: 100%;
  font-family: var(--sans);
  font-size: 13px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
}
.chat-drawer-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 0;
  scrollbar-width: thin;
}
.chat-drawer-empty { padding: 8px 2px; }
.chat-thread-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 9px 10px;
  border-radius: 10px;
  cursor: pointer;
  border: 1px solid transparent;
}
.chat-thread-item:hover { background: var(--surface-alt); }
.chat-thread-item.active { background: rgba(var(--accent-rgb), 0.10); border-color: rgba(var(--accent-rgb), 0.25); }
.chat-thread-main { flex: 1; min-width: 0; }
.chat-thread-title {
  font-family: var(--sans); font-size: 12.5px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-thread-preview {
  font-size: 11.5px; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px;
}
.chat-thread-delete {
  background: none; border: none; color: var(--text-muted); font-size: 15px;
  line-height: 1; cursor: pointer; padding: 3px 5px; border-radius: 6px; flex-shrink: 0; opacity: 0;
}
.chat-thread-item:hover .chat-thread-delete { opacity: 1; }
.chat-thread-delete:hover { color: var(--red); background: var(--surface-alt); }
.chat-drawer-storage { padding-top: 4px; border-top: 1px solid var(--border); }

@media (max-width: 800px) {
  .mobile-nav-toggle { display: flex; }
  .rail-backdrop:not(.hidden) { display: block; }

  .deck, .deck:has(.rail:hover) { grid-template-columns: 1fr; }
  .deck { display: block; } /* .rail becomes position:fixed below - a grid column for it would just leave a dead gap */

  /* The rail itself: fully off-canvas at rest (not even a collapsed
     icon strip) - only .mobile-nav-toggle (the hamburger) shows - and
     slides in as a full labeled drawer over the page when opened,
     exactly the ChatGPT/Claude mobile pattern this was asked to match.
     Sliding via transform (not width) keeps the whole rail, including
     its labels, laid out at its final open size the entire time, so
     nothing has to fade/reflow into place after the slide-in the way a
     width-collapse would. */
  .rail {
    position: fixed;
    left: 0;
    top: 0;
    height: 100vh;
    width: min(248px, 78vw);
    flex-direction: column;
    overflow: hidden;
    z-index: 50;
    padding: 16px 8px;
    transform: translateX(-100%);
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s ease;
    box-shadow: none;
  }
  .rail:hover { transform: translateX(-100%); } /* desktop-only hover-expand doesn't apply here - .rail-open (tap-driven) is what opens it */
  .rail.rail-open {
    transform: translateX(0);
    box-shadow: 12px 0 40px rgba(var(--shadow-rgb), 0.35);
  }
  .rail .rail-label,
  .rail .rail-brand-text { opacity: 1; transform: none; } /* fully off-canvas at rest anyway - no need for the old collapsed-icon fade-in trick once it slides open */

  .rail-nav {
    flex-direction: column;
    overflow-y: auto;
    overflow-x: hidden;
  }
  .rail-settings { margin-top: auto; border-top: 1px solid var(--border); padding-top: 14px; }
  .rail-status { display: none; } /* still no room for it even opened - not worth showing partially */

  /* The rail no longer reserves any permanent space (it's fully
     off-canvas at rest) - content uses the full width, and the drawer
     opens as an overlay on top of it via .rail's own fixed positioning
     + z-index instead of pushing it over. */
  .main { margin: 0; padding: 0 16px 40px; max-width: 100%; }

  /* The menu + chat-history buttons sit beside the category toggle on one
     row instead of .topbar's desktop column stack putting them on
     separate lines - the login chip/platform legend/Post Now stack
     (.topbar-stack, switched to static positioning above) still gets its
     own line below. */
  .topbar { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 10px; }
  .topbar-stack { flex-basis: 100%; }

  /* Platform legend: no room for a whole wrapped row of chips on a phone
     - collapses to a single box that cycles through every platform's
     name one at a time (wirePlatformStripRotator() in app.js toggles
     which chip carries .active), its border/text tinted with that
     platform's own color via --platform-color (set per chip above). */
  .topbar-stack .platform-strip { display: block; width: 100%; min-height: 28px; }
  .topbar-stack .platform-strip .platform-chip { display: none; width: 100%; box-sizing: border-box; justify-content: center; }
  .topbar-stack .platform-strip .platform-chip.active {
    display: flex;
    border-color: var(--platform-color, var(--border));
    color: var(--platform-color, var(--text));
    animation: fadeSlideIn 0.3s ease;
  }
  .topbar-stack .platform-strip .platform-chip.active .dot { background: var(--platform-color, var(--text-muted)) !important; }

  /* Assistant: a real full-height chat screen instead of a boxed-in
     520px-tall widget on a page - the log fills most of the viewport
     and the composer sits right under it, the same shape as Claude/
     ChatGPT's own mobile chat rather than a form element that happens
     to hold messages. */
  #view-assistant .view-head { padding: 16px 0 12px; }
  #view-assistant:not(.assistant-floating) .assistant-card { padding: 12px 10px 10px; }
  #view-assistant:not(.assistant-floating) .assistant-chat { max-height: none; height: calc(100vh - 340px); min-height: 260px; }
  #view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-card { min-height: 50vh; }
}

@media (max-width: 480px) {
  /* Same idea as the 800px breakpoint, just tighter for a phone-width
     screen: bigger tap targets matter more than fitting more on screen,
     and a couple of newer components (theme picker, media library) need
     their own adjustments to stay usable this narrow. */
  .view-head h1 { font-size: 19px; }
  .assistant-home-mark { width: 40px; height: 40px; }
  .assistant-home-title { font-size: 21px; }
  .assistant-home-sub { font-size: 12.5px; }
  #view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-card { padding: 32px 16px; }

  .theme-picker-menu { width: min(220px, calc(100vw - 24px)); }
  .media-library-grid { grid-template-columns: repeat(auto-fill, minmax(68px, 1fr)); }

  .modal-card { padding: 16px; }
  .card { padding: 16px; }
}

/* --- Engagement --- */
.engagement-card { display: flex; flex-direction: column; gap: 8px; }

.draft-text {
  width: 100%;
  min-height: 60px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-family: var(--sans);
  font-size: 13px;
  padding: 8px;
  resize: vertical;
}
.draft-text:focus { outline: none; border-color: var(--amber); }
.draft-text:disabled { opacity: 0.7; }

.eng-actions { display: flex; gap: 8px; }

.status-pill.status-drafted, .status-pill.status-rejected { background: rgba(136,146,160,0.15); color: var(--text-muted); }
.account-picker { position:relative; }
.account-picker-button { width:100%; text-align:left; }
.account-picker-menu { position:absolute; z-index:50; left:0; right:0; top:calc(100% + 6px); background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:10px; max-height:260px; overflow:auto; box-shadow: 0 16px 40px rgba(var(--shadow-rgb),0.18); }
.account-picker-menu label { display:flex; gap:8px; align-items:center; padding:8px; border-radius:8px; }
.account-picker-menu label:hover { background:var(--surface-alt); }
#oauthPickerList label { display:flex; gap:8px; align-items:center; padding:8px; border-radius:8px; }
#oauthPickerList label:hover { background:var(--surface-alt); }
.preview-panel { margin-top:10px; display:grid; gap:10px; }
.preview-summary { font-size:12.5px; font-weight:600; color:var(--text); background:var(--surface-alt); border:1px solid var(--border); border-radius:10px; padding:8px 12px; }
.preview-panel video,.preview-panel img { width:min(100%,420px); max-height:640px; object-fit:contain; border-radius:10px; background:#000; }
.preview-item { padding:10px; border:1px solid var(--border); border-radius:12px; }

/* Shared media-library picker modal (see openMediaLibraryPicker in
   app.js) - a grid of thumbnails from every past upload. */
.media-library-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 8px;
  max-height: 360px;
  overflow-y: auto;
  margin: 4px 0 14px;
}
.media-library-item {
  aspect-ratio: 1;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-alt);
  cursor: pointer;
}
.media-library-item:hover { border-color: var(--amber); }
.media-library-item img, .media-library-item video { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }

/* AI Video gallery */
.ai-video-card { display: flex; flex-direction: column; gap: 8px; }
.ai-video-thumb { width: 100%; max-height: 160px; object-fit: cover; border-radius: 8px; }

/* Media Library page - dedicated gallery of every upload (see #view-medialibrary) */
.medialib-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
  margin: 10px 0 18px;
}
.medialib-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-alt);
  overflow: hidden;
  padding-bottom: 8px;
}
.medialib-thumb-wrap { aspect-ratio: 1; background: var(--surface); }
.medialib-thumb-wrap img, .medialib-thumb-wrap video { width: 100%; height: 100%; object-fit: cover; display: block; }
.medialib-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 0 8px; }
.medialib-actions { display: flex; gap: 6px; padding: 0 8px; flex-wrap: wrap; }
.medialib-actions .btn-ghost, .medialib-actions .btn-primary { flex: 1; }
.medialib-browse-label { cursor: pointer; }

/* A styled stand-in for the browser's own unstyled "Choose Files / No
   file chosen" native file input - same btn-ghost look as every other
   button in the app, wrapping a visually-hidden real <input type="file">
   (still fully keyboard/screen-reader accessible - a <label> click still
   opens the native picker exactly like clicking the input itself would).
   Used anywhere media is picked from the local device - see
   .medialib-browse-label above for the original instance of this pattern. */
.file-picker-label { cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.ai-video-card video { width: 100%; max-height: 320px; border-radius: 8px; background: #000; }

/* Music library search + multi-clip timeline editor */
.music-library { margin-top:10px; display:flex; flex-direction:column; gap:8px; }
.music-results { display:flex; flex-direction:column; gap:6px; }
.music-result-row { display:flex; align-items:center; gap:8px; padding:8px; border:1px solid var(--border); border-radius:6px; background:var(--surface-alt); flex-wrap:wrap; }
.music-result-meta { flex:1; min-width:140px; font-family:var(--sans); font-size:12px; }
.music-result-meta .mr-title { color:var(--text); font-weight:600; }
.music-result-meta .mr-sub { color:var(--text-muted); }
.music-result-row audio { height:30px; max-width:220px; }
.music-timeline { display:flex; flex-direction:column; gap:6px; }
.music-clip { display:flex; align-items:center; gap:8px; padding:8px; border:1px solid var(--border); border-radius:6px; background:var(--surface); flex-wrap:wrap; }
.music-clip-index { font-family:var(--sans); color:var(--amber); font-weight:700; font-size:12px; min-width:18px; }
.music-clip-meta { font-family:var(--sans); font-size:12px; min-width:120px; flex:1; }
.music-clip-meta .mc-title { color:var(--text); font-weight:600; }
.music-clip-meta .mc-sub { color:var(--text-muted); }
.music-clip-trim { display:flex; align-items:center; gap:4px; font-family:var(--sans); font-size:11px; color:var(--text-muted); }
.music-clip-trim input[type="number"] { width:60px; padding:5px 6px; font-size:12px; }
.music-clip-actions { display:flex; gap:4px; }
.music-clip-actions button { padding:4px 8px; font-size:12px; }
.music-timeline-summary { font-family:var(--sans); }

.pre-json{white-space:pre-wrap;background:var(--surface-alt);border:1px solid var(--border);color:var(--text);font-family:var(--mono);padding:10px;border-radius:10px;overflow:auto;font-size:12px;max-height:360px}.preview-item video,.preview-item img{max-width:100%;max-height:360px;border-radius:8px}

/* Each viewer's own local time (see startLocalClock() in app.js) - just
   the browser's own clock, no IP-geolocation lookup needed since that's
   already exactly the right time for wherever the viewer actually is. */
.local-clock {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 4px;
}
.intro-local-clock { font-size: 12px; letter-spacing: 0.5px; opacity: 0.8; }

/* Usage (Settings > Usage - see server/routes/usage.js) */
.usage-bars { display: flex; flex-direction: column; gap: 12px; margin: 8px 0; }
.usage-bar-label { display: flex; justify-content: space-between; font-family: var(--sans); font-size: 12.5px; color: var(--text); margin-bottom: 4px; }
.usage-bar-track { height: 8px; border-radius: 4px; background: var(--surface-alt); overflow: hidden; }
.usage-bar-fill { height: 100%; background: var(--amber); border-radius: 4px; }

/* Connectors (Settings > Connectors) */
#connectorsEndpointHint { font-family: var(--mono); font-size: 11px; background: var(--surface-alt); padding: 1px 5px; border-radius: 4px; }

/* Image Studio (AI generate/edit - see #view-imagestudio) */
.image-studio-tabs { display: flex; gap: 8px; margin: 4px 0 14px; }
.image-studio-tab.active { background: var(--amber); color: #1a1a1a; border-color: var(--amber); }
.image-studio-pane.hidden { display: none; }
.image-gen-card { display: flex; flex-direction: column; gap: 8px; }
.image-gen-thumb { width: 100%; max-height: 260px; object-fit: contain; border-radius: 8px; background: var(--surface-alt); }
.image-gen-source-thumb { width: 64px; height: 64px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); }

/* "✨ Enhance prompt" button + its suggestion popover, shared by Image
   Studio, AI Video and the Assistant composer - see wireEnhancePrompt()
   in app.js and POST /api/llm/enhance-prompt (server/llm.js). */
.enhance-btn { white-space: nowrap; }
.assistant-enhance-btn { flex-shrink: 0; width: 30px; height: 36px; border: none; background: transparent; font-size: 16px; cursor: pointer; padding: 0; line-height: 1; opacity: 0.8; }
.assistant-enhance-btn:hover { opacity: 1; }
.assistant-enhance-btn:disabled { opacity: 0.4; cursor: default; }
.hint-text.enhance-suggestion { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; background: var(--surface-alt); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; margin-top: 4px; }
.enhance-suggestion-text { flex: 1; min-width: 160px; color: var(--text); font-style: italic; }

/* A single trimmable clip built from a browser/computer upload rather
   than a library search result (see addUploadedClip() in app.js) - same
   .music-clip row, just no license/attribution to show. */
.music-clip.direct-upload .music-clip-meta .mc-sub { font-style: italic; }

/* ============================================================
   ASSISTANT (ChatGPT/Claude-style chat front door)
   Two-column layout: the conversation itself (left, wide) plus a live
   "Action preview" side panel (right) that shows the tool call being
   built up - which action, with what parameters, and its current status
   (Draft -> Running -> Done/Failed) - instead of a plan only ever
   flashing inline as chat text. See renderAssistantDraftCard() in app.js.
   ============================================================ */
/* A full dedicated page, not a card-plus-side-panel widget squeezed into
   the shared 1100px content column every other tab uses - the old right
   "Action preview" column is gone (that card now renders INLINE in the
   chat itself, see .tool-call-card below/renderAssistantDraftCard() in
   app.js), and the whole tab gets more width + more height to actually
   read like a real, dedicated AI chat page. */
.main:has(#view-assistant:not(.hidden)) { max-width: 1400px; }

.assistant-layout {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.assistant-main {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}

.assistant-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 16px 14px;
  min-width: 0;
}

/* ------------------------------------------------------------
   Assistant "home" screen - shown until the first real message is
   sent: a centered logo mark, a big greeting and a large composer
   with no side panel and no visible log, the same shape as the
   front screen Claude/ChatGPT/Gemini show before a conversation
   starts. updateAssistantHomeState() in app.js toggles .is-empty
   on .assistant-layout based on assistantHistory.length. The
   floating mini-panel (.assistant-floating, opened over another
   tab) always stays in the compact chat layout instead - it's a
   utility popup, not a front page. ------------------------------ */
.assistant-home { display: none; }

#view-assistant:not(.assistant-floating):has(.assistant-layout.is-empty) .view-head { display: none; }

#view-assistant:not(.assistant-floating) .assistant-layout.is-empty { display: block; }
#view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-side { display: none; }

#view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  min-height: min(56vh, 460px);
  /* The actual root cause of the long-standing mobile overflow bug
     (confirmed with a real headless-browser measurement, not a guess):
     a flex item with auto side margins and no explicit width is NOT
     stretched to its container's width - it's sized to fit its content
     instead (that's what lets the auto margins have space to center it
     in), so on a narrow screen this card grew to whatever width its
     un-wrapped content (the chip-btn row) preferred, up to 424px+ wide,
     instead of ever actually being 358px-ish. width:100% pins the box to
     the container first - only once the container is wider than
     max-width does any space exist left over for the auto margins to
     center it in. */
  width: 100%;
  max-width: 680px;
  margin: 0 auto;
  padding: 48px 24px;
  text-align: center;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}

#view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-home {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  order: 1;
}

.assistant-home-mark {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  background: rgba(var(--accent-rgb), 0.12);
  color: var(--amber);
  display: flex;
  align-items: center;
  justify-content: center;
}
.assistant-home-mark svg { width: 24px; height: 24px; }

.assistant-scroll-hint {
  margin: 0;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--text-muted);
  text-transform: uppercase;
}

.assistant-home-title {
  font-size: 26px;
  font-weight: 600;
  color: var(--text);
  margin: 0;
  letter-spacing: -0.3px;
}

.assistant-home-sub {
  font-size: 13.5px;
  color: var(--text-muted);
  max-width: 440px;
  line-height: 1.5;
  margin: 0;
}

#view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-composer {
  order: 2;
  width: 100%;
  max-width: 560px;
  padding: 8px 8px 8px 20px;
}
#view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-composer #assistantInput { font-size: 15px; padding: 10px 4px; }

/* The real mobile overflow bug (confirmed with a real headless-browser
   measurement, not a guess): .assistant-card switches to align-items:
   center for this "is-empty" home-screen layout so its children size to
   their own content instead of stretching - but a flex-wrap row with no
   width of its own doesn't wrap against anything, it just grows to fit
   every chip on one line and blows out the card (and the whole page,
   since overflow-x:hidden on body only clips it rather than containing
   it). width:100% here gives it something real to wrap against. */
#view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-chips { order: 3; justify-content: center; width: 100%; }
#view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-attach-strip { order: 3; justify-content: center; width: 100%; }
#view-assistant:not(.assistant-floating) .assistant-layout.is-empty #assistantMediaStatus,
#view-assistant:not(.assistant-floating) .assistant-layout.is-empty #assistantMsg { order: 4; }
#view-assistant:not(.assistant-floating) .assistant-layout.is-empty .assistant-chat { display: none; }

.assistant-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-btn {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 7px 14px;
  font-family: var(--sans);
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, transform 0.15s;
}
.chip-btn:hover { border-color: var(--amber); color: var(--amber); transform: translateY(-1px); }

.assistant-chat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 220px;
  /* Fills most of the viewport (a real chat page), not a fixed small
     box - roughly the same "screen minus header/composer" sizing the
     mobile-only override further down used to be alone. */
  max-height: calc(100vh - 300px);
  overflow-y: auto;
  padding: 4px 2px;
  scroll-behavior: smooth;
}

/* Each turn is a full-width row (avatar + text), the way Claude/ChatGPT
   lay out a conversation, rather than two-tone chat "bubbles" - easier to
   read at a glance, and it scales naturally to longer assistant replies. */
.assistant-row {
  display: flex;
  gap: 10px;
  padding: 10px 8px;
  border-radius: 10px;
  align-items: flex-start;
  animation: fadeSlideIn 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.assistant-row.assistant { background: var(--surface-alt); }
.assistant-row.user { background: transparent; flex-direction: row-reverse; text-align: right; }

.assistant-avatar {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
}
.assistant-row.assistant .assistant-avatar { background: rgba(var(--accent-rgb), 0.18); color: var(--amber); }
.assistant-row.user .assistant-avatar { background: var(--amber); color: var(--on-accent); }

.assistant-bubble {
  flex: 1;
  min-width: 0;
  padding-top: 2px;
  font-size: 13.5px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text);
}
.assistant-row.user .assistant-bubble { color: var(--text); }

/* Typing indicator - three pulsing dots in an assistant-shaped row, shown
   while a reply is in flight so the wait never looks like nothing is
   happening (removed the instant a reply/error comes back). */
.assistant-row.typing .assistant-bubble { display: flex; align-items: center; height: 20px; }
.typing-dots { display: inline-flex; gap: 4px; }
.typing-dots span {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-muted);
  animation: typingBounce 1.2s ease-in-out infinite;
}
.typing-dots span:nth-child(2) { animation-delay: 0.15s; }
.typing-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes typingBounce {
  0%, 60%, 100% { opacity: 0.35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

/* --- Inline tool-call card: the action the assistant is proposing,
   rendered as its OWN row right in the chat scrollback (see
   renderAssistantDraftCard()/setToolCardStatus() in app.js) - not a
   separate side panel anymore. Indented to roughly line up under the
   assistant avatar column above it (26px avatar + 10px gap), so it
   visually reads as "part of what the assistant just said" rather than
   a floating unrelated box, and it stays in scrollback permanently once
   run (done/failed), the same way a past tool call stays visible in
   Claude/ChatGPT's own history instead of disappearing. */
.tool-call-card {
  border: 1px solid var(--amber);
  background: rgba(var(--accent-rgb), 0.07);
  border-radius: 10px;
  padding: 12px 13px;
  margin: 2px 8px 6px 44px;
  max-width: 640px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  animation: fadeSlideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.tool-call-card.hidden { display: none; }
.tool-call-card.tc-running { border-color: var(--cyan); background: rgba(var(--info-rgb), 0.07); }
.tool-call-card.tc-done { border-color: #4CAF6A; background: rgba(76, 175, 106, 0.07); }
.tool-call-card.tc-failed { border-color: var(--red); background: rgba(var(--danger-rgb), 0.07); }
/* A pending card the user moved past without confirming (sent another
   message, or navigated to the full tab instead) - kept in scrollback as
   an honest "this was proposed but never sent" record instead of either
   vanishing or staying misleadingly clickable. */
.tool-call-card.tc-superseded { opacity: 0.55; border-color: var(--border); background: var(--surface-alt); }
.tool-call-card.tc-superseded .tool-call-title { color: var(--text-muted); }

.tool-call-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tool-call-title { font-weight: 700; color: var(--amber); font-size: 13px; display: flex; align-items: center; gap: 6px; }
.tc-running .tool-call-title { color: var(--cyan); }
.tc-done .tool-call-title { color: #4CAF6A; }
.tc-failed .tool-call-title { color: var(--red); }

.tool-call-badge {
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(var(--accent-rgb), 0.18);
  color: var(--amber);
  flex-shrink: 0;
}
.tc-running .tool-call-badge { background: rgba(var(--info-rgb), 0.18); color: var(--cyan); }
.tc-done .tool-call-badge { background: rgba(76, 175, 106, 0.18); color: #4CAF6A; }
.tc-failed .tool-call-badge { background: rgba(var(--danger-rgb), 0.18); color: var(--red); }

.tool-call-body { display: flex; flex-direction: column; gap: 5px; }
.tool-call-row { font-size: 12px; color: var(--text); display: flex; gap: 6px; }
.tool-call-row .tc-key { color: var(--text-muted); font-weight: 600; flex-shrink: 0; min-width: 64px; }
.tool-call-row .tc-val { min-width: 0; word-break: break-word; }

.tool-call-actions { display: flex; gap: 8px; margin-top: 2px; flex-wrap: wrap; }
.tool-call-actions button { font-size: 12px; padding: 7px 12px; }

@media (max-width: 900px) {
  .assistant-layout { grid-template-columns: 1fr; }
  .tool-panel { position: static; }
}

.assistant-attach-strip { display: flex; flex-wrap: wrap; gap: 8px; }
.assistant-attach-thumb {
  position: relative;
  width: 56px;
  height: 56px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--surface-alt);
}
.assistant-attach-thumb img,
.assistant-attach-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.assistant-attach-thumb .attach-remove {
  position: absolute;
  top: 2px;
  right: 2px;
  background: rgba(0,0,0,0.65);
  color: #fff;
  border: none;
  border-radius: 50%;
  width: 16px;
  height: 16px;
  font-size: 10px;
  line-height: 16px;
  padding: 0;
  cursor: pointer;
}

/* Composer: a single rounded pill (input + attach + send) like ChatGPT/
   Claude's message bar, instead of separate boxed controls in a row. */
.assistant-composer {
  display: flex;
  gap: 6px;
  align-items: center;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 26px;
  padding: 6px 6px 6px 16px;
  transition: border-color 0.15s, box-shadow 0.15s;
  box-shadow: 0 1px 2px rgba(var(--shadow-rgb), 0.06);
}
.assistant-composer:focus-within { border-color: var(--amber); box-shadow: 0 4px 20px rgba(var(--shadow-rgb), 0.12); }
.assistant-composer #assistantInput {
  flex: 1;
  min-width: 0; /* a text input's intrinsic min-width is its default ~20-char
    size, not 0 - without this the composer row (attach + input + enhance +
    send) refuses to shrink below that on a narrow screen and overflows the
    viewport instead of the input just getting narrower. */
  border: none;
  background: none;
  padding: 8px 2px;
}
.assistant-composer #assistantInput:focus { outline: none; box-shadow: none; }
.assistant-attach-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 16px;
}
.assistant-attach-btn:hover { color: var(--amber); background: rgba(var(--accent-rgb), 0.12); }

/* Connectors quick-access, right beside the attach button in the type
   bar - a small popover listing WhatsApp + every connected AI
   Integration (see wireAssistantConnectorsMenu() in app.js). */
.assistant-connectors { position: relative; flex-shrink: 0; }
.assistant-connectors-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 16px;
}
.assistant-connectors-btn:hover, .assistant-connectors-btn.active { color: var(--amber); background: rgba(var(--accent-rgb), 0.12); }

.assistant-connectors-menu {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 0;
  width: 260px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 8px;
  box-shadow: 0 16px 40px rgba(var(--shadow-rgb), 0.30);
  z-index: 60;
}
.assistant-connectors-menu.hidden { display: none; }
.assistant-connectors-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 6px 8px 4px;
}
.assistant-connector-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: 10px;
  padding: 8px;
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
}
.assistant-connector-item:hover { background: var(--surface-alt); }
.assistant-connector-item .aci-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.assistant-connector-item .aci-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.assistant-connector-item .aci-status { font-size: 10.5px; color: var(--text-muted); flex-shrink: 0; }
.assistant-connectors-manage {
  display: block;
  text-align: center;
  margin-top: 4px;
  padding: 7px 8px;
  border-radius: 10px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--amber);
  text-decoration: none;
  cursor: pointer;
}
.assistant-connectors-manage:hover { background: var(--surface-alt); }

.assistant-send-btn {
  width: 36px;
  height: 36px;
  padding: 0 !important;
  flex-shrink: 0;
  border-radius: 50% !important;
  display: flex;
  align-items: center;
  justify-content: center;
}
.assistant-send-btn svg { width: 17px; height: 17px; }
.assistant-send-btn:disabled { opacity: 0.5; cursor: default; }

/* --- Floating AI Agent launcher (opens the Assistant tab as an overlay
   panel from any other tab - see openAssistantFloating in app.js) --- */
.ai-agent-fab {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 4000;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--amber);
  color: var(--on-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  box-shadow: 0 8px 24px rgba(var(--shadow-rgb),0.28);
  transition: transform 0.15s;
  touch-action: none;
  user-select: none;
}
.ai-agent-fab .rail-icon { width: 24px; height: 24px; pointer-events: none; }
.ai-agent-fab:hover { transform: translateY(-2px); }
.ai-agent-fab.hidden { display: none; }
.ai-agent-fab.dragging { cursor: grabbing; transform: none; transition: none; }

.ai-agent-fab-dot {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--red);
  border: 2px solid var(--bg);
  pointer-events: none;
}
.ai-agent-fab-dot.hidden { display: none; }

.view#view-assistant.assistant-floating {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 4000;
  width: min(400px, calc(100vw - 32px));
  max-height: min(640px, calc(100vh - 48px));
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(var(--shadow-rgb),0.30);
}
.view#view-assistant.assistant-floating .view-head { position: relative; padding: 0 24px 14px 0; }
.view#view-assistant.assistant-floating .view-head h1 { font-size: 17px; }
.view#view-assistant.assistant-floating .view-head p { font-size: 12.5px; }
.view#view-assistant.assistant-floating .assistant-layout { display: block; margin-bottom: 0; }
.view#view-assistant.assistant-floating .assistant-card { max-width: none; margin-bottom: 12px; }
.view#view-assistant.assistant-floating .assistant-chat { max-height: 280px; }
.view#view-assistant.assistant-floating .tool-panel { position: static; }

.assistant-float-close {
  position: absolute;
  top: 0;
  right: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface-alt);
  color: var(--text-muted);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}
.assistant-float-close:hover { color: var(--text); border-color: var(--amber); }
.assistant-float-close.hidden { display: none; }

/* ============================================================
   GLASS
   Every theme is real frosted glass now - light and dark, all 3
   color variants each: translucent surfaces (--surface/--surface-alt/
   --border, set per theme/variant above) with a backdrop-filter blur,
   so the glowing color blobs painted on <body> (also above) show
   softly through every card, the sidebar, dropdowns and the composer -
   like frosted glass over a lit background, not a flat rectangle.
   Not gated per theme: every theme's tokens are already translucent,
   so the same rules produce the right glass look in all six. Shadows
   use --shadow-rgb (cool-dark for light glass, black for dark glass)
   so they read as depth in either case instead of a flat dark smear.
   The primary button is the one thing kept solid/opaque on purpose,
   with a colored glow (using --accent-rgb, so it matches whichever
   variant is picked) instead of glass, so the main action still pops
   against all the translucent panels around it.
   ============================================================ */
.card, .entity-card, .container-card, .platform-tile, .insight-card,
.tool-panel, .modal-card, .tool-call-card, .account-picker-menu,
.assistant-composer, .auth-tabs, .category-strip, .user-chip, .rail {
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.35), 0 12px 32px rgba(var(--shadow-rgb), 0.22);
}

.rail { box-shadow: inset -1px 0 0 rgba(255,255,255,0.30), 6px 0 32px rgba(var(--shadow-rgb), 0.18); }

.entity-card:hover, .platform-tile:hover {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.40), 0 16px 40px rgba(var(--shadow-rgb), 0.28);
}

input, select, textarea {
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: inset 0 1px 2px rgba(var(--shadow-rgb), 0.18);
}

.rail-btn.active { backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }

.btn-primary {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.35), 0 8px 22px rgba(var(--accent-rgb), 0.35);
}
.btn-primary:hover {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.35), 0 12px 28px rgba(var(--accent-rgb), 0.45);
}
.btn-primary:active {
  box-shadow: inset 0 1px 4px rgba(var(--shadow-rgb), 0.30);
}

.btn-ghost { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }

.auth-tab.active, .cat-btn.active {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.30), 0 4px 14px rgba(var(--shadow-rgb), 0.22);
}

@media (prefers-reduced-transparency: reduce) {
  * { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }
}

/* ============================================================
   VIDEO EDITOR (Video Template Studio) - see public/videoStudio.js
   ============================================================ */

.vs-tabs { display: flex; gap: 6px; margin: 4px 0 16px; }
.vs-tab {
  padding: 8px 16px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); color: var(--text-muted); font-weight: 600; font-size: 13px; cursor: pointer;
}
.vs-tab.active { background: var(--amber); color: var(--on-accent); border-color: transparent; }

.vs-gallery-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }

.template-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 14px; }
.template-card { display: flex; flex-direction: column; gap: 6px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-alt); overflow: hidden; padding-bottom: 8px; }
.template-card-preview { width: 100%; aspect-ratio: 9/16; background: #000; display: flex; align-items: center; justify-content: center; }
.template-card-preview video { width: 100%; height: 100%; object-fit: cover; display: block; }
.template-card-noPreview { color: var(--text-muted); font-size: 12px; text-align: center; padding: 8px; }
.template-card-label { font-size: 12.5px; font-weight: 600; padding: 0 8px; overflow-wrap: anywhere; }
.template-card-actions { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 8px; }
.template-card-actions button { flex: 1 1 auto; }

.vs-editor { margin-top: 4px; }
.vs-editor-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 8px; }
.vs-label-input { flex: 1 1 220px; min-width: 160px; }
.vs-editor-body { display: grid; grid-template-columns: minmax(220px, 300px) 1fr; gap: 20px; margin-top: 12px; }
@media (max-width: 860px) { .vs-editor-body { grid-template-columns: 1fr; } }

.vs-preview-col { display: flex; flex-direction: column; gap: 8px; }
#vsCanvas { width: 100%; max-width: 270px; aspect-ratio: 9/16; background: #000; border-radius: 10px; display: block; }
.vs-preview-controls { display: flex; align-items: center; gap: 8px; }
.vs-preview-controls input[type="range"] { flex: 1 1 auto; }
#vsRealPreviewWrap video { width: 100%; max-width: 270px; border-radius: 10px; background: #000; display: block; }
.vs-sample-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 4px; }
.vs-sample-thumb { width: 40px; height: 40px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); }

.vs-timeline-col { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.vs-effects { display: flex; flex-wrap: wrap; gap: 6px; max-height: 140px; overflow-y: auto; padding: 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); }
.vs-effect-chip {
  padding: 4px 10px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface-alt);
  color: var(--text-muted); font-size: 11.5px; cursor: pointer; white-space: nowrap;
}
.vs-effect-chip.active { background: var(--amber); color: var(--on-accent); border-color: transparent; }

.vs-timeline {
  display: flex; gap: 4px; align-items: stretch; overflow-x: auto; padding: 10px 6px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface); min-height: 96px;
}
.vs-clip {
  position: relative; flex: 0 0 auto; min-width: 48px; border: 2px solid var(--border); border-radius: 8px;
  background: var(--surface-alt); overflow: hidden; cursor: grab; display: flex; flex-direction: column; justify-content: flex-end;
}
.vs-clip.selected { border-color: var(--amber); box-shadow: 0 0 0 2px rgba(var(--shadow-rgb), 0.12); }
.vs-clip-thumb { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 20px; }
.vs-clip-thumb img { width: 100%; height: 100%; object-fit: cover; opacity: 0.85; }
.vs-clip-label { position: relative; z-index: 1; font-size: 9.5px; color: #fff; background: rgba(0,0,0,0.55); padding: 2px 4px; text-align: center; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; }
.vs-clip-remove {
  position: absolute; top: 2px; right: 2px; z-index: 2; width: 16px; height: 16px; line-height: 14px; padding: 0;
  border-radius: 50%; border: none; background: rgba(0,0,0,0.6); color: #fff; font-size: 11px; cursor: pointer;
}
.vs-clip-resize { position: absolute; top: 0; right: 0; bottom: 0; width: 8px; cursor: ew-resize; background: rgba(255,255,255,0.08); z-index: 2; }

.vs-inspector { margin-top: 12px; padding: 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.vs-clip-photo-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 6px; }

.vs-apply-images { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.vs-apply-thumb { position: relative; width: 72px; height: 72px; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
.vs-apply-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vs-apply-thumb button { position: absolute; top: 2px; right: 2px; width: 18px; height: 18px; line-height: 16px; padding: 0; border-radius: 50%; border: none; background: rgba(0,0,0,0.6); color: #fff; font-size: 12px; cursor: pointer; }
#vsApplyResultVideo { width: 100%; max-width: 360px; border-radius: 10px; background: #000; display: block; margin: 8px 0; }

/* ============================================================
   SEO / marketing landing content (guest view of the Assistant tab -
   see #seoLandingSection in index.html and applyGuestLandingVisibility()
   in app.js). Reuses the app's existing .card/.grid/.hint-text tokens so
   it matches whichever theme/variant is active instead of needing its
   own palette.
   ============================================================ */
.seo-landing { margin-bottom: 22px; }
.seo-hero { padding: 4px 0 14px; }
.seo-hero h2 { margin: 0 0 8px; font-size: 1.5rem; }
.seo-hero p { margin: 0; color: var(--text-muted); max-width: 780px; }
.seo-platform-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.seo-platform-pill {
  font-size: 0.82rem; padding: 5px 12px; border-radius: 999px;
  background: var(--surface-alt); border: 1px solid var(--border); color: var(--text-muted);
}
.seo-feature-grid { margin-bottom: 14px; }
.seo-pricing-note { margin-bottom: 18px; }
.seo-faq { max-width: 780px; }
.seo-faq h3 { margin: 0 0 10px; font-size: 1.15rem; }
.seo-faq details {
  border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; margin-bottom: 8px; background: var(--surface);
}
.seo-faq summary { cursor: pointer; font-weight: 600; }
.seo-faq details p { margin: 8px 0 2px; color: var(--text-muted); }
