@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Space+Grotesk:wght@500;600;700&display=swap');

:root {
  /* The Index Podcast brand: black + warm cream + burnt-orange accent */
  --bg: #0a0908;
  --bg-soft: #100e0c;
  --surface: #17140f;
  --surface-2: #201a13;
  --border: #2f2820;
  --border-soft: #221c15;
  --text: #f5efe2;
  --text-muted: #a89b87;
  --text-dim: #6b6152;

  --orange: #e8823c;
  --orange-deep: #cf6a24;
  --cream: #f2e9d8;

  /* Functional tag colors (Solana / Non-Solana) — independent of brand accent */
  --purple: #9945ff;
  --green: #2fbf71;
  --gold: #e8823c;
  --blue: #4c8dff;
  --red: #ff5c7a;

  --grad-brand: linear-gradient(120deg, #e8823c 0%, #f2a35e 100%);
  --grad-gold: linear-gradient(120deg, #f2e9d8 0%, #e2d2ac 100%);

  --radius: 14px;
  --radius-sm: 9px;
  --shadow-lg: 0 20px 50px -20px rgba(0,0,0,.65);
  --shadow-sm: 0 4px 14px -6px rgba(0,0,0,.45);
  color-scheme: dark;
}

:root[data-theme="light"] {
  --bg: #faf6ec;
  --bg-soft: #f3ecda;
  --surface: #ffffff;
  --surface-2: #f6efdd;
  --border: #e2d6b8;
  --border-soft: #ece2c8;
  --text: #201a12;
  --text-muted: #6e6350;
  --text-dim: #9d9078;
  --shadow-lg: 0 20px 50px -20px rgba(60,45,10,.25);
  --shadow-sm: 0 4px 14px -6px rgba(60,45,10,.15);
  color-scheme: light;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: radial-gradient(1200px 600px at 90% -10%, rgba(232,130,60,.10), transparent 60%),
              radial-gradient(1000px 500px at -10% 10%, rgba(242,233,216,.05), transparent 55%),
              var(--bg);
  color: var(--text);
  font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  min-height: 100vh;
  transition: background-color .15s ease, color .15s ease;
}
:root[data-theme="light"] body {
  background: radial-gradient(1200px 600px at 90% -10%, rgba(232,130,60,.08), transparent 60%),
              radial-gradient(1000px 500px at -10% 10%, rgba(153,69,255,.04), transparent 55%),
              var(--bg);
}

h1, h2, h3, h4, .brand-font {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  letter-spacing: -.01em;
}

a { color: inherit; text-decoration: none; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 10px; }

/* ---------- Layout ---------- */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  /* The sidebar always stays on the dark brand palette, independent of the
     light/dark page theme — these local overrides re-anchor every var(--x)
     used inside it, light theme or not. */
  --bg-soft: #100e0c;
  --surface: #17140f;
  --surface-2: #201a13;
  --border: #2f2820;
  --border-soft: #221c15;
  --text: #f5efe2;
  --text-muted: #a89b87;
  --text-dim: #6b6152;

  width: 232px;
  flex-shrink: 0;
  color: var(--text);
  background: linear-gradient(180deg, #100e0c 0%, #0a0908 100%);
  border-right: 1px solid var(--border-soft);
  display: flex;
  flex-direction: column;
  padding: 18px 14px;
  position: sticky;
  top: 0;
  height: 100vh;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 6px 18px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border-soft);
}

.brand-mark {
  width: 36px; height: 36px;
  border-radius: 10px;
  background: #000;
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
}
.brand-mark svg { width: 26px; height: 26px; }

.brand-text { line-height: 1.15; }
.brand-text .t1 { font-weight: 800; font-size: 15px; }
.brand-text .t2 { font-size: 10px; letter-spacing: .14em; color: var(--orange); font-weight: 600; text-transform: uppercase; }

.nav-group { margin-top: 4px; display: flex; flex-direction: column; gap: 2px; }
.nav-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .12em; color: var(--text-dim); margin: 14px 10px 5px; font-weight: 700; }

.nav-link {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: 13.5px; font-weight: 500;
  transition: all .15s ease;
}
.nav-link svg { width: 16px; height: 16px; flex-shrink: 0; opacity: .85; }
.nav-link:hover { background: var(--surface); color: var(--text); }
/* Pending-count badge (e.g. password reset requests waiting on Users) — pushed to the far
   right of the nav row so it reads as a notification, not just more label text. */
.nav-badge {
  margin-left: auto; background: var(--red); color: #fff; font-size: 10.5px; font-weight: 800;
  line-height: 1; padding: 3px 6px; border-radius: 999px; flex-shrink: 0;
}
.nav-link.active {
  background: linear-gradient(90deg, rgba(232,130,60,.18), rgba(232,130,60,.04));
  color: #fff;
  box-shadow: inset 3px 0 0 var(--orange);
}

.sidebar-foot {
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
}

.user-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--border-soft);
}
.user-avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--grad-gold);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 12.5px; color: #241a0c; flex-shrink: 0;
}
.user-meta { line-height: 1.2; flex: 1; min-width: 0; }
.user-meta .name { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-meta .role { font-size: 10.5px; color: var(--text-dim); text-transform: capitalize; }
.logout-btn { color: var(--text-dim); }
.logout-btn:hover { color: var(--red); }

.main { flex: 1; min-width: 0; padding: 10px 24px 18px; }

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px; flex-wrap: wrap; gap: 10px;
}
.page-title { font-size: 21px; font-weight: 700; margin: 0; }
.page-sub { color: var(--text-muted); font-size: 13px; margin-top: 3px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 15px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 13px; font-weight: 600;
  cursor: pointer;
  transition: all .15s ease;
}
.btn svg { width: 15px; height: 15px; }
.btn:hover { border-color: var(--orange); transform: translateY(-1px); }
.btn-primary {
  background: var(--grad-brand);
  border: none; color: #241300;
  box-shadow: 0 8px 20px -8px rgba(232,130,60,.5);
}
.btn-primary:hover { filter: brightness(1.06); }
.btn-gold { background: var(--grad-gold); border: none; color: #241500; }
/* Export: deliberately a different, eye-catching color from every other filter-bar button
   (Filter is the orange brand accent, Clear/dropdowns are neutral) so it reads as its own
   distinct action at a glance. */
.btn-export { background: var(--green); border: none; color: #06210f; box-shadow: 0 8px 20px -8px rgba(47,191,113,.5); }
.btn-export:hover { filter: brightness(1.08); border-color: transparent; }
.btn-danger { background: rgba(255,92,122,.12); border-color: rgba(255,92,122,.35); color: var(--red); }
.btn-danger:hover { border-color: var(--red); }
.btn-sm { padding: 6px 11px; font-size: 12px; border-radius: 8px; }
.btn-ghost { background: transparent; border-color: var(--border-soft); }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.btn-icon { padding: 6px 8px; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  transition: all .15s ease;
}
.icon-btn svg { width: 14px; height: 14px; }
.icon-btn:hover { color: var(--text); border-color: var(--orange); }
.icon-btn.danger:hover { color: var(--red); border-color: var(--red); background: rgba(255,92,122,.1); }

.toggle-group {
  display: flex; gap: 3px; background: var(--bg-soft);
  border: 1px solid var(--border-soft); border-radius: 9px; padding: 3px;
}
.toggle-group a {
  padding: 5px 9px; border-radius: 6px; font-size: 11px; font-weight: 700;
  color: var(--text-dim); letter-spacing: .02em;
}
.toggle-group a.active { background: var(--grad-brand); color: #241300; }
.toggle-group a:hover:not(.active) { color: var(--text); }
.sidebar-toggles { display: flex; gap: 8px; margin-bottom: 10px; }
.sidebar-toggles .toggle-group { flex: 1; justify-content: center; }

/* Persistent multi-zone clock strip (item 7) — Madrid/ET/PST at a glance from anywhere in the
   app, not just the dedicated Timezone Converter page. Deliberately low-visual-weight (small
   muted text, no icons/borders of its own) so it reads as a quiet reference line rather than
   competing with the nav links above it or the user chip below — see renderMultiZoneClock() in
   assets/js/app.js (shared with calendar.php's own Madrid-only reference clock). */
.sidebar-clock-strip {
  /* Was var(--text-dim) — nearly invisible against the dark-theme sidebar background (a
     near-black on near-black read). var(--text-muted) is the same "quiet reference line"
     weight the rest of the sidebar uses for secondary text, just legible. */
  font-size: 11px; color: var(--text-muted); text-align: center;
  padding: 6px 8px 10px; letter-spacing: .01em; font-variant-numeric: tabular-nums;
  display: flex; flex-direction: column; gap: 2px;
}
.sidebar-clock-strip .row { display: flex; justify-content: space-between; gap: 8px; }
.sidebar-clock-strip .row .zone { color: var(--text-dim); }
.theme-toggle-btn {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 9px;
  background: var(--bg-soft); border: 1px solid var(--border-soft); color: var(--text-dim);
}
.theme-toggle-btn:hover { color: var(--orange); border-color: var(--orange); }
.theme-toggle-btn svg { width: 15px; height: 15px; }

/* ---------- Cards / stats ---------- */
.grid { display: grid; gap: 14px; }
.grid > * { min-width: 0; } /* let grid items shrink below their content's intrinsic width — otherwise a
                                wide table/canvas inside one card stretches the whole row (a classic CSS
                                Grid gotcha) instead of scrolling internally. */
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 1200px) { .grid-4 { grid-template-columns: repeat(2, 1fr); } .grid-3 { grid-template-columns: repeat(2,1fr); } }

/* ---------- Mobile (<=760px): drawer sidebar + stacked layout ---------- */
.mobile-menu-btn { display: none; }
.mobile-backdrop { display: none; }

@media (max-width: 760px) {
  .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr; }
  .main { padding: 14px; padding-top: 58px; }

  .mobile-menu-btn {
    display: flex; align-items: center; justify-content: center;
    position: fixed; top: 12px; left: 12px; z-index: 60;
    width: 38px; height: 38px; border-radius: 10px;
    background: var(--surface); border: 1px solid var(--border);
    color: var(--text); box-shadow: var(--shadow-sm);
  }
  .mobile-menu-btn svg { width: 18px; height: 18px; }

  .sidebar {
    position: fixed; top: 0; left: 0; height: 100vh; z-index: 65;
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: 20px 0 40px -20px rgba(0,0,0,.5);
  }
  .sidebar.open { transform: translateX(0); }

  .mobile-backdrop.open {
    display: block; position: fixed; inset: 0; z-index: 62;
    background: rgba(0,0,0,.5);
  }

  .modal { padding: 18px; border-radius: 14px; }
  .modal-backdrop { padding: 16px 10px; }
  table { min-width: 640px; }
  .topbar { gap: 10px; }
  .page-title { font-size: 18px; }
  .filter-bar select, .filter-bar input { min-width: 0; flex: 1 1 140px; }

  /* Calendar: 7 columns is tight on a phone — shrink text/padding instead of
     letting cells force a horizontal scroll. */
  .cal-grid { gap: 3px; }
  .cal-cell { min-height: 58px; padding: 3px; }
  .cal-dow { font-size: 9px; }
  .cal-daynum { font-size: 10px; }
  .cal-chip { font-size: 9px; padding: 3px 4px; }
  .cal-chip .chip-eco { font-size: 7.5px; }
  .cal-chip .rec-status-badge { font-size: 7px; padding: 0 2px; }
  .rec-eco-label { font-size: 7.5px; }
  .cal-chip .chip-field { font-size: 8px; }
  .cal-add { font-size: 8px; }

  /* Stat tiles: two per row instead of one-per-row keeps them from looking
     oversized on a tall narrow screen. */
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}

.card {
  background: linear-gradient(180deg, var(--surface) 0%, var(--bg-soft) 120%);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 11px 13px;
  box-shadow: var(--shadow-sm);
}
.card-title { font-size: 12px; font-weight: 700; margin: 0 0 6px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }

.stat-tile { position: relative; overflow: hidden; padding: 12px 14px; }
.stat-tile .icon {
  width: 28px; height: 28px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 7px;
}
.stat-tile .icon svg { width: 16px; height: 16px; }
.stat-tile .value { font-size: 22px; font-weight: 800; font-family: 'Space Grotesk', sans-serif; line-height: 1.1; }
.stat-tile .label { color: var(--text-muted); font-size: 11.5px; margin-top: 2px; }
.stat-tile .delta { font-size: 11px; margin-top: 7px; display: inline-flex; align-items: center; gap: 4px; font-weight: 600; }

.icon-purple { background: rgba(153,69,255,.15); color: var(--purple); }
.icon-green { background: rgba(47,191,113,.15); color: var(--green); }
.icon-gold { background: rgba(232,130,60,.15); color: var(--orange); }
.icon-blue { background: rgba(76,141,255,.15); color: var(--blue); }

/* ---------- Badges / pills ---------- */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .01em;
  white-space: nowrap;
}
.pill-dot { width: 6px; height: 6px; border-radius: 50%; }

.pill-solana { background: rgba(153,69,255,.14); color: #c69bff; }
.pill-solana .pill-dot { background: var(--purple); }
.pill-nonsolana { background: rgba(76,141,255,.14); color: #9dc0ff; }
.pill-nonsolana .pill-dot { background: var(--blue); }
:root[data-theme="light"] .pill-solana { background: rgba(153,69,255,.14); color: #6b21d6; }
:root[data-theme="light"] .pill-nonsolana { background: rgba(76,141,255,.16); color: #1656c9; }

/* pill-done/pill-scheduled/pill-pending/pill-blocked belong to Buzzsprout/X-Clips' own,
   separate status models — not part of the 9-phase PIPELINE_STATUS_OPTIONS palette below. */
.pill-done { background: rgba(47,191,113,.14); color: #7fe3ac; }
.pill-done .pill-dot { background: var(--green); }
.pill-scheduled { background: rgba(232,130,60,.14); color: #f3b57d; }
.pill-scheduled .pill-dot { background: var(--orange); }
.pill-pending { background: rgba(255,92,122,.14); color: #ff9fb2; }
.pill-pending .pill-dot { background: var(--red); }
.pill-blocked { background: rgba(168,155,135,.16); color: var(--text-muted); }
.pill-blocked .pill-dot { background: var(--text-dim); }
/* ---------- The 10-phase pipeline status palette (single source of truth — this exact set of
   hex values is mirrored in dashboard.php's $statusColors and calendar.php's $statusColors,
   so all three surfaces read as one consistent system; the calendar's recording-chip status
   badge reuses these exact .pill-* classes directly rather than recomputing its own colors).
   Phase order/names come from pipeline.php's PIPELINE_STATUS_OPTIONS:
     0 Cancelled (dark red) · 1 Stand-by (light red) · 2 Precall (orange) ·
     3 Pre-Record (light blue/celeste) · 4 Recorded (blue) · 5 Editing (purple) ·
     6 Ready for Publish · 7 Publish Scheduled · 8 Published · 9 Published + Ads —
     the last 4 are all greens, deliberately getting darker the further along the phase;
     Published + Ads additionally gets a bold gold outline so it still reads as "the final
     phase" even against the darkest green.
   pill-published is also reused as-is by Buzzsprout's PUBLISHED status (a separate, simpler
   status model) — same concept, same color, intentionally shared. */
.pill-cancelled { background: rgba(139,30,43,.22); color: #ff8f9c; }
.pill-cancelled .pill-dot { background: #8b1e2b; }
.pill-standby { background: rgba(232,116,127,.16); color: #ffb3bd; }
.pill-standby .pill-dot { background: #e8747f; }
.pill-precall { background: rgba(242,149,74,.16); color: #ffc38a; }
.pill-precall .pill-dot { background: #f2954a; }
.pill-prerecord { background: rgba(90,200,232,.16); color: #a8e6f7; }
.pill-prerecord .pill-dot { background: #5ac8e8; }
.pill-recorded { background: rgba(59,111,214,.18); color: #a3bdf7; }
.pill-recorded .pill-dot { background: #3b6fd6; }
.pill-editing { background: rgba(139,92,246,.16); color: #c6b2fb; }
.pill-editing .pill-dot { background: #8b5cf6; }
.pill-readyforpublish { background: rgba(127,217,154,.18); color: #b3f0c4; }
.pill-readyforpublish .pill-dot { background: #7fd99a; }
.pill-publishscheduled { background: rgba(79,211,131,.20); color: #8ce6ae; }
.pill-publishscheduled .pill-dot { background: #4fd383; }
.pill-published { background: rgba(47,191,113,.22); color: #7fe3ac; }
.pill-published .pill-dot { background: #2fbf71; }
/* Published + Ads: same dark-green fill as Published, plus a bold gold outline so it always
   reads as "the final phase" at a glance, distinct from plain Published. */
.pill-publishedads { background: rgba(31,122,63,.26); color: #4fd383; border: 2px solid #ffd54a; padding: 1px 9px; }
.pill-publishedads .pill-dot { background: #1f7a3f; }
/* "Check" flag on Calendar chips (replaces an earlier red-outline/blink treatment) for phases
   still needing admin review — Recorded/Editing/Ready for Publish/Published (see calendar.php's
   $checkFlagStatuses). Publish Scheduled is deliberately excluded: a cron job already advances it
   to Published on its own once pub_date arrives, so it doesn't need a manual check. Solid red
   (not the translucent tint the other pills use) so it reads as an alert, not just another status. */
.pill-checkflag { background: var(--red); color: #fff; }
.pill-checkflag .pill-dot { background: #fff; }

/* Light theme: the dark-optimized pastel text colors above are unreadable on a
   cream background — swap in darker, saturated tones for the same hues. */
:root[data-theme="light"] .pill-done { color: #147a45; }
:root[data-theme="light"] .pill-scheduled { color: #b4590f; }
:root[data-theme="light"] .pill-pending { color: #c21f45; }
:root[data-theme="light"] .pill-blocked { color: #6e6350; }
:root[data-theme="light"] .pill-cancelled { color: #7a1925; }
:root[data-theme="light"] .pill-standby { color: #c23347; }
:root[data-theme="light"] .pill-precall { color: #b4560d; }
:root[data-theme="light"] .pill-prerecord { color: #0f7a95; }
:root[data-theme="light"] .pill-recorded { color: #1c46a8; }
:root[data-theme="light"] .pill-editing { color: #5b32c9; }
:root[data-theme="light"] .pill-readyforpublish { color: #1f7a45; }
:root[data-theme="light"] .pill-publishscheduled { color: #12633d; }
:root[data-theme="light"] .pill-published { color: #0f5230; }
:root[data-theme="light"] .pill-publishedads { color: #0a3d22; border-color: #c9a227; }

/* ---------- Tables ---------- */
.table-wrap { overflow-x: auto; border-radius: var(--radius); border: 1px solid var(--border-soft); }
table { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 720px; }
thead th {
  text-align: left; padding: 10px 13px;
  background: var(--surface-2);
  color: var(--text-muted); font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: .06em;
  border-bottom: 1px solid var(--border-soft);
  white-space: nowrap;
}
tbody td { padding: 10px 13px; border-bottom: 1px solid var(--border-soft); vertical-align: middle; }
tbody tr:hover { background: rgba(255,255,255,.02); }
tbody tr:last-child td { border-bottom: none; }
.cell-muted { color: var(--text-muted); }
.cell-strong { font-weight: 600; }
.row-actions { display: flex; gap: 9px; justify-content: flex-end; }

/* Compact table variant (Buzzsprout, X-Clips, PR, dashboard's interviewer breakdown) */
table.table-compact { font-size: 12.5px; }
table.table-compact td { padding: 6px 12px; }
table.table-compact thead th { padding: 8px 12px; }
table.table-compact tbody tr td:first-child { color: var(--text-dim); font-size: 11.5px; }

/* PR roster table (pr.php) — explicit column widths instead of letting the browser size each
   one by its widest cell, which is what made "Met founders/CEOs" (a long header over a short
   Yes/No pill) balloon out with a lot of dead space before Contact name next to it. Met founders
   is also center-aligned so the pill sits under its own header instead of hugging the left edge
   of that wide column. Notes gets a capped width + wrapping (title="" on the cell carries the
   full text for anything still truncated) so one long note can't stretch the whole table. */
.table-pr .col-pr-agency, .table-pr .col-pr-name { min-width: 150px; }
.table-pr .col-pr-type { min-width: 130px; }
.table-pr .col-pr-met { width: 90px; text-align: center; white-space: nowrap; }
.table-pr .col-pr-position { min-width: 100px; }
.table-pr .col-pr-email { min-width: 190px; }
.table-pr .col-pr-phone { min-width: 120px; white-space: nowrap; }
.table-pr .col-pr-social { min-width: 100px; }
.table-pr .col-pr-notes { max-width: 280px; white-space: normal; }

/* X-Clips table (xclips.php) — narrow fixed columns for # and # Clips so they don't stretch
   wider than their short content, matching the same explicit-width approach as .table-pr above. */
.table-xc .col-xc-num { width: 36px; text-align: right; color: var(--text-dim); }
.table-xc .col-xc-clips { width: 70px; }

/* ---------- Forms ---------- */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 760px) {
  .form-grid, .form-grid.cols-3 { grid-template-columns: 1fr; }
}
.field { display: flex; flex-direction: column; gap: 6px; }
.field.full { grid-column: 1 / -1; }
.field label { font-size: 12px; font-weight: 600; color: var(--text-muted); }
.field-hint { font-size: 11px; color: var(--text-dim); }
input, select, textarea {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 10px 12px;
  border-radius: 9px;
  font-size: 13.5px;
  font-family: inherit;
  width: 100%;
  transition: border-color .15s ease;
}
textarea { resize: vertical; min-height: 90px; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--orange); }
input[readonly] { color: var(--text-muted); background: var(--surface-2); }
::placeholder { color: var(--text-dim); }
input[type="checkbox"] { width: auto; accent-color: var(--orange); }
.checkbox-row { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-muted); }
.checkbox-row label { font-size: 13px; font-weight: 500; color: var(--text); }

/* Pipeline create modal: the rest of the form dims until a Guest type is picked
   (progressive reveal — see onGuestTypeChange() in pipeline.php). The fields themselves
   are also set .disabled via JS; this is just the visual cue. */
#f_progressive_wrap.progressive-locked { opacity: .4; pointer-events: none; }

/* Status/Schedule Video/Riverside link fields: hidden only during CREATE (see
   openCreateModal()/openEditModal() and CREATE_ONLY_HIDDEN_WRAPS in pipeline.php). */
.create-only-hidden { display: none; }

/* Pipeline create/edit modal (item 6 design pass): a light section divider ahead of each major
   field group (the Non-Solana guided flow, the full-recording/status/expenses block, the
   pre-brief upload, and the sync-calendar checkbox) so the modal reads as distinct sections
   instead of one undifferentiated wall of fields — deliberately subtle, matching this app's
   existing hairline-border conventions (fieldset.panel, .table-wrap, etc.) rather than
   introducing a new visual language. */
.form-section-div { border-top: 1px solid var(--border-soft); padding-top: 16px; margin-top: 2px; }

fieldset.panel {
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 14px 16px 16px;
  margin: 4px 0 0;
  grid-column: 1 / -1;
}
fieldset.panel legend {
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--orange); padding: 0 6px;
}

.filter-bar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 16px; }
.filter-bar select, .filter-bar input { width: auto; min-width: 150px; }
.search-input { position: relative; flex: 1; min-width: 200px; max-width: 320px; }
/* The search box's own <input> was inheriting ".filter-bar input"'s `width: auto` above, which
   discards the base `input{width:100%}` rule and lets the browser fall back to its native
   intrinsic text-input width (~size=20) instead of filling the .search-input wrapper. At the
   wrapper's wider flex sizes that left a chunk of unfilled, unbordered wrapper space next to a
   visibly smaller boxed input — reading as "no frame" next to the fully-filled, evenly-bordered
   select/status-filter-btn controls beside it. Pinning width:100% (and restating border/
   background explicitly, matching those siblings exactly) back on the actual <input> fixes both
   the sizing mismatch and makes the border/frame consistent end-to-end. */
.search-input input { width: 100%; border: 1px solid var(--border); background: var(--bg-soft); }

/* Status filter: a small popover of checkboxes (replaces the old single-select) — see
   toggleStatusFilterPanel() in pipeline.php. */
.status-filter-dropdown { position: relative; }
.status-filter-panel {
  /* Tinted to match the app's soft panel surfaces (same tone as .filter-daterange-group)
     instead of pure white (--surface), which read as a stark, out-of-place box against the
     cream/dark page background — especially jarring in light theme. */
  display: none; position: absolute; top: calc(100% + 6px); left: 0; z-index: 50;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 6px; box-shadow: var(--shadow-lg); min-width: 210px;
  flex-direction: column; gap: 0; max-height: 70vh; overflow-y: auto;
}
.status-filter-panel.open { display: flex; }
/* Trimmed padding (was 6px 8px) — with the Status panel now holding 10 phases, the old row
   height needed a scrollbar to fit them all; this alone gets every row on screen without one. */
.status-filter-option { display: flex; align-items: center; gap: 8px; padding: 4px 8px; border-radius: 6px; font-size: 12.5px; cursor: pointer; white-space: nowrap; }
.status-filter-option:hover { background: var(--surface); }
/* Custom checkbox — the native OS checkbox rendered as a plain white square even with
   accent-color set (only the checked fill picks up the theme color, not the idle box), which
   stood out as its own little "ugly white box" inside the panel. A fully custom appearance
   keeps it themed in both states. */
.status-filter-option input[type="checkbox"] {
  /* .filter-bar input sets min-width:150px for its plain <select>/text-input siblings — that
     rule still reaches this checkbox (it's inside the same <form>) and was stretching it into
     a huge 150px+ bar instead of a small square, since min-width overrides an explicit smaller
     width. min-width:0 here cancels that inherited floor back out. */
  appearance: none; -webkit-appearance: none;
  width: 16px; min-width: 0; height: 16px; flex-shrink: 0; margin: 0;
  border: 1.5px solid var(--border); border-radius: 4px; background: var(--bg-soft);
  cursor: pointer; position: relative; transition: background .12s ease, border-color .12s ease;
}
.status-filter-option input[type="checkbox"]:hover { border-color: var(--orange); }
.status-filter-option input[type="checkbox"]:checked { background: var(--orange); border-color: var(--orange); }
.status-filter-option input[type="checkbox"]:checked::after {
  content: ''; position: absolute; left: 5px; top: 1px; width: 4px; height: 8px;
  border: solid #1a1208; border-width: 0 2px 2px 0; transform: rotate(45deg);
}

/* Promoter typeahead (pipeline.php's f_promoter field, backed by pr_contacts — see pr.php) —
   the PR roster is too large to dump into a plain <select>, so this filters by substring match
   as the admin types instead. Same floating-panel visual language as .status-filter-panel above. */
.autocomplete-list {
  display: none; position: absolute; top: 100%; left: 0; right: 0; z-index: 50; margin-top: 4px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 4px; box-shadow: var(--shadow-lg); max-height: 220px; overflow-y: auto;
}
.autocomplete-list.open { display: block; }
.autocomplete-item { padding: 6px 10px; border-radius: 6px; font-size: 13px; cursor: pointer; }
.autocomplete-item:hover { background: var(--surface); }

/* Recording-time / Publication-time range filters: compact labeled date pairs. */
.filter-daterange { display: flex; flex-direction: column; gap: 2px; }
.filter-daterange-lbl { font-size: 10px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; }
.filter-daterange input[type="date"] { min-width: 132px; }

/* Recording/Publication date-range filters, visually grouped apart from the dropdown/checkbox
   filters above them (item 4 — previously these 4 date inputs sat inline in the same row as
   Month/Eco/Status/Interviewer/Search, hard to tell apart at a glance). .filter-daterange-row
   forces onto its own line below the rest of .filter-bar's flex-wrap row (flex-basis:100%);
   each .filter-daterange-group is a small bordered/tinted card with its own heading so "these
   are date ranges" reads instantly, distinct from the plain filter controls above. */
.filter-daterange-row { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 12px; margin-top: 2px; }
.filter-daterange-group {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: 10px;
  padding: 10px 14px;
}
.filter-daterange-group-title { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-dim); }
.filter-daterange-group-fields { display: flex; gap: 14px; flex-wrap: wrap; }

/* Status filter popover trigger: styled to match the plain <select> filters sitting next to it
   in the filter bar (same height/padding/border/radius/font-size as the global input/select
   rule below) rather than reading as a visually distinct button — only the manual chevron svg
   gives away that it opens a popover instead of a native dropdown. */
.status-filter-btn {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 10px;
  min-width: 150px;
  background: var(--bg-soft); border: 1px solid var(--border); color: var(--text);
  padding: 10px 12px; border-radius: 9px; font-size: 13.5px; font-weight: 400;
  font-family: inherit; cursor: pointer; transition: border-color .15s ease;
}
.status-filter-btn:hover { border-color: var(--orange); }
.status-filter-btn svg { flex-shrink: 0; opacity: .7; }

/* Pipeline table: dedicated class (item 6 design pass) for column alignment/width tweaks and
   roomier cell padding than the base <table> rule — the multi-line Recording Time/Publication
   cells and stacked icon-button groups (Pre-brief / row actions) read as crowded ("amontonado")
   at the base compact padding. Scoped to this table only — X-Clips/Buzzsprout/Users keep the
   base <table> padding untouched. */
/* Trimmed from 13px/15px, 1.5 line-height — at real 100% browser zoom the table read as
   noticeably heavier/roomier than the calendar (which runs at a deliberate 80% zoom, see
   .cal-grid), an awkward mismatch between the two main pages. This keeps rows readable but
   closer in visual weight to the rest of the app. */
.table-pipeline td, .table-pipeline th { padding: 10px 13px; }
.table-pipeline td { line-height: 1.4; }
.table-pipeline .col-promoter { min-width: 108px; }
/* Recording Time/Publication cells now hold a short US-format date+time string ("09/08/26,
   11:30 ET") instead of the old verbose one ("Tuesday, Sep 8th, 2026 - 11:30 ET") — shrunk from
   168px down to fit that, so the column stops reserving width the shorter text never uses.
   white-space:nowrap still keeps each date on one line; .table-wrap already scrolls horizontally
   (same as every other wide table in this app) so a wider row never breaks the layout. */
.table-pipeline .col-recording, .table-pipeline .col-publication { min-width: 118px; white-space: nowrap; }
/* Subtle divider marking where the data columns end and the icon-only action columns
   (Comment / Post Info / row-actions) begin. */
.table-pipeline .col-icons-start { padding-left: 18px; }

/* Pre-brief column: up to 4 stacked icon-buttons (download/preview/copy-link/replace) with no
   wrapping container before — plain adjacent <button>s whose spacing depended on incidental
   HTML whitespace. This gives them the same deliberate flex/gap treatment as .row-actions. */
.prebrief-icons { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ---------- Tabs ---------- */
.tabbar { display: flex; gap: 4px; background: var(--surface); border: 1px solid var(--border-soft); border-radius: 11px; padding: 4px; width: fit-content; margin-bottom: 18px; }
.tabbar a { padding: 8px 16px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--text-muted); }
.tabbar a.active { background: var(--grad-brand); color: #241300; }
.tabbar a:hover:not(.active) { color: var(--text); }

/* ---------- Modal ---------- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(5,4,3,.75);
  backdrop-filter: blur(3px);
  display: none; align-items: flex-start; justify-content: center;
  padding: 40px 16px; overflow-y: auto; z-index: 100;
}
.modal-backdrop.open { display: flex; }
.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  width: 100%; max-width: 640px;
  padding: 24px;
  box-shadow: var(--shadow-lg);
  animation: modalIn .18s ease;
}
.modal.wide { max-width: 820px; }
.prebrief-preview-frame { width: 100%; height: 70vh; border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2); }
@keyframes modalIn { from { opacity:0; transform: translateY(10px);} to {opacity:1; transform:none;} }
.modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.modal-head h3 { margin: 0; font-size: 16.5px; }
.modal-close { cursor: pointer; color: var(--text-muted); background: none; border: none; font-size: 20px; line-height: 1; }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }

/* ---------- Login ---------- */
.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 20px;
  background: radial-gradient(900px 500px at 50% -10%, rgba(232,130,60,.12), transparent 60%), var(--bg);
}
.login-card {
  width: 100%; max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 20px;
  padding: 36px 32px;
  box-shadow: var(--shadow-lg);
}
.login-logo { display: flex; flex-direction: column; align-items: center; gap: 12px; margin-bottom: 24px; }
.login-error {
  background: rgba(255,92,122,.1); border: 1px solid rgba(255,92,122,.3);
  color: #ff9fb2; padding: 10px 14px; border-radius: 10px; font-size: 13px; margin-bottom: 16px;
}
.login-success {
  background: rgba(47,191,113,.1); border: 1px solid rgba(47,191,113,.3);
  color: #7fe3ac; padding: 10px 14px; border-radius: 10px; font-size: 13px; margin-bottom: 16px;
}
.login-hint { text-align: center; color: var(--text-dim); font-size: 11.5px; margin-top: 18px; line-height: 1.6; }
.login-link { color: var(--orange); font-weight: 600; }
.login-link:hover { text-decoration: underline; }

/* ---------- Empty state ---------- */
.empty-state { text-align: center; padding: 40px 20px; color: var(--text-muted); }
.empty-state svg { width: 40px; height: 40px; margin-bottom: 12px; opacity: .5; }

/* ---------- Calendar ---------- */
/* 3-month window (previous / current / next): each month card is now full viewport width,
   with the 3 cards laid out in a horizontally-scrollable, swipe/scroll-snapping strip — the
   previous 3-up grid (three 7-col mini-calendars sharing one row) read as too cramped to
   actually work with (per user feedback). scroll-snap-type + each card's scroll-snap-align
   gives a clean "one full month at a time" swipe/scroll feel; the prev/next month-window nav
   arrows above still shift which 3 months are rendered server-side exactly as before — this is
   purely a layout change to how those 3 already-rendered cards are arranged. initCalScrollSnap()
   in the <script> block below scrolls the center (current) month into view on load so the admin
   always lands on "this month" first, with the previous/next month a swipe away either side. */
.cal-3month {
  display: flex; gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: 6px;
}
.cal-month-card { display: flex; flex-direction: column; gap: 10px; flex: 0 0 100%; min-width: 100%; scroll-snap-align: start; scroll-snap-stop: always; }
.cal-month-card.is-center .cal-month-title { color: var(--orange); }
.cal-month-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px; }
.cal-month-title { font-size: 14px; font-weight: 800; font-family: 'Space Grotesk', sans-serif; }
.cal-legend-sm { font-size: 10px; gap: 10px; }

/* Calendar header: month-nav on the left, filter dropdowns (Eco/Interviewer/Phase) on the
   right — replaces the old row that also carried a standalone Madrid clock + always-on phase
   legend, both removed (Madrid time now shows per-event on the relevant chips instead, and
   phase is a real filter below rather than just a color key). */
.cal-filter-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 14px; margin-bottom: 18px; }
.cal-nav { display: flex; align-items: center; gap: 12px; }
/* The 3 filter controls (Eco/Interviewer/Phase) were stacking one per line instead of sitting
   in a row — the global `select { width: 100% }` rule (assets/css/style.css) meant each one
   tried to fill the entire flex container by itself, so 3 of them could never fit side by
   side. Pinning width:auto + a shared min-width here is the same fix pipeline.php's own
   .filter-bar already applies to its selects, now mirrored for the calendar's filter row. */
.cal-filter-form { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.cal-filter-form select { width: auto; min-width: 170px; }
.cal-filter-form .status-filter-dropdown, .cal-filter-form .status-filter-btn { min-width: 170px; }

/* grid-auto-rows: 1fr previously forced EVERY row to the same height — because same-fr-factor
   tracks share leftover space equally, one busy row (2 recording chips) was inflating every
   other row in the month to match it, including the near-empty lead-in row before day 1. That
   produced a huge blank gap up top and pushed the whole grid taller than the viewport, forcing
   a page scroll. `auto` lets each row size to its own content instead. Zoom eased up from an
   earlier 0.8 to 0.95 — at 0.8 the (now longer, 4-6 line) chips read too small/cramped; a
   busy month may need a bit of page scroll now, which reads better than everything shrunk. */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); grid-auto-rows: auto; gap: 4px; zoom: 0.95; }
.cal-dow { text-align: center; font-size: 13px; font-weight: 700; color: var(--text-dim); text-transform: uppercase; letter-spacing: .06em; padding-bottom: 2px; }
.cal-cell {
  min-height: 86px; background: var(--bg-soft); border: 1px solid var(--border-soft);
  border-radius: 6px; padding: 4px; display: flex; flex-direction: column; gap: 2px;
  transition: border-color .15s ease;
}
.cal-cell:hover { border-color: var(--border); }
.cal-cell.empty { background: transparent; border: none; }
.cal-cell.today { border-color: var(--orange); box-shadow: 0 0 0 1px var(--orange) inset; }
.cal-daynum { font-size: 13px; color: var(--text-dim); font-weight: 700; }
.cal-cell.today .cal-daynum { color: var(--orange); }
.cal-chip {
  font-size: 12px; font-weight: 700; padding: 4px 5px; border-radius: 4px;
  line-height: 1.3; cursor: default; word-break: break-word;
  display: flex; flex-direction: column; gap: 1px;
  background: rgba(255,255,255,.06); border-left: 2px solid var(--border);
}
.cal-chip .chip-eco { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; opacity: .85; }
.rec-eco-label { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; opacity: .85; }
/* Ecosystem now paints the WHOLE chip background (not just the label text) — purple for Solana,
   a soft/pale sky-blue for Non Solana — per admin request, so the ecosystem reads at a glance
   without having to find and parse the small label. The phase/status color stays on the left
   border + the small badge inside (see .rec-status-badge below, reusing pipeline.php's exact
   .pill-<slug> colors) so status is still a separate, equally legible signal from ecosystem. */
.cal-chip.eco-solana { background: rgba(153,69,255,.32); }
.cal-chip.eco-nonsolana { background: rgba(120,200,255,.20); }
/* Recording chips sit in the same cell as publication chips — solid left border colored per
   pipeline_events.status (see $statusColors in calendar.php, reusing the same hues as the
   pill-* classes on pipeline.php/dashboard.php app-wide). Every recording chip is clickable
   (jumps to Pipeline filtered to this event) and shows: ecosystem, a colored phase badge, then
   Guest name/Company/Interviewer/Schedule record time as their own labeled lines — same layout
   render_pub_chip() uses for publication chips, so both chip types read consistently. */
.cal-chip.recording { border-left-style: solid; gap: 1px; padding: 4px 6px; cursor: pointer; }
.cal-chip.recording:hover { filter: brightness(1.1); }
:root[data-theme="light"] .cal-chip { background: rgba(0,0,0,.045); }
/* Light theme needs its own (higher-alpha) eco tints — placed after the light .cal-chip rule
   above and matching its specificity via the data-theme attribute, so it reliably wins over it
   in the cascade; the plain rgba purple/blue above would otherwise read too faint on a cream
   background at the same alpha that works on a dark one. */
:root[data-theme="light"] .cal-chip.eco-solana { background: rgba(153,69,255,.22); }
:root[data-theme="light"] .cal-chip.eco-nonsolana { background: rgba(70,170,235,.24); }
/* Status badge reuses the exact .pill-<slug> classes from pipeline.php (assets/css/style.css's
   single-source-of-truth status palette) instead of a one-off inline color — that's what keeps
   this badge a real status GREEN (or whatever hue) instead of reading as a washed-out grey. A
   1px border in the badge's own text color (currentColor) outlines its shape distinctly, so
   Published/Publish Scheduled/etc. stay clearly told apart now that the chip's own background
   is colored by ecosystem rather than status. */
.cal-chip .rec-status-badge {
  align-self: flex-start; max-width: 100%; font-size: 10px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .01em; padding: 1px 5px; border-radius: 3px; line-height: 1.6;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  border: 1px solid currentColor;
}
/* Eco+badge, then Guest+Company, then Interviewer+Schedule time — each PAIR packed onto its own
   flex row (wrapping only if it doesn't fit) instead of 4-6 fully separate stacked lines. Cuts
   a chip's vertical footprint roughly in half at the same font size, so more of the month fits
   on screen without shrinking text again. */
.cal-chip .chip-top-row { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
/* Guest and company each get their own row now (never sharing one with wrap-dependent line
   breaks — a short guest+company pair used to end up on a single line while a long pair wrapped
   onto two, reading as inconsistent). Guest stays italic/regular weight, company is always bold,
   so the two are tellable apart at a glance even without their labels. */
.cal-chip .chip-fields-row { display: flex; flex-wrap: wrap; gap: 0 8px; }
.cal-chip .chip-field { font-size: 10px; line-height: 1.4; font-weight: 500; word-break: break-word; }
.cal-chip .chip-field-lbl { font-weight: 800; opacity: .7; margin-right: 2px; }
.cal-chip .chip-field-guest .chip-field-val { font-style: italic; font-weight: 500; }
.cal-chip .chip-field-company .chip-field-val { font-weight: 800; }
.cal-add { align-self: flex-end; opacity: 0; font-size: 9px; color: var(--text-dim); cursor: pointer; }
.cal-cell:hover .cal-add { opacity: 1; }
.cal-legend { display: flex; gap: 16px; align-items: center; font-size: 12px; color: var(--text-muted); flex-wrap: wrap; }
.cal-legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend-dot { width: 9px; height: 9px; border-radius: 3px; }

/* Mobile day-list view: hidden on desktop, replaces the 7-col grid on small screens. */
.cal-list { display: none; flex-direction: column; gap: 8px; }
.cal-list-day {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--bg-soft); border: 1px solid var(--border-soft);
  border-radius: 10px; padding: 10px 12px;
}
.cal-list-day.today { border-color: var(--orange); box-shadow: 0 0 0 1px var(--orange) inset; }
.cal-list-daynum { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; width: 40px; }
.cal-list-daynum .n { font-size: 18px; font-weight: 800; font-family: 'Space Grotesk', sans-serif; }
.cal-list-day.today .cal-list-daynum .n { color: var(--orange); }
.cal-list-daynum .dow { font-size: 9.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; }
.cal-list-chips { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
.cal-list-chips .cal-chip { font-size: 12px; padding: 6px 9px; }
.cal-list-chips .cal-chip .rec-status-badge { font-size: 9.5px; padding: 1px 6px; }
.cal-list-chips .cal-chip .chip-field { font-size: 11px; }

@media (max-width: 640px) {
  .cal-grid { display: none; }
  .cal-list { display: flex; }
}

/* ---------- Prompts ---------- */
.prompt-card { display: flex; flex-direction: column; gap: 0; padding: 0; overflow: hidden; }
.prompt-card .prompt-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 18px; background: var(--surface-2); border-bottom: 1px solid var(--border-soft);
}
.prompt-card .prompt-head-title { display: flex; align-items: center; gap: 10px; min-width: 0; }
.prompt-icon {
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0;
  background: rgba(232,130,60,.15); color: var(--orange);
  display: flex; align-items: center; justify-content: center;
}
.prompt-icon svg { width: 15px; height: 15px; }
.prompt-title { font-weight: 700; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.prompt-actions { display: flex; gap: 6px; flex-shrink: 0; }
.prompt-body {
  padding: 16px 18px; white-space: pre-wrap; word-break: break-word;
  font-size: 13px; line-height: 1.6; color: var(--text-muted);
  max-height: 130px; overflow: hidden; position: relative;
  transition: max-height .25s ease;
}
.prompt-body.expanded { max-height: 2000px; }
.prompt-body:not(.expanded)::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 46px;
  background: linear-gradient(180deg, transparent, var(--surface) 85%);
}
.prompt-body mark {
  background: rgba(232,130,60,.22); color: var(--orange); border-radius: 4px;
  padding: 0 3px; font-weight: 600; font-family: inherit;
}
.prompt-toggle {
  display: block; width: 100%; text-align: center; padding: 9px;
  font-size: 12px; font-weight: 700; color: var(--orange);
  background: var(--surface-2); border-top: 1px solid var(--border-soft);
  cursor: pointer;
}
.prompt-toggle:hover { background: var(--surface); }

.toast {
  position: fixed; bottom: 24px; right: 24px; z-index: 200;
  background: var(--surface); border: 1px solid var(--green); color: var(--text);
  padding: 12px 18px; border-radius: 10px; box-shadow: var(--shadow-lg);
  font-size: 13.5px; font-weight: 600; display: none;
}
.toast.show { display: block; animation: toastIn .2s ease; }
.toast.error { border-color: var(--red); }
@keyframes toastIn { from { opacity:0; transform: translateY(8px);} to {opacity:1; transform:none;} }

.badge-role {
  font-size: 10px; text-transform: uppercase; letter-spacing: .08em; font-weight: 800;
  padding: 2px 8px; border-radius: 6px; background: var(--grad-gold); color: #241500;
}
.readonly-note {
  font-size: 12px; color: var(--text-dim); background: var(--bg-soft);
  border: 1px dashed var(--border); padding: 7px 12px; border-radius: 9px;
  display: inline-flex; align-items: center; gap: 8px; margin-bottom: 14px;
}

/* ---------- Chart legend (HTML, not canvas) ---------- */
.chart-legend { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.chart-legend-row { display: flex; align-items: center; gap: 8px; font-size: 11.5px; }
.chart-legend-row .sw { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.chart-legend-row .lbl { color: var(--text-muted); flex: 1; }
.chart-legend-row .val { font-weight: 700; font-family: 'Space Grotesk', sans-serif; }

/* ---------------- Tasks (tasks.php): private admin task log, spreadsheet-style ---------------- */
.tk-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 12px; }
.tk-seg { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; }
.tk-seg-btn { border: 0; background: transparent; color: var(--text-muted); padding: 5px 13px; font-size: 12px; font-weight: 600; cursor: pointer; font-family: inherit; }
.tk-seg-btn:hover { color: var(--text); }
.tk-seg-btn.active { background: var(--orange); color: #fff; }
.tk-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.tk-chip { border: 1px solid var(--border); background: transparent; color: var(--text-muted); border-radius: 999px; padding: 4px 12px; font-size: 12px; font-weight: 600; cursor: pointer; font-family: inherit; }
.tk-chip:hover { color: var(--text); border-color: var(--orange); }
.tk-chip.active { background: var(--orange); border-color: var(--orange); color: #fff; }
.tk-alert { border-radius: 999px; padding: 4px 11px; font-size: 12px; font-weight: 700; }
.tk-alert[hidden], #tkClearDone[hidden] { display: none; }
.tk-alert-overdue { background: rgba(255,92,122,.16); color: var(--red); }
.tk-alert-today { background: rgba(232,130,60,.18); color: #d98a00; }
.tk-search { margin-left: auto; max-width: 240px; min-width: 150px; }

table.tk-table { min-width: 940px; table-layout: fixed; }
.tk-table td { padding: 3px 5px; border-bottom: 1px solid var(--border-soft); vertical-align: middle; }
.tk-table thead th { padding: 8px 8px; }
.tk-c-check { width: 38px; text-align: center; }
.tk-c-del { width: 72px; text-align: center; }
.tk-c-date { width: 128px; } .tk-c-cat { width: 116px; }
.tk-c-st { width: 118px; } .tk-c-photo { width: 84px; text-align: center; }
/* Cells look like a plain table until focused, then like an input — click anywhere to edit. */
.tk-table input, .tk-table select { width: 100%; border: 1px solid transparent; background: transparent; padding: 6px 7px; font-size: 12.5px; border-radius: 7px; color: var(--text); font-family: inherit; min-width: 0; }
.tk-table input:hover, .tk-table select:hover { border-color: var(--border); }
.tk-table input:focus, .tk-table select:focus { border-color: var(--orange); background: var(--bg-soft); outline: none; }
.tk-table input::placeholder { color: var(--text-dim); }
.tk-new td { background: var(--surface-2); border-bottom: 2px solid var(--border); }
.tk-new input, .tk-new select { border-color: var(--border); background: var(--bg-soft); }
.tk-plus { color: var(--orange); font-weight: 800; font-size: 18px; line-height: 1; }
.tk-act { font-weight: 600; }
/* Status / ecosystem selects read as colored pills, like the spreadsheet this replaces. */
.tk-sel { font-weight: 700; text-align: center; cursor: pointer; }
.tk-sel[data-v="Pending"] { background: rgba(255,92,122,.16); color: var(--red); }
.tk-sel[data-v="In progress"] { background: rgba(153,69,255,.16); color: var(--purple); }
.tk-sel[data-v="Done"] { background: rgba(47,191,113,.18); color: var(--green); }
.tk-sel option { background: var(--surface); color: var(--text); font-weight: 500; }
.tk-check { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--text-dim); background: transparent; color: transparent; cursor: pointer; display: inline-grid; place-items: center; padding: 0; }
.tk-check svg { width: 12px; height: 12px; }
.tk-check:hover { border-color: var(--green); color: var(--green); }
/* Deadline reached: the whole row turns red (amber when it's due today) until it's marked Done. */
.tk-tr.is-overdue td { background: rgba(255,92,122,.12); }
.tk-tr.is-overdue .tk-due, .tk-tr.is-overdue .tk-act { color: var(--red); }
.tk-tr.is-overdue .tk-due { font-weight: 800; }
.tk-tr.is-overdue .tk-check { border-color: var(--red); }
.tk-tr.is-today td { background: rgba(232,130,60,.12); }
.tk-tr.is-today .tk-due { color: #d98a00; font-weight: 800; }
.tk-tr.is-done .tk-check { background: var(--green); border-color: var(--green); color: #fff; }
.tk-tr.is-done .tk-act { text-decoration: line-through; color: var(--text-dim); }
.tk-tr.is-done input:not(.tk-act) { color: var(--text-dim); }
/* Native datalist arrow removed from the Tasks cells — suggestions still appear while typing. */
.tk-table input[list]::-webkit-calendar-picker-indicator,
.tk-table input[list]::-webkit-list-button { display: none !important; opacity: 0; }
/* Task photo: camera button when empty, orange image button (opens the viewer) when there is one. */
.tk-photo-cell { display: flex; justify-content: center; align-items: center; gap: 6px; }
.icon-btn.tk-photo-on { color: var(--orange); border-color: var(--orange); background: rgba(232,130,60,.12); }
.tk-uploading { opacity: .5; pointer-events: none; }
.tk-img-modal { width: min(920px, 94vw); max-width: none; }
.tk-img { display: block; max-width: 100%; max-height: 68vh; margin: 4px auto 12px; border-radius: 10px; object-fit: contain; }
.tk-img-modal .modal-foot { flex-wrap: wrap; }
.tk-danger:hover { color: var(--red); border-color: var(--red); }

/* Pipeline: dedicated Pre-brief column + advance banner inside the edit modal */
.prebrief-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 600; text-decoration: none; white-space: nowrap;
  color: var(--orange); border: 1px solid var(--orange); background: rgba(232,130,60,.12);
  transition: all .15s ease;
}
.prebrief-btn svg { width: 14px; height: 14px; }
a.prebrief-btn:hover { background: var(--orange); color: #fff; }
.prebrief-btn.is-empty { color: var(--text-muted); border-color: var(--border-soft); background: transparent; font-weight: 500; }
.icon-btn.is-on { color: var(--orange); border-color: var(--orange); background: rgba(232,130,60,.12); }
.advance-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  margin: 0 0 16px; padding: 12px 16px; border-radius: 12px;
  border: 1px solid var(--orange); background: linear-gradient(90deg, rgba(232,130,60,.18), rgba(232,130,60,.05));
}
.advance-banner-text { display: flex; flex-direction: column; gap: 2px; }
.advance-banner-kicker { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.advance-banner-btn { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; box-shadow: 0 4px 14px rgba(232,130,60,.35); }
.advance-banner-btn svg { width: 16px; height: 16px; }
