/* ============================================================
   gantts.app — app styles
   ============================================================ */
@font-face { font-family:'Inter'; src:url('/assets/fonts/inter.woff2') format('woff2'); font-weight:100 900; font-display:swap; font-style:normal; }
@font-face { font-family:'Bricolage'; src:url('/assets/fonts/bricolage.woff2') format('woff2'); font-weight:200 800; font-display:swap; font-style:normal; }
@font-face { font-family:'Space Grotesk'; src:url('/assets/fonts/space-grotesk.woff2') format('woff2'); font-weight:300 700; font-display:swap; font-style:normal; }
@font-face { font-family:'JetBrains Mono'; src:url('/assets/fonts/jetbrains-mono.woff2') format('woff2'); font-weight:100 800; font-display:swap; font-style:normal; }

:root {
  --bg: #f5f5fb;
  --panel: #ffffff;
  --ink: #1c1926;
  --ink-soft: #6a6579;
  --line: #e8e5f1;
  --line-strong: #d4cfe4;
  --brand: #6c4cf1;
  --brand-soft: #ece8ff;
  --danger: #dc2626;
  --weekend: #f6f5fb;
  --today: #ef4444;
  --critical: #f97316;
  --dep: #5a5470;
  --grid-w: 560px;              /* left grid width (JS-adjustable) */
  --row-h: 36px;
  --head-h: 56px;
  --shadow: 0 1px 3px rgba(28,25,38,.09), 0 1px 2px rgba(28,25,38,.04);
  --shadow-lg: 0 12px 32px rgba(60,40,140,.2);
  --radius: 8px;
  --font: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: 'Bricolage', var(--font);
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --gantt-font: var(--font);    /* user-selectable chart font */
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-size: 13px;
}

/* ---------- Top bar ---------- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 14px; background: var(--panel);
  border-bottom: 1px solid var(--line);
  gap: 12px; z-index: 30;
}
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand-mark { display: flex; }
.brand-text { display: flex; flex-direction: column; min-width: 0; }
.project-name {
  border: 1px solid transparent; background: transparent;
  font-size: 15px; font-weight: 700; color: var(--ink);
  padding: 2px 6px; border-radius: 6px; width: 260px; max-width: 40vw;
}
.project-name:hover { border-color: var(--line); }
.project-name:focus { outline: none; border-color: var(--brand); background: #fff; }
.brand-tag { font-size: 10.5px; color: var(--ink-soft); padding-left: 6px; letter-spacing: .02em; }
.topbar-actions { display: flex; align-items: center; gap: 8px; }

/* ---------- Buttons ---------- */
.btn {
  border: 1px solid var(--line-strong); background: #fff; color: var(--ink);
  padding: 6px 11px; border-radius: 7px; cursor: pointer; font-size: 12.5px;
  font-family: var(--font); line-height: 1; white-space: nowrap;
  transition: background .12s, border-color .12s, transform .04s;
}
.btn:hover { background: #f1f5f9; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-primary:hover { background: #1d4ed8; }
.btn-danger-ghost:hover { background: #fef2f2; border-color: #fecaca; color: var(--danger); }
.icon-btn { border: none; background: transparent; font-size: 16px; cursor: pointer; color: var(--ink-soft); padding: 4px 8px; border-radius: 6px; }
.icon-btn:hover { background: #f1f5f9; color: var(--ink); }

/* ---------- Menus ---------- */
.menu { position: relative; }
.menu-panel {
  position: absolute; right: 0; top: calc(100% + 6px);
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--shadow-lg); padding: 6px; min-width: 210px; z-index: 50;
  display: flex; flex-direction: column; gap: 2px;
}
.menu-panel button {
  text-align: left; border: none; background: transparent; padding: 8px 10px;
  border-radius: 6px; cursor: pointer; font-size: 12.5px; color: var(--ink);
}
.menu-panel button:hover { background: var(--brand-soft); }

/* ---------- Toolbar ---------- */
.toolbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 7px 14px; background: var(--panel);
  border-bottom: 1px solid var(--line); z-index: 20;
}
.tgroup { display: flex; align-items: center; gap: 6px; }
.tgroup.grow { flex: 1; }
.tlabel { font-size: 11px; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .04em; }
.select { border: 1px solid var(--line-strong); border-radius: 7px; padding: 5px 8px; font-size: 12.5px; background: #fff; color: var(--ink); }
.chk { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink); cursor: pointer; user-select: none; }
.autosave { font-size: 11px; color: var(--ink-soft); min-width: 54px; text-align: right; }
.lang-select { border: 1px solid var(--line-strong); background: #fff; color: var(--ink); border-radius: 7px; padding: 6px 6px; font-size: 12.5px; font-family: var(--font); cursor: pointer; }
:root[data-theme="dark"] .lang-select { background: #0e0b1a; color: var(--ink); border-color: var(--line-strong); }

/* ---------- subtle sponsor / banner slot ---------- */
.ad-slot { flex: none; height: 24px; display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 10.5px; letter-spacing: .01em; color: var(--ink-soft); background: var(--panel); border-top: 1px dashed var(--line-strong); opacity: .62; user-select: none; z-index: 6; }
.ad-slot:hover { opacity: .95; }
.ad-slot .ad-dot { color: var(--line-strong); }
.ad-slot a { color: var(--ink-soft); text-decoration: none; }
.ad-slot a:hover { color: var(--brand); text-decoration: underline; }
body.presenting .ad-slot { display: none; }
@media (max-width: 560px) { .ad-slot { font-size: 10px; } }

/* ---------- Gantt layout ---------- */
.gantt { flex: 1; display: flex; min-height: 0; overflow: hidden; position: relative; font-family: var(--gantt-font); }
.gantt input, .gantt select, .gantt .bar-label, .gantt .head-tier, .gantt .gh-cell { font-family: var(--gantt-font); }

/* Left grid — configurable columns (fixed widths + horizontal scroll) */
.grid-pane { width: var(--grid-w); flex: none; display: flex; flex-direction: column; background: var(--panel); border-right: 1px solid var(--line); overflow: hidden; }
.grid-head { display: flex; height: var(--head-h); border-bottom: 2px solid var(--line-strong); background: #f8fafc; flex: none; overflow: hidden; }
.gh-cell { position: relative; display: flex; align-items: center; padding: 0 8px; font-size: 11px; font-weight: 700; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .03em; border-right: 1px solid var(--line); flex: none; }
/* column resize grip — straddles the header's right edge */
.gh-resize { position: absolute; top: 0; right: -3px; width: 7px; height: 100%; cursor: col-resize; z-index: 3; }
.gh-resize::after { content: ''; position: absolute; top: 20%; left: 3px; width: 2px; height: 60%; background: transparent; border-radius: 1px; transition: background .12s; }
.gh-resize:hover::after { background: var(--brand); }
body.col-resizing { cursor: col-resize; user-select: none; }
body.col-resizing .grow-row:hover { background: none; }
.grid-body { flex: 1; overflow-x: auto; overflow-y: hidden; }
.grid-body::-webkit-scrollbar { height: 8px; }

.col-name { min-width: 130px; }
.col-id, .col-wbs2 { justify-content: center; }
.col-dur, .col-prog { justify-content: center; }
.col-slack, .col-cost { justify-content: flex-end; }
.ro-text { font-size: 12px; color: var(--ink-soft); padding: 0 4px; width: 100%; text-align: inherit; }
.col-slack .ro-text, .col-cost .ro-text { text-align: right; }
.col-id .ro-text, .col-wbs2 .ro-text { text-align: center; }
.ro-text.slack-crit { color: var(--critical); font-weight: 700; }
.col-pred .cell-input { font-family: var(--font-mono); font-size: 11px; }
/* columns chooser menu */
.menu-title { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); padding: 4px 10px 6px; }
.col-toggle { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 6px; cursor: pointer; font-size: 12.5px; color: var(--ink); }
.col-toggle:hover { background: var(--brand-soft); }
.menu-sep { height: 1px; background: var(--line); margin: 6px 4px; }
.menu-act { display: block; width: 100%; text-align: left; padding: 6px 10px; border: 0; background: none; border-radius: 6px; cursor: pointer; font: inherit; font-size: 12.5px; color: var(--ink); }
.menu-act:hover { background: var(--brand-soft); }
.menu-hint { padding: 6px 10px 2px; font-size: 11px; line-height: 1.4; color: var(--ink-soft); }

.grow-row { display: flex; align-items: center; height: var(--row-h); border-bottom: 1px solid var(--line); cursor: pointer; width: 100%; }
.grow-row:hover { background: #f8fafc; }
.grow-row.selected { background: var(--brand-soft); }
.grow-row.dragover { box-shadow: inset 0 -2px 0 var(--brand); }
.grow-cell { padding: 0 8px; display: flex; align-items: center; height: 100%; border-right: 1px solid var(--line-soft, transparent); font-size: 12px; overflow: hidden; flex: none; }
.grow-cell.col-name { gap: 4px; }
.cell-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grow-row.is-group .cell-name-text { font-weight: 700; }
.grow-row.is-milestone .cell-name-text { font-style: italic; }
.twisty { width: 14px; height: 14px; flex: none; display: inline-flex; align-items: center; justify-content: center; color: var(--ink-soft); cursor: pointer; border-radius: 3px; font-size: 9px; }
.twisty:hover { background: var(--line); }
.twisty.leaf { visibility: hidden; }
.dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.cell-input { border: 1px solid transparent; background: transparent; font: inherit; width: 100%; padding: 2px 4px; border-radius: 4px; color: var(--ink); }
.cell-input:hover { border-color: var(--line); }
.cell-input:focus { outline: none; border-color: var(--brand); background: #fff; }
/* A clipped task name shows an ellipsis rather than a hard cut, so it
   reads as "there is more" instead of looking like the name just ends.
   On focus the ellipsis is dropped so the caret can reach the full text.
   Full text is on the title (hover) and the column drags wider. */
.col-name .cell-input { text-overflow: ellipsis; }
.col-name .cell-input:focus { text-overflow: clip; }
:root[data-theme="dark"] .cell-input:focus { background: var(--bg-softer); }
.col-start .cell-input, .col-end .cell-input { font-size: 11.5px; }
/* hide native number spinners (they crowd the narrow Days/% columns) */
.cell-input[type=number]::-webkit-outer-spin-button,
.cell-input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cell-input[type=number] { -moz-appearance: textfield; appearance: textfield; text-align: center; }
.col-dur .cell-input, .col-prog .cell-input { width: 100%; padding: 2px; }
.col-start .cell-input::-webkit-calendar-picker-indicator,
.col-end .cell-input::-webkit-calendar-picker-indicator { padding: 0; margin-left: 1px; opacity: .55; }
:root[data-theme="dark"] .cell-input::-webkit-calendar-picker-indicator { filter: invert(1); opacity: .5; }
/* the % cell shows a mini progress bar under the number */
.prog-wrap { position: relative; width: 100%; display: flex; align-items: center; }
.prog-bar { position: absolute; left: 2px; right: 2px; bottom: 1px; height: 3px; border-radius: 2px; background: var(--line); overflow: hidden; }
.prog-bar > i { display: block; height: 100%; background: var(--brand); border-radius: 2px; }

/* Splitter */
.splitter { width: 5px; flex: none; cursor: col-resize; background: var(--line); }
.splitter:hover, .splitter.active { background: var(--brand); }

/* Chart */
.chart-pane { flex: 1; display: flex; flex-direction: column; min-width: 0; background: var(--panel); overflow: hidden; }
.chart-head { height: var(--head-h); flex: none; border-bottom: 2px solid var(--line-strong); overflow: hidden; position: relative; background: #f8fafc; }
.chart-scroll { flex: 1; overflow: auto; position: relative; }
.chart-canvas { position: relative; }
.chart-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.bars-layer { position: absolute; inset: 0; }

/* header cells */
.head-tier { position: absolute; top: 0; height: 27px; display: flex; align-items: center; padding-left: 6px; font-size: 11px; font-weight: 700; color: var(--ink); border-right: 1px solid var(--line-strong); overflow: hidden; white-space: nowrap; }
.head-tier.lower { top: 28px; height: 28px; font-weight: 500; color: var(--ink-soft); border-top: 1px solid var(--line); font-size: 10.5px; }
.head-tier.weekend { background: #eef2f7; }

/* grid background columns */
.col-line { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line); }
.col-weekend { position: absolute; top: 0; bottom: 0; background: var(--weekend); }
.row-line { position: absolute; left: 0; right: 0; height: 1px; background: var(--line); }
.today-line { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--today); z-index: 4; pointer-events: none; }
.today-flag { position: absolute; top: 0; transform: translateX(-50%); background: var(--today); color: #fff; font-size: 9px; padding: 1px 5px; border-radius: 0 0 4px 4px; z-index: 5; }

/* Bars */
.bar {
  position: absolute; height: 22px; border-radius: 6px; cursor: grab;
  display: flex; align-items: center; box-shadow: var(--shadow);
  user-select: none; overflow: visible;
}
.bar:active { cursor: grabbing; }

/* ---------- baseline (tracking Gantt) ---------- */
/* thin ghost of the committed plan, tucked under the live bar */
.baseline-bar {
  position: absolute; height: 6px; border-radius: 3px;
  background: repeating-linear-gradient(90deg, #9a94ad 0 5px, #b6b1c4 5px 10px);
  opacity: .72; pointer-events: none; z-index: 1;
}
.baseline-bar.slipped { background: repeating-linear-gradient(90deg, #d98a5a 0 5px, #e8b294 5px 10px); opacity: .85; }
.baseline-bar.milestone { border-radius: 2px; }
:root[data-theme="dark"] .baseline-bar { opacity: .6; }

/* variance cells */
.ro-text.var-late { color: #c0392b; font-weight: 700; }
.ro-text.var-early { color: #157f4a; font-weight: 700; }
.ro-text.var-onplan { color: var(--ink-soft); }
.ro-text.base-date { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.col-svar, .col-fvar { justify-content: center; }
.bar.selected { outline: 2px solid var(--brand); outline-offset: 1px; }
.bar.critical { box-shadow: 0 0 0 2.5px var(--critical), 0 0 12px rgba(249,115,116,.55); border: 1px solid var(--critical); }
.bar.critical .bar-fill { background: rgba(120,40,0,.28); }
.bar-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 6px 0 0 6px; background: rgba(0,0,0,.22); pointer-events: none; }
.bar-label { position: absolute; left: calc(100% + 8px); white-space: nowrap; font-size: 11.5px; color: var(--ink); pointer-events: none; }
.bar-label.inside { left: 8px; color: #fff; font-weight: 600; }
.bar-handle { position: absolute; top: 0; bottom: 0; width: 8px; cursor: ew-resize; }
.bar-handle.l { left: -2px; } .bar-handle.r { right: -2px; }
.bar-progress-handle { position: absolute; top: 50%; width: 12px; height: 12px; transform: translate(-50%,-50%); background: #fff; border: 2px solid rgba(0,0,0,.35); border-radius: 50%; cursor: ew-resize; z-index: 3; opacity: 0; transition: opacity .1s; }
.bar:hover .bar-progress-handle { opacity: 1; }
/* connector dots — faintly visible always so the feature is discoverable,
   and enlarge on hover with a ring + link glyph */
/* connector dots — hidden until you hover the specific bar, so the chart stays
   clean and you don't start a dependency by accident while moving bars */
.bar-dep-dot { position: absolute; top: 50%; width: 12px; height: 12px; transform: translate(-50%,-50%); border-radius: 50%; background: #fff; border: 2px solid var(--brand); cursor: crosshair; opacity: 0; z-index: 6; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: transform .1s, opacity .12s; pointer-events: none; }
.bar-dep-dot::after { content: ""; position: absolute; inset: 2px; border-radius: 50%; background: var(--brand); opacity: 0; }
.bar-dep-dot.r { left: calc(100% + 6px); } .bar-dep-dot.l { left: -6px; }
.bar:hover .bar-dep-dot, .bar-dep-dot:hover { opacity: .95; pointer-events: auto; }
/* the selected task always shows its link handles, so the "drag to connect"
   affordance is discoverable without having to hover the right pixel first */
.bar.selected .bar-dep-dot { opacity: .55; pointer-events: auto; }
.bar.selected:hover .bar-dep-dot { opacity: .95; }
.bar-dep-dot:hover { transform: translate(-50%,-50%) scale(1.3); }
.bar-dep-dot:hover::after { opacity: 1; }
body.presenting .bar-dep-dot { display: none; }

/* milestone bar */
.bar.milestone { background: transparent !important; box-shadow: none; width: 22px !important; }
.milestone-diamond { width: 16px; height: 16px; transform: rotate(45deg); margin: 3px; box-shadow: var(--shadow); border-radius: 3px; }
.bar.milestone .bar-label { left: calc(100% + 2px); }

/* group bar */
.bar.group { height: 12px; border-radius: 3px; background: #475569; }
.bar.group::before, .bar.group::after { content: ""; position: absolute; bottom: -4px; border-top: 7px solid #475569; width: 0; height: 0; }
.bar.group::before { left: 0; border-right: 6px solid transparent; }
.bar.group::after { right: 0; border-left: 6px solid transparent; }

/* dependency arrows — bolder & higher-contrast so links are easy to follow */
.dep-path { fill: none; stroke: var(--dep); stroke-width: 2.2; stroke-linejoin: round; stroke-linecap: round; }
.dep-path.critical { stroke: var(--critical); stroke-width: 3; }
.dep-arrow { fill: var(--dep); }
.dep-arrow.critical { fill: var(--critical); }
.dep-drag { stroke: var(--brand); stroke-width: 2.5; stroke-dasharray: 5 4; fill: none; }
.bar.dep-target { outline: 2.5px dashed var(--brand); outline-offset: 2px; }
.dep-hit { fill: none; stroke: transparent; stroke-width: 14; pointer-events: stroke; cursor: pointer; }
body.dragging-dep .dep-hit { pointer-events: none; }
.dep-path.dep-hover { stroke: var(--brand); stroke-width: 3.2; }

/* dependency link editor popover */
.dep-editor {
  position: fixed; z-index: 200; min-width: 232px;
  background: var(--surface, #fff); color: var(--text, #16151d);
  border: 1px solid var(--border, #e6e4ef); border-radius: 12px;
  box-shadow: 0 12px 34px rgba(20,16,45,.22); padding: 12px 13px;
  font-size: 13px; animation: depPop .12s ease;
}
@keyframes depPop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.dep-editor .de-title { font-weight: 600; margin-bottom: 10px; line-height: 1.3; }
.dep-editor .de-sep { color: var(--brand); font-weight: 700; }
.dep-editor .de-row { display: flex; gap: 10px; margin-bottom: 11px; }
.dep-editor .de-row label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--muted, #6b6880); font-weight: 600; text-transform: uppercase; letter-spacing: .02em; }
.dep-editor select, .dep-editor input { font: inherit; padding: 6px 8px; border: 1px solid var(--border, #e6e4ef); border-radius: 8px; background: var(--bg, #fff); color: var(--text, #16151d); }
.dep-editor .de-row label:last-child input { width: 68px; }
.dep-editor .de-del { width: 100%; border: 1px solid #f3c6bd; background: #fff2ee; color: #c0392b; border-radius: 8px; padding: 7px; font: inherit; font-weight: 600; cursor: pointer; }
.dep-editor .de-del:hover { background: #ffe3db; }
:root[data-theme="dark"] .dep-editor .de-del { background: rgba(192,57,43,.16); border-color: rgba(192,57,43,.4); color: #ff9b8a; }

/* empty state — a clean card that sits above the chart (no more text over the Today flag) */
.empty-state { position: absolute; inset: 0; display: flex; align-items: flex-start; justify-content: center; padding-top: 96px; z-index: 12; pointer-events: none; }
.empty-card { background: var(--panel); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow-lg); padding: 30px 34px 28px; text-align: center; max-width: 460px; pointer-events: auto; }
.empty-ic { display: flex; justify-content: center; margin-bottom: 12px; }
.empty-card h2 { color: var(--ink); margin: 0 0 6px; font-size: 20px; font-family: var(--font-display); }
.empty-card p { color: var(--ink-soft); margin: 0 0 20px; font-size: 13.5px; }
.empty-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* ---------- Drawer ---------- */
/* Task card — a popover anchored to the task you clicked, instead of a
   full-height side drawer. Falls back to a bottom sheet under 760px. */
.drawer {
  position: fixed; top: 0; left: 0; width: 330px; max-height: min(62vh, 540px);
  background: #fff; border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 18px 48px rgba(20,16,45,.26); z-index: 120;
  display: flex; flex-direction: column; overflow: hidden;
  animation: cardPop .14s cubic-bezier(.2,.9,.3,1.1);
}
@keyframes cardPop { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }
/* little pointer toward the anchored task */
.drawer::before {
  content: ''; position: absolute; top: var(--arrow-top, 24px); left: -7px;
  width: 12px; height: 12px; background: #fff;
  border-left: 1px solid var(--line); border-bottom: 1px solid var(--line);
  transform: rotate(45deg); border-radius: 0 0 0 3px;
}
.drawer.on-left::before { left: auto; right: -7px; transform: rotate(225deg); }
/* dragged away from its task — the pointer would lie, so drop it */
.drawer.dragged::before { display: none; }
.drawer.dragged { box-shadow: 0 22px 60px rgba(20,16,45,.34); }
.drawer .drawer-head { cursor: grab; user-select: none; }
.drawer.as-sheet .drawer-head { cursor: default; }
body.card-dragging, body.card-dragging .drawer-head { cursor: grabbing; user-select: none; }
body.card-dragging .drawer { animation: none; }
.drawer.as-sheet {
  left: 0 !important; right: 0; top: auto !important; bottom: 0;
  width: 100%; max-width: 100%; max-height: 80vh;
  border-radius: 16px 16px 0 0; animation: slideUpSheet .18s ease;
}
.drawer.as-sheet::before { display: none; }
@keyframes slideUpSheet { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
:root[data-theme="dark"] .drawer, :root[data-theme="dark"] .drawer::before { background: var(--surface, #1c1b26); }
@keyframes slideIn { from { transform: translateX(20px); opacity: .4; } to { transform: none; opacity: 1; } }
.drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px 10px 14px; border-bottom: 1px solid var(--line); }
.drawer-head h3 { margin: 0; font-size: 15px; }
.drawer-body { padding: 12px 14px 14px; overflow: auto; display: flex; flex-direction: column; gap: 10px; }
.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 11px; font-weight: 700; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .03em; }
.field input, .field select, .field textarea { border: 1px solid var(--line-strong); border-radius: 7px; padding: 8px 10px; font: inherit; color: var(--ink); background: #fff; }
.field textarea { resize: vertical; min-height: 64px; }
.field-row { display: flex; gap: 10px; }
.field-row .field { flex: 1; }
.swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.swatch { width: 24px; height: 24px; border-radius: 6px; cursor: pointer; border: 2px solid transparent; }
.swatch.active { border-color: var(--ink); }
.dep-list { display: flex; flex-direction: column; gap: 6px; }
.dep-item { display: flex; align-items: center; gap: 6px; font-size: 12px; background: #f8fafc; border: 1px solid var(--line); border-radius: 6px; padding: 5px 8px; }
.dep-item select { padding: 3px 5px; font-size: 11px; }
.dep-item .rm { margin-left: auto; color: var(--danger); cursor: pointer; }

/* ---------- Modal ---------- */
.modal-backdrop { position: fixed; inset: 0; background: rgba(15,23,42,.45); display: flex; align-items: center; justify-content: center; z-index: 70; padding: 20px; }
.modal { background: #fff; border-radius: 14px; box-shadow: var(--shadow-lg); width: 720px; max-width: 100%; max-height: 88vh; display: flex; flex-direction: column; }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.modal-head h3 { margin: 0; }
.modal-body { padding: 20px; overflow: auto; }
.template-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.template-card { border: 1px solid var(--line); border-radius: 10px; padding: 14px; cursor: pointer; transition: border-color .12s, box-shadow .12s; }
.template-card:hover { border-color: var(--brand); box-shadow: var(--shadow); }
.template-card h4 { margin: 0 0 4px; font-size: 14px; }
.template-card p { margin: 0; font-size: 12px; color: var(--ink-soft); }
.template-card .tc-icon { font-size: 26px; margin-bottom: 6px; }

/* the searchable catalogue below the six featured cards */
.tpl-cat-head { margin: 22px 0 10px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.tpl-cat-search {
  width: 100%; font: inherit; font-size: 15px; padding: 11px 14px; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--card); color: var(--ink);
}
.tpl-cat-search:focus { outline: 2px solid var(--brand); outline-offset: 1px; border-color: var(--brand); }
.tpl-cat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 8px; max-height: 46vh; overflow-y: auto; }
.tpl-cat-item {
  text-align: left; font: inherit; font-size: 13.5px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 9px; padding: 10px 12px;
  background: var(--card); color: var(--ink); line-height: 1.3;
}
.tpl-cat-item:hover { border-color: var(--brand); background: var(--bg-soft); }
.tpl-cat-item:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.tpl-cat-none { color: var(--ink-soft); font-size: 14px; padding: 12px 2px; }
.projects-list { display: flex; flex-direction: column; gap: 4px; }
.project-row { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 7px; cursor: pointer; }
.project-row:hover { background: #f1f5f9; }
.project-row.active { background: var(--brand-soft); }
.project-row .pr-name { flex: 1; }
.project-row .pr-meta { font-size: 11px; color: var(--ink-soft); }

/* toast */
.toast { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); background: var(--ink); color: #fff; padding: 10px 18px; border-radius: 8px; font-size: 13px; z-index: 90; box-shadow: var(--shadow-lg); }

/* ============================================================
   DARK THEME (app) — activated by data-theme="dark" on <html>
   ============================================================ */
:root[data-theme="dark"] {
  --bg: #0e0b1a;
  --panel: #171230;
  --ink: #ece9f7;
  --ink-soft: #a49dbe;
  --line: #2b2545;
  --line-strong: #3d3560;
  --brand: #8b5cf6;
  --brand-soft: #241d40;
  --weekend: #130f24;
  --today: #f87171;
  --critical: #fb923c;
  --dep: #9c95b8;
  --shadow: 0 1px 3px rgba(0,0,0,.5), 0 1px 2px rgba(0,0,0,.4);
  --shadow-lg: 0 18px 44px rgba(0,0,0,.6);
}
:root[data-theme="dark"] .grid-head,
:root[data-theme="dark"] .chart-head { background: #0e1729; }
:root[data-theme="dark"] .gh-cell { color: var(--ink-soft); }
:root[data-theme="dark"] .grow-row:hover { background: #0e1729; }
:root[data-theme="dark"] .head-tier.weekend { background: #0c1424; }
:root[data-theme="dark"] .head-tier { color: var(--ink); }
:root[data-theme="dark"] .head-tier.lower { color: var(--ink-soft); }
:root[data-theme="dark"] .cell-input { color: var(--ink); }
:root[data-theme="dark"] .cell-input:focus { background: #0e1729; }
:root[data-theme="dark"] .btn { background: #1a2540; border-color: var(--line-strong); color: var(--ink); }
:root[data-theme="dark"] .btn:hover { background: #22304f; }
:root[data-theme="dark"] .select, :root[data-theme="dark"] .field input,
:root[data-theme="dark"] .field select, :root[data-theme="dark"] .field textarea { background: #0e1729; color: var(--ink); border-color: var(--line-strong); }
:root[data-theme="dark"] .empty-state h2 { color: var(--ink); }
:root[data-theme="dark"] .modal, :root[data-theme="dark"] .drawer,
:root[data-theme="dark"] .menu-panel, :root[data-theme="dark"] .cmdk { background: var(--panel); }
:root[data-theme="dark"] .dep-item, :root[data-theme="dark"] .toc { background: #0e1729; }

/* ============================================================
   New toolbar bits
   ============================================================ */
.brand-home { display: inline-flex; text-decoration: none; border-radius: 8px; transition: transform .1s; }
.brand-home:hover { transform: scale(1.06); }
.btn-accent { background: linear-gradient(120deg,#6366f1,#06b6d4); border: none; color: #fff; }
.btn-accent:hover { filter: brightness(1.06); }
.btn-home { text-decoration: none; font-weight: 600; background: var(--brand-soft); color: var(--brand); border-color: color-mix(in srgb, var(--brand) 30%, transparent); }
.btn-home:hover { background: var(--brand); border-color: var(--brand); color: #fff; text-decoration: none; }
:root[data-theme="dark"] .btn-home { background: #241d40; color: #b9a8f5; }
:root[data-theme="dark"] .btn-home:hover { background: var(--brand); color: #fff; }

/* critical-path legend + toggle emphasis (shown only when enabled) */
.crit-legend { display: none; align-items: center; gap: 5px; font-size: 11px; color: var(--critical); font-weight: 700; white-space: nowrap; }
.crit-legend::first-letter { font-size: 13px; }
.toolbar:has(#toggleCritical:checked) .crit-legend { display: inline-flex; }
.chk-critical:has(input:checked) { color: var(--critical); font-weight: 700; }

/* ============================================================
   COMMAND PALETTE
   ============================================================ */
.cmdk-backdrop { position: fixed; inset: 0; background: rgba(8,12,22,.5); z-index: 120; display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; }
.cmdk { width: 560px; max-width: 92vw; background: #fff; border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-lg); overflow: hidden; display: flex; flex-direction: column; animation: cmdkIn .12s ease; }
@keyframes cmdkIn { from { transform: translateY(-8px); opacity: .6; } to { transform: none; opacity: 1; } }
.cmdk-input { border: none; border-bottom: 1px solid var(--line); padding: 16px 18px; font-size: 16px; outline: none; background: transparent; color: var(--ink); font-family: var(--font); }
.cmdk-list { max-height: 46vh; overflow: auto; padding: 6px; }
.cmdk-item { display: flex; align-items: center; gap: 12px; padding: 9px 12px; border-radius: 8px; cursor: pointer; }
.cmdk-item.active { background: var(--brand-soft); }
.cmdk-ic { width: 22px; text-align: center; }
.cmdk-name { flex: 1; font-size: 14px; }
.cmdk-hint { font-size: 11px; color: var(--ink-soft); border: 1px solid var(--line); border-radius: 5px; padding: 2px 6px; }
.cmdk-foot { display: flex; gap: 16px; padding: 8px 14px; border-top: 1px solid var(--line); font-size: 11px; color: var(--ink-soft); }

/* ============================================================
   PASTE TO GANTT modal
   ============================================================ */
.muted { color: var(--ink-soft); }
.paste-help { background: var(--brand-soft); border-radius: 10px; padding: 10px 12px; margin: 10px 0; display: flex; flex-direction: column; gap: 6px; }
.paste-syntax { display: flex; gap: 10px; align-items: baseline; font-size: 12.5px; }
.paste-syntax code { background: rgba(0,0,0,.06); padding: 2px 6px; border-radius: 4px; white-space: nowrap; color: var(--ink); }
:root[data-theme="dark"] .paste-syntax code { background: rgba(255,255,255,.08); }
.paste-syntax span { color: var(--ink-soft); }
.paste-area { width: 100%; min-height: 180px; border: 1px solid var(--line-strong); border-radius: 10px; padding: 12px; font-family: var(--font-mono); font-size: 13px; resize: vertical; color: var(--ink); background: var(--panel); }
.paste-count { font-size: 13px; color: var(--brand); font-weight: 600; }
.paste-actions { display: flex; align-items: center; gap: 10px; margin-top: 12px; }

/* ============================================================
   COACH MARKS / TIPS
   ============================================================ */
.tips-fab { position: fixed; right: 20px; bottom: 20px; width: 52px; height: 52px; border-radius: 50%; border: none; background: linear-gradient(120deg,#6366f1,#06b6d4); color: #fff; font-size: 22px; cursor: pointer; box-shadow: var(--shadow-lg); z-index: 80; transition: transform .12s; }
.tips-fab:hover { transform: translateY(-2px) scale(1.05); }
.coach { position: fixed; inset: 0; z-index: 110; pointer-events: none; }
.coach::before { content: ""; position: absolute; inset: 0; background: rgba(8,12,22,.35); pointer-events: auto; }
.coach-card { position: fixed; width: 300px; background: #fff; border-radius: 12px; box-shadow: var(--shadow-lg); padding: 16px; pointer-events: auto; z-index: 111; border: 1px solid var(--line); animation: cmdkIn .15s ease; }
:root[data-theme="dark"] .coach-card { background: var(--panel); }
.coach-card h4 { margin: 0 0 6px; font-size: 15px; color: var(--ink); }
.coach-card p { margin: 0; font-size: 13.5px; color: var(--ink-soft); line-height: 1.5; }
.coach-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 14px; }
.coach-progress { font-size: 12px; color: var(--ink-soft); }
.coach-spot { position: relative; z-index: 112; box-shadow: 0 0 0 3px var(--brand), 0 0 0 8px rgba(59,130,246,.28); border-radius: 8px; animation: pulse 1.6s ease infinite; }
@keyframes pulse { 0%,100% { box-shadow: 0 0 0 3px var(--brand), 0 0 0 8px rgba(59,130,246,.28); } 50% { box-shadow: 0 0 0 3px var(--brand), 0 0 0 12px rgba(59,130,246,.12); } }

/* ============================================================
   PRESENT MODE
   ============================================================ */
body.presenting .topbar, body.presenting .toolbar, body.presenting .splitter,
body.presenting .tips-fab, body.presenting .grid-pane { display: none !important; }
body.presenting .gantt { border-top: none; }
body.presenting .chart-head { height: 64px; }
body.presenting .head-tier { font-size: 13px; }
body.presenting .head-tier.lower { font-size: 12px; }
body.presenting .bar-label { font-size: 13px; }
body.presenting .today-line { width: 3px; }
.present-exit { position: fixed; top: 14px; right: 16px; z-index: 145; border: none; background: rgba(20,16,40,.82); color: #fff; padding: 9px 15px; border-radius: 8px; cursor: pointer; font-size: 13px; }

/* ---- presenter tools (laser / spotlight / zoom) ---- */
.present-tools { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); z-index: 148;
  display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 999px;
  background: rgba(20,16,40,.9); backdrop-filter: saturate(150%) blur(10px);
  border: 1px solid rgba(255,255,255,.14); box-shadow: 0 12px 34px rgba(0,0,0,.5); }
.pt-btn { border: none; background: rgba(255,255,255,.12); color: #fff; padding: 8px 14px; border-radius: 999px; cursor: pointer; font-size: 13px; font-weight: 600; font-family: var(--font); }
.pt-btn:hover { background: rgba(255,255,255,.24); }
.pt-btn.active { background: var(--critical); color: #fff; }
.pt-ico { padding: 7px 13px; font-size: 15px; line-height: 1; }
.pt-zoom { color: #fff; font-size: 13px; min-width: 42px; text-align: center; font-variant-numeric: tabular-nums; }
.pt-sep { width: 1px; height: 22px; background: rgba(255,255,255,.18); }
.pt-exit { background: rgba(255,255,255,.18); }
.laser { position: fixed; width: 24px; height: 24px; border-radius: 50%; transform: translate(-50%,-50%); pointer-events: none; z-index: 155;
  background: radial-gradient(circle, rgba(255,60,40,.98) 0%, rgba(255,60,40,.55) 38%, transparent 70%);
  box-shadow: 0 0 16px 7px rgba(255,50,30,.55); }
.spotlight { position: fixed; inset: 0; pointer-events: none; z-index: 138;
  background: radial-gradient(circle 150px at var(--x,50%) var(--y,50%), transparent 0, transparent 135px, rgba(8,6,18,.74) 210px); }

/* micro-animations */
.bar { transition: box-shadow .12s, outline-color .12s; }
.dep-path { transition: stroke .2s; }
.toast { animation: toastIn .22s ease; }
@keyframes toastIn { from { transform: translate(-50%, 12px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }

/* ============================================================
   RESPONSIVE (app)
   ============================================================ */
@media (max-width: 820px) {
  .topbar { flex-wrap: wrap; gap: 8px; }
  .brand-tag { display: none; }
  .project-name { width: 150px; }
  .toolbar { gap: 8px; overflow-x: auto; }
  .col-assignee, .gh-cell.col-assignee { display: none; }
  .col-start, .col-end { width: 62px; }
  :root { --grid-w: 300px; }
  .presentBtn, #presentBtn { display: none; }
}
@media (max-width: 560px) {
  .col-dur, .gh-cell.col-dur, .col-prog, .gh-cell.col-prog { display: none; }
  .topbar-actions .btn span { display: none; }
  :root { --grid-w: 220px; }
  .drawer { width: 100%; }
}

/* print */
@media print {
  .topbar, .toolbar, .splitter, .drawer, .modal-backdrop { display: none !important; }
  body { overflow: visible; }
  .gantt { overflow: visible; }
  .chart-scroll { overflow: visible; }
}

/* ---- storage failure banner ----
   Sits above everything and does not auto-dismiss. A toast was wrong
   here: it vanishes in two seconds and the user keeps editing a plan
   that is no longer being saved. */
.save-error {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 200;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 18px;
  background: #7f1d1d; color: #fff;
  box-shadow: 0 -4px 24px rgba(0,0,0,.28);
  font-size: 14px; line-height: 1.45;
}
/* Deliberately NOT animated into position. A slide-up via transform
   leaves the banner below the fold until the animation completes, and
   animations do not advance in a throttled or unpainted tab — which
   would hide the one warning standing between the user and lost work.
   It appears instantly, in place. */
.save-error-text { flex: 1 1 320px; min-width: 0; }
.save-error-text strong { display: inline; }
.save-error .btn { flex: 0 0 auto; }
.save-error .btn-primary { background: #fff; color: #7f1d1d; border-color: #fff; }
.save-error .btn:not(.btn-primary) { background: transparent; color: #fff; border-color: rgba(255,255,255,.55); }
.save-error-x { color: #fff; background: transparent; border: 0; font-size: 16px; cursor: pointer; }
@media (max-width: 560px) { .save-error { font-size: 13px; padding: 12px 14px; } }

.storage-meter { margin-top: 14px; font-size: 12px; color: var(--muted); }
.storage-meter.is-tight { color: #b91c1c; font-weight: 600; }

/* Holidays are shaded like weekends but tinted, so a non-working day the
   user configured is visibly different from a plain weekend. */
.col-holiday { background: color-mix(in srgb, var(--accent, #ff6a3d) 13%, transparent); }

/* ---- working calendar modal ---- */
.cal-enable { font-weight: 600; font-size: 13px; }
.cal-note { font-size: 11.5px; color: var(--ink-soft); margin: 6px 0 12px; line-height: 1.5; }
.cal-warn { font-size: 12px; color: var(--danger); margin: 8px 0 0; }
.cal-h { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); margin: 18px 0 8px; }
.cal-days { display: flex; gap: 6px; flex-wrap: wrap; }
.cal-day { display: flex; align-items: center; gap: 5px; border: 1px solid var(--line-strong);
  border-radius: 7px; padding: 6px 9px; font-size: 12px; cursor: pointer; user-select: none; }
.cal-day.is-on { background: var(--brand-soft); border-color: var(--brand); font-weight: 600; }
.cal-add { display: flex; gap: 6px; margin: 10px 0; flex-wrap: wrap; }
.cal-add .cell-input { flex: 1 1 140px; border: 1px solid var(--line-strong); border-radius: 7px; padding: 6px 8px; }
.cal-list { max-height: 210px; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; }
.cal-list:empty { display: none; }
.cal-row { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.cal-row:last-child { border-bottom: 0; }
.cal-date { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); flex: none; }
.cal-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- PDF export dialog ---- */
.pdf-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 10px 0; }
.pdf-row > label { font-size: 12.5px; color: var(--ink-soft); flex: none; }
.pdf-row .select, .pdf-row > div { flex: 1 1 auto; max-width: 260px; }
.pdf-scale { display: flex; align-items: center; gap: 10px; }
.pdf-scale input[type=range] { flex: 1; }
.pdf-scaleval { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); min-width: 40px; text-align: right; }
.pdf-range { display: flex; align-items: center; gap: 6px; }
.pdf-range .cell-input { flex: 1; border: 1px solid var(--line-strong); border-radius: 7px; padding: 5px 7px; min-width: 0; }
.pdf-summary { margin: 16px 0 12px; padding: 10px 12px; background: var(--brand-soft);
  border-radius: 8px; font-size: 12.5px; color: var(--ink); line-height: 1.5; }
.pdf-go { width: 100%; padding: 10px; }
.pdf-auto { flex: none; font-size: 11.5px; gap: 4px; }
.pdf-scale input[type=range]:disabled { opacity: .45; }

/* ---- workload lane ----
   Shares the chart's x-axis so an over-booked column sits directly
   under the tasks that caused it. */
.workload { display: flex; flex: none; height: 132px; border-top: 2px solid var(--line-strong);
  background: var(--panel); overflow: hidden; }
.wl-names { width: var(--grid-w); flex: none; border-right: 1px solid var(--line);
  overflow-y: auto; background: var(--bg); }
.wl-name { display: flex; flex-direction: column; justify-content: center; gap: 1px;
  height: 34px; padding: 0 12px; border-bottom: 1px solid var(--line); font-size: 12px; }
.wl-name.is-over .wl-who { color: var(--danger); font-weight: 700; }
.wl-who { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wl-meta { font-size: 10.5px; color: var(--ink-soft); }
.wl-name.is-over .wl-meta { color: var(--danger); }
.wl-empty { padding: 14px 12px; font-size: 12px; color: var(--ink-soft); line-height: 1.5; }
.wl-scroll { flex: 1; overflow: hidden; }   /* panned by transform, see wireScrollSync */
.wl-track { position: relative; will-change: transform; }
.wl-row { position: relative; height: 34px; border-bottom: 1px solid var(--line); }
.wl-bar { position: absolute; bottom: 0; background: var(--brand); opacity: .5; border-radius: 1px 1px 0 0; }
.wl-bar.is-over { background: var(--danger); opacity: .85; }
.wl-capline { position: absolute; left: 0; right: 0; bottom: 50%; height: 1px;
  background: var(--line-strong); pointer-events: none; }
#workloadBtn.is-on { background: var(--brand-soft); border-color: var(--brand); }

/* ============================================================
   View strip, S-curve panel, and the accessibility affordances
   added alongside the lookahead / milestone views.
   ============================================================ */

/* ---- the strip that says the chart is filtered ---- */
.view-note {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 14px;
  background: var(--accent-soft, #eef2ff);
  border-bottom: 1px solid var(--border, #e2e8f0);
  font-size: 13px; font-weight: 600;
  color: var(--text, #1e293b);
}
.view-note #viewNoteText { margin-right: auto; }
.btn.btn-sm { padding: 3px 9px; font-size: 12px; min-height: 26px; }

/* ---- S-curve ---- */
.evm-verdict {
  font-weight: 700; font-size: 15px; margin: 0 0 10px;
  padding: 9px 12px; border-radius: 8px;
  border-left: 4px solid var(--muted, #94a3b8);
  background: var(--bg-soft, #f8fafc);
}
/* Status is carried by the wording too, never by colour alone (1.4.1). */
.evm-ahead    { border-left-color: #16a34a; }
.evm-ontrack  { border-left-color: #2563eb; }
.evm-behind   { border-left-color: #ea580c; }
.evm-nodata   { border-left-color: #94a3b8; }

.evm-chart { margin: 6px 0 14px; }
.evm-svg { display: block; max-width: 100%; height: auto; }
.evm-axis { stroke: var(--text, #334155); stroke-width: 1; }
.evm-grid { stroke: var(--border, #e2e8f0); stroke-width: 1; }
.evm-tick { font-size: 10px; fill: var(--muted, #64748b); }
.evm-now  { stroke: #ef4444; stroke-width: 1.5; stroke-dasharray: 3 3; }

/* Line IDENTITY is stroke pattern; colour is a redundant second cue.
   The chart stays readable in greyscale, in print, and to a
   colourblind reader — WCAG 1.4.1. */
.evm-line { stroke-width: 2.5; fill: none; }
.evm-planned { stroke: #2563eb; stroke-dasharray: none; }
.evm-earned  { stroke: #16a34a; stroke-dasharray: 7 4; }
.evm-actual  { stroke: #ea580c; stroke-dasharray: 2 3; }

.evm-legend { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12px; color: var(--muted, #64748b); }
.evm-key { display: inline-flex; align-items: center; gap: 6px; }
.evm-swatch { display: inline-block; width: 22px; height: 0; border-top-width: 3px; border-top-style: solid; }
.evm-swatch.evm-planned { border-top-color: #2563eb; border-top-style: solid; }
.evm-swatch.evm-earned  { border-top-color: #16a34a; border-top-style: dashed; }
.evm-swatch.evm-actual  { border-top-color: #ea580c; border-top-style: dotted; }

.evm-table { width: 100%; border-collapse: collapse; margin: 14px 0; font-size: 13px; }
.evm-table th, .evm-table td { padding: 6px 8px; border-bottom: 1px solid var(--border, #e2e8f0); text-align: left; }
.evm-table th { font-weight: 600; color: var(--muted, #64748b); }
.evm-table td { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }

.evm-details { margin-top: 8px; font-size: 12.5px; color: var(--muted, #64748b); }
.evm-details summary { cursor: pointer; font-weight: 600; }
.evm-notes { margin: 8px 0 0; padding-left: 18px; }
.evm-notes li { margin-bottom: 6px; line-height: 1.5; }

.code-box {
  width: 100%; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12.5px; line-height: 1.5; padding: 10px;
  border: 1px solid var(--border, #e2e8f0); border-radius: 8px;
  background: var(--bg-soft, #f8fafc); color: var(--text, #1e293b);
  resize: vertical;
}
.modal-actions { display: flex; gap: 8px; margin: 10px 0; flex-wrap: wrap; }
.small { font-size: 12px; }

/* A context row in a filtered view is a heading, not work in the
   window — dim it so the distinction is visible, not just semantic. */
.is-context > * { opacity: .62; }

/* ---- accessibility ---- */

/* Announcements for screen readers. Visually hidden, never
   display:none — a display:none live region is not announced. */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* A focused bar must be unmistakable, and must not be hidden under the
   sticky chart header (WCAG 2.4.11 Focus Not Obscured). */
.bar:focus-visible,
.bar:focus {
  outline: 3px solid #111827;
  outline-offset: 2px;
  z-index: 6;
}
:root[data-theme="dark"] .bar:focus-visible,
:root[data-theme="dark"] .bar:focus { outline-color: #f8fafc; }

/* SC 2.5.8: 24x24 CSS px minimum for pointer targets. */
.view-note .btn.btn-sm { min-width: 26px; }

@media (prefers-reduced-motion: reduce) {
  .bar, .bar * { transition: none !important; animation: none !important; }
}

/* ============================================================
   Touch and pointer targets (WCAG 2.5.8, and basic usability).
   ============================================================ */

/* The other half of the Pointer Events migration in interactions.js.
   Without this the browser claims the first few pixels of a drag as a
   scroll, fires pointercancel and the bar never moves — the JS is
   correct and the browser overrules it. */
.bar,
.bar-handle,
.bar-progress-handle,
.bar-dep-dot {
  touch-action: none;
}

/* On a touch screen the 6px handles are unhittable. Grow the HIT AREA
   with a transparent inset pseudo-element rather than the visible
   handle, so the chart looks identical and the target reaches 24px+
   (SC 2.5.8). Note the criterion is also satisfied for mouse users by
   the "Equivalent" exception — the task drawer has real date fields —
   but a target you cannot hit is a usability failure regardless. */
@media (pointer: coarse) {
  .bar-handle,
  .bar-progress-handle,
  .bar-dep-dot {
    position: relative;
  }
  .bar-handle::after,
  .bar-progress-handle::after,
  .bar-dep-dot::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 30px; height: 30px;
    transform: translate(-50%, -50%);
  }
  /* A bar thin enough to be untappable gets a taller invisible target. */
  .bar { min-height: 24px; }
}

/* The view strip's week arrows are real controls, not decoration. */
.view-note .btn.btn-sm { min-height: 26px; min-width: 26px; }

/* ============================================================
   WCAG 1.4.1 Use of Color — the critical path was orange and
   nothing else, so to a reader with deuteranopia, in greyscale, or
   on a black-and-white printout it was simply not marked. The
   toolbar legend even read "orange = critical path", which is the
   criterion's exact failure case written out.

   A diagonal hatch carries the same meaning with no colour in it.
   ============================================================ */
.bar.critical::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    135deg,
    rgba(255, 255, 255, .30) 0 3px,
    rgba(255, 255, 255, 0) 3px 7px
  );
}
:root[data-theme="dark"] .bar.critical::before {
  background-image: repeating-linear-gradient(
    135deg,
    rgba(0, 0, 0, .34) 0 3px,
    rgba(0, 0, 0, 0) 3px 7px
  );
}

/* The legend must describe both cues, not just the colour. */
.crit-legend .crit-swatch {
  display: inline-block;
  width: 15px; height: 11px;
  vertical-align: -1px;
  margin-right: 4px;
  border-radius: 3px;
  border: 1.5px solid var(--critical);
  background-image: repeating-linear-gradient(135deg,
    var(--critical) 0 2px, transparent 2px 5px);
}

/* Dependency arrows on the critical path get a dash pattern too. */
.dep-path.critical { stroke-dasharray: 6 3; }

@media print {
  /* Printers drop background images by default, which would take the
     hatch away and leave colour alone again — exactly the case this
     exists for. */
  .bar.critical::before { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ---- the plain-table view ---- */
.table-scroll { overflow-x: auto; max-height: 55vh; overflow-y: auto; }
.data-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.data-table caption {
  text-align: left; font-weight: 600; padding: 0 0 8px;
  color: var(--muted, #64748b); font-size: 12.5px;
}
.data-table th, .data-table td {
  padding: 5px 8px; border-bottom: 1px solid var(--border, #e2e8f0);
  text-align: left; white-space: nowrap;
}
.data-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg, #fff); font-weight: 600;
}
.data-table tbody th { font-weight: 600; }
.data-table tbody tr:hover { background: var(--bg-soft, #f8fafc); }

/* ---- first-visit sample banner ---- */
.sample-note {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 14px;
  background: linear-gradient(90deg, rgba(108,76,241,.10), rgba(108,76,241,.04));
  border-bottom: 1px solid var(--border, #e2e8f0);
  font-size: 13px;
}
.sample-note > span { margin-right: auto; }

/* ============================================================
   Windows High Contrast / forced-colors.

   In forced-colors mode the OS replaces every colour, and background
   images are dropped entirely. That silently removes BOTH cues for the
   critical path — the fill and the hatch — so it needs a third one that
   survives: a border style, which forced-colors preserves.
   ============================================================ */
@media (forced-colors: active) {
  .bar {
    border: 1px solid CanvasText;
    forced-color-adjust: none;
    background: Canvas;
  }
  .bar.critical {
    /* Dashes survive where a gradient does not. */
    border: 3px dashed Highlight;
  }
  .bar-fill { background: Highlight; }
  .bar:focus-visible, .bar:focus { outline: 3px solid Highlight; outline-offset: 2px; }

  .evm-planned { stroke: CanvasText; }
  .evm-earned  { stroke: Highlight; }
  .evm-now     { stroke: CanvasText; }

  /* Pattern swatches lose their gradient; keep the outline meaningful. */
  .crit-swatch { border: 2px dashed CanvasText; background: Canvas; }
  .evm-swatch  { border-top-color: CanvasText; }

  .view-note, .sample-note { border: 1px solid CanvasText; }
}

/* ---- nudge controls ----
   W3C's own example for SC 2.5.7 is "up/down buttons to reorder list
   items". These are the horizontal equivalent: click-only, no drag, no
   keyboard required — which matters because 2.5.7 is aimed at people
   who CAN use a pointer but cannot hold a precise drag. */
.nudge-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.nudge-row .btn { min-width: 34px; min-height: 30px; padding: 4px 8px; }
.nudge-label { font-size: 11.5px; color: var(--muted, #64748b); margin-right: 2px; }
