/* Post Pipeline — Monday.com-flavoured dark theme.
   Style sheet derived from the reference board screenshots: near-black canvas,
   solid-colour status cells, pill chips, swimlane Gantt with a "today" line. */

:root {
  --bg:        #0e0f13;
  --bg-2:      #14161c;
  --surface:   #181a21;
  --surface-2: #1e212a;
  --surface-3: #252934;
  --row:       #181a21;
  --row-alt:   #1b1e26;
  --hover:     #232733;
  --border:    rgba(255,255,255,.075);
  --border-2:  rgba(255,255,255,.13);
  --text:      #e7e9f0;
  --text-2:    #aeb2c0;
  --text-3:    #777c8c;
  --accent:    #5b6cff;
  --accent-2:  #3547d6;
  --ink-dark:  #11131a;

  --st-not_started: #c4c4c4;
  --st-ready:       #5fb0f0;
  --st-in_progress: #fdab3d;
  --st-review:      #a25ddc;
  --st-approved:    #00c875;
  --danger:         #ff5b6e;

  --radius: 10px;
  --radius-sm: 7px;
  --shadow: 0 12px 34px rgba(0,0,0,.46);
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* Structural knobs, only consumed by [data-skin="expressive"] themes. The
     defaults mirror today's look so the six plain palettes are untouched. */
  --r-card: 10px;                 /* panels, cards, popovers, modals   */
  --r-ctl: 8px;                   /* buttons, inputs, selects, chips   */
  --r-bar: 5px;                   /* timeline bars & status cells      */
  --ring: 1px;                    /* border weight on cards/controls   */
  --ring-color: var(--border);
  --lift: var(--shadow);          /* card elevation                    */
  --page-art: none;               /* optional gradient over the canvas */
  --card-blur: none;              /* glass themes set a blur           */

  /* Icon drawing (js/icons.js). One line set, re-weighted per theme — this is
     what lets the same glyph feel native in Wireframe and in Bookshop. */
  --icon-stroke: 1.7;
  --icon-cap: round;
  --icon-join: round;
}

/* ----------------------------------------------------------------- themes
   Each theme re-declares the palette above; nothing else in the sheet needs
   to know which one is active. Set from the preferences menu, which writes
   data-theme onto <html> (see App.applyTheme). "midnight" is the default
   declared in :root, so it needs no block of its own. */
:root[data-theme="graphite"] {
  --bg: #131314; --bg-2: #191a1b; --surface: #1f2021; --surface-2: #26282a; --surface-3: #303234;
  --row: #1f2021; --row-alt: #232527; --hover: #2e3134;
  --border: rgba(255,255,255,.07); --border-2: rgba(255,255,255,.13);
  --text: #eceef0; --text-2: #b2b6bb; --text-3: #7c8288;
  --accent: #2fbf9f; --accent-2: #1f9c80;
}
:root[data-theme="nord"] {
  --bg: #242933; --bg-2: #2e3440; --surface: #333a48; --surface-2: #3b4252; --surface-3: #434c5e;
  --row: #333a48; --row-alt: #39404f; --hover: #4c566a;
  --border: rgba(255,255,255,.08); --border-2: rgba(255,255,255,.15);
  --text: #eceff4; --text-2: #d8dee9; --text-3: #97a1b4;
  --accent: #5e81ac; --accent-2: #4c6f96;
}
:root[data-theme="indigo"] {
  --bg: #0f0d1a; --bg-2: #171327; --surface: #1d1830; --surface-2: #251f3c; --surface-3: #2f2749;
  --row: #1d1830; --row-alt: #211b35; --hover: #332a52;
  --border: rgba(255,255,255,.08); --border-2: rgba(255,255,255,.15);
  --text: #ece9f7; --text-2: #b3adcb; --text-3: #7f7899;
  --accent: #8b5cf6; --accent-2: #6d38e0;
}
:root[data-theme="forest"] {
  --bg: #0c1310; --bg-2: #111a16; --surface: #16211c; --surface-2: #1c2a23; --surface-3: #24352c;
  --row: #16211c; --row-alt: #1a2620; --hover: #26382f;
  --border: rgba(255,255,255,.07); --border-2: rgba(255,255,255,.14);
  --text: #e6efe9; --text-2: #a9bdb1; --text-3: #74897e;
  --accent: #d9a441; --accent-2: #b8862c;
}
:root[data-theme="daylight"] {
  --bg: #f4f6fa; --bg-2: #ffffff; --surface: #ffffff; --surface-2: #f1f4f9; --surface-3: #e5eaf2;
  --row: #ffffff; --row-alt: #f7f9fc; --hover: #e9eef6;
  --border: rgba(16,24,40,.10); --border-2: rgba(16,24,40,.18);
  --text: #171a21; --text-2: #4a5164; --text-3: #79808f;
  --accent: #4f5bd5; --accent-2: #3a45b0;
  --shadow: 0 12px 34px rgba(16,24,40,.14);
}
/* the timeline's weekend/zebra shading is a white wash tuned for a dark
   canvas — invert it for every light theme (data-mode, not a theme name) */
:root[data-mode="light"] .grid-col.weekend,
:root[data-mode="light"] .thead-cell.secondary.weekend { background: rgba(16,24,40,.045); }
:root[data-mode="light"] .g-row.sub { background: rgba(16,24,40,.035); }
:root[data-mode="light"] .pn-row { background: rgba(16,24,40,.02); }
/* background-color only — the base rule's transparent border + content-box
   clip is what gives the thumb its inset, and the shorthand would reset it */
:root[data-mode="light"] ::-webkit-scrollbar-thumb { background-color: #c3ccdb; }
:root[data-mode="light"] ::-webkit-scrollbar-thumb:hover { background-color: #a8b4c8; }

/* ------------------------------------------------- expressive skins ------
   These five go further than a palette: they also set the typeface, corner
   radii, border weight and card elevation, which the [data-skin="expressive"]
   block below applies. None of them touch --st-* — status colour coding is
   identical in every theme (see App.THEMES). */
:root[data-theme="moppets"] {              /* Playful — cream on teal */
  --bg: #89c7b6; --bg-2: #fdf6e3; --surface: #fdf6e3; --surface-2: #f7ecd2; --surface-3: #f0cd9a;
  --row: #fdf6e3; --row-alt: #faf1dd; --hover: #f5e6c8;
  --border: rgba(74,74,74,.14); --border-2: rgba(74,74,74,.24);
  --text: #4a4a4a; --text-2: #6b6660; --text-3: #948d84;
  --accent: #e78c45; --accent-2: #d67a33; --accent-ink: #fff;
  --font: 'Nunito', system-ui, sans-serif;
  --r-card: 18px; --r-ctl: 999px; --r-bar: 999px;
  --lift: 0 6px 22px rgba(74,74,74,.13);
}
:root[data-theme="cardio"] {               /* Tech — charcoal + lime, very round */
  --bg: #1a1a1a; --bg-2: #262626; --surface: #2f2f2f; --surface-2: #383838; --surface-3: #434343;
  --row: #2f2f2f; --row-alt: #343434; --hover: #454545;
  --border: rgba(255,255,255,.09); --border-2: rgba(255,255,255,.17);
  --text: #f2f2ee; --text-2: #bdbdb6; --text-3: #8a8a84;
  --accent: #d9e112; --accent-2: #b8bf10; --accent-ink: #1a1a1a;
  --font: 'Space Grotesk', system-ui, sans-serif;
  --r-card: 26px; --r-ctl: 999px; --r-bar: 999px;
  --lift: 0 8px 30px rgba(0,0,0,.5);
}
:root[data-theme="bookshop"] {             /* Bookshop — pastel glass, serif */
  --bg: #ece7f7; --bg-2: #f6f3fd; --surface: #f7f4fd; --surface-2: #efeaf9; --surface-3: #e3ddf3;
  --row: #f7f4fd; --row-alt: #f2eefb; --hover: #e7e1f6;
  --border: rgba(44,46,93,.12); --border-2: rgba(255,255,255,.75);
  --text: #2c2e5d; --text-2: #5b5e91; --text-3: #8a8db8;
  --accent: #2c2e5d; --accent-2: #3d407a; --accent-ink: #fff;
  --font: 'Spectral', Georgia, serif;
  --r-card: 22px; --r-ctl: 13px; --r-bar: 9px;
  --lift: 0 8px 32px rgba(31,38,135,.10);
  --page-art: linear-gradient(135deg, #ffe3d4 0%, #e6e1f9 45%, #d4e5ff 100%);
  --card-bg: rgba(255,255,255,.62); --card-blur: blur(10px);
}
:root[data-theme="retro"] {                /* Wireframe — hard black rules, mono */
  --bg: #f2e8d5; --bg-2: #f7f0e2; --surface: #ffffff; --surface-2: #f7f0e2; --surface-3: #efe3cc;
  --row: #ffffff; --row-alt: #faf5ea; --hover: #ffe9a8;
  --border: #111111; --border-2: #111111;
  --text: #111111; --text-2: #3a3a3a; --text-3: #6f6f6f;
  --accent: #ff5c39; --accent-2: #e04a29; --accent-ink: #111111;
  --font: 'Space Mono', ui-monospace, Menlo, monospace;
  --r-card: 0px; --r-ctl: 0px; --r-bar: 0px;
  --ring: 2px; --ring-color: #111111;
  --lift: 4px 4px 0 #111111;
}
:root[data-theme="botanical"] {            /* Botanical — sage on soft green */
  --bg: #eaf3e0; --bg-2: #f2f6ed; --surface: #ffffff; --surface-2: #f2f6ed; --surface-3: #e5ecd9;
  --row: #ffffff; --row-alt: #f7faf4; --hover: #e5ecd9;
  --border: rgba(51,77,53,.13); --border-2: rgba(51,77,53,.24);
  --text: #334d35; --text-2: #4f6b51; --text-3: #7d9280;
  --accent: #6a946d; --accent-2: #567a58; --accent-ink: #fff;
  --font: 'Nunito', system-ui, sans-serif;
  --r-card: 16px; --r-ctl: 10px; --r-bar: 8px;
  --lift: 0 4px 24px rgba(152,172,116,.20);
}

/* ---- the structural layer: only expressive themes opt in ----
   Everything here reads the vars above, so adding a sixth skin is a palette
   block and nothing more. Deliberately NOT restyled: .status-cell (status
   coding stays pixel-identical), and anything that must stay a circle
   (avatars, dots, switches, swatches). */
:root[data-skin="expressive"] body { background-image: var(--page-art); background-attachment: fixed; }

/* cards, panels, popovers */
:root[data-skin="expressive"] .gantt,
:root[data-skin="expressive"] .ep-group,
:root[data-skin="expressive"] .widget,
:root[data-skin="expressive"] .show-manager,
:root[data-skin="expressive"] .adm-add,
:root[data-skin="expressive"] .adm-permcard,
:root[data-skin="expressive"] .adm-card,
:root[data-skin="expressive"] .adm-table,
:root[data-skin="expressive"] .modal-card,
:root[data-skin="expressive"] .prefs-pop,
:root[data-skin="expressive"] .pn-editor,
:root[data-skin="expressive"] .status-pop,
:root[data-skin="expressive"] .dep-menu,
:root[data-skin="expressive"] .login-card,
:root[data-skin="expressive"] .kpi {
  border-radius: var(--r-card);
  border-width: var(--ring);
  border-style: solid;
  border-color: var(--ring-color);
  box-shadow: var(--lift);
}
/* Glass only where it can't hurt legibility: the big content surfaces. Modals,
   popovers and the sticky timeline rails stay fully opaque — a translucent
   sticky rail would let the bars underneath bleed through it. */
:root[data-skin="expressive"] .widget,
:root[data-skin="expressive"] .adm-permcard,
:root[data-skin="expressive"] .adm-card,
:root[data-skin="expressive"] .adm-table,
:root[data-skin="expressive"] .kpi,
:root[data-skin="expressive"] .show-manager {
  background-color: var(--card-bg, var(--surface));
  -webkit-backdrop-filter: var(--card-blur);
  backdrop-filter: var(--card-blur);
}
/* the timeline/board bodies scroll inside their card, so keep the clip */
:root[data-skin="expressive"] .gantt,
:root[data-skin="expressive"] .ep-group,
:root[data-skin="expressive"] .widget { overflow: hidden; }

/* controls */
:root[data-skin="expressive"] .btn-primary,
:root[data-skin="expressive"] .btn-ghost,
:root[data-skin="expressive"] .btn-danger,
:root[data-skin="expressive"] .adm-btn,
:root[data-skin="expressive"] .btn-addshow,
:root[data-skin="expressive"] .prefs-btn,
:root[data-skin="expressive"] .prefs-select,
:root[data-skin="expressive"] .prefs-seg,
:root[data-skin="expressive"] .prefs-seg .seg,
:root[data-skin="expressive"] .fld,
:root[data-skin="expressive"] .filter,
:root[data-skin="expressive"] .adm-search,
:root[data-skin="expressive"] .login-input,
:root[data-skin="expressive"] #search,
:root[data-skin="expressive"] .view-tab,
:root[data-skin="expressive"] .role-dd,
:root[data-skin="expressive"] .ghost { border-radius: var(--r-ctl); }

/* chips & pills */
:root[data-skin="expressive"] .dept-chip,
:root[data-skin="expressive"] .stage-chip,
:root[data-skin="expressive"] .ep-code,
:root[data-skin="expressive"] .dep-chip,
:root[data-skin="expressive"] .dep-tag,
:root[data-skin="expressive"] .adm-role-chip { border-radius: var(--r-ctl); }

/* timeline bars & producer notes (status cells intentionally excluded) */
:root[data-skin="expressive"] .bar,
:root[data-skin="expressive"] .phase-bar,
:root[data-skin="expressive"] .pn-note { border-radius: var(--r-bar); }

/* accent-filled controls need theme-aware ink — lime-on-white is unreadable */
:root[data-skin="expressive"] .btn-primary,
:root[data-skin="expressive"] .btn-addshow,
:root[data-skin="expressive"] .adm-btn.primary,
:root[data-skin="expressive"] .prefs-seg .seg.active,
:root[data-skin="expressive"] .pn-done,
:root[data-skin="expressive"] .view-tab.active { color: var(--accent-ink, #fff); }

/* Wireframe: buttons get the same hard offset as the cards, and lose it when
   pressed so the click reads physically */
:root[data-theme="retro"] .btn-primary,
:root[data-theme="retro"] .btn-addshow,
:root[data-theme="retro"] .adm-btn,
:root[data-theme="retro"] .prefs-btn,
:root[data-theme="retro"] .view-tab.active {
  border: 2px solid #111; box-shadow: 3px 3px 0 #111;
}
:root[data-theme="retro"] .btn-primary:active,
:root[data-theme="retro"] .btn-addshow:active,
:root[data-theme="retro"] .adm-btn:active,
:root[data-theme="retro"] .prefs-btn:active { box-shadow: 0 0 0 #111; transform: translate(2px, 2px); }
/* mono is wide — let the timeline's label rail breathe */
:root[data-theme="retro"] .g-label .l-title { font-size: 10.5px; }

/* ---- icons ----
   .ico is an inline box the size of the surrounding text; the svg inside
   inherits colour via currentColor and its weight from the theme vars. */
.ico { display: inline-flex; align-items: center; justify-content: center; flex: none; line-height: 0; }
.ico-svg {
  stroke-width: var(--icon-stroke);
  stroke-linecap: var(--icon-cap);
  stroke-linejoin: var(--icon-join);
  overflow: visible;                     /* keeps thick Wireframe strokes from clipping */
}
/* Per-theme re-weighting. Equal-specificity selectors, so ORDER MATTERS:
   the light-mode baseline goes first and the named themes override it. */
:root[data-mode="light"]     { --icon-stroke: 1.8; }   /* hairlines wash out on light */
:root[data-theme="cardio"]   { --icon-stroke: 1.5; }
:root[data-theme="moppets"]  { --icon-stroke: 2; }
:root[data-theme="botanical"]{ --icon-stroke: 1.8; }
:root[data-theme="bookshop"] { --icon-stroke: 1.3; }   /* engraved, to suit the serif */
:root[data-theme="retro"]    { --icon-stroke: 2.2; --icon-cap: butt; --icon-join: miter; }

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
button { font-family: inherit; cursor: pointer; }
::selection { background: rgba(91,108,255,.35); }

/* scrollbars */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #333845; border-radius: 8px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: #475063; border: 3px solid transparent; background-clip: content-box; }

#app { display: flex; flex-direction: column; height: 100vh; }

/* ----------------------------------------------------------------- topbar */
#topbar {
  display: flex; align-items: center; gap: 18px;
  padding: 0 18px; height: 56px; flex: 0 0 auto;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border);
  z-index: 30;
}
.brand { display: flex; align-items: center; gap: 11px; }
/* the logo doubles as the preferences button — it morphs into a cog on hover */
.brand-logo {
  position: relative; width: 32px; height: 32px; border-radius: 9px; border: 0;
  display: grid; place-items: center; font-size: 17px; padding: 0; cursor: pointer;
  background: linear-gradient(135deg, #5b6cff, #9b5bff);
  box-shadow: 0 4px 14px rgba(91,108,255,.45);
}
.brand-logo .logo-film, .brand-logo .logo-cog {
  grid-area: 1 / 1; transition: opacity .18s ease, transform .25s ease; line-height: 1;
}
.brand-logo .logo-cog { opacity: 0; transform: rotate(-90deg) scale(.7); }
.brand-logo:hover .logo-film { opacity: 0; transform: scale(.7); }
.brand-logo:hover .logo-cog { opacity: 1; transform: rotate(0) scale(1); }

/* quick-preferences popover */
.prefs-pop {
  position: fixed; z-index: 950; width: 320px;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 12px;
  box-shadow: var(--shadow); padding: 6px; animation: pop-in .14s ease;
}
@keyframes pop-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.prefs-title {
  font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase;
  letter-spacing: .6px; padding: 7px 10px 5px;
}
.prefs-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 9px 10px; border-radius: 8px; cursor: pointer;
}
.prefs-row:hover { background: var(--hover); }
.prefs-row-title { font-size: 12.5px; font-weight: 600; white-space: nowrap; }
.prefs-seg { display: flex; gap: 3px; flex: none; background: var(--bg); border: 1px solid var(--border-2); border-radius: 8px; padding: 2px; }
.prefs-seg .seg {
  border: 0; background: transparent; color: var(--text-2); font-size: 11px; font-weight: 700;
  padding: 4px 10px; border-radius: 6px; transition: background .13s, color .13s;
}
.prefs-seg .seg:hover { color: var(--text); }
.prefs-seg .seg.active { background: var(--accent); color: #fff; }
/* controls that must wrap as a unit rather than being split across rows */
.toolbar-group { display: flex; align-items: center; gap: 8px; flex: none; }

/* the same segmented control, standing on its own in the toolbar rather than
   paired with a label inside the preferences popover */
.toolbar-seg { background: var(--bg-2); }
.toolbar-seg .seg { padding: 6px 11px; font-size: 11.5px; }
.prefs-actions { display: flex; gap: 6px; flex: none; }
.prefs-btn {
  border: 1px solid var(--border-2); background: var(--bg); color: var(--text-2);
  font-size: 11px; font-weight: 700; padding: 5px 10px; border-radius: 7px; cursor: pointer;
  transition: background .13s, color .13s, border-color .13s;
}
.prefs-btn:hover { background: var(--hover); color: var(--text); border-color: var(--accent); }
.prefs-note { font-size: 12px; color: var(--text-3); padding: 4px 10px 10px; }
/* a second section in the popover (Appearance) — ruled off from the rows above */
.prefs-title.sep { border-top: 1px solid var(--border); margin-top: 4px; padding-top: 10px; }
.prefs-select {
  flex: none; max-width: 160px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border-2); border-radius: 8px; padding: 5px 8px;
  font-size: 11.5px; font-weight: 700; font-family: inherit; cursor: pointer;
}
.prefs-select:hover { border-color: var(--accent); }
.prefs-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(91,108,255,.18); }

/* Create Project steps — a little wider than a confirm, and scrollable when a
   department has a long template list */
.modal-card.ws-step { max-width: 480px; }
.ws-step .modal-body { max-height: 56vh; overflow-y: auto; }

/* ---- per-subtask workspace (App.workspace) ---- */
.ws { display: flex; flex-direction: column; gap: 16px; margin-top: 18px; }
.ws-block { background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 13px 14px; }
.ws-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.ws-path {
  font-family: ui-monospace, monospace; font-size: 10.5px; color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 55%;
}
.ws-sub { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; margin: 12px 0 6px; }
.ws-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.ws-btn { padding: 8px 13px; font-size: 12px; }
.ws-note { font-size: 12px; color: var(--text-3); line-height: 1.5; padding: 6px 2px; }
/* A companion serving the wrong folder is a data-placement problem, not a
   status line — it reads as an error, like the log's error chips. */
.ws-note.ws-wrongroot { border-color: rgba(255,91,110,.45); color: #ffb3bc; background: rgba(255,91,110,.08); }
.ws-note.ws-wrongroot code { background: rgba(0,0,0,.3); padding: 1px 5px; border-radius: 4px; font-size: 11px; }
.ws-note.tight { padding: 2px 2px 0; font-size: 11.5px; }
/* Which machine's filesystem the panel is talking to — sits above the three
   blocks, so it reads as a property of the whole panel rather than of any one
   section. Quiet on purpose: it explains, it doesn't warn. */
.ws-mode {
  display: flex; align-items: center; gap: 7px;
  margin-bottom: 4px; padding: 7px 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; font-size: 11.5px;
}
.ws-mode svg { width: 13px; height: 13px; flex: none; opacity: .8; }
.ws-mode .ws-x { margin-left: auto; }
/* the pairing prompt stacks: explanation, then the field to act on it */
.ws-pair { display: block; }
.ws-pair-row { display: flex; gap: 7px; margin-top: 8px; }
.ws-pair-in {
  flex: 1; min-width: 0; font-family: ui-monospace, monospace;
  letter-spacing: .06em; text-transform: uppercase;
}

.ws-list { display: flex; flex-direction: column; gap: 4px; margin-top: 9px; }
.ws-item {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font-size: 12px; padding: 7px 10px; border-radius: 8px; cursor: pointer;
  transition: background .13s, border-color .13s;
}
.ws-item:hover { background: var(--hover); border-color: var(--accent); }
.ws-item.static { cursor: default; }
.ws-item.static:hover { background: var(--surface); border-color: var(--border); }
.ws-ic { flex: none; font-size: 13px; }
.ws-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.ws-name { color: var(--accent-2, #8fa2ff); text-decoration: none; }
a.ws-name:hover { text-decoration: underline; }
.ws-meta { flex: none; font-size: 10.5px; color: var(--text-3); }
.ws-go { flex: none; color: var(--text-3); font-size: 11px; }
.ws-x { flex: none; border: 0; background: transparent; color: var(--text-3); cursor: pointer; padding: 2px 4px; border-radius: 5px; }
.ws-x:hover { color: #ff8a95; background: rgba(255,91,110,.12); }

/* assets, grouped by the dependency that owes them */
.ws-dep { border-top: 1px solid var(--border); padding: 10px 0 4px; }
.ws-dep:first-of-type { border-top: 0; }
.ws-dep-head { display: flex; align-items: center; gap: 9px; }
.ws-dep-name { flex: 1; min-width: 0; font-size: 12.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-chip { flex: none; font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.ws-chip.ok { background: rgba(0,200,117,.16); color: #6ee0aa; }
.ws-chip.pending { background: rgba(253,171,61,.16); color: #ffce8e; }
.ws-dep.pending .ws-dep-name { color: var(--text-2); }

/* deliver drop area */
.ws-drop {
  border: 1.5px dashed var(--border-2); border-radius: 11px; padding: 20px 14px;
  text-align: center; cursor: pointer; transition: background .13s, border-color .13s;
}
.ws-drop:hover { border-color: var(--accent); background: var(--hover); }
.ws-drop.over { border-color: var(--accent); background: rgba(91,108,255,.10); }
.ws-drop-main { font-size: 12.5px; font-weight: 700; }
.ws-drop-sub { font-size: 10.5px; color: var(--text-3); margin-top: 3px; }
.ws-progress:empty { display: none; }
.ws-prog-line { font-size: 11.5px; color: var(--text-2); padding: 8px 2px 0; }
.ws-prog-line.ok { color: #6ee0aa; }
.ws-prog-line.err { color: #ff8a95; }
.ws-delivered { margin-top: 4px; }

/* folder picker (App.folderPicker) — server-side directory browser */
.modal-card.fp-card { max-width: 560px; }
.fp-roots { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.fp-root {
  border: 1px solid var(--border-2); background: var(--bg); color: var(--text-2);
  font-size: 11.5px; font-weight: 700; padding: 5px 11px; border-radius: 999px; cursor: pointer;
}
.fp-root:hover { background: var(--hover); color: var(--text); }
.fp-root.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.fp-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.fp-up { padding: 7px 12px; font-size: 12px; flex: none; }
.fp-up:disabled { opacity: .4; cursor: default; }
.fp-path {
  flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 11px; font-family: ui-monospace, monospace;
  font-size: 11.5px; color: var(--text-2); overflow-x: auto; white-space: nowrap;
}
.fp-list {
  height: 300px; overflow-y: auto; background: var(--bg);
  border: 1px solid var(--border); border-radius: 10px; padding: 5px;
}
.fp-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  border: 0; background: transparent; color: var(--text); font-size: 12.5px;
  padding: 8px 10px; border-radius: 7px; cursor: pointer;
}
.fp-item:hover { background: var(--hover); }
.fp-ic { flex: none; font-size: 13px; }
.fp-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fp-arrow { flex: none; color: var(--text-3); }
.fp-size { flex: none; font-size: 10.5px; color: var(--text-3); }
.fp-item.sel { background: rgba(91,108,255,.16); outline: 1px solid var(--accent); }
/* multi-select ticks (Deliver → pick files or a whole folder) */
.fp-check {
  flex: none; width: 15px; height: 15px; border-radius: 4px; position: relative;
  border: 1.5px solid var(--border-2); background: var(--bg-2); cursor: pointer;
}
.fp-check:hover { border-color: var(--accent); }
.fp-item.sel .fp-check { background: var(--accent); border-color: var(--accent); }
.fp-item.sel .fp-check::after {
  content: ''; position: absolute; left: 4px; top: 1px;
  width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.fp-selinfo { margin-right: auto; font-size: 11.5px; font-weight: 600; color: var(--text-2); }
.fp-loading, .fp-empty, .fp-error, .fp-notice { font-size: 12.5px; color: var(--text-3); padding: 14px 12px; }
.fp-error { color: #ff8a95; white-space: pre-line; }
.fp-notice { color: #ffce8e; padding: 10px 12px; line-height: 1.5; }
/* a disabled action must not look pressable */
.btn-primary:disabled, .btn-ghost:disabled, .btn-danger:disabled {
  opacity: .45; cursor: default; filter: grayscale(.4);
}
.btn-primary:disabled:hover { background: var(--accent); }

/* Admin → Workflow → Storage: the generated-tree preview */
.storage-tree {
  margin: 0; padding: 12px 14px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 10px; font-family: ui-monospace, monospace; font-size: 11.5px;
  line-height: 1.65; color: var(--text-2); overflow-x: auto; white-space: pre;
}
.brand-name { font-weight: 800; font-size: 15px; letter-spacing: .2px; line-height: 1; }
.brand-sub { font-size: 10.5px; color: var(--text-3); margin-top: 3px; letter-spacing: .3px; }

.view-tabs { display: flex; gap: 2px; background: var(--surface); padding: 3px; border-radius: 10px; border: 1px solid var(--border); }
.view-tab {
  border: 0; background: transparent; color: var(--text-2);
  padding: 7px 14px; border-radius: 7px; font-size: 12.5px; font-weight: 600;
  display: flex; align-items: center; gap: 7px; transition: .12s;
}
.view-tab:hover { color: var(--text); background: var(--hover); }
.view-tab.active { background: var(--accent); color: #fff; box-shadow: 0 2px 10px rgba(91,108,255,.4); }
.view-tab .ic { font-size: 13px; }

.topbar-spacer { flex: 1; }

.role-tabs { display: flex; gap: 3px; }
.role-tab {
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text-2); padding: 6px 11px; border-radius: 999px;
  font-size: 12px; font-weight: 600; display: flex; align-items: center; gap: 6px; transition: .12s;
}
.role-tab:hover { background: var(--hover); color: var(--text); }
.role-tab.active { background: rgba(91,108,255,.16); border-color: rgba(91,108,255,.55); color: #cdd3ff; }

button.ghost {
  border: 1px solid var(--border-2); background: transparent; color: var(--text-2);
  padding: 7px 12px; border-radius: 8px; font-size: 12px; font-weight: 600; transition: .12s;
}
button.ghost:hover { background: var(--hover); color: var(--text); }
button.ghost.active { background: rgba(155,91,255,.16); border-color: #9b5bff; color: #cbb2ff; }
button.ghost.active:hover { background: rgba(155,91,255,.24); }
button.ghost:disabled { opacity: .45; cursor: default; filter: grayscale(.4); }
button.ghost:disabled:hover { background: transparent; }

/* ----------------------------------------------------------------- toolbar */
#toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 18px; flex: 0 0 auto;
  background: var(--bg-2); border-bottom: 1px solid var(--border);
}
.filter, #search {
  background: var(--surface); border: 1px solid var(--border-2); color: var(--text);
  padding: 7px 10px; border-radius: 8px; font-size: 12px; font-family: inherit;
}
.filter:focus, #search:focus { outline: none; border-color: var(--accent); }
#search { min-width: 210px; }
.filter { cursor: pointer; }

/* Show/Dept/Owner multi-select — a button styled to the same footprint as
   the .filter selects it replaced, so the toolbar's layout doesn't shift. */
.filter-multi {
  display: inline-flex; align-items: center; gap: 6px; max-width: 220px;
}
.filter-multi-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filter-multi-chev { font-size: 9px; color: var(--text-3); flex: none; }
.filter-pop {
  position: fixed; z-index: 950; min-width: 190px; max-height: 320px; overflow-y: auto;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 12px;
  box-shadow: var(--shadow); padding: 6px; animation: pop-in .14s ease;
}
.filter-pop-row {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px;
  border-radius: 8px; cursor: pointer; font-size: 12.5px; white-space: nowrap;
}
.filter-pop-row:hover { background: var(--hover); }
.filter-pop-row input[type="checkbox"] { accent-color: var(--accent); cursor: pointer; margin: 0; flex: none; }
.filter-pop-row.active { color: var(--accent); font-weight: 600; }
.filter-pop-check { width: 14px; flex: none; color: var(--accent); font-weight: 700; }
.filter-pop-sep { height: 1px; background: var(--border); margin: 4px 2px; }
.toolbar-label { font-size: 10.5px; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; margin-right: -4px; }
.legend { display: flex; gap: 13px; align-items: center; margin-left: auto; flex-wrap: wrap; }
.legend-item { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-2); }
.legend .swatch { width: 11px; height: 11px; border-radius: 3px; }

/* ----------------------------------------------------------------- KPIs */
.kpis { display: flex; gap: 10px; padding: 8px 18px 4px; flex: 0 0 auto; flex-wrap: wrap; }
.kpi {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 9px; padding: 6px 14px; min-width: 0;
  display: flex; flex-direction: row; align-items: baseline; gap: 7px;
  position: relative; overflow: hidden; cursor: default;
}
.kpi::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--accent); opacity: .85; }
.kpi.k-green::before { background: var(--st-approved); }
.kpi.k-orange::before { background: var(--st-in_progress); }
.kpi.k-purple::before { background: var(--st-review); }
.kpi.k-red::before { background: var(--danger); }
.kpi-num { font-size: 16px; font-weight: 800; line-height: 1; letter-spacing: -.3px; white-space: nowrap; }
.kpi-sub { font-size: 11.5px; font-weight: 600; color: var(--text-3); }
/* Re-Arrange / Create / Add Show cluster together on the right of the KPI
   strip — the wrapper owns the push-right now, not the button itself, so the
   three sit adjacent instead of Add Show alone floating away from the others. */
.kpi-actions { display: flex; gap: 8px; align-items: center; margin-left: auto; }
.kpis .btn-addshow { align-self: center; }
.kpi-actions .btn-addshow { margin-left: 0; }
.kpi-label { font-size: 10.5px; color: var(--text-2); white-space: nowrap; }

/* ----------------------------------------------------------------- main scroller */
#view {
  flex: 1 1 auto; overflow: auto; padding: 14px 18px 40px;
  /* Prevent scroll-anchor jumps when content updates in-place */
  overflow-anchor: auto;
  /* Fade-in new content so view switches don't flash blank */
  animation: viewFade .12s ease;
}
@keyframes viewFade { from { opacity: .55; } to { opacity: 1; } }
.section-title { font-size: 12px; font-weight: 700; color: var(--text-2); text-transform: uppercase; letter-spacing: .8px; margin: 6px 2px 12px; }

/* shared chips ---------------------------------------------------- */
.dept-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px 3px 7px; border-radius: 6px; font-size: 11px; font-weight: 600;
  background: var(--surface-3); color: var(--text); white-space: nowrap;
}
.dept-chip .dot { width: 8px; height: 8px; border-radius: 50%; }
.avatar {
  width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  font-size: 9.5px; font-weight: 700; color: #fff; flex: 0 0 auto;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.18);
}
.avatar.empty { background: var(--surface-3) !important; color: var(--text-3); box-shadow: inset 0 0 0 1px var(--border-2); }
.dep-chip {
  display: inline-flex; align-items: center; padding: 3px 8px; border-radius: 6px;
  background: rgba(91,108,255,.16); color: #b9c2ff; border: 1px solid rgba(91,108,255,.32);
  font-size: 10.5px; font-weight: 600; white-space: nowrap;
}
.dep-chip.ok { background: rgba(0,200,117,.13); color: #6ee0aa; border-color: rgba(0,200,117,.3); }
.dep-chip.wait { background: rgba(255,91,110,.12); color: #ffa3ad; border-color: rgba(255,91,110,.3); }

/* status pill (board cell + timeline labels) ---------------------- */
.status-pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  padding: 4px 10px; border-radius: 6px; font-size: 11px; font-weight: 700; white-space: nowrap;
}

/* =================================================================
   TIMELINE  (Gantt)
================================================================= */
.gantt { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.gantt-scroll { overflow: auto; overscroll-behavior: contain; }
.gantt-inner { position: relative; min-width: max-content; }

/* column header (weeks + days) */
.time-head { position: sticky; top: 0; z-index: 6; background: var(--bg-2); border-bottom: 1px solid var(--border-2); }
.time-weeks, .time-days { display: flex; }
.time-week {
  border-right: 1px solid var(--border-2); padding: 4px 10px; font-size: 10.5px; font-weight: 700;
  color: var(--text-2); white-space: nowrap; overflow: hidden;
}
.time-week .wk-sub { color: var(--text-3); font-weight: 500; margin-left: 6px; font-size: 10px; }
.time-day {
  border-right: 1px solid var(--border); padding: 3px 0; text-align: center;
  font-size: 9.5px; color: var(--text-3); white-space: nowrap;
}
.time-day.weekend { background: rgba(255,255,255,.022); }
.time-day.is-today { color: #fff; }
.time-day .dnum { font-weight: 700; color: var(--text-2); }
.time-day.is-today .dnum { color: #fff; }

/* adaptive header rows (days / weeks / months / quarters / years) */
.thead-row { display: flex; }
.thead-cell { border-right: 1px solid var(--border); white-space: nowrap; overflow: hidden; }
.thead-cell.primary { padding: 4px 10px; font-size: 10.5px; font-weight: 700; color: var(--text-2); border-right: 1px solid var(--border-2); display: flex; align-items: baseline; gap: 6px; }
.thead-cell.primary .seg-sub { color: var(--text-3); font-weight: 500; font-size: 10px; }
.thead-cell.secondary { padding: 3px 2px; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1.25; }
.thead-cell.secondary .seg-main { font-size: 9.5px; font-weight: 700; color: var(--text-2); }
.thead-cell.secondary .seg-sub { font-size: 8.5px; color: var(--text-3); }
.thead-cell.secondary .wd { font-size: 9px; color: var(--text-3); }
.thead-cell.secondary .dnum { font-size: 9.5px; font-weight: 700; color: var(--text-2); }
.thead-cell.secondary.weekend { background: rgba(255,255,255,.022); }
.thead-cell.secondary.is-today { background: rgba(91,155,255,.18); box-shadow: inset 0 -2px 0 #5b9bff; }
.thead-cell.secondary.is-today .dnum, .thead-cell.secondary.is-today .wd { color: #fff; }
.grid-line { position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(255,255,255,.045); }
.grid-line.strong { background: var(--border-2); }

/* the left label rail is sticky over the scrolling timeline */
.lane { position: relative; }
/* outer band pins vertically under the time header; the inner wrapper pins
   horizontally (a full-width element has no room to shift, so left:0 on the
   band itself does nothing — the wrapper is what keeps the text on screen) */
.lane-head {
  position: sticky; top: var(--gantt-head-h, 57px); z-index: 5;
  background: var(--bg-2); border-top: 1px solid var(--border); width: 100%;
}
.lane-head-in {
  position: sticky; left: 0;
  display: inline-flex; align-items: center; gap: 8px; width: max-content;
  padding: 4px 14px; font-size: 10.5px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .6px;
}
.lane-head .dot { width: 8px; height: 8px; border-radius: 50%; }
.lane-head .lane-count { color: var(--text-3); font-weight: 600; letter-spacing: 0; text-transform: none; }

.g-row { display: flex; align-items: stretch; border-top: 1px solid var(--border); min-height: 31px; }
.g-row:hover { background: var(--hover); }
.g-row.sub { min-height: 23px; background: rgba(0,0,0,.16); }

/* latch scrolling (preference): episode rows pin beneath the time header while
   their tasks scroll past — the row most recently scrolled into wins the slot.
   Portrait has no equivalent (see settleRows' guard in js/gantt.js) — the
   :not() keeps the two preferences from combining into something broken
   rather than the "no additional effect" the Timeline View toggle promises. */
.gantt.latch:not(.gantt-portrait) .g-row:not(.sub) {
  position: sticky; top: var(--latch-top, 82px); z-index: 5; background: var(--surface);
}
.gantt.latch:not(.gantt-portrait) .g-row:not(.sub):hover { background: var(--hover); }
.g-label {
  position: sticky; left: 0; z-index: 4;
  width: 220px; min-width: 220px; padding: 3px 12px;
  background: var(--surface); border-right: 1px solid var(--border-2);
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  cursor: pointer;
}
.g-row:hover .g-label { background: var(--hover); }
.g-row.sub .g-label { padding-left: 24px; background: var(--surface-2); }
/* Show sort's third level — a task row nested under a Department row that is
   itself nested under a Show row. One more step than the ordinary `.sub`
   indent, so Show → Department → Task reads as a chain instead of two things
   sitting at the same depth. */
.g-row.sub.sub-deep .g-label { padding-left: 44px; }
.g-label .l-title { font-size: 11.5px; font-weight: 700; display: flex; align-items: center; gap: 6px; min-width: 0; }
.g-label .l-title .chev { color: var(--text-3); font-size: 8px; transition: transform .15s; }
.g-label .l-title .chev.open { transform: rotate(90deg); }
.g-label .l-sub { font-size: 9.5px; color: var(--text-3); display: flex; align-items: center; gap: 5px; }
.g-label .code { color: var(--text-2); font-weight: 700; }

.g-track { position: relative; flex: 1; }
.bar {
  position: absolute; top: 50%; transform: translateY(-50%); height: 17px;
  border-radius: 5px; display: flex; align-items: center; padding: 0 7px;
  font-size: 10px; font-weight: 700; color: #11131a; white-space: nowrap;
  overflow: visible; box-shadow: 0 2px 8px rgba(0,0,0,.35); cursor: pointer;
}
.g-row.sub .bar { height: 12px; font-size: 9px; border-radius: 4px; }
.bar .bar-out { position: absolute; left: calc(100% + 8px); color: var(--text-2); font-weight: 600; font-size: 10px; }
.bar.delivered { opacity: .55; }
/* Quarters and wider: the bar is a shape, not a label. No padding to reserve
   for text that isn't there, and a floor so a short task stays visible. */
.bar.bare { padding: 0; min-width: 2px; }
/* Unused revision budget, left as a grey tail after an approved bar rather
   than quietly dropped — see App.revisionGhostDays. Not a real scheduled
   span (nothing else is drawn or clamped against it), so it's styled to
   read as slack, not as work: hatched, dashed, no fill. The ✕ only shows on
   hover, same as the rest of the app's dismiss controls. */
.rev-ghost {
  position: absolute; top: 50%; transform: translateY(-50%); height: 17px;
  border-radius: 4px; z-index: 1; cursor: default;
  background: repeating-linear-gradient(45deg, rgba(255,255,255,.08) 0, rgba(255,255,255,.08) 4px, rgba(255,255,255,.03) 4px, rgba(255,255,255,.03) 8px);
  border: 1px dashed rgba(255,255,255,.22);
  display: flex; align-items: center; justify-content: flex-end; padding: 0 3px;
}
.g-row.sub .rev-ghost { height: 12px; border-radius: 3px; }
.rev-ghost:hover { border-color: rgba(255,255,255,.4); }
.rev-ghost-x {
  font-size: 8px; color: var(--text-3); opacity: 0; transition: opacity .12s;
  cursor: pointer; line-height: 1; padding: 1px 2px; border-radius: 3px;
}
.rev-ghost:hover .rev-ghost-x { opacity: 1; }
.rev-ghost-x:hover { background: rgba(255,255,255,.15); color: var(--text); }
/* End-of-episode milestones (Delivery Date, Live Date). Each claims its own
   day column so it reads as a dated event on the calendar — red D for the
   delivery, blue LD for going live — rather than a marker floating beside the
   bar. Fixed dates, so there is nothing to drag or open. */
.ms-day {
  position: absolute; top: 50%; transform: translateY(-50%); height: 17px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  border-radius: 3px; cursor: default; z-index: 2; box-shadow: 0 2px 8px rgba(0,0,0,.35);
}
.ms-day .ms-tag {
  font-size: 9.5px; font-weight: 800; letter-spacing: .02em; color: #fff;
  line-height: 1; pointer-events: none;
}
.ms-day.ms-delivery_date { background: #e2445c; }
.ms-day.ms-live_date { background: #2f6fed; }
.ms-day.clickable { cursor: pointer; }
.ms-day.clickable:hover { filter: brightness(1.15); outline: 1.5px solid rgba(255,255,255,.5); outline-offset: -1.5px; }
/* held at a date of its own rather than derived — always true of a live date,
   true of a delivery date only when someone has pinned it */
.ms-day.fixed { box-shadow: 0 0 0 1.5px rgba(255,255,255,.75), 0 2px 8px rgba(0,0,0,.35); }
/* …and the work has since run past it */
.ms-day.late { box-shadow: 0 0 0 1.5px #ffce8e, 0 0 10px rgba(253,171,61,.55); }

/* milestone panel — whether the date is held or following, and for the
   delivery date what has to be in hand on the day */
.ms-status {
  display: flex; align-items: center; gap: 7px; margin: 12px 0 4px;
  font-size: 11.5px; font-weight: 600; color: var(--text-2);
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 8px 11px;
}
.ms-status.ok { color: #6ee0aa; border-color: rgba(0,200,117,.32); background: rgba(0,200,117,.07); }
.ms-status.bad { color: #ffce8e; border-color: rgba(253,171,61,.35); background: rgba(253,171,61,.09); }
.ms-auto { font-size: 10.5px; color: var(--text-3); margin-top: 8px; line-height: 1.5; }
.ms-auto strong { color: var(--text-2); }
.dlv-list { display: flex; flex-direction: column; gap: 2px; }
.dlv-row { display: flex; align-items: center; gap: 10px; padding: 6px 2px; }
.dlv-what { min-width: 0; flex: 1; }
.dlv-dept { display: flex; align-items: center; gap: 5px; font-size: 9.5px; color: var(--text-3); text-transform: uppercase; letter-spacing: .4px; }
.dlv-dept .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.dlv-asset { font-size: 12px; font-weight: 600; margin-top: 2px; }
.dlv-meta { font-size: 10px; color: var(--text-3); margin-top: 1px; }
/* Task bars carry no status dot (too little room) — the live states are marked
   with a hairline ring in the status colour instead, set inline per bar. Drawn
   as an outline rather than a shadow or border so it neither fights .dragging's
   box-shadow nor eats into the bar's width. */
.bar.st-ring { outline: 1.5px solid currentColor; outline-offset: -1.5px; }
.g-row.sub .bar.st-ring { outline-width: 1px; outline-offset: -1px; }
/* drag-to-reschedule (Timeline): move from the middle, resize from an edge.
   Small grip tabs fade in at the edges on hover (and stay while dragging) to
   show the bar is adjustable there. */
.bar.dragging { box-shadow: 0 0 0 2px rgba(255,255,255,.6), 0 6px 16px rgba(0,0,0,.5); z-index: 3; }
.bar.warn.dragging { box-shadow: 0 0 0 2px #ff5b6e, 0 6px 16px rgba(0,0,0,.5); }
body.gantt-dragging { user-select: none; }
.bar.adjustable::before, .bar.adjustable::after, .bar.dragging::before, .bar.dragging::after {
  content: ''; position: absolute; top: 50%; width: 6px; height: 78%;
  background: #fff; border: 1px solid rgba(0,0,0,.3); border-radius: 3px;
  box-shadow: 0 1px 3px rgba(0,0,0,.4); pointer-events: none;
  opacity: 0; transition: opacity .12s ease, transform .12s ease;
}
.g-row.sub .bar.adjustable::before, .g-row.sub .bar.adjustable::after,
.g-row.sub .bar.dragging::before, .g-row.sub .bar.dragging::after { width: 4px; height: 85%; border-radius: 2px; }
/* straddle the exact edge — half sits on the bar, half hangs off it */
.bar.adjustable::before, .bar.dragging::before { left: 0; transform: translate(-50%, -50%); }
.bar.adjustable::after, .bar.dragging::after { right: 0; transform: translate(50%, -50%); }
.bar.adjustable:hover::before, .bar.adjustable:hover::after,
.bar.dragging::before, .bar.dragging::after { opacity: 1; }
.bar.adjustable:hover::before, .bar.dragging::before { transform: translate(-50%, -50%) scaleX(1.15); }
.bar.adjustable:hover::after, .bar.dragging::after { transform: translate(50%, -50%) scaleX(1.15); }
.drag-tip { font-weight: 700; }

/* ---- Shift-selected task bars ----
   A white ring plus a lift, not a colour change: the bar's own colour is
   already carrying its department or show, and a selection that recoloured it
   would cost the reading it was picked out of. The ring sits outside the bar so
   a 3px-wide task still shows it. */
.bar.selected {
  outline: 2px solid #fff !important; outline-offset: 1px;
  box-shadow: 0 0 0 4px rgba(91,108,255,.35), 0 3px 10px rgba(0,0,0,.45);
  /* below .g-label (4) — the sticky label column is the chart's Y axis, and a
     selected bar sliding under it must pass BEHIND the axis, not over it. 3
     still clears the grid, the today line and unselected bars. */
  z-index: 3;
}
.bar.selected.delivered { opacity: .8; }
/* every member of a group drag lifts together, so the group reads as one thing
   in motion rather than one dragged bar and some followers */
.bar.selected.dragging { box-shadow: 0 0 0 4px rgba(91,108,255,.5), 0 6px 16px rgba(0,0,0,.5); }
/* Shift held: the open grid becomes a place to sweep, so say so on the cursor */
body.gantt-shift .g-row.sub .g-track { cursor: crosshair; }
/* fixed, not absolute — the band and the bars it catches are both measured in
   viewport coordinates, so they can't drift apart (see startMarquee) */
.g-marquee {
  position: fixed; z-index: 900; pointer-events: none;
  border: 1.5px dashed rgba(255,255,255,.85); border-radius: 4px;
  background: rgba(91,108,255,.16);
}
/* Toolbar pill — the selection's only presence outside the chart itself */
.sel-pill {
  display: inline-flex; align-items: center; gap: 8px; padding: 5px 6px 5px 11px;
  border-radius: 999px; background: rgba(91,108,255,.14);
  border: 1px solid rgba(91,108,255,.45); white-space: nowrap;
}
.sel-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }
.sel-count { font-size: 11.5px; font-weight: 700; }
.sel-sub { font-size: 10.5px; color: var(--text-3); }
.sel-clear {
  background: none; border: 0; color: var(--text-3); cursor: pointer;
  font-size: 11px; line-height: 1; padding: 4px 6px; border-radius: 50%;
}
.sel-clear:hover { background: var(--hover); color: var(--text); }

/* ---- "+ Create" row (Timeline, draw to create an episode/task) ----
   Same header+track shape as the Producer Notes row just below, with its own
   accent (purple, not the notes' yellow/blue) so a create-draw never reads
   as "drawing a note". */
.create-row { background: rgba(155,91,255,.05); }
.create-label .l-title { color: var(--text-3); font-weight: 600; }
.g-track.cr-drawable { cursor: crosshair; }
.create-ghost {
  position: absolute; top: 50%; transform: translateY(-50%); height: 18px;
  border-radius: 5px; display: flex; align-items: center; justify-content: center; padding: 0 8px;
  font-size: 10px; font-weight: 700; white-space: nowrap;
  opacity: .8; pointer-events: none; border: 1px dashed rgba(255,255,255,.7);
  box-shadow: 0 2px 6px rgba(0,0,0,.3);
}

/* ---- Producer Notes swimlane (Timeline, per-show) ---- */
.pn-head { background: var(--bg-2); border-top: 1px solid var(--border-2); }
.pn-label { cursor: pointer; background: var(--bg-2); }
.pn-label:hover { background: var(--hover); }
.pn-label .l-title { font-size: 10.5px; font-weight: 800; letter-spacing: .5px; color: var(--text-2); text-transform: uppercase; gap: 6px; }
.pn-count { color: var(--text-3); font-weight: 700; letter-spacing: 0; }
.pn-row { min-height: 26px; background: rgba(255,255,255,.015); }
.pn-sublabel { background: var(--surface); }
/* empty notes grid invites drawing a new note */
.g-track.pn-drawable { cursor: crosshair; }
.pn-ghost { opacity: .6; pointer-events: none; border: 1px dashed rgba(255,255,255,.7); }
.pn-note {
  position: absolute; top: 50%; transform: translateY(-50%); height: 18px;
  border-radius: 5px; display: flex; align-items: center; justify-content: center; padding: 0 8px;
  font-size: 10px; font-weight: 700; white-space: nowrap; overflow: visible;
  box-shadow: 0 2px 6px rgba(0,0,0,.3);
}
.pn-note > span { display: block; overflow: hidden; text-overflow: ellipsis; min-width: 0; max-width: 100%; }
/* narrow note → upright text in a portrait box (height set inline) */
.pn-note.portrait {
  writing-mode: vertical-rl; text-orientation: mixed; padding: 6px 0; font-size: 9.5px;
}
.pn-note.portrait > span { max-width: none; max-height: 100%; white-space: nowrap; }
.pn-note.editable { cursor: grab; }
.pn-note.dragging { box-shadow: 0 0 0 2px rgba(255,255,255,.6), 0 6px 16px rgba(0,0,0,.5); z-index: 3; }
/* reuse the task bar's edge grip-tab look */
.pn-note.adjustable::before, .pn-note.adjustable::after, .pn-note.dragging::before, .pn-note.dragging::after {
  content: ''; position: absolute; top: 50%; width: 5px; height: 80%;
  background: #fff; border: 1px solid rgba(0,0,0,.3); border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0,0,0,.4); pointer-events: none;
  opacity: 0; transition: opacity .12s ease;
}
.pn-note.adjustable::before, .pn-note.dragging::before { left: 0; transform: translate(-50%, -50%); }
.pn-note.adjustable::after, .pn-note.dragging::after { right: 0; transform: translate(50%, -50%); }
.pn-note.adjustable:hover::before, .pn-note.adjustable:hover::after,
.pn-note.dragging::before, .pn-note.dragging::after { opacity: 1; }

/* note editor popover */
.pn-editor {
  position: fixed; z-index: 960; width: 240px; padding: 10px;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 11px;
  box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 9px;
  animation: pop-in .12s ease;
}
.pn-note-input {
  width: 100%; background: var(--bg); border: 1px solid var(--border-2); border-radius: 8px;
  padding: 7px 10px; font-size: 12.5px; color: var(--text); font-family: inherit; outline: none;
}
.pn-note-input:focus { border-color: var(--accent); }
.pn-swatches { display: flex; gap: 6px; }
.pn-swatch { width: 20px; height: 20px; border-radius: 50%; border: 2px solid transparent; padding: 0; cursor: pointer; }
.pn-swatch:hover { transform: scale(1.12); }
.pn-swatch.on { border-color: var(--text); box-shadow: 0 0 0 2px var(--surface-2), 0 0 0 3px var(--text); }
.pn-editor-actions { display: flex; justify-content: space-between; align-items: center; }
.pn-del { background: transparent; border: 0; color: var(--danger); font-size: 11.5px; font-weight: 600; padding: 4px 6px; border-radius: 6px; }
.pn-del:hover { background: rgba(255,91,110,.14); }
.pn-done { background: var(--accent); border: 0; color: #fff; font-size: 11.5px; font-weight: 700; padding: 5px 14px; border-radius: 7px; }
.pn-done:hover { background: #6b7bff; }

/* demo tour — big cursor, click ripple, caption (App.tour.play) */
.tour-cursor {
  position: fixed; left: 0; top: 0; z-index: 100000; width: 40px; height: 40px;
  margin: -4px 0 0 -4px; pointer-events: none; will-change: transform;
  filter: drop-shadow(0 4px 7px rgba(0,0,0,.55));
}
.tour-cursor svg { display: block; }
.tour-ripple {
  position: fixed; z-index: 99999; width: 16px; height: 16px; border-radius: 50%;
  background: rgba(91,108,255,.45); border: 2px solid #fff; pointer-events: none;
  transform: translate(-50%, -50%); animation: tour-ripple .55s ease-out forwards;
}
@keyframes tour-ripple {
  from { opacity: .9; width: 16px; height: 16px; }
  to   { opacity: 0; width: 56px; height: 56px; }
}
.tour-caption {
  position: fixed; left: 50%; bottom: 42px; z-index: 100000;
  transform: translateX(-50%) translateY(12px);
  background: rgba(12,14,20,.94); border: 1px solid var(--border-2); color: #fff;
  font: 700 16px/1.35 var(--font); padding: 13px 24px; border-radius: 13px;
  box-shadow: var(--shadow); pointer-events: none; max-width: 70vw; text-align: center;
  opacity: 0; transition: opacity .4s ease, transform .4s ease;
}
.tour-caption.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* action recorder — REC badge (App.recorder.start/stop) */
.rec-badge {
  position: fixed; top: 16px; right: 16px; z-index: 100000; pointer-events: none;
  display: flex; align-items: center; gap: 7px;
  background: rgba(20,10,12,.92); border: 1px solid rgba(255,91,110,.5); color: #ffb3bd;
  font: 800 12px/1 var(--font); letter-spacing: .5px; padding: 8px 13px 8px 10px;
  border-radius: 20px; box-shadow: var(--shadow);
}
.rec-dot { width: 9px; height: 9px; border-radius: 50%; background: #ff5b6e; animation: rec-pulse 1.1s ease-in-out infinite; }
@keyframes rec-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* Episode sort: department phase-span container bar (not a task, not clickable) */
.g-row.sub.phase { min-height: 20px; }
.phase-bar {
  position: absolute; top: 50%; transform: translateY(-50%); height: 8px;
  border: 1px solid; border-radius: 5px; cursor: default;
}
.bar .blk { margin-left: 5px; }

/* vertical day grid + weekend shading drawn behind bars */
.grid-bg { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.grid-col { position: absolute; top: 0; bottom: 0; border-right: 1px solid rgba(255,255,255,.04); }
.grid-col.weekend { background: rgba(255,255,255,.022); }
.grid-col.month { border-right: 1px solid var(--border-2); }
/* stays below the sticky label rail (z 4/5) and time header (z 6) so it never
   draws over episode names or dates while scrolling */
.today-line { position: absolute; top: 0; bottom: 0; width: 2px; background: #5b9bff; z-index: 3; box-shadow: 0 0 8px rgba(91,155,255,.8); }
.today-flag {
  position: absolute; top: 0; transform: translateX(-50%); z-index: 8;
  background: #5b9bff; color: #fff; font-size: 9.5px; font-weight: 700;
  padding: 2px 7px; border-radius: 0 0 6px 6px; white-space: nowrap;
}

/* =================================================================
   TIMELINE — Portrait orientation (Timeline View preference)

   Time runs top-to-bottom instead of left-to-right. Department sort only —
   see the `portrait` guard in js/gantt.js render(). Everything here is scoped
   under .gantt-portrait, so none of it can touch the rules above; Landscape's
   markup and CSS are untouched by this section entirely.

   The general move: every piece of chrome glues to the edge that is NOT its
   own varying axis (this is already how Landscape works — .time-head glues
   top because it varies with X, .g-label glues left because it varies with
   Y). Portrait keeps that rule and just swaps which edge is which:
     .date-rail   (varies with Y now) → sticky LEFT, stacked vertically
     .g-label     (varies with X now) → sticky TOP,  laid out horizontally
   DATE_RAIL_W/COL_HEAD_H/COL_W/SUB_COL_W in js/gantt.js must match the pixel
   values below — the same "must match style.css" contract LABEL_W already has.
================================================================= */
.gantt.gantt-portrait .gantt-inner { display: flex; align-items: flex-start; min-width: 0; width: max-content; }
.gantt.gantt-portrait .gantt-body { display: flex; flex-direction: row; align-items: flex-start; position: relative; height: var(--gantt-time-h); }

/* portrait's mirror of .time-head: sticky LEFT, date segments run downward */
.date-rail {
  position: sticky; left: 0; z-index: 6; flex: none;
  width: 78px; min-width: 78px; height: var(--gantt-time-h);
  background: var(--bg-2); border-right: 1px solid var(--border-2);
  display: flex; flex-direction: column;
}
.date-rail .th-corner { position: sticky; top: 0; z-index: 9; }
.date-rail .thead-row.thead-col { display: flex; flex-direction: column; flex: none; min-width: 0; overflow: hidden; }
/* the two date columns have to SHARE the rail's 78px. Left to size
   themselves, the primary column grows to fit "W35 Aug 24-30" on one line
   and shoves the day numbers out over the first department's column. */
.date-rail .thead-row.thead-col.primary { width: 60px; }
.date-rail .thead-row.thead-col.secondary { width: 18px; }
.date-rail .thead-cell { overflow: hidden; }
.date-rail .thead-col.primary .thead-cell {
  flex-direction: column; align-items: flex-start; justify-content: center;
  padding: 4px 2px 4px 4px; gap: 0; line-height: 1.25;
}
.date-rail .thead-col.primary .seg-main,
.date-rail .thead-col.primary .seg-sub { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.date-rail .thead-row.thead-col.primary .thead-cell { border-right: none; border-bottom: 1px solid var(--border-2); }
.date-rail .thead-row.thead-col.secondary .thead-cell { border-right: none; border-bottom: 1px solid var(--border); }

/* portrait's mirror of .g-row: a column instead of a row. Reuses the exact
   same .g-row/.g-label/.g-track elements departmentRows()/epTaskLines()
   already build for Landscape — nothing in that JS needed to change, only
   how far it grows and which way its own children stack. An overlapping
   episode-bar's extra .g-row.sub (see epTaskLines' interval-stacking) lands
   as a side-by-side sub-column here for free, from this flex-row alone. */
.gantt.gantt-portrait .g-row {
  flex-direction: column; align-items: stretch;
  border-top: none; border-right: 1px solid var(--border);
  width: 96px; min-width: 96px; flex: none; height: var(--gantt-time-h);
}
.gantt.gantt-portrait .g-row.sub { width: 76px; min-width: 76px; }

/* portrait's mirror of .g-label: sticky TOP instead of sticky LEFT, fixed
   height instead of fixed width, text reading normally left-to-right rather
   than rotated — a rotated label was explicitly the thing not to build. */
.gantt.gantt-portrait .g-label {
  position: sticky; top: 0; left: auto; z-index: 4;
  width: 100%; min-width: 0; height: 44px; min-height: 44px;
  flex-direction: column; align-items: center; justify-content: center; text-align: center;
  border-right: none; border-bottom: 1px solid var(--border-2);
  padding: 3px 6px; gap: 1px; overflow: hidden;
}
.gantt.gantt-portrait .g-row.sub .g-label { padding-left: 6px; background: var(--surface-2); }
/* the column is only ~76-96px wide, so both label lines have to clip rather
   than push each other sideways — nowrap without this overflowed and drew
   one dept's text straight over the next one's. */
.gantt.gantt-portrait .g-label .l-title,
.gantt.gantt-portrait .g-label .l-sub {
  justify-content: center; white-space: nowrap;
  max-width: 100%; min-width: 0; overflow: hidden; flex: none;
}
.gantt.gantt-portrait .g-label .l-title > span:last-child,
.gantt.gantt-portrait .g-label .l-sub > span { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.gantt.gantt-portrait .g-label .l-sub { font-size: 10px; }

/* an expanded department: a hairline spine instead of a full column, since
   its tasks are now drawn in the columns immediately to its right */
.gantt.gantt-portrait .g-row.spine,
.gantt.gantt-portrait .g-row.sub.spine { width: 26px; min-width: 26px; border-right: none; }
.gantt.gantt-portrait .g-row.spine .g-label { padding: 3px 0; gap: 0; }
.gantt.gantt-portrait .g-row.spine .bar {
  width: 5px; min-height: 5px; padding: 0; border-radius: 3px; box-shadow: none;
}
.gantt.gantt-portrait .g-track { flex: 1; width: 100%; }

/* bars: fixed width (the column), variable height (the duration) — the
   inverse of Landscape's fixed height / variable width */
.gantt.gantt-portrait .bar {
  left: 50%; top: 0; bottom: auto; transform: translateX(-50%); height: auto; width: 80%;
  flex-direction: column; justify-content: center; white-space: normal; text-align: center;
  padding: 3px 2px; min-height: 17px;
}
.gantt.gantt-portrait .g-row.sub .bar { min-height: 12px; }
.gantt.gantt-portrait .bar .bar-out { left: 50%; top: calc(100% + 8px); transform: translateX(-50%); }

/* Everything else that is absolutely positioned inside a .g-track and sized
   by setBarPos: same swap as .bar — pinned to the cross-axis centre, growing
   along the time axis. Without this they keep .bar's translateY(-50%) and
   float half their own length above where they belong. */
.gantt.gantt-portrait .rev-ghost,
.gantt.gantt-portrait .ms-day,
.gantt.gantt-portrait .phase-bar {
  left: 50%; top: auto; transform: translateX(-50%); height: auto;
}
.gantt.gantt-portrait .rev-ghost {
  width: 70%; flex-direction: column; justify-content: flex-end; padding: 3px 0;
}
.gantt.gantt-portrait .ms-day { width: 70%; }
.gantt.gantt-portrait .create-ghost { left: 50%; top: auto; transform: translateX(-50%); width: 80%; height: auto; }
.gantt.gantt-portrait .phase-bar { width: 8px; }

/* A department's phase span is a marker, not a lane you read across, so in
   Portrait it takes a spine's width rather than a full task column — the
   tasks it brackets sit immediately to its right. */
.gantt.gantt-portrait .g-row.sub.phase { width: 22px; min-width: 22px; }
.gantt.gantt-portrait .g-row.sub.phase .g-label { padding: 3px 0; }

/* full-span chrome: same elements, spanning the cross axis (now horizontal)
   instead of the time axis (now vertical) */
.gantt.gantt-portrait .grid-line { left: 0; right: 0; top: 0; bottom: auto; width: auto; height: 1px; }
.gantt.gantt-portrait .grid-col { left: 0; right: 0; top: auto; bottom: auto; width: auto; border-right: none; border-bottom: 1px solid rgba(255,255,255,.04); }
.gantt.gantt-portrait .grid-col.month { border-right: none; border-bottom: 1px solid var(--border-2); }
.gantt.gantt-portrait .today-line { left: 0; right: 0; top: auto; bottom: auto; width: auto; height: 2px; }
.gantt.gantt-portrait .today-flag { top: 0; left: 0; transform: none; border-radius: 0 6px 6px 0; }

/* =================================================================
   BOARD  (Monday table)
================================================================= */
.board { display: flex; flex-direction: column; gap: 16px; }
.ep-group { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.ep-row {
  display: grid; grid-template-columns: 24px 1fr auto; align-items: center; gap: 12px;
  padding: 12px 16px; cursor: pointer; position: relative; background: var(--surface-2);
}
.ep-row:hover { background: var(--hover); }
.ep-accent { position: absolute; left: 0; top: 0; bottom: 0; width: 4px; }
.ep-row .chev { color: var(--text-2); font-size: 11px; transition: transform .15s; justify-self: center; }
.ep-row .chev.open { transform: rotate(90deg); }
.ep-headline { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ep-code { font-size: 11px; font-weight: 800; color: #fff; padding: 2px 8px; border-radius: 6px; white-space: nowrap; }
.ep-title { font-size: 14px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ep-show { font-size: 11px; color: var(--text-3); white-space: nowrap; }
.count-badge { font-size: 10.5px; font-weight: 700; color: var(--text-2); background: var(--surface-3); border-radius: 999px; padding: 1px 8px; }
.ep-right { display: flex; align-items: center; gap: 18px; }
.ep-meta { display: flex; flex-direction: column; align-items: center; gap: 3px; flex: none; }
.ep-meta .m-label { font-size: 9.5px; color: var(--text-3); text-transform: uppercase; letter-spacing: .5px; }
.ep-meta .m-val { font-size: 12px; font-weight: 700; white-space: nowrap; }
.ep-meta.status-meta { width: 100px; }
.ep-meta.stage-meta { width: 120px; }
/* Delivery / Live dates — the first thing to give up its space, since the
   episode title matters more and the Timeline shows these dates too */
.ep-meta.dates-meta { width: 118px; }
.ep-meta.dates-meta .m-val { font-size: 11.5px; color: var(--text-2); }
@media (max-width: 1100px) { .ep-meta.dates-meta { display: none; } }
.ep-prog { width: 120px; flex: none; display: flex; flex-direction: column; align-items: center; }
.prog-track { width: 100%; height: 7px; border-radius: 5px; background: var(--surface-3); overflow: hidden; }
.prog-fill { height: 100%; border-radius: 5px; background: linear-gradient(90deg, #00c875, #2bd38a); }
.risk-flag { font-size: 10.5px; font-weight: 700; color: #ffb3bb; background: rgba(255,91,110,.14); border: 1px solid rgba(255,91,110,.3); padding: 2px 8px; border-radius: 6px; }

/* subitems table */
.subtable { border-top: 1px solid var(--border-2); overflow-x: auto; }
.subgrid { min-width: 980px; }
.subrow {
  display: grid;
  grid-template-columns: 184px 132px 60px 150px 96px 96px 1fr;
  align-items: center; border-top: 1px solid var(--border);
}
.subrow.head { background: var(--bg-2); position: sticky; top: 0; }
.subrow.head .cell { font-size: 10px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .5px; padding: 9px 12px; }
.subrow:not(.head):hover { background: var(--hover); }
.subrow .cell { padding: 8px 12px; min-width: 0; }
.cell.c-name { font-size: 12.5px; font-weight: 600; display: flex; align-items: center; gap: 8px; overflow: hidden; }
/* Truncate the task name text inside the name cell — not the number or edit icon */
.cell.c-name span:not(.num):not(.edit-hint) { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; flex: 1; min-width: 0; }
.cell.c-name .num { color: var(--text-3); font-size: 10px; font-weight: 700; width: 16px; }
.cell.c-deps { display: flex; flex-wrap: wrap; gap: 5px; overflow: hidden; }
/* Dep chip names truncate if the column is narrow */
.dep-chip { max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
.cell.c-date { font-size: 11.5px; color: var(--text-2); }
.cell.c-date.overdue { color: #ff8a95; font-weight: 700; }

/* status cell — full-bleed solid colour like Monday */
.status-cell {
  height: 100%; min-height: 36px; display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; cursor: pointer; position: relative; user-select: none;
  border-left: 1px solid rgba(0,0,0,.25); border-right: 1px solid rgba(0,0,0,.25);
  transition: filter .1s;
}
.status-cell:hover { filter: brightness(1.08); }
.status-cell .blk { position: absolute; right: 6px; font-size: 11px; }
.subrow .cell.c-status { padding: 0; }

/* status picker popup */
.status-pop {
  position: fixed; z-index: 200; width: 196px; background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: 10px; box-shadow: var(--shadow);
  padding: 6px; display: flex; flex-direction: column; gap: 4px;
  animation: popIn .1s ease;
}
@keyframes popIn { from { opacity: 0; transform: translateY(-4px) scale(.97); } to { opacity: 1; transform: none; } }
.status-opt {
  border: 0; border-radius: 6px; padding: 10px 8px; font-size: 11.5px; font-weight: 700;
  color: #11131a; text-align: center; min-height: 36px; display: flex; align-items: center; justify-content: center;
}
.status-opt:hover { filter: brightness(1.1); outline: 2px solid rgba(255,255,255,.28); }
.pop-note { font-size: 10px; color: var(--text-3); padding: 4px 6px 2px; border-top: 1px solid var(--border); margin-top: 2px; }
.byok-body { min-width: 320px; }
.byok-status { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--text); margin: 10px 0; }
.byok-status .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }

/* =================================================================
   DASHBOARD
================================================================= */
/* greeting bar above the widget grid */
.dash-hello { margin: 2px 2px 16px; display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.dash-tools { display: flex; align-items: center; gap: 8px; flex: none; }
.dash-hi { font-size: 21px; font-weight: 800; letter-spacing: -.3px; }
.dash-quote { font-size: 12px; color: #ffd34d; font-style: italic; margin-top: 4px; }
.dash-quote .qa { color: var(--text-3); font-style: normal; }

/* Every tile is placed by JS (App.dashboard → getLayout/resolveCollisions)
   as an exact, independent pixel rectangle rather than flowing through CSS
   grid tracks — that's what lets a resize push a specific neighbour by a
   specific amount instead of only ever repacking everything into rows.
   `.dw`'s left/top/width/height come from inline style (see `rectStyle` in
   dashboard.js), inset by half the gutter on each side so adjacent tiles
   read as separated without a literal gap property to reason about. Tiles
   stretch to fill that exact rect — see `.widget { height: 100% }` below —
   rather than sizing to content, so a box is never taller than what it was
   assigned; content that doesn't fill it just leaves calm padding, and the
   rare overflow scrolls internally (`.widget-body`). The container's own
   height is set from JS too, since absolutely-positioned children don't
   contribute to a parent's auto height. */
.dash-grid { position: relative; }
.dw { position: absolute; min-width: 0; min-height: 0; }
.dw-head-l { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dw-grip { cursor: grab; color: var(--text-3); font-size: 12px; line-height: 1; user-select: none; }
.dw-grip:hover { color: var(--text); }
/* Springboard feel: every tile in edit mode glides to its new spot rather
   than snapping — that's the "other widgets visibly moving to make room"
   while a drag or resize is live (see wireDrag/wireResize in dashboard.js,
   which recompute left/top/width/height on every pointermove). The tile
   actually under the pointer is excluded — it must track the cursor with
   zero lag, not ease toward it. */
.dash-grid.editing .dw { transition: left .16s ease, top .16s ease, width .16s ease, height .16s ease; }
.dw.dw-dragging, .dw.dw-resizing { transition: none; z-index: 50; }
.dw.dw-dragging { cursor: grabbing; }
.dw.dw-dragging .widget { box-shadow: 0 14px 30px rgba(0,0,0,.45); transform: scale(1.03); }

/* ---- layout edit mode (Dashboard → Edit) ----
   Tiles become movable and resizable; their contents go inert so arranging a
   widget can never touch what's inside it. Resizing is grabbed from an edge
   rather than a corner handle: the whole side is the target, and all it shows
   is a hairline along that edge on hover — no furniture sitting on the tile. */
.dash-grid.editing .widget { outline: 1px dashed var(--border-2); outline-offset: -1px; }
.dash-grid.editing .widget-body { pointer-events: none; user-select: none; }
/* .dw is already position:absolute (its left/top/width/height come from JS —
   see rectStyle in dashboard.js), which also anchors the edge/corner resize
   handles below; editable mode doesn't need its own positioning context. */
.dw-editable { cursor: grab; }
.dw-editable.dw-resizing { cursor: default; }
.dw-edge, .dw-corner { position: absolute; z-index: 4; touch-action: none; }
.dw-edge::after {
  content: ''; position: absolute; inset: 0; margin: auto; border-radius: 2px;
  background: var(--accent); opacity: 0; transition: opacity .12s;
}
.dw-edge:hover::after { opacity: .9; }
.e-t, .e-b { left: 16px; right: 16px; height: 12px; cursor: ns-resize; }
.e-l, .e-r { top: 16px; bottom: 16px; width: 12px; cursor: ew-resize; }
.e-t { top: -6px; } .e-b { bottom: -6px; }
.e-l { left: -6px; } .e-r { right: -6px; }
.e-t::after, .e-b::after { height: 2px; }
.e-l::after, .e-r::after { width: 2px; }

/* corners sit over the edge strips and read as a small bracket on hover */
.dw-corner { width: 20px; height: 20px; z-index: 5; }
.dw-corner::before, .dw-corner::after {
  content: ''; position: absolute; background: var(--accent); border-radius: 2px;
  opacity: 0; transition: opacity .12s;
}
.dw-corner::before { width: 13px; height: 2px; }
.dw-corner::after { width: 2px; height: 13px; }
.dw-corner:hover::before, .dw-corner:hover::after { opacity: .9; }
.c-tl { top: -6px; left: -6px; cursor: nwse-resize; }
.c-tr { top: -6px; right: -6px; cursor: nesw-resize; }
.c-bl { bottom: -6px; left: -6px; cursor: nesw-resize; }
.c-br { bottom: -6px; right: -6px; cursor: nwse-resize; }
.c-tl::before, .c-tr::before { top: 7px; } .c-bl::before, .c-br::before { bottom: 7px; }
.c-tl::before, .c-bl::before { left: 7px; } .c-tr::before, .c-br::before { right: 7px; }
.c-tl::after, .c-tr::after { top: 7px; }   .c-bl::after, .c-br::after { bottom: 7px; }
.c-tl::after, .c-bl::after { left: 7px; }  .c-tr::after, .c-br::after { right: 7px; }

/* mid-drag only the handle under the cursor stays lit */
.dw-resizing .dw-edge::after,
.dw-resizing .dw-corner::before, .dw-resizing .dw-corner::after { opacity: 0; }
.dw-resizing .dw-edge:hover::after,
.dw-resizing .dw-corner:hover::before, .dw-resizing .dw-corner:hover::after { opacity: .9; }
.dw-size {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 3; pointer-events: none; opacity: 0; transition: opacity .12s;
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
  color: var(--text-2); background: var(--bg-2);
  border: 1px solid var(--border-2); border-radius: 6px; padding: 3px 10px;
}
.dw-editable:hover .dw-size, .dw-resizing .dw-size { opacity: 1; }

/* width-aware trims: a narrow tile (≤4 of 12 columns — see `t.span <= 4` in
   dashboard.js) gives up the label gutter and the padding before it gives up
   rows of data */
.dw-narrow .widget-body { padding: 11px; }
.dw-narrow .bar-row { grid-template-columns: 86px 1fr 28px; gap: 7px; margin-bottom: 7px; }
.dw-narrow .risk-item { padding: 7px 9px; gap: 8px; }
/* the full department chip only ever renders on a non-narrow tile, but it
   can still run long there */
.risk-item .dept-chip { max-width: 86px; overflow: hidden; }
.dw-narrow .big-num { font-size: 40px; letter-spacing: -1.5px; }
.dw-narrow .big-num .of { font-size: 20px; }
.dw-narrow .pr-chip { width: 78px; font-size: 9px; padding: 2px 6px; }
.dw-narrow .pr-head { padding: 8px 10px; gap: 7px; }
.dw-narrow .pr-row { padding: 6px 10px; gap: 7px; }
/* large tiles put the headline figure and its breakdown side by side */
.dw-wide { display: flex; align-items: center; gap: 28px; flex: 1; min-width: 0; }
.dw-wide .dw-split { flex: 1; min-width: 0; }
.dw-calm { flex: 1; display: flex; align-items: center; justify-content: center; color: var(--text-3); font-size: 12.5px; min-height: 60px; }

.widget { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; display: flex; flex-direction: column; min-height: 116px; height: 100%; }
.widget-head { padding: 12px 15px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; flex: none; }
.widget-title { font-size: 12.5px; font-weight: 700; }
.widget-sub { font-size: 10.5px; color: var(--text-3); }
.widget-body { padding: 15px; flex: 1; display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
.widget-body.bare { padding: 0; }
.col-3 { grid-column: span 3; } .col-4 { grid-column: span 4; } .col-5 { grid-column: span 5; }
.col-6 { grid-column: span 6; } .col-7 { grid-column: span 7; } .col-8 { grid-column: span 8; } .col-12 { grid-column: span 12; }

.big-num { font-size: 54px; font-weight: 800; line-height: 1; letter-spacing: -2px; }
.big-num .of { font-size: 26px; color: var(--text-3); font-weight: 700; }
.donut-wrap { display: flex; align-items: center; gap: 16px; }

.bar-row { display: grid; grid-template-columns: 110px 1fr 38px; align-items: center; gap: 10px; margin-bottom: 9px; }
.bar-row .bl { font-size: 11.5px; color: var(--text-2); display: flex; align-items: center; gap: 7px; white-space: nowrap; overflow: hidden; }
.bar-row .bt { height: 9px; border-radius: 5px; background: var(--surface-3); overflow: hidden; }
.bar-row .bf { height: 100%; border-radius: 5px; }
.bar-row .bv { font-size: 11px; font-weight: 700; color: var(--text-2); text-align: right; }

/* Priority widget — collapsible urgency buckets. The left edge carries the
   group's colour so the whole band reads as one unit while scanning down. */
.pr-list { display: flex; flex-direction: column; gap: 10px; overflow-y: auto; min-height: 0; }
.pr-group {
  background: var(--surface-2); border: 1px solid var(--border);
  border-left: 3px solid var(--text-3);     /* colour set inline per group */
  border-radius: 8px; overflow: hidden;
  /* Flex items shrink to fit by default, and with `.pr-list` scrolling that
     shrink target is 0 rather than "leave it to the scrollbar" — squashing
     every group down to a sliver instead of letting the list overflow.
     `flex: none` keeps each group at its natural height so the list scrolls
     like the rest of the dashboard's widget bodies. */
  flex: none;
}
.pr-head {
  width: 100%; display: flex; align-items: center; gap: 9px; padding: 10px 12px;
  background: none; border: 0; text-align: left; cursor: pointer; color: var(--text);
}
.pr-head:hover { background: var(--hover); }
.pr-head .chev { color: var(--text-3); font-size: 9px; flex: none; transition: transform .15s; }
.pr-head .chev.open { transform: rotate(90deg); }
.pr-label { font-size: 12.5px; font-weight: 700; }
.pr-sub { font-size: 11px; color: var(--text-3); }
.pr-count { font-size: 17px; font-weight: 800; margin-left: auto; line-height: 1; }
.pr-rows { border-top: 1px solid var(--border); }
.pr-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px; cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.pr-row:last-child { border-bottom: 0; }
.pr-row:hover { background: var(--hover); }
.pr-code { font-size: 11.5px; font-weight: 700; flex: none; }
.pr-task { font-size: 11.5px; color: var(--text-2); min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pr-date { font-size: 11px; color: var(--text-3); flex: none; margin-left: auto; white-space: nowrap; }
.pr-chip {
  font-size: 10px; font-weight: 700; border-radius: 6px; padding: 3px 9px;
  flex: none; width: 104px; text-align: center; white-space: nowrap;
}
.pr-more { font-size: 10.5px; color: var(--text-3); padding: 7px 12px; }

.risk-list { display: flex; flex-direction: column; gap: 8px; }
.risk-item { display: flex; align-items: center; gap: 10px; padding: 9px 11px; border-radius: 8px; background: var(--surface-2); border: 1px solid var(--border); cursor: pointer; }
.risk-item:hover { background: var(--hover); }
.risk-item .ri-main { flex: 1; min-width: 0; }
.risk-item .ri-title { font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.risk-item .ri-sub { font-size: 10.5px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.risk-item .ri-tag { font-size: 10px; font-weight: 700; padding: 2px 7px; border-radius: 5px; white-space: nowrap; }
.ri-chat {
  flex: none; display: grid; place-items: center; width: 22px; height: 22px;
  border: 0; border-radius: 6px; background: transparent; color: var(--text-3);
  font-size: 13px;
}
.ri-chat:hover { background: var(--surface-3); color: var(--text); }
.ri-tag.over { background: rgba(255,91,110,.16); color: #ffa7b0; }
.ri-tag.blk { background: rgba(253,171,61,.16); color: #ffce8e; }

.mini-quote { font-size: 15px; font-weight: 700; line-height: 1.5; color: #ffd34d; text-align: center; padding: 8px 4px; }
.mini-quote .qa { display: block; margin-top: 10px; font-size: 11px; color: var(--text-3); font-weight: 600; }

/* ----------------------------------------------------------------- journal */
.jr { display: flex; flex-direction: column; flex: 1; min-height: 380px; position: relative; font-family: Georgia, 'Times New Roman', serif; }
.jr-nav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px; background: var(--bg-2); border-bottom: 1px solid var(--border); flex: none;
}
.jr-arrow {
  background: transparent; border: 0; color: var(--text-3); font-size: 18px; line-height: 1;
  padding: 2px 10px; border-radius: 7px; transition: color .13s, background .13s;
}
.jr-arrow:hover { color: var(--text); background: var(--hover); }
.jr-date { font-size: 12.5px; font-weight: 600; letter-spacing: .3px; color: var(--text); }

.jr-paper {
  flex: 1; overflow-y: auto; position: relative; min-height: 0;
  background:
    linear-gradient(90deg, transparent 26px, rgba(214,69,127,.28) 26px, rgba(214,69,127,.28) 27px, rgba(214,69,127,.10) 27px, rgba(214,69,127,.10) 28px, transparent 28px),
    repeating-linear-gradient(transparent, transparent 31px, rgba(148,163,184,.09) 31px, rgba(148,163,184,.09) 32px);
  background-attachment: local, local;
  background-position: 0 0, 0 10px;
  padding: 10px 0 40px;
}
.jr-row { display: flex; align-items: flex-start; min-height: 32px; padding: 0 14px 0 38px; position: relative; }
.jr-block {
  flex: 1; min-width: 0; outline: none; min-height: 32px; line-height: 32px;
  font-size: 14.5px; color: var(--text); word-break: break-word;
}
.jr-block[data-ph]:empty::before { content: attr(data-ph); color: var(--text-3); font-style: italic; pointer-events: none; }
/* Notes written in from elsewhere carry anchors (js/reviews.js files a review
   note with links back to the task and the cut) — default link blue is close
   to unreadable on the ruled paper. */
.jr-block a { color: #9fb4ff; text-decoration: underline; text-underline-offset: 2px; }
.jr-block a:hover { color: #c3cfff; }
.jr-row.t-h1 .jr-block { font-size: 20px; font-weight: 700; color: #fff; }
.jr-row.done .jr-block { color: var(--text-3); text-decoration: line-through; opacity: .7; }
.jr-check {
  flex: none; width: 15px; height: 15px; margin: 8.5px 9px 0 0; padding: 0;
  border: 1.5px solid var(--text-3); border-radius: 4px; background: var(--bg);
  color: #fff; font-size: 10px; line-height: 1; display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background .12s, border-color .12s;
}
.jr-check:hover { border-color: var(--text-2); }
.jr-check.on { background: var(--accent); border-color: var(--accent); }
.jr-dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--text-2); margin: 13px 12px 0 3px; }

.jr-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 7px 12px; background: var(--bg-2); border-top: 1px solid var(--border); flex: none;
  font-family: var(--font);
}
.jr-count { font-size: 10px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.jr-foot-r { display: flex; align-items: center; gap: 12px; }
.jr-carry {
  background: transparent; border: 0; font-size: 10px; font-weight: 700; color: #ffce8e;
  padding: 0; cursor: pointer; font-family: var(--font);
}
.jr-carry:hover { text-decoration: underline; }
.jr-today { background: transparent; border: 0; font-size: 10px; font-weight: 700; color: var(--accent); padding: 0; cursor: pointer; font-family: var(--font); }
.jr-today:hover { text-decoration: underline; }
.jr-today.off { color: var(--text-3); opacity: .5; cursor: default; text-decoration: none; }

/* floating format toolbar */
.jr-toolbar {
  position: absolute; z-index: 30; display: none; align-items: center; gap: 3px;
  background: #262833; border: 1px solid var(--border-2); border-radius: 999px;
  padding: 5px 9px; box-shadow: var(--shadow); font-family: var(--font);
}
.jr-toolbar.show { display: flex; animation: pop-in .12s ease; }
.jr-tb-btn {
  width: 24px; height: 24px; border: 0; border-radius: 50%; background: transparent;
  color: var(--text); font-size: 12px; display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background .12s;
}
.jr-tb-btn:hover { background: var(--surface-3); }
.jr-tb-btn.b { font-weight: 800; }
.jr-tb-btn.i { font-style: italic; font-family: Georgia, serif; }
.jr-tb-btn.u { text-decoration: underline; }
.jr-tb-btn.s { text-decoration: line-through; }
.jr-tb-sep { width: 1px; height: 16px; background: var(--border-2); margin: 0 3px; }
.jr-tb-btn.hl::before { content: ''; width: 11px; height: 11px; border-radius: 50%; }
.jr-tb-btn.hl.purple::before { background: #a855f7; }
.jr-tb-btn.hl.amber::before { background: #f0ad4e; }
.jr-tb-btn.hl.clear { color: var(--text-3); font-size: 10px; }
.jr-tb-btn.hl.clear::before { display: none; }

.empty { text-align: center; color: var(--text-3); padding: 40px; font-size: 13px; }

/* heat strip (team workload) */
.heat { display: grid; gap: 4px; }
.heat-row { display: grid; grid-template-columns: 110px 1fr; align-items: center; gap: 10px; }
.heat-cells { display: flex; gap: 4px; }
.heat-cell { flex: 1; height: 24px; border-radius: 5px; background: var(--surface-3); display: grid; place-items: center; font-size: 10px; font-weight: 700; color: rgba(255,255,255,.85); }

/* toast */
#toast-root { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 999; display: flex; flex-direction: column; gap: 8px; align-items: center; }
.toast {
  background: #2a2e3a; color: var(--text); border: 1px solid var(--border-2);
  padding: 10px 16px; border-radius: 9px; font-size: 12.5px; box-shadow: var(--shadow);
  transition: opacity .3s;
}
.toast.error { background: #4a1f25; border-color: #7a3038; color: #ffd5d9; }

/* ----------------------------------------------------------------- role dropdown */
.role-select { display: flex; align-items: center; gap: 7px; background: var(--surface); border: 1px solid var(--border-2); border-radius: 999px; padding: 4px 12px; }
.role-ic { font-size: 13px; }
.role-dd { background: transparent; border: 0; color: var(--text); font-size: 12.5px; font-weight: 700; font-family: inherit; cursor: pointer; padding: 4px 2px; }
.role-dd:focus { outline: none; }
.role-dd option { background: var(--surface-2); color: var(--text); }

/* ----------------------------------------------------------------- timeline bar dot + tooltip */
.bar-dot { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 0 1.5px rgba(0,0,0,.28); pointer-events: none; }
.g-row.sub .bar-dot { width: 7px; height: 7px; right: 3px; }
.bar-tip { position: fixed; z-index: 300; transform: translateX(-50%); background: #0b0c10; color: #fff; border: 1px solid var(--border-2); padding: 5px 12px; border-radius: 9px; font-size: 11.5px; font-weight: 600; display: flex; align-items: center; gap: 7px; pointer-events: none; box-shadow: var(--shadow); white-space: nowrap; }
.bar-tip .tip-dot { width: 9px; height: 9px; border-radius: 50%; }
.bar-tip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: #0b0c10; }

/* ----------------------------------------------------------------- board: edit hint + show manager */
.c-name .edit-hint { opacity: 0; color: var(--text-3); font-size: 11px; margin-left: auto; padding-right: 2px; transition: .12s; }
.c-name:hover .edit-hint { opacity: 1; }
.show-manager { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 11px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.sm-label { font-size: 10.5px; font-weight: 700; color: var(--text-3); letter-spacing: .6px; }
.show-chip { display: inline-flex; align-items: center; gap: 7px; background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 999px; padding: 5px 6px 5px 11px; font-size: 12px; font-weight: 600; }
.show-chip .dot { width: 9px; height: 9px; border-radius: 50%; }
.show-chip-count { color: var(--text-3); font-size: 10.5px; }
.show-chip-x { border: 0; background: transparent; color: var(--text-3); width: 20px; height: 20px; border-radius: 50%; font-size: 11px; }
.show-chip-x:hover { background: rgba(255,91,110,.18); color: #ff8a95; }
.btn-addshow { margin-left: auto; background: var(--accent); color: #fff; border: 0; padding: 7px 14px; border-radius: 8px; font-size: 12px; font-weight: 700; }
.btn-addshow:hover { background: #6b7bff; }

/* ----------------------------------------------------------------- sign-in */
.login-screen {
  position: fixed; inset: 0; z-index: 1000; background: var(--bg);
  display: flex; align-items: center; justify-content: center;
}
.login-card {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  padding: 40px 44px; width: min(380px, calc(100vw - 40px)); box-shadow: var(--shadow); text-align: center;
}
.login-logo {
  width: 52px; height: 52px; border-radius: 14px; background: linear-gradient(135deg, var(--accent), #8a5cf6);
  display: flex; align-items: center; justify-content: center; font-size: 24px; margin-bottom: 8px;
}
.login-title { font-size: 20px; font-weight: 800; letter-spacing: -.3px; }
.login-sub { font-size: 12px; color: var(--text-3); margin-bottom: 18px; }
.login-err {
  font-size: 12px; color: #ffb3bd; background: rgba(255,91,110,.12); border: 1px solid rgba(255,91,110,.3);
  border-radius: 9px; padding: 8px 12px; margin-bottom: 14px; max-width: 300px;
}
.login-google {
  display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%;
  background: #fff; color: #1a1c22; text-decoration: none; font-weight: 700; font-size: 13.5px;
  border-radius: 10px; padding: 11px 16px; transition: transform .12s ease, box-shadow .12s ease;
}
.login-google:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0,0,0,.35); }
.login-google.disabled { opacity: .38; pointer-events: none; }
.login-g { display: flex; }
.login-hint { font-size: 11px; color: var(--text-3); line-height: 1.5; margin-top: 10px; max-width: 290px; }
.login-div {
  display: flex; align-items: center; gap: 12px; width: 100%; margin: 16px 0 12px;
  color: var(--text-3); font-size: 11px; text-transform: uppercase; letter-spacing: .6px;
}
.login-div::before, .login-div::after { content: ''; flex: 1; height: 1px; background: var(--border-2); }
.login-dev { display: flex; gap: 8px; width: 100%; }
/* email + access code don't fit side by side — stack them */
.login-dev.stacked { flex-direction: column; }
.login-dev.stacked .btn-primary { width: 100%; padding: 10px; }
.login-input {
  flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--border-2); border-radius: 9px;
  padding: 10px 12px; font-size: 13px; color: var(--text); font-family: inherit; outline: none;
}
.login-input:focus { border-color: var(--accent); }

/* topbar — signed-in user */
.user-chip {
  display: flex; align-items: center; gap: 8px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 20px; padding: 4px 6px 4px 5px; margin-right: 10px;
}
.user-pic { width: 24px; height: 24px; border-radius: 50%; display: block; }
.user-chip .avatar { width: 24px; height: 24px; font-size: 10px; }
.user-name { font-size: 12px; font-weight: 700; white-space: nowrap; max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
.user-out {
  background: transparent; border: 0; color: var(--text-3); font-size: 14px; line-height: 1;
  padding: 3px 5px; border-radius: 6px;
}
.user-out:hover { color: var(--danger); background: var(--hover); }
.role-pin {
  font-size: 12.5px; font-weight: 700; color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border); border-radius: 9px; padding: 7px 12px; white-space: nowrap;
}

/* ----------------------------------------------------------------- admin page */
.admin { max-width: 1060px; margin: 0 auto; }
.adm-crumb { display: flex; gap: 8px; align-items: center; font-size: 11.5px; font-weight: 600; color: var(--text-3); margin-bottom: 16px; }
.adm-crumb-link { cursor: pointer; transition: color .15s; }
.adm-crumb-link:hover { color: var(--accent); }
.adm-crumb-here { color: var(--text-2); }
.adm-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 14px; flex-wrap: wrap; margin-bottom: 22px; }
.adm-title { font-size: 18px; font-weight: 700; letter-spacing: -.2px; color: var(--text); }
.adm-sub { font-size: 12px; color: var(--text-3); margin-top: 4px; }

/* hub cards */
.adm-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
.adm-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 13px;
  padding: 20px; display: flex; flex-direction: column; gap: 11px;
  transition: transform .18s ease, border-color .18s ease;
}
.adm-card:hover { transform: translateY(-2px); border-color: var(--border-2); }
.adm-card.primary { border-color: rgba(91,108,255,.35); box-shadow: 0 10px 30px rgba(91,108,255,.05); }
.adm-card-top { display: flex; align-items: center; gap: 11px; }
.adm-card-ic {
  width: 36px; height: 36px; flex: none; display: flex; align-items: center; justify-content: center;
  border-radius: 10px; background: var(--bg-2); border: 1px solid var(--border); font-size: 16px;
}
.adm-card-ic.blue   { box-shadow: inset 0 0 14px rgba(91,108,255,.14); }
.adm-card-ic.purple { box-shadow: inset 0 0 14px rgba(162,93,220,.16); }
.adm-card-ic.green  { box-shadow: inset 0 0 14px rgba(0,200,117,.12); }
.adm-card-ic.amber  { box-shadow: inset 0 0 14px rgba(253,171,61,.13); }
.adm-card-title { font-size: 13.5px; font-weight: 700; color: var(--text); }
.adm-card-desc { font-size: 12px; line-height: 1.55; color: var(--text-2); flex: 1; }
.adm-btn {
  width: fit-content; font-size: 12px; font-weight: 700; padding: 7px 14px; border-radius: 8px;
  background: var(--surface-3); color: var(--text); border: 1px solid var(--border-2); transition: background .15s;
}
.adm-btn:hover { background: var(--hover); }
.adm-btn.primary { background: var(--accent); border-color: transparent; color: #fff; }
.adm-btn.primary:hover { background: #6b7bff; }
.adm-btn.soon { opacity: .45; cursor: default; }

/* directory */
.adm-search {
  width: 300px; margin-bottom: 16px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 9px; padding: 8px 12px; font-size: 12.5px; color: var(--text); font-family: inherit; outline: none;
}
.adm-search:focus { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.adm-table { border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--surface); box-shadow: var(--shadow); }
.adm-thead, .adm-row { display: grid; grid-template-columns: 1.6fr 1fr .8fr 1fr 76px; align-items: center; gap: 12px; padding: 10px 18px; }
/* no connectors enabled → drop the Integrations column entirely */
.adm-table.no-integ .adm-thead, .adm-table.no-integ .adm-row { grid-template-columns: 1.6fr 1fr 1fr 76px; }
.adm-thead { background: var(--bg-2); border-bottom: 1px solid var(--border); }
.adm-thead .cell { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; }
.adm-row { border-top: 1px solid var(--border); cursor: pointer; transition: background .12s; position: relative; }
.adm-row:first-child { border-top: 0; }
.adm-row:hover { background: var(--hover); }
.adm-row.editing { background: var(--surface-2); box-shadow: inset 2px 0 0 var(--accent); cursor: default; }
.adm-row .cell.u { display: flex; align-items: center; gap: 11px; min-width: 0; }
/* The name+email wrapper (a bare div — only the editing-mode one gets its
   own .adm-edit-stack class) is a flex item with default overflow:visible,
   so its automatic minimum width is its content's min-content size: on a
   narrow column that's wider than the space actually available, and rather
   than the ellipsis below doing anything, the whole block overflows the
   cell and bleeds visibly into the next column. min-width:0 hands the
   shrinking down to .adm-name/.adm-name-sub's own overflow:hidden, which is
   what was supposed to be clipping it all along. */
.adm-row .cell.u > div:not(.adm-edit-stack) { min-width: 0; overflow: hidden; }
/* Every other grid-item cell (dept chip, integrations, load bar) defaults to
   min-width:auto, so on a narrow row its track can still expand to fit that
   cell's min-content and eat space the name column needed — same family of
   bug as above, just stealing width instead of visibly overflowing. */
.adm-thead > .cell, .adm-row > .cell { min-width: 0; }
.adm-name { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-name-sub { font-size: 10.5px; color: var(--text-3); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-edit-stack { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; }
.adm-inline {
  background: var(--bg); border: 1px solid var(--border-2); border-radius: 7px; color: var(--text);
  font-size: 13px; font-weight: 600; padding: 6px 10px; font-family: inherit; outline: none; width: 100%; min-width: 0;
}
.adm-inline:focus { border-color: var(--accent); }
.adm-inline-sm { font-size: 11.5px; font-weight: 500; color: var(--text-2); padding: 5px 10px; }

/* integrations — grey silhouette by default, brand colour on hover / once
   "connected" (a placeholder until real SSO/OAuth linking exists) */
.integ-icons { display: flex; gap: 10px; }
.integ-ic {
  width: 17px; height: 17px; color: var(--text-3); opacity: .4;
  transition: color .15s ease, opacity .15s ease, transform .15s ease;
}
.integ-ic svg { display: block; width: 100%; height: 100%; }
.integ-ic.on { opacity: .85; }
.integ-ic.editable { cursor: pointer; }
.integ-ic.editable:hover { transform: scale(1.12); }
.integ-ic:hover, .integ-ic.on:hover { opacity: 1; }
.integ-ic.slack:hover { color: #e01e5a; }
.integ-ic.gmail:hover { color: #ea4335; }
.integ-ic.slack.on { color: #e01e5a; opacity: .55; }
.integ-ic.gmail.on { color: #ea4335; opacity: .55; }
.integ-ic.slack.on:hover, .integ-ic.gmail.on:hover { opacity: 1; }

/* Connectors settings tab — a branded icon per row */
.conn-row-main { display: flex; align-items: center; gap: 12px; min-width: 0; }
.conn-ic {
  width: 30px; height: 30px; flex: none; padding: 6px; border-radius: 8px;
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text-3);
  transition: color .15s, opacity .15s; opacity: .6;
}
.conn-ic svg { display: block; width: 100%; height: 100%; }
.conn-ic.slack.on { color: #e01e5a; opacity: 1; }
.conn-ic.gmail.on { color: #ea4335; opacity: 1; }
.conn-ic.lucidlink.on { color: #2fbf9f; opacity: 1; }

/* ---- LucidLink Version Control ---- */
.btn-vc {
  background: rgba(47,191,159,.14); color: #4fe0bf; border: 1px solid rgba(47,191,159,.4);
  padding: 7px 14px; border-radius: 8px; font-size: 12px; font-weight: 700;
}
.btn-vc:hover { background: rgba(47,191,159,.24); }

/* board availability chip */
.vc-flag {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 8px;
  font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 20px;
  color: #ffce8e; background: rgba(253,171,61,.14); border: 1px solid rgba(253,171,61,.3); white-space: nowrap;
}
.vc-flag.mine { color: #4fe0bf; background: rgba(47,191,159,.14); border-color: rgba(47,191,159,.35); }

/* modal */
.vc-modal .vc-source {
  margin-left: auto; margin-right: 12px; font-size: 11px; font-weight: 700; white-space: nowrap;
  padding: 4px 10px; border-radius: 20px; color: var(--text-2); background: var(--surface-3); border: 1px solid var(--border);
}
.vc-modal .vc-source.live { color: #4fe0bf; background: rgba(47,191,159,.14); border-color: rgba(47,191,159,.4); }
.vc-body { display: flex; flex-direction: column; gap: 8px; }
.vc-row {
  display: grid; grid-template-columns: 1.5fr 1.3fr auto; align-items: center; gap: 16px;
  padding: 12px 14px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px;
}
.vc-row.syncing { border-color: rgba(253,171,61,.5); }
.vc-left { min-width: 0; }
.vc-ep { display: flex; align-items: center; gap: 8px; min-width: 0; }
.vc-ep .ep-code { font-size: 10px; padding: 2px 7px; border-radius: 5px; font-weight: 800; flex: none; }
.vc-title { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vc-ver { font-size: 11px; color: var(--text-3); margin-top: 3px; font-variant-numeric: tabular-nums; }
.vc-status { min-width: 0; }
.vc-badge {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700;
  padding: 3px 10px; border-radius: 20px; border: 1px solid;
}
.vc-dot { width: 7px; height: 7px; border-radius: 50%; }
.vc-lockinfo { font-size: 11px; color: var(--text-3); margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vc-actions { display: flex; align-items: center; gap: 8px; justify-content: flex-end; }
.vc-btn { font-size: 12px; padding: 7px 13px; white-space: nowrap; }
.vc-working { font-size: 12px; color: var(--text-3); font-style: italic; }
.vc-lockedby { font-size: 12px; color: #ffce8e; font-weight: 600; }
.vc-force { border-color: rgba(255,91,110,.4); color: #ff8a95; }
.vc-force:hover { background: rgba(255,91,110,.12); }
.vc-sync { min-width: 220px; }
.vc-sync-label { font-size: 11px; font-weight: 700; color: #ffce8e; margin-bottom: 6px; }
.vc-bar { height: 7px; background: var(--surface-3); border-radius: 20px; overflow: hidden; }
.vc-bar-fill { height: 100%; background: linear-gradient(90deg, #fdab3d, #2fbf9f); border-radius: 20px; transition: width .2s ease; }
.vc-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.vc-legend { font-size: 11px; color: var(--text-3); }
.vc-task-dept { font-size: 10px; color: var(--text-3); background: var(--surface-3); border-radius: 5px; padding: 1px 7px; flex: none; }

/* inline section inside the Edit Task dialog */
.vc-inline { border: 1px solid rgba(47,191,159,.35); border-radius: 10px; overflow: hidden; margin-top: 4px; background: rgba(47,191,159,.05); }
.vc-inline-head { display: flex; align-items: center; gap: 8px; padding: 9px 13px; background: rgba(47,191,159,.1); border-bottom: 1px solid rgba(47,191,159,.2); }
.vc-inline-ic { font-size: 13px; }
.vc-inline-title { font-size: 12px; font-weight: 700; color: var(--text); flex: 1; }
.vc-source-mini { font-size: 10px; font-weight: 700; color: var(--text-3); background: var(--surface-3); border-radius: 20px; padding: 2px 9px; }
.vc-source-mini.live { color: #4fe0bf; background: rgba(47,191,159,.16); }
.vc-inline-body { padding: 12px 13px; display: flex; flex-direction: column; gap: 10px; }
.vc-inline-note { font-size: 12px; color: var(--text-2); line-height: 1.5; }
.vc-inline-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.vc-inline-ver { font-size: 11.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.vc-remove { background: transparent; border: 0; color: var(--text-3); font-size: 11px; font-weight: 600; padding: 6px 8px; border-radius: 6px; }
.vc-remove:hover { color: var(--danger); background: rgba(255,91,110,.1); }
.vc-inline .vc-actions { justify-content: flex-start; flex-wrap: wrap; }
.vc-inline .vc-sync { min-width: 0; width: 100%; }

/* ---- Smart Upload (attachments) in the Edit Task dialog ---- */
.su-uploads { border: 1px solid var(--border); border-radius: 10px; background: var(--surface); padding: 12px 13px; display: flex; flex-direction: column; gap: 10px; }
.su-head { display: flex; align-items: center; gap: 8px; }
.su-ic { font-size: 13px; }
.su-title { font-size: 12px; font-weight: 700; color: var(--text); flex: 1; }
.su-count { font-size: 10.5px; font-weight: 700; color: var(--text-2); background: var(--surface-3); border-radius: 999px; padding: 1px 8px; }
.su-drop {
  border: 1.5px dashed var(--border-2); border-radius: 10px; padding: 14px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 8px; transition: border-color .15s, background .15s;
}
.su-drop.over { border-color: var(--accent); background: rgba(91,108,255,.08); }
.su-drop-ic { font-size: 18px; color: var(--text-3); }
.su-drop-text { font-size: 12px; color: var(--text-3); }
.su-drop-btns { display: flex; gap: 8px; }
.su-btn { background: var(--accent); color: #fff; border: 0; font-size: 12px; font-weight: 700; padding: 7px 13px; border-radius: 8px; }
.su-btn:hover { background: #6b7bff; }
.su-btn.ghost { background: var(--surface-3); color: var(--text); border: 1px solid var(--border-2); }
.su-btn.ghost:hover { background: var(--hover); }
.su-linkrow { display: flex; align-items: center; gap: 8px; background: var(--bg); border: 1px solid var(--border-2); border-radius: 9px; padding: 4px 4px 4px 10px; }
.su-linkrow:focus-within { border-color: var(--accent); }
.su-link-ic { font-size: 12px; flex: none; }
.su-link-in { flex: 1; min-width: 0; background: transparent; border: 0; outline: none; color: var(--text); font-size: 12.5px; font-family: inherit; padding: 6px 0; }
.su-empty { font-size: 12px; color: var(--text-3); text-align: center; padding: 6px 0; }
.su-cat { border: 1px solid var(--border); border-radius: 9px; overflow: hidden; }
.su-cat-head { display: flex; align-items: center; gap: 8px; padding: 7px 11px; background: var(--bg-2); border-bottom: 1px solid var(--border); }
.su-cat-ic { font-size: 12px; }
.su-cat-name { font-size: 11.5px; font-weight: 700; color: var(--text-2); flex: 1; }
.su-cat-count { font-size: 10px; font-weight: 700; color: var(--text-3); background: var(--surface-3); border-radius: 6px; padding: 1px 7px; }
.su-file { display: flex; align-items: center; gap: 10px; padding: 8px 11px; border-top: 1px solid var(--border); }
.su-file:first-of-type { border-top: 0; }
.su-file:hover { background: var(--hover); }
.su-file-kind { font-size: 12px; flex: none; opacity: .8; }
.su-file-main { flex: 1; min-width: 0; }
.su-file-name { font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.su-file-meta { font-size: 10.5px; color: var(--text-3); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.su-file-x { flex: none; background: transparent; border: 0; color: var(--text-3); font-size: 12px; padding: 4px 6px; border-radius: 6px; opacity: 0; }
.su-file:hover .su-file-x { opacity: 1; }
.su-file-x:hover { color: var(--danger); background: rgba(255,91,110,.12); }
.adm-role-chip {
  display: inline-block; max-width: 100%; vertical-align: middle;
  font-size: 11px; font-weight: 600; color: var(--text-2); background: var(--surface-3);
  border: 1px solid var(--border); border-radius: 7px; padding: 3px 10px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adm-load { display: flex; align-items: center; gap: 9px; }
.adm-load-num { font-size: 11px; font-weight: 700; color: var(--text-2); font-variant-numeric: tabular-nums; min-width: 30px; text-align: right; }
.adm-load-track { flex: 1; height: 5px; background: var(--surface-3); border-radius: 999px; overflow: hidden; max-width: 110px; }
.adm-load-fill { height: 100%; background: var(--accent); border-radius: 999px; }
.adm-actions { display: flex; gap: 6px; justify-content: flex-end; }
.adm-edit-hint { color: var(--text-3); font-size: 12px; opacity: 0; transition: opacity .15s; margin-left: auto; }
.adm-row:hover .adm-edit-hint { opacity: .8; }
.adm-empty { padding: 26px; text-align: center; font-size: 12.5px; color: var(--text-3); }
.adm-add { margin-top: 18px; padding: 16px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.admin-add-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.admin-add-row .filter { min-width: 170px; }

/* access control */
.adm-split { display: flex; gap: 26px; align-items: flex-start; }
.adm-side { width: 216px; flex: none; display: flex; flex-direction: column; gap: 3px; }
.adm-side-label { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; padding: 0 12px 8px; }
.adm-role {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  padding: 8px 12px; border-radius: 9px; border: 0; background: transparent;
  color: var(--text-2); font-size: 12.5px; font-weight: 600; transition: background .13s, color .13s;
}
.adm-role:hover { background: var(--surface); color: var(--text); }
.adm-role.active { background: rgba(162,93,220,.12); color: #cfa3f2; box-shadow: inset 2px 0 0 #a25ddc; }
.adm-role-ic { font-size: 14px; }
.adm-perms { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 18px; max-width: 640px; }
.adm-perms.wide { max-width: none; }
.adm-note {
  font-size: 12px; color: var(--text-2); background: var(--surface); border: 1px dashed var(--border-2);
  border-radius: 10px; padding: 10px 14px;
}
.adm-permcard { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; box-shadow: var(--shadow); }
.adm-permcard-head { padding: 13px 18px; background: var(--bg-2); border-bottom: 1px solid var(--border); }
.adm-permcard-title { font-size: 13px; font-weight: 700; color: var(--text); }
.adm-permcard-desc { font-size: 11.5px; color: var(--text-3); margin-top: 2px; }

/* ---- data-viz palette ----
   Categorical slots in a fixed order (never cycled), validated for colour-vision
   deficiency against this app's own surfaces — dark steps against #181a21, light
   steps against #ffffff for the "daylight" theme. Don't reorder or add a 7th:
   the ordering IS the CVD-safety mechanism, and a 7th series folds into "Other".
   Sequential (one hue, magnitude) and the diverging up/down pair are separate
   jobs and deliberately don't reuse the categorical slots. */
:root {
  --viz-1: #3987e5;  --viz-2: #d95926;  --viz-3: #199e70;
  --viz-4: #c98500;  --viz-5: #d55181;  --viz-6: #008300;
  --viz-seq: #3987e5;                 /* sequential: one hue, light→dark */
  --viz-seq-empty: rgba(255,255,255,.04);
  --viz-up: #3987e5;                  /* diverging pair: growth ↔ decline */
  --viz-down: #e66767;
  --viz-gridline: rgba(255,255,255,.07);
  --viz-axisline: rgba(255,255,255,.18);
}
:root[data-theme="daylight"] {
  --viz-1: #2a78d6;  --viz-2: #eb6834;  --viz-3: #1baf7a;
  --viz-4: #eda100;  --viz-5: #e87ba4;  --viz-6: #008300;
  --viz-seq: #2a78d6;
  --viz-seq-empty: rgba(11,11,11,.05);
  --viz-up: #2a78d6;
  --viz-down: #d03b3b;
  --viz-gridline: rgba(11,11,11,.09);
  --viz-axisline: rgba(11,11,11,.22);
}
.viz-svg { display: block; overflow: visible; }
.viz-chart, .viz-spark { width: 100%; }
.viz-grid { stroke: var(--viz-gridline); stroke-width: 1; }
.viz-axisline { stroke: var(--viz-axisline); stroke-width: 1; }
.viz-hair { stroke: var(--viz-axisline); stroke-width: 1; pointer-events: none; }
/* text wears text tokens — never a series colour */
.viz-axis { fill: var(--text-3); font-size: 9.5px; font-weight: 600; }
.viz-lab { fill: var(--text-2); font-size: 10.5px; font-weight: 600; }
.viz-val { fill: var(--text-2); font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.viz-legend { display: flex; flex-wrap: wrap; gap: 12px; padding: 8px 2px 0; }
.viz-legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-2); }
.viz-legend-key { width: 14px; height: 3px; border-radius: 2px; flex: none; }
.viz-tip {
  position: fixed; z-index: 980; pointer-events: none;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 9px;
  box-shadow: var(--shadow); padding: 8px 10px; min-width: 120px;
}
.viz-tip-h { font-size: 10.5px; font-weight: 700; color: var(--text-3); margin-bottom: 5px; }
.viz-tip-row { display: flex; align-items: center; gap: 7px; line-height: 1.6; }
.viz-tip-key { width: 12px; height: 3px; border-radius: 2px; flex: none; }
.viz-tip-val { font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; }
.viz-tip-lab { font-size: 11px; color: var(--text-3); }

/* ---- Audit & Event Logs ---- */
.adm-logbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.adm-tabs { display: flex; gap: 3px; background: var(--bg); border: 1px solid var(--border-2); border-radius: 9px; padding: 3px; }
.adm-tab {
  border: 0; background: transparent; color: var(--text-2); font-size: 12px; font-weight: 700;
  padding: 6px 14px; border-radius: 7px; transition: background .13s, color .13s;
}
.adm-tab:hover { color: var(--text); }
.adm-tab.active { background: var(--accent); color: #fff; }
.adm-logfilters { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.adm-logcount { font-size: 11.5px; color: var(--text-3); margin-left: auto; }
.adm-logrow {
  display: grid; grid-template-columns: 84px 1.1fr 128px 1.5fr 2fr;
  align-items: center; gap: 12px; padding: 9px 18px; border-top: 1px solid var(--border); font-size: 12px;
}
/* grid children don't shrink below their content by default, which is exactly
   how a long role label (e.g. "Post Operations") bled into the next column */
.adm-logrow > .cell { min-width: 0; }
.adm-logrow.head {
  background: var(--bg-2); border-top: 0; border-bottom: 1px solid var(--border);
  font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px;
}
.adm-logrow:hover:not(.head) { background: var(--hover); }
.adm-when { color: var(--text-3); white-space: nowrap; }
.adm-who { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-detail { color: var(--text-3); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-kind {
  display: inline-block; font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: .5px;
  padding: 2px 6px; border-radius: 5px; margin-right: 8px; vertical-align: middle;
}
.adm-kind.audit { background: rgba(253,171,61,.16); color: #ffce8e; }
.adm-kind.usage { background: rgba(91,108,255,.16); color: #a9b3ff; }
.adm-kind.error { background: rgba(255,91,110,.16); color: #ffb4bd; }
:root[data-mode="light"] .adm-kind.error { color: #b3222f; }

.adm-stat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 18px; }
.adm-stat-tile { background: var(--surface); border: 1px solid var(--border); border-radius: 11px; padding: 14px 16px 10px; }
.adm-stat-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.adm-stat-n { font-size: 26px; font-weight: 800; letter-spacing: -.5px; line-height: 1.05; font-variant-numeric: tabular-nums; }
.adm-stat-l { font-size: 11px; color: var(--text-3); margin-top: 2px; }
/* delta wears a status-ish ink, never a series colour, and always carries its
   arrow + sign so direction never rests on colour alone */
.adm-delta { font-size: 11px; font-weight: 800; font-variant-numeric: tabular-nums; }
.adm-delta.up { color: #0ca30c; }
.adm-delta.down { color: #e66767; }
.adm-delta.flat { color: var(--text-3); }
:root[data-theme="daylight"] .adm-delta.up { color: #006300; }
:root[data-theme="daylight"] .adm-delta.down { color: #d03b3b; }
/* ---- segmentation bar ---- */
.adm-segbar {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border); border-radius: 11px;
  padding: 10px 14px; margin-bottom: 16px;
}
.adm-seg-group { display: flex; align-items: center; gap: 8px; }
.adm-seg-lab { font-size: 9.5px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; }
.adm-seg-pills { display: flex; gap: 3px; background: var(--bg); border: 1px solid var(--border-2); border-radius: 8px; padding: 2px; }
.adm-seg-pill {
  border: 0; background: transparent; color: var(--text-2); font-size: 11px; font-weight: 700;
  padding: 4px 9px; border-radius: 6px; transition: background .13s, color .13s; white-space: nowrap;
}
.adm-seg-pill:hover { color: var(--text); }
.adm-seg-pill.active { background: var(--accent); color: #fff; }
.adm-seg-right { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.adm-seg-count { font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.adm-seg-clear { padding: 4px 10px; font-size: 11px; }

/* ---- KPI scorecards ---- */
.adm-kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; margin-bottom: 18px; }
.adm-kpi {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 13px 15px 10px; display: flex; flex-direction: column;
}
.adm-kpi-l { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; }
.adm-kpi-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.adm-kpi-v { font-size: 27px; font-weight: 800; letter-spacing: -.6px; line-height: 1.05; font-variant-numeric: tabular-nums; }
.adm-kpi-v.small { font-size: 16px; letter-spacing: -.2px; line-height: 1.25; }
.adm-kpi-sub { font-size: 10.5px; color: var(--text-2); margin-top: 4px; }
.adm-kpi-note { font-size: 9.5px; color: var(--text-3); margin-top: 2px; }
.adm-kpi-rows { margin-top: 9px; border-top: 1px solid var(--border); padding-top: 7px; display: flex; flex-direction: column; gap: 3px; }
.adm-kpi-row2 { display: flex; justify-content: space-between; gap: 10px; font-size: 10.5px; }
.adm-kpi-rk { color: var(--text-3); }
.adm-kpi-rv { color: var(--text-2); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---- friction & usability ---- */
.adm-friction .adm-fr-block { padding: 13px 18px; border-top: 1px solid var(--border); }
.adm-fr-h { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; margin-bottom: 10px; }
.adm-fr-none { font-size: 11.5px; color: var(--text-3); display: flex; align-items: center; gap: 6px; }
.adm-fr-ok { color: #0ca30c; }
.adm-fr-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
.adm-fr-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 10px 12px; }
.adm-fr-card.bad { border-color: rgba(230,103,103,.4); background: rgba(230,103,103,.07); }
.adm-fr-card-top { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.adm-fr-n { font-size: 19px; font-weight: 800; letter-spacing: -.3px; font-variant-numeric: tabular-nums; }
.adm-fr-lab { font-size: 11.5px; font-weight: 600; margin-top: 3px; }
.adm-fr-sub { font-size: 10px; color: var(--text-3); margin-top: 2px; }
.adm-fr-row { display: grid; grid-template-columns: 1.4fr 2fr 88px; align-items: center; gap: 12px; padding: 6px 0; }
.adm-fr-row-lab { display: flex; flex-direction: column; min-width: 0; }
.adm-fr-flow { font-size: 11.5px; font-weight: 600; }
/* part-to-whole: 2px surface gap does the separating, never a border */
.adm-fr-bar { display: flex; gap: 2px; height: 12px; border-radius: 4px; overflow: hidden; background: var(--surface-3); }
.adm-fr-bar-done { background: var(--viz-up); border-radius: 3px 0 0 3px; }
.adm-fr-bar-drop { background: var(--viz-down); border-radius: 0 3px 3px 0; }
.adm-fr-row-val { display: flex; align-items: baseline; gap: 6px; justify-content: flex-end; }
.adm-fr-pct { font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; }
.adm-fr-pct.bad { color: #e66767; }
:root[data-theme="daylight"] .adm-fr-pct.bad { color: #d03b3b; }

@media (max-width: 780px) {
  .adm-fr-row { grid-template-columns: 1fr 70px; }
  .adm-fr-row .adm-fr-bar { display: none; }
}

.adm-chartcard { padding-bottom: 6px; margin-top: 18px; }
.adm-chartcard .viz-chart, .adm-chartcard .viz-legend { padding: 0 18px; }
.adm-chartcard .viz-chart { padding-top: 10px; padding-bottom: 12px; }
.adm-usagerow { grid-template-columns: 120px repeat(8, 1fr); font-variant-numeric: tabular-nums; }
.adm-tableview { margin-top: 10px; overflow-x: auto; }

.adm-usage-role { padding: 13px 18px; border-top: 1px solid var(--border); }
.adm-usage-role:first-of-type { border-top: 0; }
.adm-usage-rolehead { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 9px; }
.adm-usage-rolename { font-size: 12.5px; font-weight: 700; }
.adm-usage-total { font-size: 10.5px; color: var(--text-3); }
.adm-usage-bars { display: flex; flex-direction: column; gap: 5px; }
.adm-usage-bar { display: grid; grid-template-columns: 170px 1fr 40px; align-items: center; gap: 10px; }
.adm-usage-label { font-size: 11px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-usage-track { height: 7px; background: var(--surface-3); border-radius: 999px; overflow: hidden; }
.adm-usage-fill { height: 100%; background: var(--accent); border-radius: 999px; min-width: 2px; }
.adm-usage-fill.alt { background: linear-gradient(90deg, #5b6cff, #9b5bff); }
.adm-usage-n { font-size: 11px; font-weight: 700; color: var(--text-2); text-align: right; font-variant-numeric: tabular-nums; }

@media (max-width: 900px) {
  .adm-logrow { grid-template-columns: 70px 1fr 90px 1.2fr; }
  .adm-logrow .adm-detail { display: none; }
  .adm-usage-bar { grid-template-columns: 120px 1fr 36px; }
}

.adm-permrow {
  display: flex; align-items: center; justify-content: space-between; gap: 22px;
  padding: 14px 18px; cursor: pointer; transition: background .12s; border-top: 1px solid var(--border);
}
.adm-permrow:first-of-type { border-top: 0; }
.adm-permrow:hover { background: var(--hover); }
.adm-permrow.locked { cursor: default; opacity: .72; }
.adm-permrow.locked:hover { background: transparent; }
.adm-perm-title { font-size: 12.5px; font-weight: 600; color: var(--text); }
.adm-perm-title.danger { color: var(--danger); }
.adm-perm-desc { font-size: 11.5px; color: var(--text-3); margin-top: 3px; line-height: 1.5; }

/* workflow & status settings */
.wf-list { display: flex; flex-direction: column; }
.wf-row {
  display: grid; grid-template-columns: 34px 1fr auto 30px; align-items: center; gap: 14px;
  padding: 10px 18px; border-top: 1px solid var(--border);
}
.wf-row:first-child { border-top: 0; }
.wf-swatch {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--border-2);
  cursor: pointer; position: relative; overflow: hidden; box-shadow: inset 0 0 0 1px rgba(0,0,0,.25);
}
.wf-swatch input[type="color"] { position: absolute; inset: -4px; width: calc(100% + 8px); height: calc(100% + 8px); border: 0; padding: 0; background: none; cursor: pointer; opacity: 0; }
.wf-name {
  background: var(--bg); border: 1px solid var(--border-2); border-radius: 8px; color: var(--text);
  font-size: 13px; font-weight: 600; padding: 7px 11px; font-family: inherit; outline: none; max-width: 220px;
}
.wf-name:focus { border-color: var(--accent); }
.wf-preview { justify-self: start; pointer-events: none; }
.wf-row .status-cell.wf-preview { min-height: 0; padding: 4px 12px; border-radius: 6px; font-size: 11px; font-weight: 700; }
.wf-lock { width: 30px; }
.wf-add { display: flex; gap: 10px; align-items: center; padding: 14px 18px; border-top: 1px solid var(--border); }

/* pipeline presets */
.preset-row {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px;
  padding: 11px 18px; border-top: 1px solid var(--border);
}
.preset-row:first-child { border-top: 0; }
.preset-type {
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .5px;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.preset-type.animation { color: #7fd4e2; background: rgba(41,194,214,.13); border: 1px solid rgba(41,194,214,.35); }
.preset-type.live_action { color: #ffc98e; background: rgba(255,176,46,.13); border: 1px solid rgba(255,176,46,.35); }
.preset-actions { display: flex; gap: 6px; }
.preset-edit-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.preset-edit-flds { display: flex; gap: 8px; align-items: center; }
.preset-pipe-bar { display: flex; align-items: center; gap: 10px; padding: 10px 18px; border-bottom: 1px solid var(--border); }
.preset-pipe-body { padding: 10px 12px; max-height: 46vh; overflow: auto; }

/* shows & archive */
.show-arch-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 18px; border-top: 1px solid var(--border);
}
.show-arch-row:first-child { border-top: 0; }
.show-arch-row.archived { opacity: .88; }
.show-arch-row.expandable { cursor: pointer; }
.show-arch-row.expandable:hover { background: var(--hover); }
.show-arch-row .chev { color: var(--text-3); font-size: 9px; flex: none; transition: transform .15s; }
.show-arch-row .chev.open { transform: rotate(90deg); }
.show-arch-dot { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.ep-arch-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 18px 6px 41px; border-top: 1px solid var(--border);
  background: rgba(0,0,0,.14);
}
.ep-arch-code {
  font-size: 9.5px; font-weight: 800; border-radius: 5px; padding: 2px 7px;
  white-space: nowrap; flex: none; letter-spacing: .3px;
}
.ep-arch-title { font-size: 12px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ep-arch-dates { font-size: 10.5px; color: var(--text-3); white-space: nowrap; flex: none; }
.arch-actions { margin-left: auto; display: flex; gap: 6px; flex: none; align-items: center; }
.arch-actions .btn-mini { white-space: nowrap; height: auto; width: auto; padding: 6px 11px; font-size: 11.5px; }
.btn-mini.danger { border-color: rgba(255,91,110,.45); color: #ff8a95; }
.btn-mini.danger:hover { background: rgba(255,91,110,.14); border-color: rgba(255,91,110,.7); }

/* toggle switch */
.switch {
  position: relative; width: 38px; height: 21px; flex: none; border-radius: 999px;
  background: var(--surface-3); border: 1px solid var(--border-2); transition: background .18s, border-color .18s;
}
.switch .knob {
  position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.45); transition: transform .18s ease;
}
.switch.on { background: var(--accent); border-color: transparent; }
.switch.on .knob { transform: translateX(17px); }
.switch.on.danger { background: var(--danger); }

@media (max-width: 860px) {
  .adm-split { flex-direction: column; }
  .adm-side { width: 100%; flex-direction: row; flex-wrap: wrap; }
  .adm-side-label { width: 100%; }
}

/* ----------------------------------------------------------------- modal / dialog */
.modal-overlay { position: fixed; inset: 0; z-index: 400; background: rgba(0,0,0,.62); backdrop-filter: blur(3px); display: flex; align-items: flex-start; justify-content: center; padding: 42px 16px; overflow: auto; }
.modal-card { width: 100%; max-width: 640px; background: var(--surface); border: 1px solid var(--border-2); border-radius: 16px; box-shadow: var(--shadow); animation: pop .14s ease; }
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; padding: 20px 22px 4px; }
.modal-head-main { display: flex; gap: 12px; align-items: center; }
.modal-ic { width: 34px; height: 34px; border-radius: 9px; background: rgba(91,108,255,.16); color: #aab4ff; display: grid; place-items: center; font-size: 16px; }
.modal-title { font-size: 18px; font-weight: 800; }
.modal-subtitle { font-size: 12px; color: var(--text-3); margin-top: 2px; }
.modal-x { border: 0; background: transparent; color: var(--text-3); font-size: 14px; width: 30px; height: 30px; border-radius: 7px; }
.modal-x:hover { background: var(--hover); color: var(--text); }
.modal-body { padding: 8px 22px 4px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 22px 20px; }
.modal-section-title { font-size: 13px; font-weight: 800; margin: 18px 0 10px; }

/* confirmation prompt (App.confirm) — narrow, message-only */
.modal-card.confirm-card { max-width: 440px; }
.confirm-card .modal-ic { background: rgba(255,91,110,.16); color: #ff8a95; }
.confirm-msg { font-size: 13.5px; line-height: 1.55; color: var(--text-2); white-space: pre-line; }
.confirm-card .btn-danger:focus-visible { outline: 2px solid #ff8a95; outline-offset: 2px; }

.ctx-box { background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; }
.ctx-label { font-size: 11px; color: var(--text-3); margin-bottom: 7px; }
.ctx-row { display: flex; align-items: center; gap: 10px; }
.ctx-chip { background: rgba(91,108,255,.16); color: #b9c2ff; font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 7px; }
.ctx-title { font-size: 14px; font-weight: 700; }
/* slim single-line context header */
.ctx-box.slim { display: flex; align-items: center; gap: 10px; padding: 9px 12px; }
.ctx-box.slim .ctx-title { font-size: 13px; }
.ctx-dept { margin-left: auto; font-size: 10.5px; color: var(--text-3); background: var(--surface-3); border-radius: 6px; padding: 2px 8px; }

/* compact click-to-edit rows (settings-menu style) */
.et-list { border: 1px solid var(--border); border-radius: 10px; background: var(--surface); overflow: hidden; }
.et-row { display: grid; grid-template-columns: 96px 1fr; align-items: start; gap: 10px; padding: 4px 10px; border-top: 1px solid var(--border); }
.et-row:first-child { border-top: 0; }
.et-label { font-size: 12px; font-weight: 600; color: var(--text-3); padding-top: 13px; }
.et-control { min-width: 0; padding: 5px 0; }
.et-display {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 32px;
  font-size: 13px; font-weight: 500; color: var(--text); padding: 5px 9px; border-radius: 8px; cursor: pointer; box-sizing: border-box;
}
.et-display > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.et-display:hover { background: var(--hover); }
.et-row.locked .et-display { cursor: default; color: var(--text-2); }
.et-row.locked .et-display:hover { background: transparent; }
.et-pencil { margin-left: auto; color: var(--text-3); font-size: 11px; opacity: 0; transition: opacity .12s; flex: none; }
.et-display:hover .et-pencil { opacity: .75; }
.et-edit { padding: 2px 0 4px; }
.et-edit .sched-box { margin-top: 2px; }
.et-empty { color: var(--text-3); }
.et-status { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; }
.et-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.et-owner { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.et-owner .avatar { width: 20px; height: 20px; font-size: 9px; flex: none; }
.et-sched { display: inline-flex; align-items: center; gap: 7px; }

.field { margin-bottom: 14px; }
.fld-label { display: block; font-size: 12.5px; font-weight: 700; margin-bottom: 6px; }
.fld { width: 100%; background: var(--bg-2); border: 1px solid var(--border-2); color: var(--text); padding: 10px 12px; border-radius: 9px; font-size: 13px; font-family: inherit; }
.fld:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(91,108,255,.18); }
select.fld { cursor: pointer; }
.fld-hint { font-size: 11px; color: var(--text-3); margin-top: 6px; }

.sched-box { background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 14px; }
.sched-grid { display: flex; align-items: flex-end; gap: 10px; }
.sched-grid .field { flex: 1; margin-bottom: 0; }
.sched-arrow { color: var(--text-3); font-size: 16px; padding-bottom: 11px; }
.range-pill { margin-top: 12px; display: flex; align-items: center; gap: 9px; background: rgba(91,108,255,.12); border: 1px solid rgba(91,108,255,.28); color: #c2caff; padding: 9px 12px; border-radius: 9px; font-size: 12.5px; font-weight: 600; }
.range-pill.bad { background: rgba(255,91,110,.12); border-color: rgba(255,91,110,.3); color: #ffb3bb; }
.range-days { margin-left: auto; color: var(--text-2); font-weight: 700; }

.ep-name-list { display: flex; flex-direction: column; gap: 8px; max-height: 240px; overflow: auto; padding-right: 4px; }
.ep-name-row { display: flex; align-items: center; gap: 10px; }
.ep-name-num { font-size: 11px; font-weight: 700; color: var(--text-3); width: 28px; flex: 0 0 auto; }
.ep-name-row .fld { margin: 0; }
.ep-name-row .ep-name-fld { flex: 1; min-width: 0; }
/* Per-episode live date. Filled in from the plan, so it reads as a suggestion
   until it's changed — `.moved` marks the ones now driving their own timing. */
.ep-live-cell { flex: none; display: flex; align-items: center; gap: 6px; }
.ep-live-lbl { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); }
.ep-live-fld { width: 148px; padding: 6px 9px; font-size: 12px; color: var(--text-2); }
.ep-live-fld.moved { color: var(--text-1); border-color: var(--accent); font-weight: 600; }

.btn-primary { background: var(--accent); color: #fff; border: 0; padding: 10px 16px; border-radius: 9px; font-size: 13px; font-weight: 700; }
.btn-primary:hover { background: #6b7bff; }
.btn-ghost { background: transparent; border: 1px solid var(--border-2); color: var(--text-2); padding: 10px 16px; border-radius: 9px; font-size: 13px; font-weight: 700; }
.btn-ghost:hover { background: var(--hover); color: var(--text); }
.btn-danger { background: transparent; border: 1px solid rgba(255,91,110,.5); color: #ff8a95; padding: 10px 16px; border-radius: 9px; font-size: 13px; font-weight: 700; }
.btn-danger:hover { background: rgba(255,91,110,.12); }
.btn-mini {
  border: 1px solid transparent; background: transparent; color: var(--text-3);
  width: 28px; height: 28px; border-radius: 8px; font-size: 13px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.btn-mini:hover { background: var(--hover); border-color: var(--border-2); color: var(--text); }
.btn-mini.danger:hover { background: rgba(255,91,110,.12); border-color: rgba(255,91,110,.35); color: #ff8a95; }

@media (max-width: 1100px) {
  .col-3, .col-4, .col-5 { grid-column: span 6; }
  .col-7, .col-8 { grid-column: span 12; }
}

/* ----------------------------------------------------------------- touch / mobile */
/* On coarse-pointer (touch) devices expand hit areas to ≥ 44 px as per WCAG 2.5.5 */
@media (pointer: coarse) {
  .status-cell { min-height: 44px; }
  .status-opt  { min-height: 44px; padding: 12px 8px; }
  .subrow .cell { min-height: 44px; }
  .show-chip-x { width: 36px; height: 36px; }
  .view-tab { padding: 10px 16px; }
  button.ghost { padding: 10px 14px; }
  .btn-primary, .btn-ghost, .btn-danger { padding: 13px 18px; }
  .filter, #search { padding: 10px 12px; }
  /* Toolbar wraps more aggressively on small screens */
  #toolbar { gap: 8px; padding: 10px 12px; }
  #search { min-width: 160px; }
}

@media (max-width: 700px) {
  .ep-right { display: none; }          /* hide episode meta strip on very small screens */
  .ep-title { font-size: 12px; }
  .kpis { gap: 8px; padding: 8px 12px 4px; }
  .kpi { padding: 6px 12px; }
  .kpi-num { font-size: 15px; }
}

/* ============================================================
   Add Show — schedule planner + pipeline editor
   ============================================================ */
.modal-card.wide { max-width: 900px; }
.modal-card.wide .modal-body { max-height: 74vh; overflow-y: auto; overflow-x: hidden; }

.plan-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
.plan-grid.two { grid-template-columns: 1fr 1fr; }
.plan-grid .field { margin-bottom: 0; }
.end-row { margin-top: 12px; align-items: start; }
.end-btn-slot { display: flex; align-items: flex-end; padding-top: 24px; }

.rec-pill {
  display: flex; align-items: center; gap: 8px; margin: 12px 0 0;
  background: rgba(91,108,255,.1); border: 1px solid rgba(91,108,255,.32);
  border-radius: 9px; padding: 9px 12px; font-size: 12.5px; font-weight: 600;
}
.rec-pill .range-days { margin-left: auto; color: var(--text-2); font-weight: 600; font-size: 11.5px; }
.rec-cmp {
  flex: none; font-size: 11px; font-weight: 700;
  border-radius: 12px; padding: 2px 9px; border: 1px solid;
}
.rec-cmp.short { color: #ffce8e; background: rgba(253,171,61,.12); border-color: rgba(253,171,61,.3); }
.rec-cmp.long  { color: #6ee0aa; background: rgba(0,200,117,.12);  border-color: rgba(0,200,117,.28); }

.end-feedback { margin-top: 8px; font-size: 12px; font-weight: 600; border-radius: 8px; padding: 8px 11px; }
.end-feedback.ok   { color: #6ee0aa; background: rgba(0,200,117,.1);  border: 1px solid rgba(0,200,117,.28); }
.end-feedback.warn { color: #ffce8e; background: rgba(253,171,61,.1); border: 1px solid rgba(253,171,61,.3); }
.end-feedback.bad  { color: #ffa3ad; background: rgba(255,91,110,.1); border: 1px solid rgba(255,91,110,.32); }

/* icon-only button (tooltip carries the label) */
.btn-icon {
  width: 30px; height: 30px; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-3); border: 1px solid var(--border-2); color: var(--text);
  border-radius: 8px; font-size: 15px; line-height: 1; cursor: pointer; font-family: inherit; padding: 0;
}
.btn-icon:hover { background: var(--hover); border-color: var(--accent); color: var(--accent); }
/* undo / redo — slightly smaller than ＋, and clearly inert with nothing to
   reverse rather than hidden, so the control's position never jumps */
.btn-icon.pipe-hist { width: 26px; height: 26px; font-size: 13px; }
.btn-icon.pipe-hist:disabled { opacity: .32; cursor: default; }
.btn-icon.pipe-hist:disabled:hover { background: var(--surface-3); border-color: var(--border-2); color: var(--text); }

.pipe-head { display: flex; align-items: center; justify-content: space-between; margin-top: 18px; }
.pipe-head .pipe-title { display: flex; align-items: center; gap: 8px; margin: 0; }

/* collapsed-by-default pipeline customisation */
.pipe-toggle {
  display: flex; align-items: center; gap: 9px; margin-top: 18px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px;
  padding: 11px 13px; cursor: pointer; font-size: 13px; font-weight: 800; user-select: none;
}
.pipe-toggle:hover { background: var(--hover); border-color: var(--border-2); }
.pipe-toggle .chev { color: var(--text-2); font-size: 10px; transition: transform .15s; }
.pipe-toggle .chev.open { transform: rotate(90deg); }
/* only the first button pushes right, so the tool group stays together
   (several `margin-left:auto` items would each absorb free space and spread) */
.pipe-toggle .btn-icon { margin-left: 0; }
.pipe-toggle .btn-icon:first-of-type { margin-left: auto; }
.preset-pipe-bar .btn-icon:first-of-type { margin-left: auto; }
.pipe-body { margin-top: 8px; }
.pipe-list { display: flex; flex-direction: column; gap: 6px; max-height: 340px; overflow-y: auto; padding-right: 2px; }

.pipe-row {
  display: grid; align-items: center; gap: 7px;
  /* lead · grip · name · dept · days · min · wait · deps.
     Days/Min/Wait are all the same fixed width — they hold the same kind of
     small number — and Deps takes the slack instead. */
  grid-template-columns: 20px 22px minmax(88px, 1.1fr) 90px 60px 60px 60px minmax(108px, 1.3fr);
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 7px 9px;
}
.pipe-actions { display: flex; align-items: center; gap: 4px; flex: none; }
.pipe-row:hover { border-color: var(--border-2); }
.pipe-row > * { min-width: 0; }           /* let grid children shrink instead of overflowing */
/* Bottom-align the editing row so every input shares one baseline — the
   Days/Min columns carry a label above their input, which would otherwise push
   those inputs lower than the label-less Name/Dept/Deps fields. Small controls
   (number, grip, actions) stay vertically centred. */
.pipe-row.editing { border-color: var(--accent); background: rgba(91,108,255,.06); align-items: end; }
.pipe-row.editing .pipe-lead,
.pipe-row.editing .pipe-grip,
.pipe-row.editing .pipe-actions { align-self: center; }

/* compact (read-only) row — click to expand into the editor */
.pipe-row.compact { display: flex; align-items: center; gap: 9px; padding: 6px 10px; cursor: pointer; }
.pipe-row.compact:hover { background: var(--hover); }
.pipe-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.pipe-name-ro {
  font-size: 12.5px; font-weight: 600; flex: none; max-width: 42%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pipe-deps-sum {
  flex: 1; min-width: 0; color: var(--text-3); font-size: 11px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pipe-dur {
  flex: none; font-size: 10.5px; font-weight: 700; color: var(--text-2);
  background: var(--surface-3); border: 1px solid var(--border); border-radius: 12px; padding: 2px 8px;
}
/* a task's waiting period (lag) — reads as a gap before the duration pill */
.pipe-lag {
  flex: none; font-size: 10.5px; font-weight: 700; color: #ffce8e;
  background: rgba(253,171,61,.14); border: 1px solid rgba(253,171,61,.3);
  border-radius: 12px; padding: 2px 8px;
}
/* a task's revision budget, read the same way as the old wait tag it replaced */
.pipe-rev {
  flex: none; font-size: 10.5px; font-weight: 700; color: #cbb2ff;
  background: rgba(155,91,255,.14); border: 1px solid rgba(155,91,255,.32);
  border-radius: 12px; padding: 2px 8px;
}
/* Per-revision day pickers — dropped onto their own full-width row (see
   `gridColumn: '1 / -1'` in editRow) rather than squeezed into the row's own
   fixed grid columns, since the number of dropdowns varies with Max Revisions
   and a fixed column has no give. */
.pipe-rev-block {
  display: flex; flex-direction: column; gap: 5px; margin-top: 2px;
  padding-top: 8px; border-top: 1px dashed var(--border-2);
}
.pipe-rev-block-lbl { font-size: 9px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .3px; }
.pipe-rev-days { display: flex; flex-wrap: wrap; gap: 8px; }
.pipe-rev-day { display: flex; align-items: center; gap: 5px; }
.pipe-rev-day-lbl { font-size: 10.5px; font-weight: 700; color: var(--text-3); }
.pipe-rev-sel { width: 56px; padding: 4px 6px; font-size: 11px; }

/* ---- production team (Add Show step 2, Admin → Shows → Team) ----
   One block per department the show's pipeline uses. The head is a single
   line — what the department is, how much work it holds, who's on it — with
   the "assign" picker pushed to the far end, so the blocks scan as a list of
   departments rather than a stack of forms. */
.team-intro { margin: 0 0 12px; }

/* Progress across the show, so "is this staffed" is answerable without
   counting cards — and so leaving it empty reads as a permitted choice
   rather than an unfinished form. */
.team-summary {
  display: flex; flex-direction: column; gap: 7px;
  padding: 10px 13px; margin-bottom: 12px;
  border: 1px solid var(--border-2); border-radius: 10px; background: var(--surface-2);
}
.team-summary-txt { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.team-summary-lead { font-size: 12.5px; font-weight: 700; }
.team-summary-sub { font-size: 11px; color: var(--text-3); }
.team-bar { height: 4px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.team-bar-fill {
  height: 100%; border-radius: 999px; background: var(--accent);
  transition: width .22s cubic-bezier(.2,.8,.2,1);
}
.team-summary.done .team-bar-fill { background: var(--ok, #00c875); }
.team-summary.done .team-summary-lead { color: #9fe8c4; }
.team-summary.empty .team-summary-lead { color: var(--text-2); }

/* One row per department, laid out like Admin → Software: the department on
   the left, who's on it as chips, and a (+) to add. Only assigned people are
   listed, so a row is a short answer rather than the whole directory. */
.team-rows {
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface-2); overflow: hidden;
}

/* Section headers. "Key roles" carries the add-a-role control, so the label
   and the button share the line rather than the button sitting loose above
   the rows it adds to. */
.team-sect {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 14px 2px 6px;
}
.team-sect:first-of-type { margin-top: 4px; }
.team-sect-lbl {
  font-size: 9.5px; font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .5px;
}
.team-addrole {
  flex: none; background: none; border: 1px dashed var(--border-2);
  color: var(--text-2); font: inherit; font-size: 11px; font-weight: 600;
  padding: 3px 10px; border-radius: 999px; cursor: pointer; white-space: nowrap;
}
.team-addrole:hover { border-style: solid; border-color: var(--accent); color: var(--text); }
.team-addrole:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* An oversight role has no department colour to carry, so its icon does the
   identifying instead — and reads as a different kind of row for it. */
.team-row.role .team-rowdept { color: var(--text); }
.team-role-ic { flex: none; font-size: 13px; color: var(--text-3); width: 13px; }
.team-row.role .team-dept-tasks { font-style: italic; opacity: .8; }

/* the add-a-role picker reuses .sw-menu, which expects a search box in its head */
.sw-menu-headline {
  font-size: 10px; font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .4px; padding: 2px 2px 1px;
}
.team-row {
  display: flex; align-items: center; gap: 14px;
  padding: 9px 13px; border-top: 1px solid var(--border);
}
.team-row:first-child { border-top: 0; }
/* wider than Software's 150px because this column carries the task count as
   well as the name — at 150 "Post Operations" wrapped onto two lines */
.team-rowdept { flex: none; width: 178px; display: flex; align-items: center; gap: 8px; }
.team-dept-lbl { font-size: 12.5px; font-weight: 700; white-space: nowrap; }
.team-dept-tasks { font-size: 10px; color: var(--text-3); flex: none; }
.team-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.team-none { font-size: 11.5px; color: var(--text-3); font-style: italic; }

/* A person on the show: their own colour in the avatar, the share of their
   time this show gets, the star where the department has a choice of lead. */
.team-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 7px 3px 3px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 15%, var(--bg-2));
  color: var(--text);
}
.team-chip.lead { border-color: rgba(253,171,61,.55); background: rgba(253,171,61,.13); }
.team-chip .avatar { width: 20px; height: 20px; font-size: 8px; }
.team-chip-name { font-size: 11.5px; font-weight: 600; white-space: nowrap; cursor: help; }

/* Availability: a quiet annotation until it drops to half or less, which is
   the point at which "could someone else do this" is worth asking. */
.team-pct {
  flex: none; font-size: 10px; font-weight: 700; cursor: help;
  padding: 1px 5px; border-radius: 999px;
  background: rgba(255,255,255,.07); color: var(--text-3);
}
.team-pct.thin { background: rgba(253,171,61,.16); color: #ffce8e; }

/* Manager, shown on whichever row the person already occupies — a sub-role
   marking a person, not a slot of its own. */
.team-mgr {
  flex: none; font-size: 8.5px; font-weight: 800; letter-spacing: .4px;
  padding: 1px 4px; border-radius: 4px; cursor: help;
  background: rgba(91,108,255,.22); color: #b9c2ff;
}

/* Admin directory: role and its sub-role toggle share the cell */
.adm-rolecell { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; min-width: 0; }
.adm-subrole {
  flex: none; background: none; border: 1px dashed var(--border-2);
  color: var(--text-3); font: inherit; font-size: 10px; font-weight: 700;
  padding: 2px 8px; border-radius: 999px; cursor: pointer; white-space: nowrap;
}
.adm-subrole:hover { border-style: solid; border-color: var(--accent); color: var(--text); }
.adm-subrole.on {
  border-style: solid; border-color: rgba(91,108,255,.5);
  background: rgba(91,108,255,.16); color: #b9c2ff;
}
.adm-mgr-chip {
  flex: none; font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 999px;
  background: rgba(91,108,255,.16); color: #b9c2ff; border: 1px solid rgba(91,108,255,.35);
  white-space: nowrap;
}

.team-star {
  flex: none; background: none; border: 0; padding: 0 0 0 1px; cursor: pointer;
  color: var(--text-3); font-size: 11px; line-height: 1;
}
.team-star:hover { color: #ffd479; }
.team-star.on { color: #fdab3d; }
.team-star:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.team-chip-x {
  flex: none; border: none; background: none; padding: 0 2px; color: var(--text-3);
  font: inherit; font-size: 10px; cursor: pointer; line-height: 1;
}
.team-chip-x:hover { color: var(--danger); }

.team-add {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  border: 1px dashed var(--border-2); background: none; color: var(--text-2);
  font: inherit; font-size: 12px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.team-add:hover { border-style: solid; border-color: var(--accent); color: var(--text); }
.team-add:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* the staff picker is the software picker with a face on each row */
.staff-menu-av { width: 20px; height: 20px; font-size: 8px; flex: none; }
.sw-menu-meta.thin { color: #ffce8e; }

/* the read-only roster in Admin is the same chip with nothing to click */
.team-chip.static .team-chip-name { cursor: default; }
.team-star.static { cursor: default; padding: 0; }

/* team roster shown under an expanded show row in Admin → Shows */
.show-team-view {
  border-top: 1px solid var(--border); background: rgba(0,0,0,.14);
  padding: 8px 18px 10px 41px;
}
.show-team-view-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 10px; font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .4px; margin-bottom: 7px;
}
.show-team-view-head > span { display: inline-flex; align-items: center; gap: 6px; }
.show-team-view-head .btn-mini {
  white-space: nowrap; flex: none; height: auto; width: auto;
  padding: 5px 10px; font-size: 11px; text-transform: none; letter-spacing: 0;
}
.team-dept-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.show-team-line { display: flex; align-items: center; gap: 9px; padding: 3px 0; }
.show-team-dept { font-size: 11px; font-weight: 600; color: var(--text-2); width: 118px; flex: none; }
.show-team-people { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.show-team-none { font-size: 10.5px; color: var(--text-3); font-style: italic; }
/* mandatory end-of-episode milestones — listed, but nothing to interact with */
/* ---- drag to reorder (pipeline editor) ----
   The grip is the only grab point, so a click anywhere else on the row still
   opens it for editing. Hidden until the row is hovered, like the insert ＋. */
.pipe-grip {
  flex: none; width: 22px; padding: 0;
  background: none; border: 0; color: var(--text-3); font-size: 12px; line-height: 1;
  cursor: grab; touch-action: none; user-select: none;
}
.pipe-grip:hover { color: var(--text); }
.pipe-grip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 5px; }
.pipe-row.compact .pipe-grip.hov { opacity: 0; transition: opacity .12s; }
.pipe-row.compact:hover .pipe-grip.hov,
.pipe-row.compact .pipe-grip.hov:focus-visible { opacity: 1; }

/* The lifted row follows the cursor 1:1 — no transition on it, or it would lag
   behind the pointer. Everything else glides, which is what reads as the rows
   flicking apart to open a gap. */
.pipe-list.reordering { cursor: grabbing; }
.pipe-list.reordering .pipe-row { transition: transform .18s cubic-bezier(.2,.8,.2,1); }
.pipe-list.reordering .pipe-row:hover { background: none; border-color: var(--border); }
.pipe-row.pipe-dragging {
  transition: none !important; position: relative; z-index: 3;
  background: var(--surface-2); border-color: var(--accent);
  box-shadow: 0 10px 24px rgba(0,0,0,.45); cursor: grabbing;
}
.pipe-row.pipe-dragging .pipe-grip { cursor: grabbing; color: var(--text); opacity: 1; }

/* pipeline task version-control toggle (LucidLink) */
.pipe-vc {
  flex: none; background: var(--surface-3); border: 1px solid var(--border-2); border-radius: 8px;
  font-size: 12px; line-height: 1; padding: 5px 7px; cursor: pointer; filter: grayscale(1); opacity: .5;
}
.pipe-vc:hover { opacity: .85; }
.pipe-vc.on { filter: none; opacity: 1; background: rgba(47,191,159,.16); border-color: rgba(47,191,159,.5); }
.pipe-vc-tag { flex: none; font-size: 10px; opacity: .9; }

.btn-done {
  background: none; border: none; color: #6ee0aa; font-size: 13px; font-weight: 800;
  cursor: pointer; padding: 4px; border-radius: 6px;
}
.btn-done:hover { background: rgba(0,200,117,.12); }
.pipe-num { font-size: 11px; color: var(--text-3); font-weight: 700; text-align: right; }
/* Lead cell: the row number, swapping to an insert-below ＋ on hover. Both sit
   stacked in the same box so the swap never changes the row's width. */
.pipe-lead { position: relative; width: 20px; height: 18px; flex: none; }
.pipe-lead .pipe-num,
.pipe-lead .pipe-insert {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  transition: opacity .12s;
}
.pipe-lead .pipe-insert {
  opacity: 0; padding: 0; border: 1px solid var(--border-2); border-radius: 5px;
  background: var(--surface-3); color: var(--text-2); font-size: 12px; line-height: 1; cursor: pointer;
}
.pipe-row:hover .pipe-lead .pipe-num { opacity: 0; }
.pipe-row:hover .pipe-lead .pipe-insert { opacity: 1; }
.pipe-lead .pipe-insert:hover { background: var(--accent); border-color: transparent; color: #fff; }
.pipe-lead .pipe-insert:focus-visible { opacity: 1; outline: 2px solid var(--accent); outline-offset: 1px; }
/* ---- Dependency clash: impact list + before/after picture ---- */
.si-headline {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  margin: 12px 0 4px; font-size: 13px;
}
.si-arrow { color: var(--text-3); }
.si-shift {
  font-size: 10.5px; font-weight: 700; color: #ffce8e;
  background: rgba(253,171,61,.14); border: 1px solid rgba(253,171,61,.3);
  border-radius: 12px; padding: 2px 8px;
}
.si-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.si-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 11px;
  background: rgba(255,91,110,.06); border: 1px solid rgba(255,91,110,.28); border-radius: 9px;
}
.si-item-ic { color: var(--danger); flex: none; font-size: 12px; }
.si-item-main { flex: 1; min-width: 0; }
.si-item-title { font-size: 12.5px; font-weight: 600; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.si-dir {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
  color: var(--text-3); background: var(--surface-3); border-radius: 8px; padding: 1px 6px;
}
.si-item-sub { font-size: 10.5px; color: var(--text-3); margin-top: 2px; }
.si-overlap {
  flex: none; font-size: 10.5px; font-weight: 700; color: #ffb3bd;
  background: rgba(255,91,110,.16); border-radius: 12px; padding: 2px 8px;
}

/* the picture: one row per involved task, bars positioned by date across a
   shared window. Only the moved task draws two bars (was / would be). */
.si-chart {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 12px;
}
.si-axis {
  display: flex; justify-content: space-between;
  font-size: 10px; color: var(--text-3); margin-bottom: 8px; padding-left: 122px;
}
.si-rows { display: flex; flex-direction: column; gap: 7px; }
.si-row { display: flex; align-items: center; gap: 10px; }
.si-label { flex: none; width: 112px; display: flex; align-items: center; gap: 6px; min-width: 0; }
.si-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.si-name {
  font-size: 10.5px; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.si-row-moved .si-name { color: var(--text); font-weight: 700; }
.si-tag {
  flex: none; font-size: 8.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px;
  color: var(--accent); background: rgba(91,108,255,.14); border-radius: 8px; padding: 1px 5px;
}
.si-track {
  position: relative; flex: 1; height: 22px;
  background: repeating-linear-gradient(to right, transparent 0, transparent 13px, rgba(255,255,255,.045) 13px, rgba(255,255,255,.045) 14px);
  border-radius: 4px;
}
.si-bar {
  position: absolute; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 700; white-space: nowrap; overflow: hidden; min-width: 3px;
}
/* Where it is now: a dashed, unfilled frame the full height of the track. The
   proposal is drawn shorter and centred INSIDE it, so the two stay legible when
   one contains the other — which is every stretch, where the start doesn't move
   and only the tail grows. */
.si-bar.si-old {
  top: 0; bottom: 0; background: transparent;
  border: 1px dashed var(--text-3); opacity: .8; z-index: 1;
}
.si-bar.si-new {
  top: 50%; transform: translateY(-50%); height: 12px;
  z-index: 3; box-shadow: 0 1px 5px rgba(0,0,0,.4);
}
.si-bar.si-fixed { top: 50%; transform: translateY(-50%); height: 12px; z-index: 2; opacity: .92; }
/* The days the two would run at once. A strip under the bars rather than a
   block over them — it has to mark the collision without hiding whose bar it is.
   Scoped to the track: the legend reuses this class as a static swatch. */
.si-track .si-clash {
  position: absolute; bottom: 0; height: 5px; z-index: 4; border-radius: 2px; min-width: 2px;
  background: repeating-linear-gradient(45deg, rgba(255,91,110,.9) 0, rgba(255,91,110,.9) 2px, rgba(255,91,110,.35) 2px, rgba(255,91,110,.35) 5px);
  box-shadow: 0 0 0 1px rgba(255,91,110,.55);
}
/* The delivery date, drawn down every track so the bars can be read against it.
   Solid where the promise stands, dashed where it would move to. */
.si-ms {
  position: absolute; top: -3px; bottom: -3px; width: 0; z-index: 5;
  border-left: 2px solid #e2445c;
  /* the bars underneath are department-coloured, so the line needs its own edge
     to stay a line rather than reading as part of whatever it crosses */
  box-shadow: -1px 0 0 rgba(0,0,0,.55), 1px 0 0 rgba(0,0,0,.55);
}
.si-ms.next { border-left: 2px dashed #ffce8e; }

/* The offer to move the promise with the work */
.si-del {
  border: 1px solid rgba(226,68,92,.45); background: rgba(226,68,92,.08);
  border-radius: 10px; padding: 10px 12px; margin-bottom: 14px;
}
.si-del-head { display: flex; align-items: flex-start; gap: 9px; }
.si-del-opt {
  display: flex; align-items: flex-start; gap: 9px; margin-top: 10px;
  padding-top: 10px; border-top: 1px dashed var(--border-2);
  font-size: 12.5px; cursor: pointer;
}
.si-del-opt input { margin-top: 2px; flex: none; accent-color: var(--accent); }
.si-del-note { display: block; font-size: 10.5px; color: var(--text-3); margin-top: 2px; font-weight: 400; }

.si-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 10px; }
.si-key { display: inline-flex; align-items: center; gap: 6px; font-size: 10.5px; color: var(--text-3); }
.si-swatch { width: 16px; height: 10px; border-radius: 3px; flex: none; }
.si-swatch.si-old { background: transparent; border: 1px dashed var(--text-3); }
.si-swatch.si-new { background: var(--accent); }
.si-swatch.si-swatch-ms { width: 3px; height: 12px; border-radius: 1px; background: #e2445c; }
.si-swatch.si-clash {
  height: 5px;
  background: repeating-linear-gradient(45deg, rgba(255,91,110,.9) 0, rgba(255,91,110,.9) 2px, rgba(255,91,110,.35) 2px, rgba(255,91,110,.35) 5px);
  box-shadow: 0 0 0 1px rgba(255,91,110,.55);
}

/* ---- Re-Arrange: the episode reorder list ---- */
.ra-list { display: flex; flex-direction: column; gap: 6px; max-height: 380px; overflow-y: auto; padding-right: 2px; }
.ra-empty {
  padding: 22px 14px; text-align: center; font-size: 12.5px; color: var(--text-3);
  background: var(--bg-2); border: 1px dashed var(--border-2); border-radius: 9px;
}
.ra-row {
  display: flex; align-items: center; gap: 11px; padding: 8px 11px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px;
}
.ra-row.moved { border-color: rgba(91,108,255,.45); background: rgba(91,108,255,.06); }
.ra-pos {
  flex: none; width: 20px; text-align: right;
  font-size: 11px; font-weight: 700; color: var(--text-3); font-variant-numeric: tabular-nums;
}
.ra-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ra-title { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; }
.ra-title > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ra-sub { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 10.5px; color: var(--text-3); }
.ra-delta { color: #9fb0ff; font-weight: 700; }
.ra-same { color: var(--text-3); }
.ra-lock {
  display: inline-flex; align-items: center; gap: 3px; font-weight: 700;
  color: #ffce8e; background: rgba(253,171,61,.14);
  border: 1px solid rgba(253,171,61,.3); border-radius: 12px; padding: 1px 7px;
}
.ra-lock .ico { font-size: 9px; }
.ra-move { flex: none; display: flex; flex-direction: column; gap: 2px; }

.btn-move {
  background: var(--surface-3); border: 1px solid var(--border); color: var(--text-2);
  border-radius: 4px; font-size: 7px; line-height: 1; padding: 3px 4px; cursor: pointer;
}
.btn-move:hover:not(:disabled) { color: var(--text); border-color: var(--accent); }
.btn-move:disabled { opacity: .25; cursor: default; }
.pipe-row .fld { padding: 7px 9px; font-size: 12.5px; border-radius: 7px; }
/* stack the label above the input so the number gets the full column width */
/* Days / Min / Wait all hold the same kind of small number, so they're pinned
   to one width rather than left to stretch. An explicit width beats the grid's
   default justify-self:stretch, which keeps them identical whichever track
   they land in — the narrow layout reflows them onto different tracks. */
.pipe-days { display: flex; flex-direction: column; align-items: stretch; gap: 3px; width: 60px; }
.pipe-days-lbl { font-size: 9px; line-height: 1; color: var(--text-3); font-weight: 700; text-transform: uppercase; letter-spacing: .3px; }
.fld-num { width: 100%; min-width: 0; padding: 6px 4px; text-align: center; -moz-appearance: textfield; }
.fld-num::-webkit-inner-spin-button, .fld-num::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.btn-row-x {
  background: none; border: none; color: var(--text-3); font-size: 13px;
  cursor: pointer; padding: 4px; border-radius: 6px;
}
.btn-row-x:hover { color: var(--danger); background: rgba(255,91,110,.1); }

/* shared styled hover tooltip (replaces the native title tooltip app-wide — see App.tooltip) */
.app-tooltip {
  position: fixed; z-index: 900; max-width: 280px;
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border-2);
  border-radius: 9px; padding: 8px 12px; font-size: 11.5px; font-weight: 600; line-height: 1.5;
  white-space: pre-line; text-align: left; box-shadow: var(--shadow);
  pointer-events: none; opacity: 0; visibility: hidden;
  transform: translateY(3px); transition: opacity .12s ease, transform .12s ease;
}
.app-tooltip.flip { transform: translateY(-3px); }
.app-tooltip.show { opacity: 1; visibility: visible; transform: translateY(0); }
.app-tooltip::after {
  content: ''; position: absolute; left: var(--arrow-x, 50%); transform: translateX(-50%);
  width: 0; height: 0; border: 6px solid transparent;
}
.app-tooltip:not(.flip)::after { top: 100%; border-top-color: var(--surface-2); }
.app-tooltip.flip::after { bottom: 100%; border-bottom-color: var(--surface-2); }

/* board — current-stage chip (dim = another department, mine = viewer's turn) */
.stage-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-3); border: 1px solid var(--border-2); color: var(--text);
  border-radius: 20px; padding: 3px 10px; font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.stage-chip .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.stage-chip.dim { opacity: .45; font-weight: 600; }
.stage-chip.mine {
  border-color: var(--accent); background: rgba(91,108,255,.14);
  box-shadow: 0 0 0 3px rgba(91,108,255,.12);
}
.stage-chip.done { color: #6ee0aa; border-color: rgba(0,200,117,.3); background: rgba(0,200,117,.1); }

/* dependency tags + picker */
.dep-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.dep-tag {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--surface-3); border: 1px solid var(--border-2); color: var(--text-2);
  border-radius: 20px; padding: 2px 4px 2px 9px; font-size: 10.5px; font-weight: 600;
  max-width: 130px; white-space: nowrap;
}
.dep-tag > button.dep-tag-x {
  background: none; border: none; color: var(--text-3); font-size: 9px;
  cursor: pointer; padding: 2px 4px; border-radius: 50%; line-height: 1;
}
.dep-tag > button.dep-tag-x:hover { color: var(--danger); }
.dep-add {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--surface-3); border: 1px dashed var(--border-2); color: var(--text-2);
  font-size: 11px; line-height: 1; cursor: pointer; flex: none;
}
.dep-add:hover { color: var(--accent); border-color: var(--accent); }
/* The pipeline editor lives inside the Add Show / Edit Show dialog, and this
   menu is appended to <body> to escape that dialog's own scroll container — so
   it has to clear .modal-overlay (400) or it opens behind the very dialog that
   asked for it. Still under .app-tooltip (900) and the toasts (999). */
.dep-menu {
  position: fixed; z-index: 420; min-width: 200px; max-width: 260px; max-height: 260px; overflow-y: auto;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 10px;
  box-shadow: var(--shadow); padding: 5px;
}
.dep-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: none; border: none; color: var(--text); font-size: 12px; font-family: inherit;
  padding: 7px 9px; border-radius: 7px; cursor: pointer;
}
.dep-menu-item:hover { background: var(--hover); }
.dep-menu-item .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.dep-menu-empty { color: var(--text-3); font-size: 11.5px; padding: 8px 10px; }

/* Board backups — label field + trigger above the snapshot list. The card
   itself carries no padding (its rows each own theirs), so these two set
   their own to line up with the rows between them. */
.adm-backup-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px; border-bottom: 1px solid var(--border);
}
.adm-backup-bar .fld { flex: 1; min-width: 0; padding: 8px 12px; font-size: 12.5px; }
.adm-backup-bar .adm-btn { flex: none; }
.adm-backup-cap:not(:empty) { padding: 11px 18px 13px; border-top: 1px solid var(--border); }

/* Remove-task confirmation, shown in place of the row it belongs to — this
   editor already lives inside a dialog, so a modal here would close its host. */
.pipe-row.pipe-confirm {
  display: block; border-color: #ff5b6e; background: rgba(255,91,110,.07);
}
.pc-msg { display: flex; align-items: flex-start; gap: 8px; font-size: 12.5px; font-weight: 600; }
.pc-ic { flex: none; color: #ff8a95; margin-top: 1px; }
.pc-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pc-hint { flex: 1; min-width: 140px; font-size: 11px; color: var(--text-3); }
.pc-btn { padding: 6px 12px; font-size: 11.5px; flex: none; }

/* "what depended on this?" list in the remove-task prompt */
.dep-migrate {
  margin: 10px 0 4px; display: flex; flex-direction: column; gap: 2px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 8px 10px;
  max-height: 190px; overflow-y: auto;
}
.dm-row { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 3px 0; }
.dm-row .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.dm-name { font-weight: 700; flex: none; }
.dm-arrow { color: var(--text-3); flex: none; }
.dm-new { color: var(--text-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 760px) {
  .pipe-row.editing { grid-template-columns: 22px 20px 1fr 74px 74px auto; }
  .pipe-row.editing .fld-dept, .pipe-row.editing .dep-tags { grid-column: span 3; }
  .pipe-row.editing .pipe-actions { grid-column: span 3; justify-content: flex-end; }
  .plan-grid, .plan-grid.two { grid-template-columns: 1fr; }
}

/* ----------------------------------------------------------------- planning
   Planning & Optimization: proposal intake, rate lock, simulated variants and
   the slate optimizer. Mirrors the Admin page's card/table rhythm so the two
   oversight areas feel like one system. */
.planning { max-width: 1060px; margin: 0 auto; }
.pl-crumb { display: flex; gap: 8px; align-items: center; font-size: 11.5px; font-weight: 600; color: var(--text-3); margin-bottom: 16px; }
.pl-crumb-link { cursor: pointer; transition: color .15s; }
.pl-crumb-link:hover { color: var(--accent); }
.pl-crumb-here { color: var(--text-2); }
.pl-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 14px; flex-wrap: wrap; margin-bottom: 20px; }
.pl-title { font-size: 18px; font-weight: 700; letter-spacing: -.2px; }
.pl-sub { font-size: 12px; color: var(--text-3); margin-top: 4px; max-width: 62ch; line-height: 1.5; }

.pl-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  overflow: hidden; box-shadow: var(--shadow); margin-bottom: 16px;
}
.pl-card-head { padding: 13px 18px; background: var(--bg-2); border-bottom: 1px solid var(--border); }
.pl-card-title { font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 7px; }
.pl-card-desc { font-size: 11.5px; color: var(--text-3); margin-top: 3px; line-height: 1.5; }
.pl-card-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 16px; }
.pl-brain .pl-card-title svg { color: var(--accent); }

.pl-grid { padding: 16px 18px; display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 15px 18px; }
.pl-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pl-label { font-size: 11px; font-weight: 700; color: var(--text-2); letter-spacing: .2px; }
.pl-money { display: flex; gap: 7px; }
.pl-money .pl-cur { flex: none; width: 92px; }
.pl-brief { resize: vertical; min-height: 120px; line-height: 1.55; font-family: inherit; }

/* priority + contingency sliders */
.pl-slider { display: flex; align-items: center; gap: 12px; }
.pl-range { flex: 1; min-width: 0; accent-color: var(--accent); cursor: pointer; }
.pl-slider-val {
  flex: none; min-width: 116px; text-align: right; font-size: 11.5px; font-weight: 700; color: var(--text-2);
}
.pl-cont-val { min-width: 44px; color: var(--accent); font-size: 13px; }

/* calendar rules */
.pl-check { display: grid; grid-template-columns: auto 1fr; gap: 4px 10px; align-items: center; cursor: pointer; }
.pl-check input { accent-color: var(--accent); cursor: pointer; }
.pl-check > span { font-size: 12.5px; font-weight: 600; }
.pl-check-hint { grid-column: 2; font-size: 11px; color: var(--text-3); font-weight: 400; line-height: 1.45; }
.pl-date-add-row { display: flex; gap: 8px; }
.pl-date-add { max-width: 190px; }
.pl-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.pl-tags-empty { font-size: 11.5px; color: var(--text-3); }
.pl-tag {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600;
  background: rgba(253,171,61,.14); color: #ffce8e; border: 1px solid rgba(253,171,61,.3);
  border-radius: 20px; padding: 3px 6px 3px 11px;
}
.pl-tag-x { background: transparent; border: 0; color: inherit; opacity: .7; cursor: pointer; font-size: 11px; padding: 0 3px; border-radius: 50%; }
.pl-tag-x:hover { opacity: 1; background: rgba(255,255,255,.14); }
.pl-cal-summary { border-top: 1px dashed var(--border-2); padding-top: 13px; display: flex; flex-direction: column; gap: 5px; }
.pl-cal-stat { font-size: 12px; color: var(--text-2); }
.pl-cal-stat strong { color: var(--text); }
.pl-cal-stat.dim { font-size: 11px; color: var(--text-3); }
.pl-cal-hols { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
.pl-cal-hol {
  font-size: 10px; font-weight: 600; color: var(--text-3);
  background: var(--surface-3); border: 1px solid var(--border); border-radius: 5px; padding: 2px 7px;
}

/* the system-context disclosure on the brain card */
.pl-prompt summary { font-size: 11.5px; font-weight: 600; color: var(--text-2); cursor: pointer; }
.pl-prompt summary:hover { color: var(--accent); }
.pl-prompt-text {
  margin: 9px 0 0; padding: 11px 13px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 9px; font-size: 11px; line-height: 1.6; color: var(--text-2);
  white-space: pre-wrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* proposal table */
.pl-table { }
.pl-thead, .pl-row {
  display: grid; grid-template-columns: 1.6fr .9fr .7fr 1fr 1fr 1.1fr 76px;
  align-items: center; gap: 12px; padding: 10px 18px;
}
.pl-thead { background: var(--bg-2); border-bottom: 1px solid var(--border); }
.pl-thead .cell { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; }
.pl-row { border-top: 1px solid var(--border); font-size: 12.5px; transition: background .12s; }
.pl-row:first-of-type { border-top: 0; }
.pl-row:hover { background: var(--hover); }
.pl-row .cell { min-width: 0; }
.pl-row-title { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-row-code { font-size: 10.5px; color: var(--text-3); font-weight: 700; margin-top: 1px; }
.pl-row-actions { display: flex; gap: 5px; justify-content: flex-end; }
.pl-status {
  display: inline-block; font-size: 10.5px; font-weight: 700; border-radius: 20px; padding: 3px 10px; white-space: nowrap;
}
.pl-status.draft { color: var(--text-2); background: var(--surface-3); border: 1px solid var(--border); }
.pl-status.green { color: #6ee0aa; background: rgba(0,200,117,.12); border: 1px solid rgba(0,200,117,.32); }
.pl-status.red { color: #ffb3bd; background: rgba(255,91,110,.12); border: 1px solid rgba(255,91,110,.32); }

.pl-empty { padding: 34px 18px; text-align: center; color: var(--text-2); font-size: 13px; }
.pl-empty-hint { font-size: 11.5px; color: var(--text-3); margin-top: 6px; }
.pl-actions { display: flex; justify-content: flex-end; gap: 9px; margin: 4px 0 26px; }
.pl-next {
  display: flex; align-items: center; gap: 9px; font-size: 11.5px; color: var(--text-3);
  background: var(--bg-2); border: 1px dashed var(--border-2); border-radius: 10px; padding: 11px 14px;
}
.pl-next svg { color: var(--text-3); flex: none; }

@media (max-width: 860px) {
  .pl-thead, .pl-row { grid-template-columns: 1.4fr 1fr 1fr 70px; }
  .pl-thead .cell:nth-child(3), .pl-row .cell:nth-child(3),
  .pl-thead .cell:nth-child(5), .pl-row .cell:nth-child(5),
  .pl-thead .cell:nth-child(2), .pl-row .cell:nth-child(2) { display: none; }
}

/* ---- planning: rate sheet (Step 2) ---- */
.pl-rate-head, .pl-rate-row {
  display: grid; grid-template-columns: 1.5fr .9fr .8fr .9fr .8fr .9fr;
  align-items: center; gap: 10px; padding: 9px 18px;
}
.pl-rate-head { background: var(--bg-2); border-bottom: 1px solid var(--border); }
.pl-rate-head .cell { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; }
.pl-rate-row { border-top: 1px solid var(--border); font-size: 12.5px; }
.pl-rate-row:first-of-type { border-top: 0; }
.pl-rate-row:hover { background: var(--hover); }
.pl-rate-dept { display: flex; align-items: center; gap: 8px; font-weight: 600; }
.pl-rate-dept .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.pl-rate .pl-unit, .pl-rate { min-width: 0; }
.pl-rate { text-align: right; }
.pl-rate:disabled { opacity: .35; }
.pl-switch-lab { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-2); cursor: pointer; }
.pl-switch-lab input { accent-color: var(--accent); cursor: pointer; }

.pl-issues { border-radius: 10px; padding: 11px 14px; margin-bottom: 16px; font-size: 12px; }
.pl-issues.ok { background: rgba(0,200,117,.09); border: 1px solid rgba(0,200,117,.28); color: #6ee0aa; }
.pl-issues.bad { background: rgba(255,91,110,.09); border: 1px solid rgba(255,91,110,.28); color: #ffb3bd; }
.pl-issues-head { display: flex; align-items: center; gap: 8px; font-weight: 700; }
.pl-issue { margin-top: 5px; padding-left: 24px; font-size: 11.5px; opacity: .85; }
.btn-mini.warn { border-color: rgba(253,171,61,.5); color: #ffce8e; }

/* ---- planning: variant tabs + stats (Step 3) ---- */
.pl-head-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.pl-tabs { display: flex; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.pl-tab {
  flex: 1; min-width: 160px; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: 11px;
  padding: 10px 13px; display: flex; flex-direction: column; gap: 2px; transition: border-color .14s, background .14s;
}
.pl-tab:hover { border-color: var(--border-2); background: var(--hover); }
.pl-tab.active { border-color: var(--accent); background: rgba(91,108,255,.09); }
.pl-tab-key { font-size: 10px; font-weight: 800; letter-spacing: .5px; text-transform: uppercase; color: var(--text-3); }
.pl-tab.active .pl-tab-key { color: var(--accent); }
.pl-tab-name { font-size: 12.5px; font-weight: 700; color: var(--text); }
.pl-variant-note { font-size: 11.5px; color: var(--text-3); line-height: 1.5; margin: 0 2px 16px; max-width: 78ch; }

.pl-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-bottom: 16px; }
.pl-stat {
  background: var(--surface); border: 1px solid var(--border); border-radius: 11px; padding: 12px 14px;
  position: relative; overflow: hidden;
}
.pl-stat::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--accent); opacity: .8; }
.pl-stat.good::before { background: var(--st-approved); }
.pl-stat.bad::before { background: var(--danger); }
.pl-stat-lab { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .6px; color: var(--text-3); }
.pl-stat-val { font-size: 17px; font-weight: 800; letter-spacing: -.3px; margin-top: 5px; }
.pl-stat.bad .pl-stat-val { color: #ffb3bd; }
.pl-stat.good .pl-stat-val { color: #6ee0aa; }
.pl-stat-sub { font-size: 10.5px; color: var(--text-3); margin-top: 3px; }

/* ---- planning: phase gantt ---- */
.pl-g-scroll { overflow-x: auto; overscroll-behavior-x: contain; }
.pl-g-inner { position: relative; min-width: max-content; }
.pl-g-grid { position: relative; height: 18px; }
.pl-g-off { position: absolute; top: 0; bottom: -10000px; background: rgba(255,255,255,.035); }
.pl-g-off.hol { background: rgba(253,171,61,.13); }
.pl-g-tick { position: absolute; top: 0; bottom: -10000px; border-left: 1px solid var(--border-2); }
.pl-g-tick-lab { position: absolute; top: 1px; left: 4px; font-size: 9px; font-weight: 700; color: var(--text-3); white-space: nowrap; }
.pl-g-rows { position: relative; }
.pl-g-row { display: flex; align-items: stretch; min-height: 26px; border-top: 1px solid var(--border); }
.pl-g-lab {
  position: sticky; left: 0; z-index: 3; width: 128px; min-width: 128px;
  display: flex; align-items: center; gap: 7px; padding: 0 10px;
  background: var(--surface); border-right: 1px solid var(--border-2);
  font-size: 10.5px; font-weight: 600;
}
.pl-g-lab .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.pl-g-track { position: relative; flex: 1; }
.pl-g-bar {
  position: absolute; top: 50%; transform: translateY(-50%); height: 13px; border-radius: 4px;
  display: flex; align-items: center; padding: 0 4px; font-size: 8.5px; font-weight: 800;
  color: rgba(0,0,0,.62); overflow: hidden; box-shadow: 0 1px 4px rgba(0,0,0,.3);
}
.pl-g-key { display: flex; gap: 14px; margin-top: 10px; font-size: 10.5px; color: var(--text-3); }
.pl-g-key-item { display: inline-flex; align-items: center; gap: 6px; }
.pl-g-key-sw { width: 12px; height: 10px; border-radius: 3px; background: rgba(255,255,255,.06); border: 1px solid var(--border); }
.pl-g-key-sw.hol { background: rgba(253,171,61,.2); border-color: rgba(253,171,61,.35); }

/* ---- planning: budget ledger ---- */
.pl-led-head, .pl-led-row {
  display: grid; grid-template-columns: 1.5fr .8fr 1fr 1fr 1fr; gap: 10px;
  padding: 8px 2px; align-items: center; font-size: 12px;
}
.pl-led-head { border-bottom: 1px solid var(--border); }
.pl-led-head .cell { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; }
.pl-led-head .cell:not(:first-child), .pl-led-row .cell:not(:first-child) { text-align: right; }
.pl-led-row { border-top: 1px solid var(--border); }
.pl-led-row:first-of-type { border-top: 0; }
.pl-led-dept { display: flex; align-items: center; gap: 8px; }
.pl-led-dept .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.pl-led-sub { font-weight: 700; font-variant-numeric: tabular-nums; }
.pl-led-row.total { color: var(--text-2); border-top: 1px solid var(--border-2); }
.pl-led-row.grand { border-top: 2px solid var(--border-2); font-size: 13.5px; font-weight: 800; color: var(--text); }

.pl-budget-bar { margin-top: 16px; }
.pl-bb-track { height: 9px; border-radius: 6px; background: var(--surface-3); overflow: hidden; }
.pl-bb-fill { height: 100%; border-radius: 6px; background: var(--st-approved); transition: width .3s ease; }
.pl-bb-fill.over { background: var(--danger); }
.pl-bb-meta { display: flex; justify-content: space-between; gap: 10px; margin-top: 7px; font-size: 11.5px; color: var(--text-3); flex-wrap: wrap; }
.pl-bb-delta { font-weight: 700; }
.pl-bb-delta.over { color: #ffb3bd; }
.pl-bb-delta.under { color: #6ee0aa; }

@media (max-width: 860px) {
  .pl-rate-head, .pl-rate-row { grid-template-columns: 1.2fr .8fr .8fr .8fr; }
  .pl-rate-head .cell:nth-child(5), .pl-rate-row .cell:nth-child(5),
  .pl-rate-head .cell:nth-child(6), .pl-rate-row .cell:nth-child(6) { display: none; }
  .pl-led-head, .pl-led-row { grid-template-columns: 1.3fr 1fr 1fr; }
  .pl-led-head .cell:nth-child(2), .pl-led-row .cell:nth-child(2),
  .pl-led-head .cell:nth-child(3), .pl-led-row .cell:nth-child(3) { display: none; }
}

/* ---- planning: role-level rate sheet ---- */
.pl-rate-head, .pl-rate-row {
  grid-template-columns: 1.5fr 92px 92px 78px 1fr 78px 1fr 34px;
}
.pl-rate-group {
  display: flex; align-items: center; gap: 10px; padding: 9px 18px;
  background: var(--bg-2); border-top: 1px solid var(--border-2);
}
.pl-rate-group:first-of-type { border-top: 0; }
.pl-rate-group-name { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 800; }
.pl-rate-group-name .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.pl-rate-count { font-size: 10.5px; font-weight: 600; color: var(--text-3); }
.pl-rate-group .btn-mini { margin-left: auto; width: auto; padding: 0 9px; font-size: 11px; font-weight: 700; }
.pl-rate-none { padding: 9px 18px 9px 36px; font-size: 11.5px; color: #ffce8e; }
.pl-rate-row.off { opacity: .5; }
.pl-role-name { font-size: 12px; }
.pl-heads-cell { display: flex; align-items: center; gap: 7px; }
.pl-heads { width: 48px; text-align: center; }
.pl-role-share { font-size: 10px; font-weight: 700; color: var(--text-3); }
.pl-rate-x { display: flex; justify-content: flex-end; }

/* role detail lines under each department in the ledger */
.pl-led-row.role { font-size: 11.5px; color: var(--text-3); border-top: 0; }
.pl-led-row.role .pl-led-sub { font-weight: 600; color: var(--text-2); }
.pl-led-role { padding-left: 18px; }

/* Narrow screens drop Unit and Crew (both have sane defaults) rather than the
   In-house/Contractor toggles — losing those would leave two unlabelled rate
   columns and no way to switch how a role is staffed. */
@media (max-width: 980px) {
  .pl-rate-head, .pl-rate-row { grid-template-columns: 1.2fr 74px 1fr 74px 1fr 32px; }
  .pl-rate-head .cell:nth-child(2), .pl-rate-row .cell:nth-child(2),
  .pl-rate-head .cell:nth-child(3), .pl-rate-row .cell:nth-child(3) { display: none; }
}

/* ---- planning: portfolio slate (Step 4) ---- */
.pl-thead, .pl-row { grid-template-columns: 30px 1.5fr .85fr .65fr .95fr .95fr 1.25fr 100px; }
.pl-row.picked { background: rgba(91,108,255,.08); box-shadow: inset 2px 0 0 var(--accent); }
.pl-row-pick { display: flex; align-items: center; }
.pl-row-pick input { accent-color: var(--accent); cursor: pointer; }
.pl-slate-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.pl-slate-tools { display: flex; align-items: center; gap: 8px; }
.pl-year-lab { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .6px; color: var(--text-3); }
.pl-year { width: 116px; }
.pl-slate-tag {
  margin-left: 7px; font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px;
  color: var(--accent); background: rgba(91,108,255,.14); border: 1px solid rgba(91,108,255,.34);
  border-radius: 4px; padding: 1px 5px;
}
.pl-status-sel { font-size: 11.5px; font-weight: 700; padding: 5px 8px; }
.pl-status-sel.green { color: #6ee0aa; border-color: rgba(0,200,117,.38); }
.pl-status-sel.red { color: #ffb3bd; border-color: rgba(255,91,110,.38); }
.pl-status-sel.draft { color: var(--text-2); }

.pl-optbar {
  position: sticky; bottom: 10px; display: flex; align-items: center; gap: 12px;
  background: var(--surface-2); border: 1px solid var(--accent); border-radius: 12px;
  padding: 11px 14px; box-shadow: var(--shadow); margin-top: 4px;
}
.pl-optbar-txt { flex: 1; font-size: 12px; color: var(--text-2); }
.pl-optbar-txt strong { color: var(--text); }

/* proposed moves table */
.pl-moves-head, .pl-moves-row {
  display: grid; grid-template-columns: 1.4fr 1.5fr .8fr .9fr 1.1fr 1fr;
  gap: 10px; padding: 9px 18px; align-items: center; font-size: 12px;
}
.pl-moves-head { background: var(--bg-2); border-bottom: 1px solid var(--border); }
.pl-moves-head .cell { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .6px; }
.pl-moves-row { border-top: 1px solid var(--border); }
.pl-moves-row:first-of-type { border-top: 0; }
.pl-moves-name { font-weight: 700; }
.pl-moves-cost { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
.pl-shift { font-size: 11px; font-weight: 800; color: #ffce8e; background: rgba(253,171,61,.14); border-radius: 5px; padding: 2px 7px; }
.pl-shift.none { color: var(--text-3); background: var(--surface-3); font-weight: 600; }

@media (max-width: 980px) {
  .pl-thead, .pl-row { grid-template-columns: 28px 1.4fr 1fr 1.2fr 76px; }
  .pl-thead .cell:nth-child(3), .pl-row .cell:nth-child(3),
  .pl-thead .cell:nth-child(4), .pl-row .cell:nth-child(4),
  .pl-thead .cell:nth-child(6), .pl-row .cell:nth-child(6) { display: none; }
  .pl-moves-head, .pl-moves-row { grid-template-columns: 1.3fr .8fr 1fr 1fr; }
  .pl-moves-head .cell:nth-child(2), .pl-moves-row .cell:nth-child(2),
  .pl-moves-head .cell:nth-child(4), .pl-moves-row .cell:nth-child(4) { display: none; }
}

/* ---- task knowledge base ---- */
/* Eight columns since the Anim/Live pair went away — each show type now has
   its own library, so a per-row type toggle no longer means anything. */
.pl-kb-head, .pl-kb-row {
  display: grid; grid-template-columns: 1.7fr 118px 62px 62px 56px 74px 58px 34px;
  gap: 9px; padding: 8px 18px; align-items: center;
}
.pl-kb-head { background: var(--bg-2); border-bottom: 1px solid var(--border); }
.pl-kb-head .cell { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .5px; }
.pl-kb-row { border-top: 1px solid var(--border); font-size: 12px; }
.pl-kb-row.off { opacity: .42; }
.pl-kb-group {
  display: flex; align-items: center; gap: 10px; padding: 9px 18px;
  background: var(--bg-2); border-top: 1px solid var(--border-2);
}
.pl-kb-group .btn-mini { margin-left: auto; width: auto; padding: 0 9px; font-size: 11px; font-weight: 700; }
.pl-kb-namecell { display: flex; align-items: center; gap: 8px; }
.pl-kb-namecell input[type=checkbox] { accent-color: var(--accent); cursor: pointer; flex: none; }
.pl-kb-name { font-size: 12px; min-width: 0; }
.pl-kb-num { text-align: center; padding-left: 4px; padding-right: 4px; }
.pl-kb-scope { font-size: 11.5px; }
.pl-kb-totalcell { text-align: center; }
.pl-kb-total { font-size: 11.5px; font-weight: 800; color: var(--accent); }
/* Animation / Live Action switch — these are two separate libraries, so the
   control reads as a pair of tabs rather than a filter. */
.pl-kb-types-bar { display: flex; gap: 6px; margin: 0 0 16px; flex: none; }
.pl-kb-typetab {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--border-2); background: var(--bg-2); color: var(--text-2);
  font-size: 12.5px; font-weight: 700; padding: 8px 15px; border-radius: 9px; cursor: pointer;
  transition: background .13s, color .13s, border-color .13s;
}
.pl-kb-typetab:hover { background: var(--hover); color: var(--text); }
.pl-kb-typetab.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.pl-kb-typecount {
  font-size: 10.5px; font-weight: 800; padding: 1px 7px; border-radius: 999px;
  background: rgba(255,255,255,.14);
}
.pl-kb-typetab:not(.active) .pl-kb-typecount { background: var(--bg); color: var(--text-3); }

.pl-kb-summary { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.pl-kb-sum-lab { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .6px; color: var(--text-3); }
.pl-kb-sum-val { font-size: 16px; font-weight: 800; margin-top: 3px; }
.pl-kb-sum-sub { font-size: 10.5px; color: var(--text-3); margin-top: 2px; }
.pl-kb-summary .btn-ghost { margin-left: auto; }

/* Hiding Scope (2) leaves seven visible cells — the track count has to match or
   the delete button wraps and doubles every row's height. Cell 8 is now that
   delete button, so it must stay visible. */
@media (max-width: 980px) {
  .pl-kb-head, .pl-kb-row { grid-template-columns: 1.4fr 50px 50px 46px 58px 50px 32px; gap: 7px; }
  .pl-kb-head .cell:nth-child(2), .pl-kb-row .cell:nth-child(2) { display: none; }
}

/* ---- stage flow: the pipeline as a picture ---- */
.kbf-strip {
  display: flex; gap: 2px; padding: 14px 18px 18px; align-items: stretch;
  overflow-x: auto;
}
.kbf-seg {
  min-width: 30px; border-radius: 6px; padding: 9px 4px 7px; text-align: center;
  background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 62%, #000));
  color: #fff; flex: none; display: flex; flex-direction: column; gap: 2px; justify-content: center;
}
.kbf-seg-n { font-size: 10.5px; font-weight: 800; opacity: .85; }
.kbf-seg-d { font-size: 11px; font-weight: 800; }

.kbf-cols { display: flex; gap: 10px; padding: 14px 18px 18px; overflow-x: auto; align-items: flex-start; }
.kbf-col {
  flex: none; width: 190px; background: var(--bg-2);
  border: 1px solid var(--border); border-radius: 11px; overflow: hidden;
}
.kbf-col-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 9px 11px; background: var(--bg); border-bottom: 1px solid var(--border);
}
.kbf-col-n { font-size: 11px; font-weight: 800; }
.kbf-col-d { font-size: 10.5px; font-weight: 800; color: var(--accent); }
.kbf-col-body { padding: 8px; display: flex; flex-direction: column; gap: 7px; min-height: 62px; transition: background .13s; }
.kbf-col-body.over { background: rgba(91,108,255,.14); }
.kbf-card {
  background: var(--surface); border: 1px solid var(--border-2); border-radius: 9px;
  padding: 8px 9px; cursor: grab; transition: border-color .13s, transform .08s;
}
.kbf-card:hover { border-color: var(--accent); }
.kbf-card.dragging { opacity: .45; cursor: grabbing; }
.kbf-card-top { display: flex; align-items: center; gap: 6px; }
/* the shared .dot has no size of its own outside a chip, so give it one here —
   the department colour is the only thing telling these cards apart */
.kbf-card-top .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.kbf-card-name { font-size: 11.5px; font-weight: 700; line-height: 1.3; }
.kbf-card-meta { display: flex; justify-content: space-between; gap: 6px; margin-top: 5px; font-size: 10px; color: var(--text-3); }
.kbf-card-scope { opacity: .8; }

/* ---- crafted pipeline ---- */
.pl-sigs { display: flex; flex-wrap: wrap; gap: 8px; }
.pl-sig {
  display: inline-flex; align-items: baseline; gap: 7px; padding: 5px 11px;
  background: rgba(91,108,255,.12); border: 1px solid rgba(91,108,255,.32); border-radius: 20px;
}
.pl-sig-lab { font-size: 11.5px; font-weight: 700; color: var(--text); }
.pl-sig-hit { font-size: 10.5px; color: var(--accent); font-style: italic; }
.pl-sig-none { font-size: 12px; color: var(--text-3); }

.pl-notes { display: flex; flex-direction: column; gap: 6px; }
.pl-note { display: flex; align-items: flex-start; gap: 8px; font-size: 11.5px; line-height: 1.5; padding: 7px 11px; border-radius: 8px; }
.pl-note svg { flex: none; margin-top: 1px; }
.pl-note.ok { background: rgba(0,200,117,.09); border: 1px solid rgba(0,200,117,.24); color: #8fe6bb; }
.pl-note.info { background: rgba(91,108,255,.09); border: 1px solid rgba(91,108,255,.24); color: #b9c1ff; }
.pl-note.warn { background: rgba(253,171,61,.10); border: 1px solid rgba(253,171,61,.3); color: #ffce8e; }

.pl-craft-head, .pl-craft-row {
  display: grid; grid-template-columns: 1.5fr 74px 54px 54px 116px 58px 1.6fr;
  gap: 9px; padding: 8px 18px; align-items: center;
}
.pl-craft-head { background: var(--bg-2); border-bottom: 1px solid var(--border); }
.pl-craft-head .cell { font-size: 10px; font-weight: 800; color: var(--text-3); text-transform: uppercase; letter-spacing: .5px; }
.pl-craft-row { border-top: 1px solid var(--border); font-size: 12px; }
.pl-craft-row.off { opacity: .4; }
.pl-craft-row.off .pl-craft-name { text-decoration: line-through; }
.pl-craft-row.manual { box-shadow: inset 2px 0 0 var(--accent); }
.pl-craft-name { font-weight: 600; }
.pl-craft-scope { font-size: 10.5px; color: var(--text-3); }
.pl-craft-rev { display: flex; align-items: center; gap: 7px; }
.pl-craft-delta { font-size: 9.5px; font-weight: 800; white-space: nowrap; }
.pl-craft-delta.down { color: #ffce8e; }
.pl-craft-delta.up { color: #b9c1ff; }
.pl-craft-why {
  font-size: 10.5px; color: var(--text-3); line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.btn-mini.on { border-color: rgba(91,108,255,.55); color: var(--accent); }

@media (max-width: 980px) {
  .pl-craft-head, .pl-craft-row { grid-template-columns: 1.4fr 50px 104px 54px; }
  .pl-craft-head .cell:nth-child(2), .pl-craft-row .cell:nth-child(2),
  .pl-craft-head .cell:nth-child(4), .pl-craft-row .cell:nth-child(4),
  .pl-craft-head .cell:nth-child(7), .pl-craft-row .cell:nth-child(7) { display: none; }
}

/* negated signals — shown as ignored, not hidden */
.pl-sig-cancel-lab {
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .6px;
  color: var(--text-3); margin-top: 4px;
}
.pl-sig.cancelled {
  background: var(--surface-3); border-color: var(--border); opacity: .8;
}
.pl-sig.cancelled .pl-sig-lab { color: var(--text-3); text-decoration: line-through; }
.pl-sig.cancelled .pl-sig-hit { color: #ffce8e; font-style: normal; }

/* ============================================================================
   Schedule Assistant — the Timeline's chat overlay (js/assistant.js)

   Fixed to the viewport bottom-right and mounted on <body>, so it survives the
   view being torn down and rebuilt on every render. It sits above the chart
   and the toasts' lane but below modals (z 400) — a dialog opened from
   anywhere must still cover it.
   ============================================================================ */
.ai-root { position: fixed; right: 22px; bottom: 22px; z-index: 380; display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }
.ai-root.hidden { display: none; }

/* the circle: sparkle normally, ✕ once the panel is up */
.ai-fab {
  width: 52px; height: 52px; border-radius: 50%; flex: none;
  border: 1px solid var(--border-2); background: var(--accent); color: #fff;
  display: grid; place-items: center; cursor: pointer; box-shadow: var(--shadow);
  transition: transform .16s ease, background .16s ease;
}
.ai-fab:hover { transform: translateY(-2px) scale(1.04); background: var(--accent-2); }
.ai-fab:active { transform: translateY(0) scale(.97); }
.ai-fab svg { width: 22px; height: 22px; }
.ai-fab-x { display: none; font-size: 17px; font-weight: 700; line-height: 1; }
.ai-root.open .ai-fab-ic { display: none; }
.ai-root.open .ai-fab-x { display: block; }

/* the panel — collapsed to nothing until .open, so there's one element to
   animate rather than a mount/unmount that would drop the transcript */
.ai-panel {
  width: min(400px, calc(100vw - 44px));
  /* stops short of the toolbar on purpose: the assistant is scoped to the show
     filter up there, so that filter has to stay readable and reachable while
     the panel is open */
  max-height: min(560px, calc(100vh - 250px));
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 16px; box-shadow: var(--shadow); overflow: hidden;
  display: flex; flex-direction: column;
  opacity: 0; transform: translateY(10px) scale(.97); transform-origin: 100% 100%;
  pointer-events: none; visibility: hidden;
  transition: opacity .17s ease, transform .17s ease, visibility .17s;
}
.ai-root.open .ai-panel { opacity: 1; transform: none; pointer-events: auto; visibility: visible; }

.ai-head { display: flex; align-items: flex-start; gap: 10px; padding: 13px 14px; border-bottom: 1px solid var(--border); background: var(--surface-3); }
.ai-head-main { flex: 1; min-width: 0; }
.ai-title { display: flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: 700; color: var(--text); }
.ai-title svg { width: 15px; height: 15px; }
.ai-scope { margin-top: 3px; font-size: 11px; font-weight: 600; color: var(--text-2); }
.ai-scope.none { color: var(--warn, #ffce8e); }
.ai-close { border: 0; background: none; color: var(--text-3); font-size: 14px; cursor: pointer; padding: 2px 4px; border-radius: 6px; }
.ai-close:hover { color: var(--text); background: var(--surface); }

.ai-log { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }

.ai-msg { display: flex; }
.ai-msg.me { justify-content: flex-end; }
.ai-bubble { max-width: 92%; border-radius: 13px; padding: 9px 12px; font-size: 12.5px; line-height: 1.5; }
.ai-msg.assistant .ai-bubble { background: var(--surface-3); color: var(--text); border: 1px solid var(--border); border-bottom-left-radius: 5px; }
.ai-msg.me .ai-bubble { background: var(--accent); color: #fff; border-bottom-right-radius: 5px; }
.ai-hint, .ai-note { margin-top: 7px; font-size: 11.5px; color: var(--text-2); line-height: 1.5; }

/* the plan card — what would change, before it changes */
.ai-plan { margin-top: 9px; border: 1px solid var(--border-2); border-radius: 11px; background: var(--surface); overflow: hidden; }
/* an answer is the same card without the plan's title bar or buttons — the
   reply text above it is the heading */
.ai-plan.ai-answer { margin-top: 8px; }
.ai-plan.ai-answer .ai-rows { padding: 9px 11px; }
.ai-plan.ai-answer .ai-plan-note { padding: 0 11px 9px; }
.ai-plan-title { padding: 9px 11px; font-size: 12px; font-weight: 700; color: var(--text); border-bottom: 1px solid var(--border); background: var(--surface-2); }
.ai-plan-note { padding: 8px 11px 0; font-size: 11px; line-height: 1.5; color: var(--text-2); }
.ai-rows { padding: 8px 11px; display: flex; flex-direction: column; gap: 5px; }
.ai-row { display: flex; gap: 8px; align-items: baseline; font-size: 11.5px; }
.ai-row.muted { opacity: .5; }
.ai-row-code { flex: none; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.ai-row-text { color: var(--text-2); line-height: 1.45; }
.ai-warn { display: flex; gap: 6px; align-items: flex-start; margin: 0 11px 9px; padding: 7px 9px; border-radius: 8px; font-size: 11px; line-height: 1.45; background: rgba(255,91,110,.10); border: 1px solid rgba(255,91,110,.28); color: #ffb4bd; }
.ai-warn svg { width: 13px; height: 13px; flex: none; margin-top: 1px; }
.ai-done { display: flex; gap: 6px; align-items: center; margin: 9px 11px; padding: 7px 9px; border-radius: 8px; font-size: 11.5px; background: rgba(0,200,117,.11); border: 1px solid rgba(0,200,117,.30); color: #6ee0aa; }
.ai-done svg { width: 13px; height: 13px; flex: none; }

/* Both inks above are pitched for a dark canvas; on a light theme they wash
   out to near-invisible, so the light modes darken them (this is what
   data-mode is for — see the theme note in state.js). */
:root[data-mode="light"] .ai-warn { color: #b3222f; background: rgba(255,91,110,.09); }
:root[data-mode="light"] .ai-done { color: #14724a; background: rgba(0,200,117,.10); }

.ai-actions { display: flex; gap: 8px; padding: 10px 11px; border-top: 1px solid var(--border); }
.ai-apply { display: inline-flex; align-items: center; gap: 6px; border: 0; background: var(--accent); color: #fff; font-size: 11.5px; font-weight: 700; padding: 7px 12px; border-radius: 8px; cursor: pointer; }
.ai-apply:hover { background: var(--accent-2); }
.ai-apply svg { width: 13px; height: 13px; }
.ai-cancel { border: 1px solid var(--border-2); background: none; color: var(--text-2); font-size: 11.5px; font-weight: 600; padding: 7px 12px; border-radius: 8px; cursor: pointer; }
.ai-cancel:hover { color: var(--text); background: var(--surface-3); }

/* Suggestions live in the transcript, offered when a turn finishes — they're
   also the only command reference there is, and every one of them has been
   run through the interpreter before being shown, so they all work. */
.ai-suggest { display: flex; flex-direction: column; gap: 6px; margin: 2px 0 4px; }
.ai-suggest-lab { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
.ai-suggest-list { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.ai-chip {
  max-width: 100%; border: 1px dashed var(--border-2); background: var(--surface);
  color: var(--text-2); font-size: 11.5px; font-weight: 600; font-family: inherit;
  padding: 6px 11px; border-radius: 999px; cursor: pointer; text-align: left; line-height: 1.35;
  transition: color .14s ease, border-color .14s ease, background .14s ease;
}
.ai-chip:hover { color: var(--text); border-color: var(--accent); border-style: solid; background: var(--surface-3); }

.ai-input { display: flex; gap: 8px; padding: 11px 14px; border-top: 1px solid var(--border); background: var(--surface-3); }
.ai-input input {
  flex: 1; min-width: 0; background: var(--surface); border: 1px solid var(--border-2);
  color: var(--text); border-radius: 9px; padding: 8px 11px; font-size: 12.5px; font-family: inherit;
}
.ai-input input:focus { outline: none; border-color: var(--accent); }
.ai-send { flex: none; border: 0; background: var(--accent); color: #fff; width: 34px; border-radius: 9px; cursor: pointer; font-size: 13px; }
.ai-send:hover { background: var(--accent-2); }

@media (max-width: 640px) {
  .ai-root { right: 14px; bottom: 14px; }
  .ai-panel { max-height: calc(100vh - 110px); }
}

/* ============================================================================
   Contextual task chat (js/chat.js) — the conversation inside the Edit Task
   dialog, below the workspace section. Sits in the modal's normal flow rather
   than floating: it is part of the task, not an overlay on it.
   ============================================================================ */
.chat { margin-top: 2px; }
.chat-head { display: flex; justify-content: flex-end; margin-bottom: 8px; }
.chat-rev-pill {
  font-size: 10px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-2);
  background: var(--surface-3); border: 1px solid var(--border);
  padding: 2px 8px; border-radius: 999px;
}

/* Unavailable is the ordinary state in local dev (no DATABASE_URL), so it is
   a quiet note; .bad is reserved for something actually going wrong. */
.chat-note {
  display: flex; align-items: center; gap: 7px;
  font-size: 11.5px; line-height: 1.5; color: var(--text-2);
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 9px; padding: 9px 11px;
}
.chat-note svg { width: 14px; height: 14px; flex: none; }
.chat-note.bad { color: #ffb4bd; background: rgba(255,91,110,.09); border-color: rgba(255,91,110,.28); }
:root[data-mode="light"] .chat-note.bad { color: #b3222f; }

.chat-log {
  max-height: 300px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 12px;
  padding: 12px; margin-bottom: 10px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px;
}
.chat-empty { font-size: 11.5px; color: var(--text-3); text-align: center; padding: 14px 0; }

.chat-msg { display: flex; gap: 9px; align-items: flex-start; }
.chat-av { width: 26px; height: 26px; font-size: 10px; flex: none; background: var(--surface-3); color: var(--text-2); }
.chat-msg.mine .chat-av { background: var(--accent); color: #fff; }
.chat-body { min-width: 0; flex: 1; }
.chat-meta { font-size: 10.5px; color: var(--text-3); margin-bottom: 2px; }
.chat-who { font-weight: 700; color: var(--text-2); }
.chat-text { font-size: 12.5px; line-height: 1.5; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.chat-refs { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.chat-ref {
  font-size: 10px; font-weight: 600; color: var(--text-2);
  background: var(--surface-3); border: 1px solid var(--border);
  padding: 2px 7px; border-radius: 999px;
}

/* A revision divider is a rule across the thread, not a message — the
   conversation continues through it. */
.chat-divider {
  display: flex; align-items: center; gap: 10px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-3);
  margin: 2px 0;
}
.chat-divider::before, .chat-divider::after {
  content: ''; flex: 1; height: 1px; background: var(--border-2);
}
.chat-divider::before { flex: 0 0 10px; }
.chat-divider-at { text-transform: none; letter-spacing: 0; font-weight: 600; opacity: .7; }

.chat-compose { display: flex; flex-direction: column; gap: 8px; }
.chat-input {
  width: 100%; resize: vertical; min-height: 46px;
  background: var(--surface); border: 1px solid var(--border-2); border-radius: 9px;
  color: var(--text); font-family: inherit; font-size: 12.5px; line-height: 1.5; padding: 9px 11px;
}
.chat-input:focus { outline: none; border-color: var(--accent); }
.chat-input:disabled { opacity: .6; }

.chat-actions { display: flex; gap: 8px; justify-content: flex-end; }
.chat-send {
  border: 0; background: var(--accent); color: #fff; font-family: inherit;
  font-size: 11.5px; font-weight: 700; padding: 7px 14px; border-radius: 8px; cursor: pointer;
}
.chat-send:hover { background: var(--accent-2); }
.chat-send:disabled { opacity: .6; cursor: default; }
.chat-rev {
  display: inline-flex; align-items: center; gap: 6px; margin-right: auto;
  border: 1px solid var(--border-2); background: none; color: var(--text-2);
  font-family: inherit; font-size: 11.5px; font-weight: 600;
  padding: 7px 12px; border-radius: 8px; cursor: pointer;
}
.chat-rev:hover { color: var(--text); background: var(--surface-3); }
.chat-rev svg { width: 13px; height: 13px; }

.chat-revrow { display: flex; gap: 6px; align-items: center; }
.chat-revrow.hidden { display: none; }
.chat-revlabel {
  flex: 1; min-width: 0; background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 8px; color: var(--text); font-family: inherit; font-size: 12px; padding: 7px 10px;
}
.chat-revlabel:focus { outline: none; border-color: var(--accent); }
.chat-rev-go, .chat-rev-x {
  border: 1px solid var(--border-2); background: none; color: var(--text-2);
  font-family: inherit; font-size: 11.5px; font-weight: 600;
  padding: 7px 11px; border-radius: 8px; cursor: pointer; flex: none;
}
.chat-rev-go { background: var(--accent); border-color: var(--accent); color: #fff; }
.chat-rev-go:hover { background: var(--accent-2); }
.chat-rev-x:hover { color: var(--text); background: var(--surface-3); }

/* ---- floating tab strip (js/dialog.js modalTabs) ---------------------------
   Only the Edit Task dialog uses these, with a null title (see the `tabbed`
   branch of card() in dialog.js) — no header bar at all. The tabs float
   above the card's own top edge like sticky-note tabs poking out of a
   folder, positioned absolutely so they take no layout space. The active
   tab's background matches the card and dips 1px into its top border,
   erasing that stretch of it so the tab reads as fused to the body beneath —
   the same illusion a foreground browser tab uses. */
.modal-card.tabbed { position: relative; }
.modal-card.tabbed > .modal-tabs {
  position: absolute; top: 0; left: 18px; transform: translateY(-100%);
  display: flex; gap: 4px; z-index: 2;
}
.modal-tab {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--border-2); border-bottom: none;
  background: var(--bg-2); color: var(--text-3);
  font-family: inherit; font-size: 13px; font-weight: 700;
  padding: 9px 16px; border-radius: 10px 10px 0 0; cursor: pointer;
  transition: color .14s ease, background .14s ease;
}
.modal-tab:hover { color: var(--text-2); }
.modal-tab.active {
  color: var(--text); background: var(--surface);
  margin-bottom: -1px; padding-bottom: 10px;
}
.modal-tab-badge {
  min-width: 17px; text-align: center;
  font-size: 10px; font-weight: 700; line-height: 1.6;
  color: var(--text-2); background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 999px; padding: 0 5px;
}
.modal-tab.active .modal-tab-badge { color: #fff; background: var(--accent); border-color: var(--accent); }
.modal-tab-badge.hidden { display: none; }
.modal-card.tabbed > .float-x { position: absolute; top: 14px; right: 14px; z-index: 2; }
.modal-card.tabbed .modal-body { padding-top: 44px; }

.et-panel.hidden { display: none; }

@media (max-width: 620px) {
  .modal-card.tabbed > .modal-tabs { left: 10px; }
  .modal-tab { padding: 8px 12px; font-size: 12px; }
}

/* ---- notification bell (js/chat.js, mounted in the topbar) ---------------- */
.bell-box { position: relative; display: inline-flex; }
.bell {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 9px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text-2);
}
.bell:hover { color: var(--text); background: var(--surface-3); }
.bell-ic { width: 15px; height: 15px; }
.bell-badge {
  position: absolute; top: -5px; right: -5px;
  min-width: 16px; padding: 0 4px; border-radius: 999px;
  font-size: 9.5px; font-weight: 800; line-height: 1.7; text-align: center;
  background: var(--danger); color: #fff;
}
.bell-pop {
  position: fixed; z-index: 960; width: 340px; max-height: 420px; overflow-y: auto;
  margin-top: 40px; right: 16px; top: 12px;
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 12px; box-shadow: var(--shadow); padding: 6px;
}
.bell-empty { font-size: 11.5px; color: var(--text-3); padding: 14px 12px; line-height: 1.5; }
.bell-item {
  display: block; width: 100%; text-align: left; cursor: pointer;
  border: 0; background: none; border-radius: 8px; padding: 9px 10px;
  font-family: inherit;
}
.bell-item:hover { background: var(--surface-3); }
.bell-item-top { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 3px; }
.bell-item-code { font-size: 11px; font-weight: 700; color: var(--text); }
.bell-item-why {
  font-size: 9.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent); flex: none;
}
.bell-item-text { font-size: 11.5px; color: var(--text-2); line-height: 1.45; word-break: break-word; }
.bell-more { font-size: 10.5px; color: var(--text-3); text-align: center; padding: 7px 0 4px; }

/* ---- chat cross-reference chips & pinned references ----------------------- */
.chat-ref { display: inline-flex; align-items: center; gap: 4px; }
.chat-ref.link, .chat-ref.jump {
  cursor: pointer; text-decoration: none;
  color: var(--accent); background: var(--surface-3);
  border: 1px solid var(--border-2); font-family: inherit;
}
.chat-ref.link:hover, .chat-ref.jump:hover { border-color: var(--accent); color: var(--text); }
.chat-ref svg { width: 11px; height: 11px; }

.chat-pins { display: flex; flex-direction: column; gap: 5px; margin-bottom: 9px; }
.chat-pin {
  display: flex; align-items: center; gap: 8px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px;
  padding: 6px 9px;
}
.chat-pin-link {
  flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600; color: var(--accent); text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-pin-link:hover { color: var(--text); }
.chat-pin-link svg { width: 12px; height: 12px; flex: none; }
.chat-pin-x {
  flex: none; border: 0; background: none; color: var(--text-3);
  font-size: 11px; cursor: pointer; padding: 2px 4px; border-radius: 5px;
}
.chat-pin-x:hover { color: var(--danger); background: var(--surface-3); }

/* ============================================================
   PHONE MODE — App.isPhone(), <= 640px (same breakpoint as PHONE_MQ in
   js/state.js; keep both numbers in sync if either ever changes).

   Only Dashboard, Board and Admin are reachable at this width (see
   renderViewTabs in js/render.js) — Timeline and Planning are drag/resize,
   hover-tooltip surfaces that don't survive a touch screen, so they're
   simply not offered rather than crammed in worse. Everything below is in
   service of two things: nothing to tap or read is smaller than
   comfortable one-handed, and a dense grid drops its secondary columns
   rather than squeeze them or force a sideways scroll — the detail they'd
   have shown is a tap into a dialog away (App.editTask, or the row's own
   inline edit in the User Directory).
   ============================================================ */
@media (max-width: 640px) {

  /* ---- let the whole page scroll, not just #view ----
     Desktop keeps the topbar/toolbar permanently on screen and scrolls only
     #view in the space left over (#app pinned to 100vh, #view the one
     child with overflow:auto) — the filter cluster is short enough there
     that always-visible is worth the fixed real estate. On a phone the same
     cluster (role pill, Show/Dept/Owner, search) runs to two or three rows
     and pinning it permanently would leave less room for content than the
     content itself. So here #app is allowed to grow past 100vh and #view
     gives up its own scrollbar — topbar, toolbar and the view scroll
     together as one normal page, which is what lets the filters scroll out
     of the way at all. See the requestAnimationFrame block in App.render
     (js/render.js) for how a fresh view opens already past them by
     default, and a same-view re-render restores exactly where the reader
     was rather than snapping back down here every time. */
  #app { height: auto; min-height: 100vh; }
  #view { overflow: visible; }

  /* ---- topbar & tabs ---- */
  #topbar { flex-wrap: wrap; height: auto; min-height: 56px; row-gap: 8px; padding: 10px 14px; }
  /* the mark alone still identifies the app; on a phone the tab bar needs
     the width more than the wordmark does */
  .brand-name, .brand-sub { display: none; }
  .topbar-spacer { display: none; }
  .view-tabs { flex-wrap: wrap; }
  .view-tab { padding: 12px 16px; font-size: 13.5px; }
  .view-tab .ic { font-size: 15px; }
  /* the name is also in the chip's title tooltip; the avatar plus role
     dropdown is enough to identify who's signed in and act as them */
  .user-name { display: none; }
  .role-select { padding: 5px 10px; }
  .role-dd { font-size: 14px; }

  /* ---- toolbar (Show / Dept / Owner / search — Board & Dashboard) ---- */
  #toolbar { padding: 10px 14px; gap: 10px; }
  /* the select's current value already says what it is; the label above
     it is the kind of secondary text this mode is explicitly trimming */
  .toolbar-label { display: none; }
  .filter, #search {
    padding: 12px 13px; font-size: 14px; min-height: 46px; box-sizing: border-box;
  }
  #search { min-width: 0; flex: 1 1 170px; }

  /* ---- buttons, inputs & chips, everywhere Dashboard/Board/Admin use them ---- */
  .btn-primary, .btn-ghost, .btn-danger { padding: 13px 18px; font-size: 14.5px; min-height: 46px; }
  button.ghost { padding: 12px 16px; font-size: 13.5px; min-height: 44px; }
  .btn-mini { width: 40px; height: 40px; font-size: 15px; }
  .fld { padding: 13px 14px; font-size: 15px; min-height: 46px; box-sizing: border-box; }
  .fld-label { font-size: 13.5px; }
  select.fld { padding-right: 30px; }
  .modal-overlay { padding: 16px 10px; }
  .modal-title { font-size: 19px; }
  .modal-subtitle { font-size: 12.5px; }

  /* ---- Board: an episode row's status/stage/date cluster already drops
     at 700px (see .ep-right above); at phone width the subitem grid does
     the same thing for the same reason — Department, Start, Due and
     Dependency are exactly the fields App.editTask already shows in full,
     so tapping the row for them beats reading seven columns squeezed into
     one screen width. Name, owner and status (which doubles as the quick
     status-change control) are what's actually acted on day to day, so
     those three stay. ---- */
  .subtable { overflow-x: visible; }
  .subgrid { min-width: 0; }
  .subrow { grid-template-columns: 1fr 38px 108px; column-gap: 8px; }
  .subrow .cell.c-dept, .subrow .cell.c-date, .subrow .cell.c-deps { display: none; }
  .subrow.head .cell:nth-child(2), .subrow.head .cell:nth-child(5),
  .subrow.head .cell:nth-child(6), .subrow.head .cell:nth-child(7) { display: none; }
  .subrow .cell.c-name { font-size: 13.5px; }
  .status-cell { font-size: 12px; min-height: 46px; }
  .status-opt { min-height: 46px; font-size: 12.5px; }

  /* ---- Admin: User Directory — same reasoning as the Board grid above.
     Integrations and the live-task load bar are read-only glance info;
     dropping them leaves name, role/department and the row's own actions
     (which already open into inline edit, department a select, password a
     dialog) as what phone mode calls "important". */
  .adm-table:not(.no-integ) .adm-thead .cell:nth-child(3),
  .adm-table:not(.no-integ) .adm-thead .cell:nth-child(4),
  .adm-table:not(.no-integ) .adm-row .cell:nth-child(3),
  .adm-table:not(.no-integ) .adm-row .cell:nth-child(4) { display: none; }
  .adm-table:not(.no-integ) .adm-thead,
  .adm-table:not(.no-integ) .adm-row { grid-template-columns: 1.6fr 1fr 76px; }
  .adm-table.no-integ .adm-thead .cell:nth-child(3),
  .adm-table.no-integ .adm-row .cell:nth-child(3) { display: none; }
  .adm-table.no-integ .adm-thead,
  .adm-table.no-integ .adm-row { grid-template-columns: 1.6fr 1fr 76px; }
  .adm-row { padding: 12px 14px; }
  .adm-name { font-size: 13.5px; }
  .adm-tab { padding: 11px 14px; font-size: 13px; }

  /* ---- Dashboard phone stack (App.dashboard.renderPhone) — a plain
     top-to-bottom list, not the absolutely-positioned tiling grid, so the
     desktop rect math (.dw's position:absolute) is overridden back to a
     normal block each widget just sizes itself. ---- */
  .dash-hello { flex-wrap: wrap; }
  .dash-hi { font-size: 19px; }
  .dash-phone { display: flex; flex-direction: column; gap: 12px; }
  .dash-phone .widget { height: auto; min-height: 0; }
  .dash-phone .widget-body { overflow-y: visible; }
  .widget-title { font-size: 13.5px; }
  .widget-sub { font-size: 11.5px; }
  .bar-row .bl, .bar-row .bv { font-size: 12.5px; }
  .pr-row, .risk-item { min-height: 46px; }
}

/* ----------------------------------------------------------------- dialog drafts
   A dismissed form keeps what was typed into it (see App.draft); this is the
   note that says so, with the way out for someone who wanted a blank form. */
.draft-note {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 0 0 14px; padding: 9px 12px;
  background: rgba(91,108,255,.09); border: 1px solid rgba(91,108,255,.28);
  border-radius: 9px; font-size: 12px; color: var(--text-2);
}
.draft-note > span { display: flex; align-items: center; gap: 7px; min-width: 0; }
.draft-note .ico { flex: none; }
.draft-clear {
  flex: none; white-space: nowrap; font-size: 11.5px; font-weight: 700;
  color: var(--text-2); background: var(--surface-3);
  border: 1px solid var(--border-2); border-radius: 7px; padding: 5px 11px;
}
.draft-clear:hover { color: var(--text); border-color: var(--text-3); }

/* Episode rate — a number and its unit read as one control ("2 per week"),
   so they share a row rather than sitting as two separate fields. */
.rate-row { display: flex; align-items: stretch; gap: 8px; }
.rate-row .fld { margin: 0; }
.rate-row .rate-num { width: 82px; flex: none; text-align: center; }
.rate-row .rate-seg { flex: 1; min-width: 0; justify-content: center; }
.rate-row .rate-seg .seg { flex: 1; padding: 6px 8px; white-space: nowrap; }

/* ----------------------------------------------------------------- save as preset
   Offered in the pipeline section's header only once the pipeline actually
   differs from what it was loaded from; naming happens inline rather than in a
   second dialog, which would have to close the one we're standing in. */
.preset-save-btn {
  width: auto; padding: 0 10px; font-size: 11px; font-weight: 700; white-space: nowrap;
  color: var(--accent); border-color: rgba(91,108,255,.45);
}
.preset-save-btn:hover { background: rgba(91,108,255,.14); color: var(--text); }
.preset-save-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 9px 11px;
  background: rgba(91,108,255,.08); border: 1px solid rgba(91,108,255,.3); border-radius: 9px;
}
.preset-save-lbl { font-size: 11.5px; font-weight: 700; color: var(--text-2); white-space: nowrap; }
.preset-save-bar .fld { flex: 1; min-width: 160px; margin: 0; }
.preset-save-bar .btn-primary.preset-save-go,
.preset-save-bar .btn-ghost { padding: 8px 14px; font-size: 12px; flex: none; }

/* ----------------------------------------------------------------- widget pop-out
   A widget can be opened in its own browser window (App.dashboard.popOut), so
   the Journal or the priority queue can sit beside another app or on a second
   screen. The grid keeps a placeholder in its place. */
.dw-head-r { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dw-pop {
  flex: none; width: 22px; height: 22px; padding: 0; border-radius: 6px;
  background: none; border: 1px solid transparent; color: var(--text-3);
  font-size: 12px; line-height: 1; opacity: 0; transition: opacity .12s, color .12s;
}
.dw:hover .dw-pop, .dw-pop:focus-visible { opacity: 1; }
.dw-pop:hover { color: var(--text); border-color: var(--border-2); background: var(--hover); }

/* the popped widget fills its window instead of a grid rect */
.dash-pop { padding: 12px; min-height: 100vh; box-sizing: border-box; background: var(--bg); }
.dw-popped { position: static; width: auto; height: auto; }
.dw-popped .widget { height: calc(100vh - 24px); }
.dw-popped .dw-pop { opacity: 1; }

/* the gap left behind, same rect so nothing reflows */
.dw-holder-card {
  height: 100%; align-items: center; justify-content: center; gap: 6px;
  border-style: dashed; background: none;
}
.dw-holder-title { font-size: 12.5px; font-weight: 700; color: var(--text-2); }
.dw-holder-note { font-size: 11px; color: var(--text-3); }
.dw-holder-btn {
  margin-top: 4px; font-size: 11.5px; font-weight: 700; color: var(--text-2);
  background: var(--surface-3); border: 1px solid var(--border-2);
  border-radius: 7px; padding: 5px 12px;
}
.dw-holder-btn:hover { color: var(--text); border-color: var(--accent); }

/* ---- Timeline bar context menu ----
   Above the modal overlay (400) is deliberate: the menu is what opens the
   dialog, never the reverse, so it only has to clear the chart chrome — but
   sitting under a dialog it can't be over is a bug waiting for a refactor. */
.ctx-menu {
  position: fixed; z-index: 420; min-width: 190px;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 10px;
  box-shadow: var(--shadow); padding: 5px; animation: pop-in .12s ease;
}
.ctx-item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; text-align: left; background: none; border: none; color: var(--text);
  font-size: 12.5px; font-family: inherit; padding: 8px 10px; border-radius: 7px; cursor: pointer;
}
.ctx-item:hover { background: var(--hover); }
.ctx-item-lbl { font-weight: 600; }
.ctx-item-sub { font-size: 10.5px; color: var(--text-3); flex: none; }
.ctx-sep { height: 1px; background: var(--border); margin: 4px 2px; }

/* ---- Batch Set Dates ----
   Controls kept on single lines so the three modes differ by one row each,
   and the preview is what carries the explaining. */
.bd-modes { align-self: flex-start; margin: 12px 0 4px; }
.bd-controls {
  display: flex; flex-direction: column; gap: 9px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 12px; margin-bottom: 10px;
}
.bd-inline { display: flex; align-items: center; gap: 9px; }
.bd-lbl { font-size: 11.5px; font-weight: 700; color: var(--text-2); width: 118px; flex: none; }
.bd-inline .fld { margin: 0; }
.bd-inline input[type="date"] { width: 168px; flex: none; }
.bd-num { width: 72px; flex: none; text-align: center; }
.bd-unit { width: 104px; flex: none; }
.bd-summary { font-size: 11px; color: var(--text-3); font-weight: 600; margin-bottom: 8px; }
.bd-preview {
  display: flex; flex-direction: column; max-height: 260px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 10px;
}
.bd-row {
  display: flex; align-items: center; gap: 10px; padding: 7px 11px;
  font-size: 11.5px; border-bottom: 1px solid var(--border);
}
.bd-row:last-child { border-bottom: 0; }
/* the first task of each batch — the line that makes grouping legible */
.bd-row-lead { background: rgba(91,108,255,.07); box-shadow: inset 2px 0 0 var(--accent); }
.bd-code { font-weight: 700; width: 62px; flex: none; }
.bd-task { color: var(--text-2); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bd-was { color: var(--text-3); flex: none; }
.bd-arrow { color: var(--text-3); flex: none; }
.bd-now { color: var(--text-3); font-weight: 600; width: 132px; flex: none; text-align: right; }
.bd-now.changed { color: var(--text); }

/* ----------------------------- Admin → Workflow → Department Software
   One row per department: who it is, then only the software it actually has,
   ending in a (+) that opens the searchable picker. */
.adm-swrow { display: flex; align-items: center; gap: 14px; padding: 11px 18px; border-top: 1px solid var(--border); }
.adm-swdept { flex: none; width: 150px; display: flex; align-items: center; gap: 8px; }
.adm-swdot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.adm-swdept-name { font-size: 12.5px; font-weight: 700; }
.adm-swchips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.adm-swnone { font-size: 11.5px; color: var(--text-3); font-style: italic; }
.adm-swchip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 6px 5px 9px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 15%, var(--bg-2));
  font-size: 11.5px; font-weight: 600; color: var(--text); }
.adm-swchip-ic { font-size: 13px; opacity: .85; }
.adm-swchip-x { border: none; background: none; padding: 0 2px; color: var(--text-3);
  font: inherit; font-size: 10px; cursor: pointer; line-height: 1; }
.adm-swchip-x:hover { color: var(--danger); }
.adm-swadd { width: 26px; height: 26px; border-radius: 50%; border: 1px dashed var(--border-2);
  background: none; color: var(--text-2); font: inherit; font-size: 12px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; }
.adm-swadd:hover { border-style: solid; border-color: var(--accent); color: var(--text); }

/* The (+) picker. Fixed like .dep-menu and for the same reason: it can be
   opened from inside a dialog, so it has to clear the overlay. */
.sw-menu { position: fixed; z-index: 420; width: 300px; display: flex; flex-direction: column;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 10px;
  box-shadow: var(--shadow); overflow: hidden; }
.sw-menu-head { padding: 8px; border-bottom: 1px solid var(--border); }
.sw-menu-search { width: 100%; background: var(--bg-2); border: 1px solid var(--border-2); color: var(--text);
  padding: 7px 9px; border-radius: 7px; font: inherit; font-size: 12px; }
.sw-menu-search:focus { outline: none; border-color: var(--accent); }
.sw-menu-list { max-height: 264px; overflow-y: auto; padding: 5px; }
.sw-menu-item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: none; border: none; color: var(--text); font: inherit; font-size: 12px;
  padding: 6px 8px; border-radius: 7px; cursor: pointer; }
.sw-menu-item:hover { background: var(--hover); }
.sw-tick { flex: none; width: 14px; height: 14px; border-radius: 4px; position: relative;
  border: 1.5px solid var(--border-2); background: var(--bg-2); }
.sw-menu-item.on .sw-tick { background: var(--accent); border-color: var(--accent); }
.sw-menu-item.on .sw-tick::after { content: ''; position: absolute; left: 4px; top: 1px;
  width: 3px; height: 7px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.sw-menu-ic { flex: none; font-size: 13px; opacity: .8; }
.sw-menu-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-menu-meta { flex: none; font-size: 10px; color: var(--text-3); font-family: ui-monospace, monospace; }
.sw-menu-del { flex: none; font-size: 11px; opacity: .45; cursor: pointer; }
.sw-menu-del:hover { opacity: 1; }
.sw-menu-empty { color: var(--text-3); font-size: 11.5px; padding: 10px; }
.sw-menu-foot { display: flex; align-items: center; gap: 8px; padding: 8px; border-top: 1px solid var(--border); }
.sw-menu-new { flex: 1; text-align: left; background: none; border: 1px dashed var(--border-2);
  color: var(--text-2); font: inherit; font-size: 11.5px; font-weight: 600;
  padding: 6px 9px; border-radius: 7px; cursor: pointer; }
.sw-menu-new:hover { border-style: solid; border-color: var(--accent); color: var(--text); }
.sw-menu-done { background: var(--accent); border: none; color: #fff; font: inherit; font-size: 11.5px;
  font-weight: 700; padding: 6px 12px; border-radius: 7px; cursor: pointer; }

/* Planner → Shows browser. A dialog, not a dropdown: the filter bar sticks to
   the top of the scrolling body so it stays reachable down a long list. */
.shows-filter-bar { position: sticky; top: -14px; z-index: 2; background: var(--bg-1);
  padding: 4px 0 12px; margin-bottom: 4px; border-bottom: 1px solid var(--border); }
.shows-filters { display: grid; grid-template-columns: repeat(5, 1fr) auto; gap: 10px; align-items: end; }
.shows-filter { min-width: 0; }
.shows-filter-lbl { display: block; font-size: 9.5px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-3); margin-bottom: 5px; }
.shows-filter-fld { width: 100%; font-size: 12px; padding: 7px 9px; }
.shows-clear { background: none; border: 1px solid var(--border); color: var(--text-3);
  font: inherit; font-size: 11.5px; font-weight: 600; padding: 7px 12px; border-radius: 8px; cursor: pointer; }
.shows-clear:hover { border-color: var(--border-2); color: var(--text); background: var(--hover); }
.shows-count { margin-top: 9px; font-size: 11px; color: var(--text-3); }

.shows-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 12px; padding: 4px 0 2px; }
.shows-empty { grid-column: 1 / -1; padding: 34px 10px; text-align: center;
  color: var(--text-3); font-size: 12.5px; }

.show-card { display: flex; text-align: left; padding: 0; overflow: hidden; cursor: pointer;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px;
  transition: border-color .12s ease, transform .12s ease, background .12s ease; }
.show-card:hover { border-color: var(--accent); background: var(--hover); transform: translateY(-1px); }
.show-card-spine { flex: none; width: 5px; }
.show-card-body { flex: 1; min-width: 0; padding: 11px 13px 10px; }
.show-card-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.show-card-code { flex: none; font-size: 10px; font-weight: 800; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 6px; font-family: ui-monospace, monospace; }
.show-card-name { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.show-card-meta { margin-top: 6px; font-size: 11.5px; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.show-card-meta.none { color: var(--text-3); font-style: italic; }
.show-card-foot { display: flex; align-items: center; gap: 6px; margin-top: 10px; font-size: 11px; color: var(--text-3); }
.show-card-stat.none { color: #ffce8e; }
.show-card-sep { opacity: .5; }
.show-card-prods { display: flex; margin-left: auto; }
/* producers overlap slightly — three of them shouldn't push the card wider */
.show-card-av { width: 20px; height: 20px; font-size: 8.5px; margin-left: -5px;
  border: 1.5px solid var(--bg-2); }
.show-card-av:first-child { margin-left: 0; }

@media (max-width: 900px) {
  .shows-filters { grid-template-columns: repeat(2, 1fr); }
  .shows-clear { grid-column: 1 / -1; }
}

/* Edit Show dialog. */
.ctx-sub { margin-left: auto; font-size: 11px; color: var(--text-3); }
.show-swatches { display: flex; gap: 7px; flex-wrap: wrap; }
.show-swatch { width: 26px; height: 26px; border-radius: 8px; border: 2px solid transparent;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.25); cursor: pointer; padding: 0; }
.show-swatch:hover { border-color: var(--border-2); }
.show-swatch.on { border-color: var(--text); box-shadow: inset 0 0 0 1px rgba(0,0,0,.25), 0 0 0 2px var(--bg-1); }
.show-edit-links { display: flex; gap: 8px; flex-wrap: wrap; }
/* labelled, not the 28px icon square .btn-mini is by default — same shape the
   Admin → Shows row actions use */
.show-edit-links .btn-mini { white-space: nowrap; width: auto; height: auto;
  padding: 7px 11px; font-size: 11.5px; font-weight: 600; gap: 6px;
  border-color: var(--border); color: var(--text-2); }

/* Add new software: name, extensions, icon grid. */
.sw-fld { margin-bottom: 14px; }
.sw-icongrid { display: grid; grid-template-columns: repeat(9, 1fr); gap: 5px; }
.sw-iconbtn { aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-2); background: var(--bg-2); color: var(--text-2);
  border-radius: 8px; font-size: 15px; cursor: pointer; }
.sw-iconbtn:hover { color: var(--text); border-color: var(--accent); }
.sw-iconbtn.on { color: #fff; border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 55%, var(--bg-2)); }

/* An "add one" row in a Create Project step: still a row in the same list,
   but dashed and quieter, so it reads as an action rather than a choice. */
.ws-item.ws-add { border-style: dashed; color: var(--text-2); }
.ws-item.ws-add:hover { border-style: solid; color: var(--text); }

/* ---- Reviews tab (js/reviews.js) -------------------------------------- */
/* Series → Episode → one row per review. The row is a grid rather than a flex
   line so the stage pill, the dates and the buttons stay in columns down the
   whole page — a director scanning "what's late" reads a column, not rows. */
.rvq-series { margin-bottom: 18px; }
.rvq-series-head { display: flex; align-items: center; gap: 8px; padding: 0 2px 8px; }
.rvq-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.rvq-series-name { font-size: 13px; font-weight: 700; }
.rvq-series-n { font-size: 10.5px; color: var(--text-3); }

.rvq-ep { border: 1px solid var(--border); border-radius: var(--r-card, 10px); background: var(--surface); margin-bottom: 10px; overflow: hidden; }
.rvq-ep-head { display: flex; align-items: center; gap: 9px; padding: 8px 12px; background: var(--surface-2); border-bottom: 1px solid var(--border); }
.rvq-ep-title { font-size: 12px; font-weight: 600; color: var(--text-2); }

.rvq-row {
  display: grid;
  grid-template-columns: minmax(160px, 1.5fr) minmax(150px, 1.1fr) 132px 96px auto;
  align-items: center; gap: 12px;
  padding: 9px 12px; border-top: 1px solid var(--border);
}
.rvq-ep .rvq-row:first-of-type { border-top: 0; }
.rvq-row:hover { background: var(--hover); }
.rvq-row.done { opacity: .62; }
.rvq-cell { min-width: 0; }

.rvq-task-name { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rvq-task-sub { display: flex; align-items: center; gap: 7px; margin-top: 3px; }
.rvq-task-sub .dept-chip { padding: 1px 7px; font-size: 10px; }
.rvq-who { font-size: 10.5px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.rvq-lbl { font-size: 9.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-3); }
.rvq-val { font-size: 11.5px; color: var(--text-2); margin-top: 2px; }
.rvq-none { color: var(--text-3); font-style: italic; }
.rvq-uploaded { font-size: 10.5px; color: var(--text-3); }
.rvq-due.late .rvq-val { color: var(--danger); font-weight: 700; }

.rvq-pill { display: inline-block; font-size: 10px; font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }

.rvq-linkbtn {
  display: inline-flex; align-items: center; gap: 5px; max-width: 100%;
  font-size: 11.5px; font-weight: 600; color: #9fb4ff; text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rvq-linkbtn:hover { text-decoration: underline; }
.rvq-linkbtn svg { flex: none; }
.rvq-link { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }

.rvq-acts { display: flex; align-items: center; justify-content: flex-end; gap: 6px; flex-wrap: wrap; }
.rvq-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; flex: none;
  background: var(--surface-2); color: var(--text-3);
  border: 1px solid var(--border); border-radius: var(--r-ctl, 8px); cursor: pointer;
}
.rvq-icon:hover { background: var(--surface-3); color: var(--text); }
.rvq-mini {
  font-size: 11px; font-weight: 600; white-space: nowrap;
  background: var(--surface-2); color: var(--text-2);
  border: 1px solid var(--border-2); border-radius: var(--r-ctl, 8px);
  padding: 5px 9px; cursor: pointer; font-family: var(--font);
}
.rvq-mini:hover:not(:disabled) { background: var(--surface-3); color: var(--text); }
.rvq-mini:disabled { opacity: .45; cursor: default; }
.rvq-mini.go { border-color: rgba(91,108,255,.55); color: #b3bcff; }
.rvq-mini.ok { border-color: rgba(0,200,117,.5); color: #6ee0aa; }
.rvq-mini.warn { border-color: rgba(253,171,61,.5); color: #ffce8e; }

/* the note composer — anchored to its own button, like the toolbar popovers */
.rvq-note-pop {
  position: fixed; z-index: 60; width: 300px;
  background: var(--surface); border: 1px solid var(--border-2);
  border-radius: var(--r-card, 10px); box-shadow: var(--shadow); padding: 10px;
}
.rvq-note-head { font-size: 11px; font-weight: 700; color: var(--text-2); margin-bottom: 7px; }
.rvq-note-in {
  width: 100%; box-sizing: border-box; resize: vertical;
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--border-2); border-radius: var(--r-ctl, 8px);
  padding: 7px 8px; font-size: 12px; font-family: var(--font);
}
.rvq-note-in:focus { outline: none; border-color: var(--accent); }
.rvq-note-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.rvq-note-hint { font-size: 10px; color: var(--text-3); }

/* narrow windows: the columns stop being columns and the row stacks */
@media (max-width: 900px) {
  .rvq-row { grid-template-columns: 1fr 1fr; }
  .rvq-acts { grid-column: 1 / -1; justify-content: flex-start; }
}
