/* ============================================================================
   Digital Media AI Orchestrator — Console UI (v2, enterprise shell)
   ============================================================================
   Complete redesign of the customer dashboard. Aligned with the platform
   design system (design-system.css) used by the admin console: same neutral
   ramp, same violet accent, same status semantics — one product language.

   Compatibility contract (do not break):
   - Every class name generated by app.js keeps working (.media-card,
     .status-pill, .cal-*, .chat-*, .post-card, .btn-mini, .stat-card, …).
   - Legacy CSS variable names (--bg, --bg-card, --bg-elev, --border, --text,
     --muted, --accent, --success, --warning, --danger, --text-dim, --bg-base)
     remain defined — app.js and inline styles reference them.
   ============================================================================ */

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

/* The `hidden` attribute must actually hide. Any component that sets its own
   `display` silently defeats the UA rule, which is why several components
   below each carry their own `[hidden]` patch — this states it once so the
   next one does not have to remember. */
[hidden] { display: none !important; }

:root {
  /* Neutral ramp — cool grey, dark-first */
  --n0:   #08080a;
  --n50:  #0e0e12;
  --n100: #131318;
  --n200: #1b1b22;
  --n300: #26262e;
  --n400: #35353f;
  --n500: #5a5a68;
  --n600: #8f8f9d;
  --n700: #b6b6c2;
  --n800: #dedee6;
  --n900: #f5f5f8;

  /* Accent — electric violet, reserved for primary actions + active state */
  --accent-300: #b3a0ff;
  --accent-500: #7c5cff;
  --accent-600: #6a45f5;
  --accent-700: #5330d8;
  --accent-glow: rgba(124, 92, 255, 0.16);

  /* Status ramp (pipeline semantics, same everywhere) */
  --status-pending:   #f0a020;
  --status-approved:  #4a9eff;
  --status-posted:    #2fc46a;
  --status-failed:    #f4485c;
  --teal:             #00c2a8;

  /* Legacy aliases — referenced by app.js and generated markup */
  --bg:        var(--n0);
  --bg-base:   var(--n0);
  --bg-card:   var(--n100);
  --bg-elev:   var(--n200);
  --border:    var(--n300);
  --border-strong: var(--n400);
  --text:      var(--n800);
  --text-dim:  var(--n500);
  --muted:     var(--n600);
  /* Fills that carry white TEXT must start at 600: white on --accent-500 is
     4.35:1, just under AA. app.js paints solid accent fills via this alias. */
  --accent:    var(--accent-600);
  --accent-dim: var(--accent-700);
  --success:   var(--status-posted);
  --warning:   var(--status-pending);
  --danger:    var(--status-failed);

  /* Surfaces that are not a plain step on the neutral ramp. Declared as
     tokens so the light theme can restate them without touching components. */
  --media-well:    #15151b;                /* see note in [data-theme="light"] */
  --topbar-bg:     rgba(8,8,10,.72);
  --sidebar-bg-mobile: rgba(14,14,18,.92); /* translucent nav rail under 960px */
  --toggle-track:  var(--n300);
  --overlay:       rgba(4,4,8,.72);
  --overlay-strong:rgba(4,4,8,.92);
  --grid-line:     rgba(255,255,255,.018);

  /* Status foregrounds are tuned per theme: a tint that reads on near-black
     is too pale to hit 4.5:1 on white, and vice versa. */
  --fg-used:    #ff7a8c;
  --fg-unused:  #4fd486;
  --fg-image:   #7ab8ff;
  --fg-video:   #ffbe55;
  --fg-error:   #ff8a99;
  --fg-success: #5fd992;
  --pill-douyin-fg: #dedee6;
  --pill-douyin-bg: rgba(255,255,255,.1);
  --pill-xhs-fg:    #ff5c77;
  --pill-ig-fg:     #f77bb4;

  --radius:    10px;
  --radius-lg: 14px;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.45);
  --shadow:    0 4px 14px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.03);
  --shadow-lg: 0 16px 44px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.04);
  --ring:      0 0 0 3px var(--accent-glow);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", Roboto,
          "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
          "Helvetica Neue", Arial, sans-serif;

  --topbar-h: 60px;
  --sidebar-w: 264px;   /* sized to fit the product wordmark on one line */
}

/* ═══ Light theme ═════════════════════════════════════════════════════════
   Opt-in via [data-theme="light"] on <html>. Dark stays the default because
   the media grid is the primary work surface and generated images are judged
   against the UI ground — which is also why --media-well stays dark here:
   light chrome, dark wells, the same split Figma and Google Photos use.
   The neutral ramp inverts; every component follows without changes. */
[data-theme="light"] {
  --n0:   #f7f7fa;   /* page ground   */
  --n50:  #f1f1f5;   /* sunken, rails */
  --n100: #ffffff;   /* surface       */
  --n200: #f3f3f7;   /* raised, hover */
  --n300: #e4e4ec;   /* borders       */
  --n400: #d0d0db;   /* strong border */
  --n500: #93939f;   /* placeholder   */
  --n600: #63636f;   /* secondary     */
  --n700: #3d3d47;   /* body          */
  --n800: #22222a;   /* headings      */
  --n900: #0d0d13;   /* max contrast  */

  /* Violet needs to go a step darker to hold 4.5:1 against white. */
  --accent-300: #5b3ce0;
  --accent-glow: rgba(124, 92, 255, .13);

  /* Shadows on light are contact shadows, not glows: much tighter and
     tinted toward the neutral hue rather than pure black. */
  --shadow-sm: 0 1px 2px rgba(16,16,28,.07);
  --shadow:    0 2px 8px rgba(16,16,28,.07), 0 1px 2px rgba(16,16,28,.05);
  --shadow-lg: 0 16px 44px rgba(16,16,28,.16);

  --topbar-bg:      rgba(255,255,255,.8);
  --overlay:        rgba(24,24,34,.42);
  --overlay-strong: rgba(18,18,26,.86);
  --grid-line:      rgba(16,16,28,.035);

  /* Darkened so each still clears 4.5:1 on a white surface. */
  --fg-used:    #a81d36;
  --fg-unused:  #0f6a30;
  --fg-image:   #1a56b0;
  --fg-video:   #7d4a00;
  --fg-error:   #a81d36;
  --fg-success: #0f6a30;
  --pill-douyin-fg: #3d3d47;
  --pill-douyin-bg: rgba(16,16,28,.07);
  --pill-xhs-fg:    #cc2444;
  --pill-ig-fg:     #c2317c;

  --sidebar-bg-mobile: rgba(241,241,245,.92);
  /* A white knob needs a darker track to stay legible on a light ground. */
  --toggle-track: var(--n400);

  --status-pending:  #7d4a00;
  --status-approved: #1a56b0;
  --status-posted:   #0f6a30;
  --status-failed:   #a81d36;
}

html { height: 100%; }
body {
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 13.5px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: var(--accent-300); text-decoration: none; }
button { font-family: inherit; cursor: pointer; }

::selection { background: rgba(124,92,255,.35); }

/* Thin neutral scrollbars everywhere */
* { scrollbar-width: thin; scrollbar-color: var(--n400) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--n400); border-radius: 8px; }
*::-webkit-scrollbar-thumb:hover { background: var(--n500); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* Skip link: first thing in the tab order, off-screen until focused so
   keyboard users can jump past the nav rail instead of tabbing every item. */
.skip-link {
  position: absolute;
  left: 8px; top: -60px;
  z-index: 2000;
  padding: 10px 16px;
  border-radius: 0 0 8px 8px;
  background: var(--accent-600);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  transition: top .12s var(--ease, ease);
}
.skip-link:focus { top: 0; outline: 2px solid var(--n900); outline-offset: 2px; }
#main-content:focus { outline: none; }

/* ═══ App shell ═══════════════════════════════════════════════════════════
   body > .shell = sidebar + main. The impersonation banner that app.js
   prepends to <body> stacks above the shell untouched. */
.shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  min-height: 100dvh;
}

/* ─── Sidebar ────────────────────────────────────────────────────────────── */
.sidebar {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--n50);
  border-right: 1px solid var(--border);
  overflow-y: auto;
  z-index: 60;
}
.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 0 18px;
  height: var(--topbar-h);
  flex-shrink: 0;
  border-bottom: 1px solid var(--border);
}
.logo-mark {
  width: 30px; height: 30px;
  border-radius: 9px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--accent-500), var(--accent-700));
  box-shadow: 0 2px 10px rgba(124,92,255,.35), inset 0 1px 0 rgba(255,255,255,.25);
  color: #fff;
}
/* legacy dot kept for any page still using it */
.logo-dot {
  width: 20px; height: 20px; border-radius: 6px;
  background: linear-gradient(135deg, var(--accent-500), var(--accent-700));
  box-shadow: 0 2px 10px rgba(124,92,255,.4);
}
.brand-text { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
/* The product name is long ("Digital Media AI Orchestrator"), so the rail is
   sized to fit it on one line. Ellipsis is a safety net, not the normal state:
   a longer future name degrades to a truncated wordmark with a title tooltip
   instead of forcing the sidebar to scroll sideways. */
.brand-name {
  font-size: 13px; font-weight: 650; color: var(--n900);
  letter-spacing: -.01em; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.brand-sub {
  font-size: 10px; font-weight: 500; color: var(--muted);
  letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}

.tabs {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 12px 20px;
  flex: 1;
}
.nav-group-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--n600);
  padding: 0 10px;
  margin: 16px 0 6px;
}
.tabs .nav-group-label:first-child { margin-top: 2px; }

.tab {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--n600);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.3;
  text-align: left;
  position: relative;
  transition: background .12s ease, color .12s ease;
}
.tab svg { flex-shrink: 0; opacity: .8; }
.tab:hover { color: var(--n800); background: var(--n200); }
.tab.active {
  color: var(--n900);
  background: var(--accent-glow);
}
.tab.active svg { color: var(--accent-300); opacity: 1; }
.tab.active::before {
  content: "";
  position: absolute;
  left: -12px; top: 7px; bottom: 7px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent-500);
}

.sidebar-foot {
  padding: 14px 18px;
  border-top: 1px solid var(--border);
  font-size: 10.5px;
  color: var(--n600);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-shrink: 0;
}

/* ─── Main column / topbar ───────────────────────────────────────────────── */
.main { min-width: 0; display: flex; flex-direction: column; }
.topbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  height: var(--topbar-h);
  padding: 0 24px;
  background: var(--topbar-bg);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 50;
}
.topbar-right { display: flex; align-items: center; gap: 10px; min-width: 0; }
.user-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 12px 0 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--n100);
  min-width: 0;
}
.user-avatar {
  width: 22px; height: 22px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--accent-500), var(--accent-700));
  color: #fff;
}
.user-chip .muted {
  font-size: 12.5px; font-weight: 500; color: var(--n700);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 140px;
}

.content {
  padding: 28px 32px 64px;
  max-width: 1440px;
  width: 100%;
  margin: 0 auto;
}
.tab-panel { display: none; }
.tab-panel.active { display: block; animation: panel-in .18s ease; }
@keyframes panel-in { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
#panel-chat.active { display: flex; }

.panel-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 22px;
  flex-wrap: wrap;
  gap: 12px;
}
.panel-head h1, .panel-head h2 {
  font-size: 21px;
  font-weight: 650;
  letter-spacing: -.015em;
  color: var(--n900);
}
.panel-head .muted { margin-top: 3px; font-size: 13px; }
.actions { display: flex; gap: 8px; align-items: center; flex-wrap: nowrap; }

.muted { color: var(--muted); }
.sub { font-size: 11px; color: var(--muted); margin-left: 6px; font-weight: normal; }
.error { color: var(--danger); font-size: 12.5px; margin-top: 12px; min-height: 18px; }
.empty {
  text-align: center;
  padding: 64px 20px;
  color: var(--muted);
  font-size: 13px;
  border: 1px dashed var(--n300);
  border-radius: var(--radius-lg);
  background: var(--n50);
}

/* ═══ Controls ════════════════════════════════════════════════════════════ */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 36px;
  padding: 0 16px;
  border: 1px solid var(--accent-700);
  border-radius: 8px;
  background: linear-gradient(180deg, var(--accent-600), var(--accent-700));
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .01em;
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.18);
  transition: filter .12s ease, transform .12s ease, box-shadow .12s ease;
}
.btn-primary:hover { filter: brightness(1.08); }
.btn-primary:active { transform: translateY(1px); }
.btn-primary:focus-visible { outline: none; box-shadow: var(--ring); }
.btn-primary:disabled { opacity: .45; cursor: not-allowed; filter: none; }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 34px;
  padding: 0 13px;
  border: 1px solid var(--n400);
  border-radius: 8px;
  background: transparent;
  color: var(--n700);
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.btn-ghost:hover { background: var(--n200); color: var(--n900); border-color: var(--n500); }
.btn-ghost:focus-visible { outline: none; box-shadow: var(--ring); }

.btn-lang { font-size: 11.5px; font-weight: 600; letter-spacing: .06em; padding: 0 11px; }

/* Square icon-only button (theme toggle). The icon shown is the theme you
   would switch TO, which is the convention users already expect. */
.btn-icon { width: 34px; padding: 0; flex-shrink: 0; }
.btn-icon svg { display: none; }
.btn-icon .icon-sun { display: block; }
[data-theme="light"] .btn-icon .icon-sun { display: none; }
[data-theme="light"] .btn-icon .icon-moon { display: block; }

.btn-mini {
  background: var(--n200);
  color: var(--n700);
  border: 1px solid var(--n400);
  padding: 4px 10px;
  border-radius: 7px;
  font-size: 12px;
  font-weight: 500;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.btn-mini:hover { background: var(--n300); color: var(--n900); }
.btn-mini.approve { color: var(--success); border-color: rgba(47,196,106,.35); background: rgba(47,196,106,.08); }
.btn-mini.approve:hover { background: rgba(47,196,106,.16); }
.btn-mini.danger { color: var(--danger); border-color: rgba(244,72,92,.35); background: rgba(244,72,92,.07); }
.btn-mini.danger:hover { background: rgba(244,72,92,.15); }

.upload-label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  height: 36px;
  padding: 0 16px;
  line-height: 1;
  white-space: nowrap;
  flex-shrink: 0;
}

.filters { display: flex; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; }

.filters select, .filters input, select, input[type=text], input[type=password],
input[type=number], input[type=datetime-local], input[type=email], textarea {
  background: var(--n50);
  color: var(--n800);
  border: 1px solid var(--n300);
  border-radius: 8px;
  padding: 8px 11px;
  font-size: 13px;
  font-family: inherit;
  transition: border-color .12s ease, box-shadow .12s ease;
}
select:focus, input[type=text]:focus, input[type=password]:focus,
input[type=number]:focus, input[type=datetime-local]:focus, input[type=email]:focus, textarea:focus {
  outline: none;
  border-color: var(--accent-500);
  box-shadow: var(--ring);
}
input::placeholder, textarea::placeholder { color: var(--n600); }
textarea { width: 100%; resize: vertical; min-height: 60px; line-height: 1.55; }
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238f8f9d' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  padding-right: 30px;
}

/* View toggle (list / calendar) */
.view-toggle {
  display: flex;
  gap: 2px;
  background: var(--n50);
  border: 1px solid var(--n300);
  border-radius: 8px;
  padding: 3px;
}
.view-toggle-btn {
  background: transparent;
  border: none;
  color: var(--muted);
  padding: 5px 12px;
  border-radius: 6px;
  font-size: 12.5px;
  font-weight: 500;
  transition: background .12s ease, color .12s ease;
}
.view-toggle-btn.active {
  background: var(--n300);
  color: var(--n900);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
}

/* ═══ Cards / stats ═══════════════════════════════════════════════════════ */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 20px;
  margin-bottom: 16px;
}
.card h3 {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--n900);
  margin-bottom: 14px;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 880px) { .grid-2 { grid-template-columns: 1fr; } }

.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 14px;
  margin-bottom: 18px;
}
.stat-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 16px 18px;
  position: relative;
  overflow: hidden;
}
.stat-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: linear-gradient(180deg, var(--accent-500), transparent);
  opacity: .55;
}
.stat-card .label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: .09em;
  text-transform: uppercase;
}
.stat-card .value {
  font-size: 27px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--n900);
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
}
.stat-card .trend { font-size: 11.5px; color: var(--success); margin-top: 4px; }

.best-time-row {
  display: flex;
  justify-content: space-between;
  padding: 9px 0;
  border-bottom: 1px solid var(--n200);
  font-size: 13px;
}
.best-time-row:last-child { border-bottom: 0; }

/* ═══ Media library ═══════════════════════════════════════════════════════ */
.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(164px, 1fr));
  gap: 14px;
}
.media-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  position: relative;
  cursor: pointer;
  transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.media-card:hover {
  transform: translateY(-2px);
  border-color: var(--n400);
  box-shadow: var(--shadow);
}
.media-card:hover .play-overlay { opacity: 1; }
.play-overlay {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 44px; height: 44px;
  background: rgba(8,8,10,.72);
  backdrop-filter: blur(4px);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 16px;
  opacity: 0;
  transition: opacity .15s ease;
  pointer-events: none;
}
/* ── Multi-select (mass delete) ── */
.media-check {
  position: absolute;
  top: 8px; left: 8px;
  z-index: 2;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,.85);
  background: rgba(8,8,10,.45);
  color: transparent;
  font-size: 13px;
  line-height: 18px;
  text-align: center;
  display: none;
  pointer-events: none;
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
.media-grid.selecting .media-check { display: block; }
.media-card.selected .media-check {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.media-card.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent);
}
/* While selecting, cards are pick targets — per-card actions get out of the way. */
.media-grid.selecting .media-card .btn-mini,
.media-grid.selecting .media-card .play-overlay { display: none; }

.bulk-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 14px;
  padding: 8px 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.bulk-bar[hidden] { display: none; }
.btn-ghost.active { border-color: var(--accent); color: var(--accent); }
.bulk-count { font-size: 13px; color: var(--muted); min-width: 70px; }

/* ── Pager (shared by media / reports / queue) ── */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 18px;
}
.pager .pager-info { font-size: 13px; color: var(--muted); }
.pager button[disabled] { opacity: .45; cursor: default; }

.media-thumb {
  width: 100%;
  position: relative;
  background: var(--media-well);
  overflow: hidden;
}
.media-thumb::before { content: ""; display: block; padding-bottom: 100%; }
.media-thumb img, .media-thumb video {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.media-meta {
  padding: 7px 10px;
  font-size: 11px;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  gap: 6px;
}
.media-meta + .media-meta { padding-top: 0; }
.media-filename { color: var(--n700) !important; }

.badge {
  font-size: 9.5px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--n200);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .06em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.badge.used   { background: rgba(244,72,92,.13);  color: var(--fg-used); }
.badge.unused { background: rgba(47,196,106,.13); color: var(--fg-unused); }
.badge.image  { background: rgba(74,158,255,.13); color: var(--fg-image); }
.badge.video  { background: rgba(240,160,32,.13); color: var(--fg-video); }
/* Quota state on the usage bar. Amber while overage is accruing and being
   charged, red once generation has actually stopped — the same two signals the
   platform console shows staff, so both sides read the account the same way. */
.badge.warn   { background: rgba(240,160,32,.13); color: var(--fg-video); }
.badge.danger { background: rgba(244,72,92,.13);  color: var(--fg-used); }

/* Lightbox */
.lightbox {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--overlay-strong);
  backdrop-filter: blur(6px);
  z-index: 1000;
  align-items: center;
  justify-content: center;
}
.lightbox.open { display: flex; }
/* Column, so the AI Studio can hang an info panel under the media. The media
   library opens the same overlay with #lb-info hidden, and then this is just
   a centred single child exactly as before. */
.lightbox { flex-direction: column; gap: 12px; padding: 24px; }
.lightbox img, .lightbox video {
  max-width: 92vw;
  max-height: 88vh;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: var(--shadow-lg);
}
.lightbox:has(#lb-info:not([hidden])) img,
.lightbox:has(#lb-info:not([hidden])) video { max-height: 62vh; }

.lb-info {
  width: min(760px, 92vw);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  box-shadow: var(--shadow-lg);
  max-height: 26vh;
  overflow-y: auto;
}
.lb-info[hidden] { display: none; }
.lb-info-title { margin: 0 0 4px; font-size: 14px; font-weight: 600; color: var(--text); }
.lb-info-prompt { margin: 0 0 10px; font-size: 13px; line-height: 1.55; color: var(--muted); }
.lb-info-facts { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.lb-fact {
  font-size: 11px; color: var(--muted);
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 5px; padding: 3px 8px;
}
.lb-fact b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.lb-info-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.lb-close {
  position: absolute;
  top: 16px; right: 20px;
  background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.14);
  color: #fff;
  font-size: 18px;
  width: 38px; height: 38px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s ease;
}
.lb-close:hover { background: rgba(255,255,255,.22); }

/* ═══ Queue ═══════════════════════════════════════════════════════════════ */
.queue-table, .top-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.queue-table th, .queue-table td, .top-table th, .top-table td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid var(--n200);
  font-size: 13px;
  vertical-align: middle;
}
.queue-table th, .top-table th {
  background: var(--n50);
  font-weight: 600;
  font-size: 10.5px;
  color: var(--muted);
  letter-spacing: .08em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.queue-table tbody tr, .top-table tbody tr { transition: background .1s ease; }
.queue-table tbody tr:hover, .top-table tbody tr:hover { background: var(--n200); }
.queue-table tr:last-child td, .top-table tr:last-child td { border-bottom: 0; }
.row-actions { display: flex; gap: 6px; flex-wrap: wrap; }

.top-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius-lg);
}
.top-table-wrap .top-table { min-width: 560px; }

.preview-cell {
  width: 56px; height: 56px;
  background: var(--n200);
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--n300);
}
.preview-cell img, .preview-cell video { width: 100%; height: 100%; object-fit: cover; }
.caption-cell { max-width: 340px; }
.caption-cell .zh { font-size: 13px; margin-bottom: 3px; color: var(--n800); }
.caption-cell .en { font-size: 12px; color: var(--muted); }

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--n200);
  color: var(--n600);
  letter-spacing: .02em;
  white-space: nowrap;
}
.status-pill::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.status-pill.pending  { color: var(--status-pending);  background: rgba(240,160,32,.12); }
.status-pill.approved { color: var(--status-approved); background: rgba(74,158,255,.12); }
.status-pill.posted   { color: var(--status-posted);   background: rgba(47,196,106,.12); }
.status-pill.failed   { color: var(--status-failed);   background: rgba(244,72,92,.12); }

.platform-pill {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--n200);
  color: var(--n700);
  white-space: nowrap;
}
.platform-pill.xiaohongshu { color: var(--pill-xhs-fg); background: rgba(255,42,77,.12); }
.platform-pill.douyin      { color: var(--pill-douyin-fg); background: var(--pill-douyin-bg); }
.platform-pill.instagram   { color: var(--pill-ig-fg); background: rgba(247,84,159,.12); }

/* Mobile queue cards */
.post-cards { display: none; }
@media (max-width: 768px) {
  #queue-table-desktop { display: none; }
  .post-cards { display: flex; flex-direction: column; gap: 10px; }
}
.post-card {
  display: flex;
  gap: 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px;
  align-items: flex-start;
  box-shadow: var(--shadow-sm);
}
.post-card-left { flex-shrink: 0; }
.post-card-thumb {
  width: 72px; height: 72px;
  object-fit: cover;
  border-radius: 8px;
  display: block;
  border: 1px solid var(--n300);
}
.post-card-thumb.no-media { background: var(--n200); }
.post-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.post-card-top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.post-card-caption {
  font-size: 13px;
  color: var(--n800);
  line-height: 1.5;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.post-card-time { font-size: 12px; color: var(--muted); }
.post-card-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }

.extra-thumbs { display: flex; gap: 4px; margin-top: 4px; }
.extra-thumb { width: 24px; height: 24px; border-radius: 4px; object-fit: cover; border: 1px solid var(--n300); }

/* ═══ Calendar ════════════════════════════════════════════════════════════ */
.cal-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.cal-month-label {
  font-size: 15px;
  font-weight: 650;
  color: var(--n900);
  min-width: 130px;
  text-align: center;
  letter-spacing: -.01em;
}
.cal-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin-bottom: 6px;
}
.cal-weekdays > div {
  text-align: center;
  font-size: 10px;
  font-weight: 600;
  color: var(--n600);
  text-transform: uppercase;
  letter-spacing: .1em;
  padding: 4px 0;
}
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.cal-day {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  min-height: 96px;
  padding: 7px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: border-color .12s ease, background .12s ease;
}
.cal-day:hover { border-color: var(--n500); background: var(--n200); }
.cal-day.other-month { opacity: .38; }
.cal-day.today {
  border-color: var(--accent-500);
  background: linear-gradient(180deg, var(--accent-glow), transparent 55%), var(--bg-card);
}
.cal-day.today .cal-day-num { color: var(--accent-300); }
.cal-day-num { font-size: 11.5px; color: var(--muted); font-weight: 600; font-variant-numeric: tabular-nums; }
.cal-day-posts { display: flex; flex-direction: column; gap: 3px; overflow: hidden; }
.cal-post-chip {
  font-size: 10.5px;
  font-weight: 500;
  padding: 2px 6px;
  border-radius: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: 4px;
}
.cal-post-chip.pending  { background: rgba(240,160,32,.14); color: var(--status-pending); }
.cal-post-chip.approved { background: rgba(74,158,255,.14); color: var(--status-approved); }
.cal-post-chip.posted   { background: rgba(47,196,106,.14); color: var(--status-posted); }
.cal-post-chip.failed   { background: rgba(244,72,92,.14);  color: var(--status-failed); }
.cal-day-more { font-size: 10.5px; color: var(--muted); padding-left: 6px; }
.cal-day-add-hint {
  font-size: 16px;
  color: var(--muted);
  text-align: center;
  opacity: 0;
  transition: opacity .12s ease;
}
.cal-day:hover .cal-day-add-hint { opacity: .6; }

.cal-day-item {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--n200);
  border: 1px solid var(--n300);
  border-radius: 8px;
  padding: 8px 10px;
}
.cal-day-item img, .cal-day-item video {
  width: 44px; height: 44px; object-fit: cover; border-radius: 6px; flex-shrink: 0;
}
.cal-day-item-body { flex: 1; min-width: 0; }
.cal-day-item-caption { font-size: 12.5px; color: var(--n800); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-day-item-time { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* ═══ Settings ════════════════════════════════════════════════════════════ */
.platform-row {
  /* Grid, not space-between flex: the toggle / label / limit columns line up
     across rows regardless of how long the platform name is. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto 70px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--n200);
  gap: 12px;
  font-size: 13px;
}
.platform-row:last-child { border-bottom: 0; }
.platform-row .name { font-weight: 600; color: var(--n800); }
.platform-row .limit { width: 70px; justify-self: end; }

.account-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--n200);
  gap: 10px;
  /* Wrapping has to be allowed at every width, not just under a breakpoint:
     the row now carries an optional third child (the reconnect error), and
     without this its flex-basis:100% only shrinks it in beside the buttons. */
  flex-wrap: wrap;
}
.account-row:last-child { border-bottom: 0; }
.account-info { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1 1 180px; }
.account-name { font-weight: 600; color: var(--n800); white-space: nowrap; }
.account-sub  { font-size: 12px; color: var(--muted); white-space: nowrap; }
.account-user {
  font-size: 12px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 180px;
}
/* The actions column grew a second status pill (auto-reconnect) and a third
   button, so at narrow widths it can no longer be flex-shrink:0 — it used to
   push straight through the account name beside it. Wrapping the row is the
   only layout that stays readable once the content genuinely does not fit. */
.account-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
/* The "last reconnect failed" line is a third child of the row, not part of
   either column, so it must claim its own line rather than sit beside them. */
.account-error { flex-basis: 100%; width: 100%; }
@media (max-width: 900px) {
  .account-row { flex-wrap: wrap; gap: 8px; }
  .account-info { width: 100%; }
  .account-actions { width: 100%; justify-content: flex-end; }
}
@media (max-width: 768px) {
  .account-sub { display: none; }
}

.toggle { display: inline-flex; align-items: center; gap: 8px; }
.toggle input[type=checkbox] {
  width: 36px; height: 20px;
  appearance: none;
  background: var(--toggle-track);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background .18s ease;
  border: 1px solid var(--n400);
}
.toggle input[type=checkbox]::after {
  content: "";
  position: absolute;
  width: 14px; height: 14px;
  background: #fff;
  border-radius: 50%;
  top: 2px; left: 2px;
  transition: left .18s ease;
  box-shadow: 0 1px 3px rgba(0,0,0,.4);
}
.toggle input[type=checkbox]:checked { background: var(--accent-500); border-color: var(--accent-600); }
.toggle input[type=checkbox]:checked::after { left: 18px; }
.check-row { display: flex; align-items: center; gap: 8px; padding: 8px 0; font-size: 13px; }

.platform-extra { border-bottom: 1px solid var(--n200); padding: 8px 0 14px; }
.platform-extra:last-child { border-bottom: 0; }
.platform-extra label { display: block; margin-bottom: 6px; }
.platform-extra input[type=text] { width: 100%; max-width: 320px; }
.ig-target-hint { font-size: 12px; margin-top: 6px; }

#platform-settings label, #account-status label, .card label, .modal-card label {
  display: block;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted);
  margin-top: 12px;
  margin-bottom: 5px;
  letter-spacing: .02em;
}

/* ═══ Modal ═══════════════════════════════════════════════════════════════ */
.modal {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--overlay);
  backdrop-filter: blur(5px);
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 16px;
}
.modal.open { display: flex; }
.modal-card {
  background: var(--n100);
  border: 1px solid var(--n300);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 24px;
  width: 480px;
  max-width: 96vw;
  max-height: 92vh;
  overflow-y: auto;
  animation: modal-in .16s ease;
}
@keyframes modal-in { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
.modal-card h3 {
  font-size: 16px;
  font-weight: 650;
  letter-spacing: -.01em;
  color: var(--n900);
  margin-bottom: 14px;
}
.modal-card label { margin-top: 12px; margin-bottom: 5px; }
.modal-card select, .modal-card input, .modal-card textarea { width: 100%; }
/* Checkboxes are not text fields: stretching one to the full card width leaves
   a small painted box beside 400px of dead click target, and squeezes the
   label it sits next to down to a one-word column. */
.modal-card input[type="checkbox"], .modal-card input[type="radio"] {
  width: auto;
  flex: 0 0 auto;
}
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--n200);
}

/* ═══ Toast ═══════════════════════════════════════════════════════════════ */
.toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  background: var(--n200);
  border: 1px solid var(--n400);
  border-left: 3px solid var(--accent-500);
  border-radius: 10px;
  padding: 12px 16px;
  font-size: 13px;
  color: var(--n800);
  box-shadow: var(--shadow-lg);
  transform: translateY(80px);
  opacity: 0;
  transition: all .22s ease;
  z-index: 200;
  max-width: min(420px, calc(100vw - 48px));
}
.toast.show { transform: translateY(0); opacity: 1; }
.toast.error   { border-left-color: var(--danger);  color: var(--fg-error); }
.toast.success { border-left-color: var(--success); color: var(--fg-success); }

/* ═══ AI Studio ═══════════════════════════════════════════════════════════ */
.ai-status-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  background: var(--n200);
  color: var(--muted);
}
.ai-sub-tabs {
  display: flex;
  gap: 2px;
  margin-bottom: 22px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}
.ai-sub-tabs::-webkit-scrollbar { display: none; }
.ai-sub-tab {
  padding: 9px 14px 11px;
  border: none;
  background: none;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color .12s ease, border-color .12s ease;
}
.ai-sub-tab:hover { color: var(--n800); }
.ai-sub-tab.active { color: var(--n900); border-bottom-color: var(--accent-500); }

.ai-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 22px;
  margin-bottom: 18px;
  max-width: 860px;
}
.ai-card h3 {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -.01em;
  color: var(--n900);
  margin: 0 0 6px;
}
.ai-card > .muted { margin: 0 0 18px; font-size: 12.5px; }

.ai-field { margin-bottom: 14px; }
.ai-field label {
  display: block;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 6px;
  letter-spacing: .02em;
}
.ai-field select, .ai-field textarea, .ai-field input { width: 100%; }
.ai-row { display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.ai-row .ai-field { flex: 1; min-width: 120px; margin-bottom: 0; }

.ai-submit { width: 100%; height: 42px; font-size: 14px; }

.ai-src-tabs { display: flex; gap: 8px; margin-bottom: 12px; }
.ai-src-tab {
  padding: 6px 14px;
  border-radius: 8px;
  border: 1px solid var(--n300);
  background: var(--bg-elev);
  color: var(--muted);
  font-size: 12.5px;
  font-weight: 500;
  transition: background .12s ease, color .12s ease;
}

.ai-upload-area {
  border: 1.5px dashed var(--n400);
  border-radius: 12px;
  padding: 30px 16px;
  text-align: center;
  cursor: pointer;
  background: var(--n50);
  transition: border-color .15s ease, background .15s ease;
  margin-bottom: 12px;
}
.ai-upload-area:hover { border-color: var(--accent-500); background: var(--accent-glow); }
.ai-upload-icon { font-size: 30px; line-height: 1; }
.ai-upload-hint { color: var(--muted); margin-top: 10px; font-size: 13px; }

.ai-lib-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  max-height: 220px;
  overflow-y: auto;
  border: 1px solid var(--n300);
  border-radius: 10px;
  padding: 8px;
  min-height: 60px;
  background: var(--n50);
}
.ai-lib-loading { color: var(--muted); font-size: 13px; padding: 16px; }
.ai-lib-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 8px;
  gap: 8px;
}
.ai-lib-count { font-size: 12px; color: var(--muted); }
.ai-lib-add {
  padding: 6px 14px;
  border-radius: 8px;
  border: none;
  background: var(--accent-600);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
}
.ai-lib-add:disabled { opacity: .45; cursor: not-allowed; }

.ai-preview-wrap { margin-bottom: 12px; }
.ai-preview-grid { display: flex; gap: 8px; flex-wrap: wrap; }
.ai-group-info { color: var(--muted); font-size: 12px; margin-top: 8px; }
.ai-selected-info { color: var(--muted); font-size: 12px; margin-bottom: 12px; }

.ai-result-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 20px;
  max-width: 860px;
}
.ai-result-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.ai-result-label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .09em;
}
.ai-result-card img, .ai-result-card video { width: 100%; border-radius: 10px; display: block; }

.ai-loading {
  text-align: center;
  padding: 44px 16px;
  color: var(--muted);
  max-width: 860px;
}
.ai-loading-icon { font-size: 30px; margin-bottom: 12px; }
.ai-loading-icon.spin::after {
  content: "";
  display: block;
  width: 28px; height: 28px;
  margin: 0 auto;
  border-radius: 50%;
  border: 3px solid var(--n300);
  border-top-color: var(--accent-500);
  animation: sa-spin .7s linear infinite;
}
@keyframes sa-spin { to { transform: rotate(360deg); } }

.ai-error-box {
  background: rgba(244,72,92,.09);
  border: 1px solid rgba(244,72,92,.35);
  border-radius: 10px;
  padding: 14px 16px;
  color: var(--fg-error);
  margin-top: 12px;
  font-size: 13px;
  max-width: 860px;
}
.ai-mode-badge {
  margin-bottom: 12px;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 12.5px;
}

/* ═══ Generate-post modal media grid ══════════════════════════════════════ */
.gen-media-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  max-height: 55vh;
  overflow-y: auto;
  padding: 8px;
  background: var(--n50);
  border: 1px solid var(--n300);
  border-radius: 10px;
  margin-bottom: 10px;
}
.gen-media-card {
  position: relative;
  width: 100%;
  overflow: hidden;
  cursor: pointer;
  border: 2px solid transparent;
  border-radius: 8px;
  transition: border-color .12s ease;
  display: block;
}
.gen-media-card::before { content: ""; display: block; padding-bottom: 100%; }
.gen-media-card img {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.gen-media-card input[type=checkbox] {
  position: absolute;
  top: 6px; left: 6px;
  width: 18px; height: 18px;
  accent-color: var(--accent-500);
  cursor: pointer;
  z-index: 2;
}
.gen-media-card.selected { border-color: var(--accent-500); }
.gen-media-card.disabled { opacity: .4; cursor: not-allowed; }
.gen-media-order {
  position: absolute;
  top: 6px; right: 6px;
  background: var(--accent-600);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  width: 20px; height: 20px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  z-index: 2;
}
@media (max-width: 600px) {
  .gen-media-grid { max-height: 320px; scrollbar-width: none; }
  .gen-media-grid::-webkit-scrollbar { display: none; }
}

.gen-type-toggle { display: flex; gap: 8px; margin: 6px 0 10px; width: 100%; }
.gen-type-btn {
  flex: 1;
  padding: 9px 0;
  border: 1px solid var(--n300);
  background: var(--n50);
  color: var(--muted);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  transition: all .12s ease;
}
.gen-type-btn.active {
  border-color: var(--accent-500);
  color: var(--accent-300);
  background: var(--accent-glow);
}

/* ═══ Chat ════════════════════════════════════════════════════════════════ */
#panel-chat {
  display: none;
  flex-direction: column;
  height: calc(100dvh - var(--topbar-h));
  margin: -28px -32px -64px;
  padding: 0;
  overflow: hidden;
}
#panel-chat.active { display: flex; }
#panel-chat .panel-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  margin-bottom: 0;
  border-bottom: 1px solid var(--border);
  background: var(--n50);
}
#panel-chat .panel-head h1, .panel-head h2 { margin: 0; font-size: 15px; }
#panel-chat .panel-head p { display: none; }

.chat-container { display: flex; flex-direction: column; flex: 1; overflow: hidden; }
.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px 24px 8px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  scroll-behavior: smooth;
}
.chat-msg {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  max-width: 76%;
}
.chat-msg.user      { align-self: flex-end; flex-direction: row-reverse; }
.chat-msg.assistant { align-self: flex-start; }
.chat-avatar {
  width: 30px; height: 30px;
  border-radius: 50%;
  font-size: 14px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: var(--n200);
  border: 1px solid var(--n300);
  color: var(--n600);
}
.chat-msg.user .chat-avatar {
  background: linear-gradient(135deg, var(--accent-500), var(--accent-700));
  border: none;
  color: #fff;
}
.chat-bubble {
  border-radius: 14px;
  padding: 10px 14px;
  font-size: 13.5px;
  line-height: 1.62;
  white-space: pre-wrap;
  word-break: break-word;
  max-width: 100%;
}
.chat-msg.assistant .chat-bubble {
  background: var(--n200);
  border: 1px solid var(--n300);
  border-bottom-left-radius: 4px;
  color: var(--n800);
}
.chat-msg.user .chat-bubble {
  background: linear-gradient(180deg, var(--accent-600), var(--accent-700));
  border: none;
  border-bottom-right-radius: 4px;
  color: #fff;
}
/* Quick-start options under the opening bubble. Authored in the admin
   console, so the count varies — they wrap rather than scroll, and a long
   label truncates instead of stretching the column. */
.chat-starters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}
/* Messages are bottom-aligned so the avatar sits beside the last line; the
   opening carries option chips under its bubble, and bottom-aligning against
   those puts the avatar level with the chips instead of the greeting. */
#chat-greeting-msg { align-items: flex-start; }
#chat-greeting-msg > div:last-child { min-width: 0; }
.chat-starter {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 6px 11px;
  border: 1px solid var(--n300);
  border-radius: 999px;
  background: var(--n100);
  color: var(--n700);
  font: inherit;
  font-size: 12.5px;
  line-height: 1.3;
  cursor: pointer;
  text-align: left;
  transition: background .15s, border-color .15s, color .15s;
}
.chat-starter:hover,
.chat-starter:focus-visible {
  background: var(--n200);
  border-color: var(--accent-500);
  color: var(--n900);
}
.chat-starter span.starter-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-bubble.streaming::after {
  content: "▋";
  display: inline-block;
  animation: blink .8s step-end infinite;
  color: var(--accent-300);
}
.chat-msg.user .chat-bubble.streaming::after { color: rgba(255,255,255,.6); }
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0} }

/* ── "The agent is working" row ──────────────────────────────────────────
   The streaming caret alone is a single blinking character in an otherwise
   empty bubble — easy to miss, and it says nothing during the long silent
   gaps while a tool runs. This is a separate row so renderBubble()'s
   innerHTML rewrite cannot destroy it, and it stays up through those gaps
   with a label saying what is actually happening. */
.chat-working {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 2px 0 6px 42px;          /* clears the avatar column */
  font-size: 12.5px;
  color: var(--muted);
}
.chat-working-label { animation: chat-pulse 1.6s ease-in-out infinite; }
@keyframes chat-pulse { 0%,100%{opacity:.55} 50%{opacity:1} }

.chat-dots { display: inline-flex; gap: 4px; align-items: center; }
.chat-dots i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent-500, var(--accent));
  animation: chat-bounce 1.2s ease-in-out infinite;
}
.chat-dots i:nth-child(2) { animation-delay: .16s; }
.chat-dots i:nth-child(3) { animation-delay: .32s; }
@keyframes chat-bounce {
  0%, 80%, 100% { transform: translateY(0);     opacity: .45; }
  40%           { transform: translateY(-4px);  opacity: 1;   }
}

/* The widget is a narrow column; the row sits flush there. */
.ai-widget-messages .chat-working { margin-left: 34px; font-size: 12px; }

@media (prefers-reduced-motion: reduce) {
  .chat-dots i, .chat-working-label { animation: none; }
  .chat-dots i { opacity: .8; }
}

.chat-input-bar {
  flex-shrink: 0;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 12px 24px 16px;
  border-top: 1px solid var(--border);
  background: var(--n50);
}
#chat-input {
  flex: 1;
  background: var(--n100);
  border: 1px solid var(--n300);
  border-radius: 12px;
  color: var(--n800);
  font-family: var(--font);
  font-size: 13.5px;
  padding: 10px 16px;
  resize: none;
  min-height: 42px;
  max-height: 120px;
  overflow-y: auto;
  line-height: 1.5;
}
#chat-input::placeholder { color: var(--n600); }
#chat-input:focus { outline: none; border-color: var(--accent-500); box-shadow: var(--ring); }
#chat-send {
  width: 42px; height: 42px;
  border-radius: 12px;
  padding: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 17px;
  flex-shrink: 0;
  background: linear-gradient(180deg, var(--accent-600), var(--accent-700));
  border: none;
  color: #fff;
  transition: filter .12s ease, transform .1s ease;
}
#chat-send:hover  { filter: brightness(1.1); }
#chat-send:active { transform: scale(.94); }
#chat-send:disabled { opacity: .4; cursor: not-allowed; }

/* ═══ Floating AI widget ══════════════════════════════════════════════════ */
#ai-fab {
  position: fixed;
  bottom: 28px; right: 28px;
  width: 52px; height: 52px;
  background: linear-gradient(135deg, var(--accent-500), var(--accent-700));
  border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  font-size: 24px;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(124,92,255,.4), 0 2px 8px rgba(0,0,0,.5);
  z-index: 9000;
  transition: transform .15s ease, box-shadow .15s ease;
  user-select: none;
}
#ai-fab:hover { transform: translateY(-2px) scale(1.06); box-shadow: 0 12px 30px rgba(124,92,255,.5), 0 4px 12px rgba(0,0,0,.5); }

#ai-widget {
  position: fixed;
  bottom: 92px; right: 28px;
  width: 350px;
  max-height: 500px;
  background: var(--n100);
  border: 1px solid var(--n300);
  border-radius: 16px;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-lg);
  z-index: 9000;
  overflow: hidden;
  transition: opacity .2s ease, transform .2s ease;
}
#ai-widget.ai-widget-closed { opacity: 0; pointer-events: none; transform: translateY(12px) scale(.97); }
#ai-widget.ai-widget-open   { opacity: 1; pointer-events: all; transform: none; }
.ai-widget-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 14px;
  background: var(--n50);
  border-bottom: 1px solid var(--n300);
  font-size: 13px;
  font-weight: 600;
  color: var(--n900);
}
.ai-widget-header button {
  background: none; border: none;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: 6px;
}
.ai-widget-header button:hover { color: var(--n900); background: var(--n300); }
.ai-widget-messages {
  flex: 1;
  overflow-y: auto;
  padding: 12px 12px 6px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ai-widget-messages .chat-msg { max-width: 92%; }
.ai-widget-input-bar {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 10px;
  border-top: 1px solid var(--n300);
  background: var(--n50);
}
.ai-widget-input-bar textarea {
  flex: 1;
  background: var(--n100);
  border: 1px solid var(--n300);
  border-radius: 10px;
  color: var(--n800);
  font-size: 13px;
  padding: 8px 11px;
  resize: none;
  max-height: 90px;
  line-height: 1.4;
  font-family: inherit;
}
.ai-widget-input-bar textarea:focus { outline: none; border-color: var(--accent-500); }
.ai-widget-input-bar button {
  background: var(--accent-600);
  border: none;
  border-radius: 10px;
  color: #fff;
  font-size: 15px;
  padding: 8px 11px;
  transition: filter .12s ease;
}
.ai-widget-input-bar button:hover { filter: brightness(1.1); }
.ai-widget-input-bar button:disabled { opacity: .4; cursor: default; }
@media (max-width: 600px) {
  #ai-widget { width: calc(100vw - 24px); right: 12px; bottom: 80px; }
  #ai-fab { bottom: 18px; right: 18px; }
}

/* ═══ Login page ══════════════════════════════════════════════════════════ */
.login-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  padding: 24px;
  background:
    radial-gradient(ellipse 60% 45% at 50% -5%, rgba(124,92,255,.14), transparent 70%),
    radial-gradient(ellipse 45% 35% at 90% 100%, rgba(0,194,168,.05), transparent 70%),
    var(--n0);
  position: relative;
}
.login-body::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, #000 20%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, #000 20%, transparent 75%);
  pointer-events: none;
}
.login-card {
  width: 400px;
  max-width: 100%;
  background: var(--n100);
  border: 1px solid var(--n300);
  border-radius: 18px;
  padding: 40px 36px 32px;
  box-shadow: var(--shadow-lg);
  position: relative;
}
.login-brand { text-align: center; margin-bottom: 28px; }
.login-brand .logo-mark { width: 44px; height: 44px; border-radius: 13px; margin: 0 auto 14px; }
.login-brand .logo-dot { margin: 0 auto 14px; width: 40px; height: 40px; border-radius: 12px; }
.login-brand h1 {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--n900);
  margin: 0 0 4px;
}
.login-brand .muted { font-size: 12.5px; }
#login-form label {
  display: block;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--muted);
  margin-top: 16px;
  margin-bottom: 6px;
  letter-spacing: .05em;
  text-transform: uppercase;
}
#login-form input {
  width: 100%;
  padding: 11px 13px;
  border-radius: 9px;
  border: 1px solid var(--n300);
  background: var(--n50);
  color: var(--n900);
  font-size: 14px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
#login-form input:focus { outline: none; border-color: var(--accent-500); box-shadow: var(--ring); }
#login-form .btn-primary { margin-top: 24px; width: 100%; height: 42px; font-size: 14px; }
.footer-hint { text-align: center; margin-top: 22px; font-size: 12px; }

/* ═══ Responsive shell ════════════════════════════════════════════════════ */
@media (max-width: 960px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .sidebar, .main { min-width: 0; max-width: 100%; }
  .sidebar {
    position: sticky;
    top: 0;
    height: auto;
    flex-direction: column;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    overflow: visible;
    background: var(--sidebar-bg-mobile);
    backdrop-filter: blur(14px);
  }
  .brand { height: 52px; padding: 0 14px; border-bottom: 1px solid var(--border); }
  .tabs {
    flex-direction: row;
    align-items: center;
    gap: 2px;
    padding: 6px 10px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .nav-group-label { display: none; }
  .tab { width: auto; padding: 7px 12px; white-space: nowrap; flex-shrink: 0; }
  .tab.active::before { display: none; }
  .sidebar-foot { display: none; }

  .topbar { height: 52px; padding: 0 14px; }
  .content { padding: 18px 14px 48px; }

  #panel-chat {
    margin: -18px -14px -48px;
    height: calc(100dvh - 52px - 52px - 53px); /* topbar + brand row + nav row */
  }
  .chat-msg { max-width: 88%; }
  .chat-messages { padding: 14px 12px 6px; }
  .chat-input-bar { padding: 10px 12px 14px; }

  .stat-cards { grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .stat-card { padding: 12px; }
  .stat-card .value { font-size: 20px; }
  .stat-card .label { font-size: 10px; }
}

@media (max-width: 520px) {
  .user-chip .muted { display: none; }
  .user-chip { padding: 0 8px; }
  .content { padding: 14px 12px 48px; }
  .panel-head h1, .panel-head h2 { font-size: 18px; }
  .stat-cards { grid-template-columns: repeat(2, 1fr); }
  .cal-day { min-height: 72px; }
}

/* ─── Usage & charges ──────────────────────────────────────────────────── */
.usage-quota {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 14px; margin-bottom: 16px;
  background: var(--bg-elev); border: 1px solid var(--n300); border-radius: 10px;
}
.usage-quota-label { font-size: 12px; color: var(--n700); font-weight: 600; }
.usage-quota-track {
  flex: 1; min-width: 160px; height: 8px; border-radius: 999px;
  background: var(--n300); overflow: hidden;
}
.usage-quota-fill {
  height: 100%; border-radius: 999px; background: var(--accent);
  transition: width .25s ease;
}
/* Amber past 80% — the point at which a customer needs to notice, not the
   point at which they're already blocked. */
.usage-quota-fill.near { background: #f5a623; }
.usage-quota-num { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

.usage-kpis {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.usage-kpi {
  padding: 14px 16px; border-radius: 10px;
  background: var(--bg-elev); border: 1px solid var(--n300);
}
.usage-kpi-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); font-weight: 600;
}
.usage-kpi-value {
  margin-top: 6px; font-size: 22px; font-weight: 700; color: var(--n900);
  font-variant-numeric: tabular-nums;
}
.usage-kpi-sub { margin-top: 2px; font-size: 11px; color: var(--muted); }
.usage-note { margin-top: 14px; font-size: 12px; }
#usage-feature-table td:nth-child(n+2),
#usage-feature-table th:nth-child(n+2) { font-variant-numeric: tabular-nums; }

/* ═══ Focus visibility ════════════════════════════════════════════════════
   .btn-primary/.btn-ghost/inputs already carry the violet ring; these are the
   controls that were falling back to the browser default, which is low
   contrast on a near-black ground. One consistent ring everywhere. */
.tab:focus-visible,
.view-toggle-btn:focus-visible,
.ai-sub-tab:focus-visible,
.ai-src-tab:focus-visible,
.gen-type-btn:focus-visible,
.btn-mini:focus-visible,
.ai-lib-add:focus-visible,
.media-card:focus-visible,
.gen-media-card:focus-visible,
.cal-day:focus-visible,
.skip-link:focus-visible,
#chat-send:focus-visible,
#ai-fab:focus-visible,
.lb-close:focus-visible,
.ai-widget-header button:focus-visible,
.ai-widget-input-bar button:focus-visible {
  outline: 2px solid var(--accent-300);
  outline-offset: 2px;
  border-radius: 8px;
}

/* ═══ Windows High Contrast / forced-colors ═══════════════════════════════
   In forced-colors mode the OS replaces our palette wholesale. Backgrounds
   and shadows are discarded, so state that we express purely with colour
   (active tab, selected media, status pills) has to be re-expressed with
   borders, which forced-colors preserves. */
@media (forced-colors: active) {
  .tab.active,
  .view-toggle-btn.active,
  .ai-sub-tab.active,
  .gen-type-btn.active {
    border: 2px solid Highlight;
    forced-color-adjust: none;
    color: Highlight;
  }
  .tab.active::before { display: none; }

  .btn-primary,
  .btn-ghost,
  .btn-mini,
  .card,
  .stat-card,
  .media-card,
  .post-card,
  .modal-card,
  .queue-table,
  .top-table,
  .cal-day {
    border: 1px solid CanvasText;
  }

  /* Tints vanish in forced colours, so pills would read as bare text. */
  .status-pill,
  .platform-pill,
  .badge,
  .cal-post-chip {
    border: 1px solid CanvasText;
    forced-color-adjust: none;
    color: CanvasText;
    background: Canvas;
  }

  .gen-media-card.selected,
  .media-card:focus-visible {
    outline: 3px solid Highlight;
  }

  /* The impersonation banner is safety-critical; keep it unmistakable. */
  .ds-impersonation-banner { border: 3px solid Highlight; }
}

/* ═══ Print ═══════════════════════════════════════════════════════════════
   Reports and Analytics are the screens people export. Drop the chrome,
   force a light ground so it does not burn a cartridge, and let tables break
   across pages sensibly. */

/* ── Settings ───────────────────────────────────────────────────────────
   Four groups behind a segmented nav rather than one long grid. The cards
   themselves are laid out with auto-fit + align-items:start, so a group with
   three cards doesn't leave a hole and a tall card doesn't stretch its
   neighbour to match — which is what the old fixed 1fr 1fr grid did. */

.settings-nav {
  display: flex;
  gap: 4px;
  padding: 4px;
  margin-bottom: 20px;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow-x: auto;                 /* narrow screens scroll the nav, not the page */
  scrollbar-width: none;
}
.settings-nav::-webkit-scrollbar { display: none; }

.settings-nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: 1 0 auto;
  justify-content: center;
  padding: 8px 14px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background .13s ease, color .13s ease;
}
.settings-nav-btn:hover { color: var(--n800); }
/* The selected tab is a raised chip on a recessed track, so it reads as
   selected rather than merely hovered — the two used to share a fill. */
.settings-nav-btn.active {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--n900);
  font-weight: 600;
  box-shadow: var(--shadow-sm);
  padding: 7px 13px;                /* keep total height with the added border */
}
.settings-nav-btn.active svg { color: var(--accent-500); opacity: 1; }
.settings-nav-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.settings-nav-btn svg { flex-shrink: 0; opacity: .8; }

.settings-group { display: none; }
.settings-group.active { display: block; animation: panel-in .16s ease; }

/* A section this workspace is not entitled to. Wins over .active on purpose:
   an entitlement the platform revoked must not be reachable by a stale class
   or a hand-typed hash. The server refuses the routes behind it either way. */
.settings-nav-btn[data-locked], .settings-group[data-locked] { display: none !important; }

.settings-grid {
  display: grid;
  /* Exactly two columns. auto-fit used to pack three uneven columns on wide
     monitors, which crushed the Account Sessions rows until their text and
     status pills collided. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;               /* cards keep their own height */
  gap: 16px;
  max-width: 1080px;
}
@media (max-width: 760px) { .settings-grid { grid-template-columns: 1fr; } }

.settings-grid .settings-card { margin-bottom: 0; }
.settings-card-wide { grid-column: 1 / -1; }

.settings-card-head { margin-bottom: 16px; }
.settings-card-head h3 { margin-bottom: 4px; }
.settings-card-desc {
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
  margin: 0;
}

/* ── Models by feature ────────────────────────────────────────────────── */
.llm-feature-row {
  display: grid;
  grid-template-columns: 10px minmax(140px, 1fr) minmax(0, 2fr) minmax(0, 1.4fr);
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--n200);
  font-size: 13px;
}
.llm-feature-row:last-child { border-bottom: 0; }
.llm-feature-name { font-weight: 600; color: var(--n800); }
.llm-feature-model { display: flex; align-items: center; gap: 8px; min-width: 0; }
.llm-feature-model .model {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.llm-feature-model .prov {
  font-size: 11px; color: var(--muted);
  background: var(--n100); border: 1px solid var(--n200);
  border-radius: 999px; padding: 1px 8px; white-space: nowrap; flex-shrink: 0;
}
.llm-feature-ctl { font-size: 12px; color: var(--muted); }
@media (max-width: 760px) {
  .llm-feature-row { grid-template-columns: 10px 1fr; }
  .llm-feature-model, .llm-feature-ctl { grid-column: 2; }
}

/* ── AI provider card ─────────────────────────────────────────────────── */

.llm-effective {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--n100);
  margin-bottom: 16px;
}
.llm-effective-main { flex: 1; min-width: 0; }
.llm-effective-model {
  font-size: 14px;
  font-weight: 600;
  color: var(--n900);
  word-break: break-all;
}
.llm-effective-sub { font-size: 12px; color: var(--muted); margin-top: 3px; }

.llm-source {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .02em;
  padding: 4px 9px;
  border-radius: 999px;
  border: 1px solid var(--n400);
  color: var(--muted);
  background: var(--bg-card);
}
.llm-source.own { color: var(--success); border-color: rgba(47,196,106,.4); background: rgba(47,196,106,.09); }

.llm-provider-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 0;
  border-bottom: 1px solid var(--n200);
  font-size: 13px;
}
.llm-provider-row:last-child { border-bottom: 0; }
.llm-provider-row .name { font-weight: 600; color: var(--n900); }
.llm-provider-row .meta { font-size: 12px; color: var(--muted); }
.llm-provider-row select { max-width: 220px; }

.llm-dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0; background: var(--muted);
}
.llm-dot.ok { background: var(--success); }
.llm-dot.error { background: var(--danger); }

.llm-note {
  font-size: 12px;
  line-height: 1.55;
  color: var(--muted);
  padding: 11px 13px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--n300);
  background: var(--n100);
  margin-top: 14px;
}
.llm-note.warn { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 38%, transparent);
  background: color-mix(in srgb, var(--warning) 9%, transparent); }

@media print {
  .sidebar, .topbar, .skip-link, #ai-fab, #ai-widget, .toast,
  .actions, .filters, .view-toggle, .row-actions, .post-card-actions { display: none !important; }

  .shell { display: block; }
  .content { padding: 0; max-width: none; }

  html, body {
    background: #fff !important;
    color: #000 !important;
  }
  .card, .stat-card, .queue-table, .top-table {
    background: #fff !important;
    border: 1px solid #999 !important;
    box-shadow: none !important;
    break-inside: avoid;
  }
  .panel-head h1, .panel-head h2, .card h3 { color: #000 !important; }
  .muted, .stat-card .label, th { color: #333 !important; }
  .stat-card .value { color: #000 !important; }
  thead { display: table-header-group; }   /* repeat headers across pages */
  tr, img { break-inside: avoid; }
  a[href]::after { content: ""; }          /* no URL noise in an app export */
}


/* ═══ AI Studio · results-first canvas ═══════════════════════════════════
   The form is a column; the output is the stage. Every tool writes into one
   shared canvas, so a result survives switching tools and can be compared
   against the prompt that produced it. Replaces seven per-tool result cards
   that each showed only their own latest output and hid on tab switch. */

.ai-studio {
  display: grid;
  /* Even split. The form was capped at 380px, which squeezed the prompt box
     and the paired size/steps selects; the canvas does not need the extra
     room until there are enough results to fill it. minmax(0, …) on both so a
     long unbroken prompt cannot push its column past its share. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 20px;
  align-items: stretch;      /* gives the sticky canvas room to travel */
}
.ai-forms { min-width: 0; }

.ai-canvas { min-width: 0; }
/* Sticky needs two things to work here: a stretched grid item (above) so the
   containing block is the full row, and a cap at the viewport height — a
   sticky box taller than the viewport has nothing to pin against and simply
   scrolls away. */
.ai-canvas-inner {
  position: sticky;
  top: calc(var(--topbar-h) + 16px);
  max-height: calc(100vh - var(--topbar-h) - 32px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: 4px;
}
.ai-canvas-inner::-webkit-scrollbar { width: 8px; }
.ai-canvas-inner::-webkit-scrollbar-thumb {
  background: var(--border-strong); border-radius: 4px;
}

.ai-canvas-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 10px;
}
.ai-canvas-head h3 {
  margin: 0; font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
}
.ai-canvas-count { font-size: 12px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.ai-canvas-sub {
  margin: 16px 0 9px; font-size: 11.5px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
}
.ai-canvas-sub[hidden] { display: none; }

.ai-canvas-empty {
  border: 1px dashed var(--border); border-radius: var(--radius-lg);
  padding: 40px 20px; text-align: center; color: var(--text-dim);
}
.ai-canvas-empty[hidden] { display: none; }
.ai-canvas-empty-icon { font-size: 30px; opacity: .55; margin-bottom: 8px; }
.ai-canvas-empty p { margin: 0; font-size: 13px; }

/* ── Hero: the newest output, large ── */
.ai-hero {
  display: block; width: 100%; padding: 0; text-align: left;
  background: var(--media-well); color: inherit; font: inherit; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden; transition: border-color .15s ease;
}
.ai-hero:hover { border-color: var(--border-strong); }
.ai-hero:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ai-hero[disabled] { cursor: default; }
.ai-hero-stage {
  position: relative; aspect-ratio: 16 / 9;
  display: grid; place-items: center; background: var(--media-well);
}
.ai-hero-stage img, .ai-hero-stage video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
}
.ai-hero-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 12px; background: var(--bg-card); border-top: 1px solid var(--border);
}
.ai-hero-bar p {
  margin: 0; font-size: 12.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ai-hero-bar span { font-size: 11px; color: var(--text-dim); white-space: nowrap; }

/* ── Grid of earlier outputs ── */
.ai-res-grid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
}
.ai-res {
  position: relative; padding: 0; text-align: left; cursor: pointer;
  background: var(--bg-card); color: inherit; font: inherit;
  border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; transition: border-color .15s ease, transform .15s ease;
}
.ai-res:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.ai-res:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ai-res[data-state="running"] { cursor: default; }
.ai-res[data-state="running"]:hover { transform: none; border-color: var(--border); }
.ai-res-thumb {
  position: relative; aspect-ratio: 1 / 1; background: var(--media-well);
  display: grid; place-items: center;
}
.ai-res-thumb img, .ai-res-thumb video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.ai-res-badge, .ai-res-play {
  position: absolute; z-index: 2;
  background: rgba(8,8,10,.66); color: #e8e8f0;
  border: 1px solid rgba(255,255,255,.14); backdrop-filter: blur(6px);
}
.ai-res-badge {
  top: 6px; left: 6px; font-size: 10px; font-weight: 600;
  letter-spacing: .03em; text-transform: uppercase;
  padding: 3px 6px; border-radius: 5px;
}
.ai-res-play {
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center; font-size: 11px; padding-left: 2px;
}
.ai-res-meta { padding: 7px 9px 9px; }
.ai-res-title {
  margin: 0 0 2px; font-size: 11.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ai-res-sub { margin: 0; font-size: 10.5px; color: var(--text-dim); }
.ai-res[data-state="failed"] .ai-res-thumb {
  background: color-mix(in srgb, var(--danger) 9%, transparent);
}
.ai-res-err { color: var(--danger); font-size: 20px; font-weight: 700; }
.ai-res-prog {
  height: 3px; margin-top: 6px; border-radius: 2px;
  background: var(--border); overflow: hidden;
}
.ai-res-prog i {
  display: block; height: 100%; border-radius: 2px;
  background: var(--accent); transition: width .35s ease;
}

/* Under 1100px the canvas cannot hold its own column. It moves above the
   form rather than below it — putting it back underneath would restore the
   exact problem this layout exists to remove. */
@media (max-width: 1100px) {
  .ai-studio { grid-template-columns: minmax(0, 1fr); }
  .ai-canvas { order: -1; }
  .ai-canvas-inner { position: static; max-height: none; overflow: visible; padding-right: 0; }
  .ai-res-grid { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }
}

/* ─── Activity centre ───────────────────────────────────────────────────
   The workspace-wide progress indicator in the topbar. Quiet when nothing
   is running: no badge, no spinner, just the clock glyph. */
.activity { position: relative; flex-shrink: 0; }

.activity-btn {
  width: 34px;
  padding: 0;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* The ring only spins while work is in flight, so motion always means
   something. Sits behind the glyph rather than replacing it. */
.activity-spinner {
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  border: 1.5px solid transparent;
  border-top-color: var(--accent-500);
  border-right-color: var(--accent-500);
  opacity: 0;
  pointer-events: none;
}
.activity.is-busy .activity-spinner {
  opacity: 1;
  animation: activity-spin .9s linear infinite;
}
.activity.is-busy .activity-btn { color: var(--accent-300); border-color: var(--accent-700); }
@keyframes activity-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .activity.is-busy .activity-spinner { animation: none; opacity: .85; }
}

.activity-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--accent);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px var(--bg-base);
}

.activity-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(360px, calc(100vw - 24px));
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  z-index: 60;
  overflow: hidden;
}

.activity-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}

.activity-list { max-height: min(420px, 60vh); overflow-y: auto; }

.activity-empty {
  padding: 26px 14px;
  text-align: center;
  color: var(--muted);
  font-size: 12.5px;
}

.activity-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.activity-item:last-child { border-bottom: none; }
.activity-item:hover { background: var(--bg-elev); }

.activity-icon { font-size: 15px; line-height: 1.3; flex-shrink: 0; width: 18px; text-align: center; }
.activity-body { flex: 1; min-width: 0; }

.activity-item-title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.activity-sub { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.activity-item.status-error .activity-sub { color: var(--danger); }
.activity-item.status-done  .activity-icon { color: var(--success); }

.activity-bar {
  margin-top: 7px;
  height: 4px;
  border-radius: 3px;
  background: var(--n300);
  overflow: hidden;
}
.activity-bar > span {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--accent);
  transition: width .4s ease;
}
/* An elapsed-time estimate is drawn hatched, so it is not mistaken for a
   measured percentage. */
.activity-bar.is-estimated > span {
  background-image: linear-gradient(115deg,
    rgba(255,255,255,.28) 25%, transparent 25%,
    transparent 50%, rgba(255,255,255,.28) 50%,
    rgba(255,255,255,.28) 75%, transparent 75%);
  background-size: 10px 10px;
}

.activity-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }

.activity-dismiss {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 16px;
  line-height: 1;
  padding: 2px 4px;
  cursor: pointer;
  border-radius: 5px;
}
.activity-dismiss:hover { color: var(--text); background: var(--n300); }

/* ─── Reports grid ──────────────────────────────────────────────────────
   Documents have no thumbnail worth generating, so the card leads with a
   format glyph and gives the space back to the filename — which is the only
   thing that distinguishes one report from another. */
.report-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }

.report-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 44px;
  background: var(--media-well);
  aspect-ratio: 16 / 10;
}

.report-card .media-filename {
  padding: 4px 8px 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--text);
  line-height: 1.35;
  /* Two lines, then ellipsis: report names are long and near-identical at the
     start, so one truncated line tells the reader nothing. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}

.report-foot { padding-top: 2px; }

.report-actions {
  display: flex;
  gap: 4px;
  padding: 6px 8px 8px;
  flex-wrap: wrap;
}
.report-actions > * { flex: 1 1 auto; text-align: center; text-decoration: none; }

/* In select mode the whole card is the hit target, so the per-card buttons
   would only get in the way. */
.report-grid.selecting .report-actions { display: none; }
.report-grid.selecting .report-card { cursor: pointer; }

/* ─── Analytics ─────────────────────────────────────────────────────────
   Chart chrome is deliberately recessive: grid lines and axes are structure,
   not content, so they sit on the muted ramp and never compete with the
   marks. */

.stat-card .value { line-height: 1.15; }

/* Movement against the previous window. Direction is stated with an arrow
   glyph as well as colour, so it reads without colour vision. */
.stat-trend {
  margin-top: 6px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .01em;
}
.stat-trend.up   { color: var(--success); }
.stat-trend.down { color: var(--danger); }
.stat-trend.flat { color: var(--muted); }

.chart-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.chart-sub { font-size: 12px; margin: 2px 0 0; }

.metric-tabs {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 9px;
}
.metric-tab {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  padding: 5px 11px;
  border-radius: 7px;
  cursor: pointer;
}
.metric-tab:hover { color: var(--text); }
.metric-tab.active {
  background: var(--bg-card);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}
.metric-tab:focus-visible { outline: none; box-shadow: var(--ring); }

/* A fixed height, so the canvas cannot grow without bound while Chart.js and
   the flex container negotiate. */
.chart-box { position: relative; height: 260px; margin-top: 10px; }

.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
}
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 4px 9px;
  font-size: 12px;
  color: var(--text);
  cursor: pointer;
}
.legend-item:hover { background: var(--bg-elev); border-color: var(--border); }
.legend-item.muted-series { opacity: .4; }
.legend-swatch {
  width: 16px;
  height: 3px;
  border-radius: 2px;
  flex-shrink: 0;
}
/* The legend swatch repeats the line's dash pattern, so identity is carried
   by shape as well as hue. */
.legend-swatch.dashed {
  height: 3px;
  background-image: linear-gradient(90deg, transparent 55%, var(--bg-card) 55%);
  background-size: 6px 3px;
}
.legend-total { color: var(--muted); font-variant-numeric: tabular-nums; }

.analytics-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 14px;
}

/* ── Platform bars ── */
.plat-row { padding: 10px 0; border-bottom: 1px solid var(--border); }
.plat-row:last-child { border-bottom: none; }
.plat-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
}
.plat-name { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; }
.plat-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.plat-val { color: var(--text); font-variant-numeric: tabular-nums; }
.plat-track {
  margin: 7px 0 5px;
  height: 8px;
  border-radius: 4px;
  background: var(--n300);
  overflow: hidden;
}
/* Rounded data-end anchored to the baseline — the bar starts flush at zero
   and only its leading edge is rounded. */
.plat-track > span {
  display: block;
  height: 100%;
  border-radius: 0 4px 4px 0;
  transition: width .45s ease;
}
.plat-foot { font-size: 11.5px; }

/* ── Best-times heatmap ── */
.heatmap { margin-top: 6px; }
.heat-row { display: flex; align-items: center; gap: 10px; margin-bottom: 5px; }
.heat-label {
  width: 78px;
  flex-shrink: 0;
  font-size: 11.5px;
  color: var(--muted);
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.heat-cells { display: flex; gap: 2px; flex: 1; min-width: 0; }
.heat-cell {
  flex: 1;
  min-width: 0;
  height: 22px;
  border-radius: 3px;
  cursor: default;
}
/* No posts in that hour yet. Drawn as an outline, never as a dark cell — a
   dark cell would read as "tried, performed badly". */
.heat-cell.is-empty {
  background: transparent;
  border: 1px dashed var(--border-strong);
  opacity: 1;
}
.heat-tick {
  flex: 1;
  min-width: 0;
  font-size: 10px;
  color: var(--muted);
  text-align: left;
  font-variant-numeric: tabular-nums;
}
.heat-ruler { margin-top: 2px; }
.heat-best { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 6px; }

@media (max-width: 560px) {
  .heat-label { width: 56px; font-size: 10.5px; }
  .chart-box { height: 220px; }
}

/* ─── People: team & sign-in accounts ───────────────────────────────────
   Both lists render through the same row so they read as siblings; what
   distinguishes them is stated in each card's description, not left to the
   reader to work out from the controls. */

.quota-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
  margin-bottom: 16px;
}
.quota-meter {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 12px;
}
.quota-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  color: var(--muted);
}
.quota-val { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.quota-track {
  margin-top: 8px;
  height: 6px;
  border-radius: 3px;
  background: var(--n300);
  overflow: hidden;
}
.quota-track > span {
  display: block;
  height: 100%;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
  transition: width .4s ease;
}
/* Colour is reserved for "pay attention" — a meter at 20% is not news. */
.quota-track > span.is-near { background: var(--warning); }
.quota-track > span.is-full { background: var(--danger); }

.team-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  font-size: 12.5px;
}

/* ── Member rows ── */
.member-list { display: flex; flex-direction: column; }
.member-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.member-row:last-child { border-bottom: none; }
.member-row.is-suspended .member-avatar,
.member-row.is-suspended .member-name { opacity: .5; }

.member-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .02em;
  color: #fff;
}
.member-body { flex: 1 1 150px; min-width: 0; }
.member-name {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
}
.member-meta { font-size: 11.5px; margin-top: 2px; }

.member-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 5px;
  background: var(--n300);
  color: var(--n700);
}
.member-badge.is-owner {
  background: var(--accent-glow);
  color: var(--accent-300);
  border: 1px solid var(--accent-700);
}

.role-select {
  font-size: 12px;
  height: 30px;
  padding: 0 26px 0 9px;
  flex-shrink: 0;
}
.role-static { font-size: 12px; flex-shrink: 0; }
.member-actions { display: flex; gap: 5px; flex-shrink: 0; }

/* ── Invite form ── */
.invite-panel {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 14px;
}
.invite-panel.is-inline { margin: 14px 0 0; }
.invite-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px;
}
.invite-panel .field { min-width: 0; }
.invite-panel .field label {
  display: block;
  font-size: 11.5px;
  color: var(--muted);
  margin-bottom: 4px;
}
.invite-panel .field input { width: 100%; }
.field-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}

.input-affix { position: relative; display: block; }
.input-affix input { width: 100%; padding-right: 34px; }
.affix-btn {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px;
}
.affix-btn:hover { color: var(--text); }

.pw-meter { font-size: 11px; font-weight: 600; }
.pw-meter.is-weak   { color: var(--danger); }
.pw-meter.is-fair   { color: var(--warning); }
.pw-meter.is-strong { color: var(--success); }

/* ── Role picker ──
   A role name alone ("Editor") does not tell an admin what they are granting,
   which is the entire decision this control exists to make. */
.role-picker { border: none; padding: 0; margin: 14px 0 0; min-width: 0; }
.role-picker > legend {
  font-size: 11.5px;
  color: var(--muted);
  padding: 0;
  margin-bottom: 6px;
}
.role-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 8px;
}
.role-option {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  cursor: pointer;
}
.role-option:hover { border-color: var(--border-strong); }
.role-option.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
.role-option input { margin-top: 2px; flex-shrink: 0; }
.role-option-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.role-option-body strong { font-size: 13px; color: var(--text); }
.role-option-desc { font-size: 11.5px; color: var(--muted); line-height: 1.4; }

.invite-actions {
  display: flex;
  gap: 8px;
  margin-top: 14px;
  flex-wrap: wrap;
}

/* Kept in the accessibility tree, out of the visual layout. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 560px) {
  .member-actions { width: 100%; justify-content: flex-end; }
}

/* ─── Chat: rendered markdown ───────────────────────────────────────────
   The assistant's answers are markdown — headings, bullets, tables, sources.
   The bubble used to be `white-space: pre-wrap` over a bold/italic pass, so a
   research report arrived as one wall of text with literal "##" in it. Block
   elements now carry the structure, which means pre-wrap has to come off for
   assistant bubbles: kept for the user's own messages, which are set as plain
   text and whose line breaks are the only formatting they have. */
.chat-msg.assistant .chat-bubble { white-space: normal; }

.chat-bubble .md-p { margin: 0 0 8px; }
.chat-bubble .md-p:last-child { margin-bottom: 0; }

.chat-bubble .md-h {
  margin: 14px 0 6px;
  font-weight: 650;
  line-height: 1.35;
  color: var(--text);
}
.chat-bubble .md-h:first-child { margin-top: 0; }
.chat-bubble h3.md-h { font-size: 15px; }
.chat-bubble h4.md-h { font-size: 13.8px; }
.chat-bubble h5.md-h,
.chat-bubble h6.md-h {
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
}

.chat-bubble .md-list { margin: 0 0 8px; padding-left: 20px; }
.chat-bubble .md-list:last-child { margin-bottom: 0; }
.chat-bubble .md-list li { margin: 3px 0; }
.chat-bubble ul.md-list { list-style: disc; }
.chat-bubble ol.md-list { list-style: decimal; }

.chat-bubble .md-quote {
  margin: 8px 0;
  padding: 2px 0 2px 12px;
  border-left: 3px solid var(--accent-700);
  color: var(--muted);
}

.chat-bubble .md-hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 12px 0;
}

.chat-bubble code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .88em;
  background: var(--n300);
  border-radius: 4px;
  padding: 1px 5px;
}
.chat-bubble .md-code {
  margin: 8px 0;
  padding: 10px 12px;
  background: var(--n50);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow-x: auto;
}
.chat-bubble .md-code code {
  background: none;
  padding: 0;
  white-space: pre;
  display: block;
}

/* A wide table scrolls inside its own box; the message column must never
   scroll sideways. */
.chat-bubble .md-table-wrap { overflow-x: auto; margin: 8px 0; }
.chat-bubble .md-table {
  border-collapse: collapse;
  font-size: 12.5px;
  min-width: 100%;
}
.chat-bubble .md-table th,
.chat-bubble .md-table td {
  border: 1px solid var(--border);
  padding: 5px 9px;
  text-align: left;
  white-space: nowrap;
}
.chat-bubble .md-table th { background: var(--n300); font-weight: 600; }

.chat-bubble a { color: var(--accent-300); text-decoration: underline; text-underline-offset: 2px; }
.chat-msg.user .chat-bubble a { color: #fff; }
.chat-bubble a:hover { text-decoration-thickness: 2px; }

.chat-media {
  max-width: 100%;
  border-radius: 8px;
  margin-top: 8px;
  display: block;
}

/* Answer actions: copy, and export when the answer is substantial. */
.chat-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
}

/* Send doubles as stop while a turn streams. */
#chat-send.is-stop {
  background: var(--n300);
  color: var(--text);
  font-size: 13px;
}
#chat-send.is-stop:hover { background: var(--n400); filter: none; }

/* Back to the live edge, shown only once the reader has scrolled away. */
.chat-jump {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 76px;
  z-index: 5;
  background: var(--bg-elev);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 5px 13px;
  font-size: 12px;
  cursor: pointer;
  box-shadow: var(--shadow);
}
.chat-jump:hover { border-color: var(--accent-500); }
#panel-chat { position: relative; }
