/* Flow — visual foundation (theme layer).
   Layers: TOKENS (ramp -> roles) -> base -> components -> utilities.
   Rules of the house:
   - Every neutral is one of the nine ramp tones (3 dark / 3 mid / 3 light).
     Dark: canvas d1, surface d2, raised d3, hair m1, text l3/m3/m2.
     Light: canvas l2, surface l3, hair l1, text d1/m2/m3. No other greys.
   - Soft material: surfaces drift between two ADJACENT ramp tones.
   - Accent (Biosort blue-teal) means STATE only: active nav, selected pill,
     focus ring, links, today. Never "press me" - primary buttons are ink.
   - Semantic hues carry meaning and nothing else: danger (late / broken),
     warn (attention), ok (done), info (just true). Each has a QUIET form
     (coloured text / outline) and a LOUD form (tinted background).
   - Brand yellow is the SIGNATURE: Lumi and the follow-star only.
   Hairline borders, no shadows, uppercase mono micro-labels. */

:root {
  --mono: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* the tonal backbone - one warm-neutral seed */
  --d1: #0c0c0e; --d2: #151518; --d3: #1e1e22;
  --m1: #3b3b41; --m2: #6c6c73; --m3: #9c9ca2;
  --l1: #dadad7; --l2: #eeeeeb; --l3: #f8f8f5;
  --signature: #f9ef63;
  /* rhythm: spacing scale (4pt), radii, type ramp - the only sizes views may use */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;
  --r-sm: 6px; --r-md: 8px; --r-lg: 10px; --r-xl: 14px; --r-pill: 99px;
  --fs-2xs: 10px; --fs-xs: 11px; --fs-sm: 12px; --fs-md: 13px; --fs-base: 14px;
  --fs-lg: 15px; --fs-xl: 16px; --fs-2xl: 20px; --fs-3xl: 22px;
  /* content widths: reading/forms stay narrow (short lines read better),
     dense rows get room, charts and boards take the window */
  --w-read: 560px; --w-card: 760px; --w-dense: 940px; --w-full: none;
}
body {
  /* roles - dark */
  --bg: var(--d1);
  --panel: var(--d2);
  --raised: var(--d3);
  --hair: var(--m1);
  --ink: var(--l3);
  --muted: var(--m3);
  --ink3: var(--m2);
  --surface-soft: linear-gradient(160deg, var(--d3) 0%, var(--d2) 55%, var(--d2) 100%);
  --accent: #3fb8cb;
  --accent-ink: #07161a;
  --primary-bg: var(--ink);
  --primary-ink: var(--bg);
  --danger: #e8625c; --danger-loud: #ff6b57; --on-danger-loud: #1a0a08; --danger-wash: #2a1513;
  --warn: #e3a83a;   --warn-loud: #f0b345;   --on-warn-loud: #1c1405;   --warn-wash: #2a2113;
  --ok: #4fae74;     --ok-loud: #5cc386;     --on-ok-loud: #08170e;     --ok-wash: #132519;
  --info: #5aa9e6;   --info-loud: #6fb6ee;   --on-info-loud: #08141c;   --info-wash: #12202b;
  --scrim: rgba(0, 0, 0, 0.55);
  --hover: rgba(127, 127, 127, 0.09);
  /* categorical (data) hues - tags, gantt, calendar. Never the semantic hues. */
  --cat-indigo: #7a6cf0; --cat-blue: #3f8fe0; --cat-teal: #2fb3a8; --cat-lime: #a3d13f;
  --cat-rose: #e06a8e; --cat-violet: #b06ae0; --cat-slate: #8a95a3;
}
body.light {
  --bg: var(--l2);
  --panel: var(--l3);
  --raised: var(--l3);
  --hair: var(--l1);
  --ink: var(--d1);
  --muted: var(--m2);
  --ink3: var(--m3);
  --surface-soft: linear-gradient(160deg, var(--l3) 0%, var(--l3) 55%, var(--l2) 100%);
  --accent: #0a7f95;
  --accent-ink: var(--l3);
  --signature: #8a7a12;
  --danger: #c23b3b; --danger-loud: #ff6b57; --on-danger-loud: #2a0c08; --danger-wash: #fdeceb;
  --warn: #a8701a;   --warn-loud: #f0b345;   --on-warn-loud: #2a1d05;   --warn-wash: #fbf1df;
  --ok: #2f8a55;     --ok-loud: #5cc386;     --on-ok-loud: #0a1f12;     --ok-wash: #e6f4ea;
  --info: #2a6fb0;   --info-loud: #6fb6ee;   --on-info-loud: #0b1a26;   --info-wash: #e6f0fa;
  --scrim: rgba(20, 20, 16, 0.35);
  --cat-indigo: #5a4bd6; --cat-blue: #2a74c4; --cat-teal: #1d8f86; --cat-lime: #6f9a1f;
  --cat-rose: #c24f73; --cat-violet: #8a4fc0; --cat-slate: #66707d;
}

/* ---------- palette packs: data-palette on <body> swaps the STATE colour.
   The ramp, semantics and categorical hues are shared; a pack is ~6 lines.
   (default = teal, defined above). ---------- */
body[data-palette="indigo"] { --accent: #7a6cf0; --accent-ink: var(--l3); }
body.light[data-palette="indigo"] { --accent: #5a4bd6; --accent-ink: var(--l3); }
body[data-palette="rose"] { --accent: #e06a8e; --accent-ink: var(--d1); }
body.light[data-palette="rose"] { --accent: #c24f73; --accent-ink: var(--l3); }
body[data-palette="lime"] { --accent: #a3d13f; --accent-ink: var(--d1); }
body.light[data-palette="lime"] { --accent: #6f9a1f; --accent-ink: var(--l3); }

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; }

/* scrollbars follow the theme — thin, hairline thumb, invisible track */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--hair) transparent;
}
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--hair); border-radius: var(--r-pill); }
::-webkit-scrollbar-thumb:hover { background: var(--muted); }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-lg);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
input, select, textarea {
  font: inherit;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--hair);
  border-radius: var(--r-sm);
  padding: 8px 10px;
  width: 100%;
}
input:focus, select:focus, textarea:focus { outline: 1px solid var(--accent); outline-offset: 0; }
::placeholder { color: var(--muted); }

/* ---------- layout shell ---------- */
#app { height: 100%; }
.shell { display: flex; height: 100%; }
.sidebar {
  width: 200px;
  flex-shrink: 0;
  border-right: 1px solid var(--hair);
  display: flex;
  flex-direction: column;
  padding: 16px 0 12px;
  padding-top: calc(16px + env(safe-area-inset-top));
}
.logo {
  font-family: var(--mono);
  font-size: var(--fs-lg);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  padding: 0 18px 18px;
}
.logo { display: flex; align-items: center; gap: 9px; }
.applogo { height: 21px; display: block; }
.login-card .logo { justify-content: center; }
.login-card .applogo { height: 26px; }
/* yellow washes out on paper-white — render as ink silhouette in light theme */
body.light .applogo { filter: brightness(0); opacity: 0.85; }
.nav { display: flex; flex-direction: column; }
.nav button {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  color: var(--muted);
  text-align: left;
  border-left: 2px solid transparent;
}
.nav button.active { color: var(--ink); border-left-color: var(--accent); }
.nav button svg { width: 16px; height: 16px; flex-shrink: 0; }
.sidebar .spacer { flex: 1; }
.userbox {
  padding: 12px 18px 0;
  border-top: 1px solid var(--hair);
  font-size: var(--fs-md);
  color: var(--muted);
}
.userbox .uname { color: var(--ink); }
.userbox button { color: var(--muted); padding: 4px 0; display: block; }
.userbox button:hover { color: var(--ink); }

.main {
  flex: 1;
  overflow-y: auto;
  padding: 24px 28px 60px;
  padding-top: calc(24px + env(safe-area-inset-top));
}
.main h1 {
  font-size: var(--fs-2xl);
  font-weight: 600;
  margin-bottom: 18px;
}

form.qform { display: contents; }

/* ---------- helper bar + sidebar search ---------- */
.helperbar {
  /* stays put while the page scrolls: Lumi, her bubble, the clock strip - and
     room for page-relevant helpers later */
  position: sticky;
  top: calc(-1 * (24px + env(safe-area-inset-top)));
  z-index: 20;
  background: var(--bg);
  margin-top: calc(-1 * (24px + env(safe-area-inset-top)));
  padding-top: calc(24px + env(safe-area-inset-top));
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: nowrap;
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  color: var(--muted);
  padding-bottom: var(--s3);
  margin-bottom: 6px;
  border-bottom: 1px solid var(--hair);
}
/* the stack to Lumi's right: bubble on top, one cycling city slot below */
.lumistack { display: flex; flex-direction: column; justify-content: center; gap: 8px; flex: 1 1 auto; min-width: 0; min-height: 96px; }
.cityslot { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity 0.3s ease; padding-left: var(--s3); }
.cityslot.fade { opacity: 0; }
.helpercity { flex: 0 0 auto; white-space: nowrap; }
.helpercity .hname { color: var(--ink); text-transform: uppercase; letter-spacing: 0.1em; font-size: var(--fs-2xs); }
.sidesearch { margin: 0 14px 14px; width: calc(100% - 28px); font-size: var(--fs-base); padding: 6px 10px; }
/* the scope pill: sidebar on desktop, top bar on phones */
.sidescope { padding: 0 14px 12px; }
.sidescope .scoperow { display: inline-flex; }
.helperbar .scoperow { display: none; }
@media (max-width: 700px) {
  .sidesearch { display: none; }
}

/* ---------- primitives ---------- */
.microlabel {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.card {
  background: var(--surface-soft);
  border: 1px solid var(--hair);
  border-radius: var(--r-md);
  padding: var(--s4);
  margin-bottom: var(--s4);
  max-width: var(--w-card);
}
.card h2 { font-size: var(--fs-base); margin-bottom: var(--s3); }
.btn {
  display: inline-block;
  border: 1px solid var(--hair);
  border-radius: var(--r-sm);
  padding: 8px 14px;
  color: var(--ink);
}
.btn.primary { background: var(--primary-bg); color: var(--primary-ink); border-color: var(--primary-bg); font-weight: 600; }
.btn.danger, .btn.warn-action { color: var(--danger); border-color: var(--danger); }
.btn:disabled { opacity: 0.5; cursor: default; }
.field { margin-bottom: var(--s3); min-width: 0; }
/* fields sharing a row split it evenly - several carried an inline
   flex:0 0 130px that never applied (the wrapper was not a flex row), so they
   silently rendered full width while one sized itself and looked ragged */
.row > .field { flex: 1 1 0; }
.field > input, .field > select, .field > textarea, .field > .combo { width: 100%; box-sizing: border-box; }
.field .microlabel { display: block; margin-bottom: 5px; }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.row > * { flex: 1; min-width: 130px; }
.row > .btn, .row > button { flex: 0 0 auto; min-width: 0; }
/* chips, micro-labels and swatches are content-sized - they never claim a column
   (this is what used to squeeze task titles into five-line wraps) */
.row > .chip, .row > .microlabel, .row > .swatch, .row > .badge, .listrow > .chip,
.row > input[type="checkbox"], .row > input[type="radio"], .listrow > input[type="checkbox"] { flex: 0 0 auto; min-width: 0; }
.row > input[type="checkbox"], .row > input[type="radio"] { width: 18px; height: 18px; }
.error { color: var(--danger); font-size: var(--fs-md); margin-top: var(--s2); }
.hint { color: var(--muted); font-size: var(--fs-md); margin-top: var(--s2); }
.empty { color: var(--muted); padding: 24px 0; }

/* ---------- tables ---------- */
table { width: 100%; border-collapse: collapse; font-size: var(--fs-base); }
th {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 400;
  text-align: left;
  padding: 8px 10px 8px 0;
  border-bottom: 1px solid var(--hair);
}
td { padding: 10px 10px 10px 0; border-bottom: 1px solid var(--hair); vertical-align: middle; }
.chip {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
  padding: 2px 9px;
  white-space: nowrap;
}
.chip.ok { color: var(--ok); border-color: var(--ok); }
.chip.off { color: var(--muted); }
/* semantic chips - quiet (text/outline) and loud (tinted background) */
.chip.danger { color: var(--danger); border-color: var(--danger); }
.chip.warn { color: var(--warn); border-color: var(--warn); }
.chip.info { color: var(--info); border-color: var(--info); }
.chip.selected { color: var(--ink); border-color: var(--ink); }
.chip.accent { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.chip.loud { font-weight: 600; }
.chip.loud.danger { background: var(--danger-loud); color: var(--on-danger-loud); border-color: var(--danger-loud); }
.chip.loud.warn { background: var(--warn-loud); color: var(--on-warn-loud); border-color: var(--warn-loud); }
.chip.loud.ok { background: var(--ok-loud); color: var(--on-ok-loud); border-color: var(--ok-loud); }
.chip.loud.info { background: var(--info-loud); color: var(--on-info-loud); border-color: var(--info-loud); }
/* a "burning" card: overdue AND mine AND today - rare by design */
.card.burning { background: var(--danger-wash); border-left: 3px solid var(--danger-loud); }
.card.current { border-left: 3px solid var(--accent); }
/* count badges */
.badge { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill); font: 700 11px var(--mono); background: var(--hair); color: var(--muted); }
.badge.danger { background: var(--danger-loud); color: var(--on-danger-loud); }
.badge.warn { background: var(--warn-loud); color: var(--on-warn-loud); }
.badge.accent { background: var(--accent); color: var(--accent-ink); }
/* state classes used by the views */
.is-done { color: var(--muted); text-decoration: line-through; }
.is-over { border-color: var(--danger); color: var(--danger); }
.card.danger-border { border-color: var(--danger); }
/* text utilities */
.t-danger { color: var(--danger); } .t-warn { color: var(--warn); } .t-ok { color: var(--ok); } .t-info { color: var(--info); }
.t-muted { color: var(--muted); } .t-ink { color: var(--ink); } .t-signature { color: var(--signature); } .t-accent { color: var(--accent); }
td .btn { padding: 4px 10px; font-size: var(--fs-md); }

/* ---------- Lumi (mascot) in the helper bar ---------- */
.lumi { position: relative; flex: 0 0 auto; width: 96px; height: 96px; padding: 0; border: none; background: none; cursor: pointer; display: block; }
.lumi lumi-mascot, .lumi lumi-vector { display: block; width: 96px; height: 96px; }
.lumi lumi-mascot::part(stack) { border-radius: var(--r-xl); overflow: hidden; }
.lumi:hover lumi-mascot::part(stack), .lumi:hover lumi-vector { transform: translateY(-2px); transition: transform 0.25s ease; }
.lumi-bubble {
  display: none; position: relative; align-self: flex-start; align-items: flex-start; gap: var(--s1);
  flex: 0 1 auto; align-self: flex-start; margin: 0 var(--s2) 0 var(--s3); max-width: min(300px, 100%);
  background: var(--raised); color: var(--ink); border: 1px solid var(--hair);
  border-radius: var(--r-lg); padding: 6px 8px 6px 10px; font-family: var(--sans); font-size: var(--fs-md); line-height: 1.35;
  letter-spacing: 0; text-transform: none; white-space: normal;
}
.lumi-bubble.on { display: inline-flex; }
.lumi-bubble::before { content: ""; position: absolute; left: -6px; top: 12px; width: 10px; height: 10px; background: var(--raised); border-left: 1px solid var(--hair); border-bottom: 1px solid var(--hair); transform: rotate(45deg); }
.lumi-bubble .lumi-text { flex: 1; }
.lumi-bubble .lumi-x { flex: 0 0 auto; color: var(--muted); font-size: var(--fs-lg); line-height: 1; padding: 0 2px; }
.lumi-bubble .lumi-x:hover { color: var(--ink); }

/* ---------- scope toggle (My world / Everything), lives in the helper bar ---------- */
.scoperow {
  display: inline-flex;
  flex: 0 0 auto;
  align-self: center;
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
  overflow: hidden;
}
.scoperow button {
  font-family: var(--mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 4px 12px;
  color: var(--muted);
  white-space: nowrap;
}
.scoperow button.active { background: var(--accent); color: var(--accent-ink); }

/* people tables: the name column stays put when the rest must scroll, and long
   emails wrap instead of forcing the table wider than the window */
table.sticky-first th:first-child, table.sticky-first td:first-child {
  position: sticky; left: 0; z-index: 1; background: var(--panel);
  box-shadow: 1px 0 0 var(--hair);
}
table.sticky-first td { overflow-wrap: anywhere; }
table.sticky-first td:last-child, table.sticky-first th:last-child { white-space: nowrap; }

/* ---------- horizontal scroll hint ----------
   Rule of the house: avoid sideways scrolling. Where a region genuinely must
   (wide tables, kanban columns, the gantt chart), it wears .hscroll so the
   clipped edge FADES - a visible cue that there is more to the side. */
.hscroll { overflow-x: auto; scrollbar-width: thin;
  background:
    linear-gradient(to right, var(--panel) 30%, rgba(0,0,0,0)),
    linear-gradient(to right, rgba(0,0,0,0), var(--panel) 70%) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.32), rgba(0,0,0,0)),
    radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.32), rgba(0,0,0,0)) 100% 0;
  background-repeat: no-repeat; background-size: 36px 100%, 36px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll; }
body.light .hscroll { background:
    linear-gradient(to right, var(--panel) 30%, rgba(0,0,0,0)),
    linear-gradient(to right, rgba(0,0,0,0), var(--panel) 70%) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.14), rgba(0,0,0,0)),
    radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.14), rgba(0,0,0,0)) 100% 0;
  background-repeat: no-repeat; background-size: 36px 100%, 36px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll; }

/* ---------- list rows (tags, columns) ---------- */
.listrow { padding: 8px 0; border-bottom: 1px solid var(--hair); flex-wrap: nowrap; }
/* Rows that navigate somewhere (inline cursor:pointer is the marker): hover
   tint + trailing chevron, so they read as clickable instead of helper text. */
.listrow[style*="cursor:pointer"] {
  position: relative;
  border-radius: var(--r-md);
  padding-left: 8px;
  padding-right: 24px;
  margin-left: -8px;
  transition: background 0.12s;
}
.listrow[style*="cursor:pointer"]:hover { background: var(--hover); }
.listrow[style*="cursor:pointer"]::after {
  content: "›";
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-size: var(--fs-lg);
}
tr[style*="cursor:pointer"]:hover td { background: var(--hover); }
.listrow input[type="text"] { flex: 1; }
.listrow .btn { padding: 4px 10px; font-size: var(--fs-md); }
.swatch {
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
  min-width: 18px;
  border-radius: var(--r-pill);
  border: 1px solid var(--hair);
}

/* ---------- project page grid ("Wide view" for meetings on a big screen) ----------
   Off: one column, normal card width. On: cards use the whole window and pair up
   into two columns, so a project meeting shows more at once - and wide content
   (tables, the timeline) gets room instead of scrolling sideways. */
.projgrid, .teamgrid { display: block; }
.projgrid > .card, .teamgrid > .card { max-width: var(--w-card); }
/* !important on purpose: several cards carry an inline max-width (--w-dense etc.)
   and Wide view must beat it - the timeline in particular fills the page. */
body.wide .projgrid > .card, body.wide .teamgrid > .card, body.wide .card.gantt { max-width: none !important; }
/* two columns only when each one gets real room (>=560px); cards pack down the
   columns instead of leaving gaps next to a tall card, and the timeline spans */
@media (min-width: 1400px) {
  body.wide .projgrid, body.wide .teamgrid { columns: 2; column-gap: 16px; }
  body.wide .projgrid > .card, body.wide .teamgrid > .card { break-inside: avoid; -webkit-column-break-inside: avoid; }
  body.wide .projgrid > .card.span2, body.wide .teamgrid > .card.span2 { column-span: all; width: 100%; }
}

/* ---------- kanban board ---------- */
.board-wrap {
  display: flex;
  gap: var(--s3);
  overflow-x: auto;
  align-items: flex-start;
  padding-bottom: 20px;
}
.bcol {
  flex: 0 0 260px;
  background: var(--surface-soft);
  border: 1px solid var(--hair);
  border-radius: var(--r-md);
  padding: 10px;
}
.colname {
  border: none;
  background: none;
  padding: 4px 0;
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.colx { padding: 2px 8px; font-size: var(--fs-base); color: var(--muted); border: none; }
.cardquick { margin: 8px 0; }
.bcol-body { display: flex; flex-direction: column; gap: var(--s2); min-height: 30px; }
.bcard {
  border: 1px solid var(--hair);
  border-radius: var(--r-sm);
  padding: 9px 10px;
  background: var(--bg);
  cursor: pointer;
  font-size: var(--fs-base);
}
.bcard-meta { display: flex; gap: 6px; margin-top: 7px; flex-wrap: wrap; }
.chip.late { color: var(--danger); border-color: var(--danger); }

/* small-screen advisory for edit-heavy views (documents, orders) */
.widenote { display: none; }
@media (max-width: 719px) {
  .widenote {
    display: block;
    font-size: var(--fs-sm);
    color: var(--muted);
    border: 1px solid var(--hair);
    border-radius: var(--r-sm);
    padding: 8px 10px;
    margin-bottom: var(--s3);
  }
}

/* ---------- searchable multi-select (combo) ---------- */
.combo { position: relative; }
.combo-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.combo-chips:empty { margin-bottom: 0; }
.combo-menu {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 30;
  background: var(--raised); border: 1px solid var(--hair); border-radius: var(--r-md);
  max-height: 240px; overflow-y: auto; margin-top: var(--s1);
}
.combo-menu button {
  display: block; width: 100%; text-align: left; padding: 8px 11px;
  border: none; background: none; color: var(--ink); font: inherit; cursor: pointer;
  border-bottom: 1px solid var(--hair);
}
.combo-menu button:last-child { border-bottom: none; }
.combo-menu button:hover, .combo-menu button.on { background: var(--raised); }
.combo-menu .none { padding: 8px 11px; color: var(--muted); font-size: var(--fs-md); }

/* ---------- per-view quick help ---------- */
.helpbtn {
  flex: 0 0 auto;
  width: 22px; height: 22px;
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
  color: var(--muted);
  font-size: var(--fs-md);
  line-height: 1;
  margin-left: 10px;
  vertical-align: middle;
}
.helpbtn:hover { color: var(--ink); border-color: var(--muted); }
.main h1 { display: flex; align-items: center; }
.help-overlay {
  position: fixed; inset: 0; z-index: 60;
  background: var(--scrim);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 60px 16px; overflow-y: auto;
}
.help-pop {
  background: var(--panel); border: 1px solid var(--hair);
  border-radius: var(--r-lg); width: 100%; max-width: 460px; padding: 18px 20px;
}
.help-pop h2 { font-size: var(--fs-lg); margin-bottom: 10px; }
.help-pop p { font-size: var(--fs-base); line-height: 1.55; margin: 0 0 10px; color: var(--ink); }
.help-pop .help-actions { display: flex; gap: var(--s2); margin-top: 6px; }

/* ---------- risk register ---------- */
.riskscore { font-family: var(--mono); font-weight: 600; border-radius: var(--r-sm); padding: 2px 8px; font-size: var(--fs-sm); white-space: nowrap; }
.riskscore.s-low { color: var(--ok); border: 1px solid var(--ok); }
.riskscore.s-med { color: var(--warn); border: 1px solid var(--warn); }
.riskscore.s-high { color: var(--warn); border: 1px solid var(--warn); background: var(--warn-wash); }
.riskscore.s-crit { color: var(--danger); border: 1px solid var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); }
.risk-row { padding: 10px 0; border-bottom: 1px solid var(--hair); cursor: pointer; display: flex; gap: 10px; align-items: flex-start; }
.risk-row .rtitle { flex: 1; min-width: 0; }
.risk-child { margin-left: 22px; }

/* ---------- calendar timeline (bounded + scrollable) ---------- */
.timeline-scroll { max-height: 420px; overflow-y: auto; }
.calfilters { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin: 0 0 10px; }
.calfilters select { width: auto; max-width: min(220px, 100%); min-width: 0; flex: 0 1 auto; font-size: var(--fs-sm); padding: 4px 6px; }

/* ---------- help: copyable example prompts ---------- */
.prompt {
  font-family: var(--mono);
  font-size: var(--fs-md);
  line-height: 1.5;
  border: 1px solid var(--hair);
  border-left: 2px solid var(--ok);
  border-radius: var(--r-md);
  padding: 9px 12px;
  margin: 0 0 8px;
  cursor: pointer;
  position: relative;
}
.prompt:hover { border-color: var(--muted); border-left-color: var(--ok); }
.prompt.copied { border-color: var(--ok); }
.prompt.copied::after {
  content: "copied";
  position: absolute;
  right: 10px;
  top: 8px;
  font-size: var(--fs-2xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ok);
}

/* ---------- progress bars + portfolio stats ---------- */
.pbar {
  height: 6px;
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
  overflow: hidden;
  background: var(--bg);
  min-width: 64px;
}
.pbar i { display: block; height: 100%; background: var(--ok); }
.pbar i.warn { background: var(--danger); }
.statgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px 22px;
}
.stat .statnum { font-size: var(--fs-3xl); font-weight: 600; line-height: 1.2; }
.stat .statnum small { font-size: var(--fs-sm); font-weight: 400; color: var(--muted); }
.stat .pbar { margin-top: 6px; }

/* ---------- plan grids (team capacity) ----------
   Rule: dense inline-edit rows share ONE grid so every control lines up;
   column labels appear once as headers, never repeated per row. */
.plan-scroll { overflow-x: auto; } /* gets .hscroll from the markup */
.plangrid {
  display: grid;
  grid-template-columns: minmax(140px, 1fr) 58px 70px 64px 64px 112px 34px;
  gap: 4px 8px;
  align-items: center;
  min-width: 580px;
}
.plangrid.compact { grid-template-columns: minmax(110px, 1fr) 58px 70px 64px 64px minmax(90px, auto); min-width: 470px; }
.plangrid .ph {
  font-family: var(--mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 2px;
}
.plangrid input, .plangrid select { padding: 5px 6px; font-size: var(--fs-md); width: 100%; }
.plangrid .pname { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
.plangrid .plannote {
  grid-column: 1 / -1;
  display: flex;
  gap: var(--s2);
  align-items: center;
  color: var(--muted);
  font-size: var(--fs-sm);
  margin: -2px 0 8px;
}
.plangrid .plannote .chip { flex: 0 0 auto; }
/* each control sits in a labeled cell: desktop collapses the cell (label
   hidden, header row labels the column); phone stacks and shows the label */
.plangrid .pf { display: contents; }
.plangrid .pl { display: none; }
@media (max-width: 700px) {
  .plan-scroll { overflow-x: visible; }
  .plangrid, .plangrid.compact { grid-template-columns: repeat(4, 1fr); min-width: 0; gap: 6px 8px; }
  .plangrid .ph { display: none; }
  .plangrid .pname { grid-column: 1 / -1; white-space: normal; margin-top: 2px; }
  .plangrid .pf { display: block; }
  .plangrid .pf.wide { grid-column: span 3; }
  .plangrid .pl {
    display: block;
    font-family: var(--mono);
    font-size: var(--fs-2xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 3px;
  }
  .plangrid .pfull { grid-column: 1 / -1; }
  .plangrid .plannote { border-bottom: 1px solid var(--hair); padding-bottom: 10px; }
}

/* ---------- task rows ---------- */
.trow { padding: 8px 0; border-bottom: 1px solid var(--hair); cursor: pointer; }
.trow-main { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; }
.trow-main .ttitle { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trow-meta { display: flex; flex-wrap: wrap; gap: 6px; margin: 5px 0 0 28px; }

/* ---------- login ---------- */
.login-wrap {
  min-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.login-card {
  width: 100%;
  max-width: 340px;
  background: var(--surface-soft);
  border: 1px solid var(--hair);
  border-radius: var(--r-lg);
  padding: 28px 24px;
}
.login-card .logo { padding: 0 0 22px; }

/* ---------- modal ---------- */
.modal-back {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  z-index: 50;
  overflow-y: auto;
}
.modal {
  background: var(--panel);
  border: 1px solid var(--hair);
  border-radius: var(--r-lg);
  width: 100%;
  max-width: 440px;
}
.modal-head {
  position: sticky;
  top: 0;
  background: var(--panel);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 16px;
  border-bottom: 1px solid var(--hair);
  border-radius: var(--r-lg) 10px 0 0;
}
.modal-head button { color: var(--muted); font-size: var(--fs-2xl); line-height: 1; padding: 2px 6px; }
.modal-body { padding: var(--s4); }

/* ---------- mobile ---------- */
@media (max-width: 700px) {
  input, select, textarea { font-size: var(--fs-xl); } /* stop iOS zoom-on-focus */
  .shell { flex-direction: column; }
  .sidebar {
    width: 100%;
    flex-direction: row;
    align-items: center;
    border-right: none;
    border-bottom: 1px solid var(--hair);
    padding: 8px 10px 6px;
    padding-top: calc(8px + env(safe-area-inset-top));
    flex-wrap: wrap;            /* nothing hides off to the side */
    row-gap: 2px;
  }
  .logo { padding: 0 10px 0 2px; }
  .nav { flex-direction: row; flex-wrap: wrap; flex: 1 1 100%; }
  .nav button { padding: 6px 9px; font-size: var(--fs-md); border-left: none; border-bottom: 2px solid transparent; white-space: nowrap; }
  .nav button.active { border-bottom-color: var(--accent); }
  .nav button svg { display: none; }
  .sidebar .spacer, .userbox { display: none; }
  .main { padding: 18px 14px 80px; }
  .helperbar { top: -18px; margin-top: -18px; padding-top: 18px; }
  /* wide content scrolls inside its card — the page itself never pans */
  .main table { display: block; overflow-x: auto; }
  .main .hscroll table, .main table.hscroll { }
  /* chip / filter rows wrap on phones instead of scrolling sideways */
  .main .row[style*="nowrap"] { flex-wrap: wrap !important; overflow: visible !important; }
  /* busy list rows wrap to two lines instead of overflowing */
  .listrow { flex-wrap: wrap; }
  .listrow input[type="text"] { min-width: 140px; }
  .mobile-userbox { display: block; }
  .lumi, .lumi lumi-mascot, .lumi lumi-vector { width: 80px; height: 80px; }
  .lumistack { min-height: 80px; }
  .sidescope { display: none; }
  .helperbar .scoperow { display: inline-flex; }
  /* phone: Lumi + stack (bubble, city) on row one; the scope pill on its own row */
  .helperbar { gap: 8px; flex-wrap: wrap; row-gap: 8px; }
  .helperbar .lumistack { flex: 1 1 0; }
  /* a zero-height break item forces the pill onto row two at its natural width */
  .helperbar::after { content: ""; flex: 0 0 100%; height: 0; order: 1; }
  .helperbar .scoperow { order: 2; flex: 0 0 auto; margin-left: 0 !important; }
}

/* ---- scorecards & focus areas ----------------------------------------------
   Depth is carried by tone and structure, not by hue: the semantic colours mean
   state (late, at risk, done) and the categorical ones mean identity, so adding
   a "focus areas are blue" rule would put two meanings on the same channel. A
   scorecard is the frame, a focus-area card sits on it, a project row sits in
   that - three levels, three tones of the same backbone. */
.scorecard { margin-bottom: var(--s6); }
.sctitle { font-size: var(--fs-3xl); font-weight: 600; letter-spacing: -0.01em; }
.scorecard > .row { border-bottom: 1px solid var(--hair); padding-bottom: var(--s2); margin-bottom: var(--s4); }
.fagrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--s3); }
.facard {
  background: var(--surface-soft);
  border: 1px solid var(--hair);
  border-radius: var(--r-md);
  padding: var(--s4);
  display: flex; flex-direction: column; gap: var(--s2);
  min-width: 0;
}
.faname { font-size: var(--fs-xl); font-weight: 600; display: flex; align-items: flex-start; gap: var(--s2); min-width: 0; }
.faname > span { min-width: 0; }
.faname svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--muted); margin-top: 4px; }
.famerta { margin-top: -2px; }
.faname:hover { text-decoration: underline; }
.faexp { margin: 0; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.krlist { border-top: 1px solid var(--hair); padding-top: var(--s2); }
.krrow { border-bottom: 1px solid var(--hair); padding: var(--s1) 0; gap: var(--s2); }
.krrow:last-child { border-bottom: none; }

/* maturity as five blocks - a position, not a percentage, so never a bar */
.mdots { display: inline-flex; align-items: center; gap: 3px; flex: 0 0 auto; }
.mdots > i { width: 10px; height: 10px; border-radius: var(--r-sm); border: 1px solid var(--ink3); display: block; }
.mdots > i.on { background: var(--ink); border-color: var(--ink); }

/* containers are named, not coloured: a small-caps kind label does the work */
.kindchip { border: 1px solid var(--hair); border-radius: var(--r-pill); padding: 2px var(--s2); display: inline-flex; align-items: center; gap: var(--s1); }
.kindchip svg { width: 12px; height: 12px; }
.crumb { margin-bottom: var(--s2); font-size: var(--fs-base); color: var(--muted); }
.crumb a { cursor: pointer; }
.crumb a:hover { text-decoration: underline; }


/* the Company Objectives x Focus Areas matrix: a grid of links, not a tree */
.matrix { border-collapse: collapse; font-size: var(--fs-md); }
.matrix th, .matrix td { border: 1px solid var(--hair); padding: 0; text-align: center; }
.matrix .mrow { text-align: left; padding: var(--s2) var(--s3); font-weight: 500; white-space: nowrap; }
.matrix .mcorner { border: none; }
/* column headers are set upright: ten capability names side by side otherwise
   force a table wider than any screen */
.matrix .mcol { padding: var(--s2) var(--s1); vertical-align: bottom; height: 150px; width: 34px; font-weight: 500; }
.matrix .mcol > span {
  writing-mode: vertical-rl; transform: rotate(180deg);
  white-space: nowrap; max-height: 140px; overflow: hidden; text-overflow: ellipsis; display: block;
}
.matrix .mcell {
  width: 100%; height: 34px; min-width: 34px; cursor: pointer;
  color: var(--ink); background: none; border: none; font-size: var(--fs-lg);
}
.matrix .mcell:hover { outline: 1px solid var(--ink3); outline-offset: -1px; }
/* a linked cell is marked by its dot and a neutral tint - no hue, because hue
   already means state everywhere else in the app */
.matrix .mcell.on { background: var(--hover); }
.matrix .mcount { padding: var(--s1) var(--s2); color: var(--muted); font-family: var(--mono); }
/* attainment reads as a number, never as maturity dots - two different scales */
.pct { font-family: var(--mono); color: var(--muted); margin-left: var(--s2); }
.pct.big { font-size: var(--fs-3xl); color: var(--ink); margin: 0; flex: 0 0 auto; }
/* a date still being typed: marked, not alerted about */
input.date-bad { border-color: var(--danger); }

/* ---------- compact view (phones) -------------------------------------------
   Decided 2026-08-25: phones get read + quick actions; iPads and up get the
   whole app (the 700px line puts an iPad's 768 on the desktop side). Anyone can
   force the full layout per device — that switches the viewport to 1100 so the
   media queries below simply stop matching, which is what "desktop site" means.
   The goal here is chrome: content used to start 295px down an 844px screen. */
.compact .sidebar { padding-bottom: 2px; row-gap: 0; }
.compact .logo { font-size: var(--fs-lg); padding: 0 8px 0 2px; }
.compact .logo .applogo { width: 18px; height: 18px; }
/* one scrolling row instead of three wrapped ones: ~99px -> ~36px */
.compact .nav {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  gap: 2px;
  -webkit-overflow-scrolling: touch;
}
.compact .nav::-webkit-scrollbar { display: none; }
.compact .nav button { flex: 0 0 auto; padding: 5px 8px; }
/* Lumi stays, smaller, and gives her row to the content */
.compact .lumi { width: 44px; height: 44px; }
.compact .lumistack { min-height: 44px; }
/* the mascot sizes itself from an inline attribute (see runtime.js SIZE) - this
   only stops a stale 80px render from spilling over the row below it */
.compact .lumi lumi-mascot, .compact .lumi lumi-vector { max-width: 44px; max-height: 44px; overflow: hidden; }
.compact .lumi-bubble { font-size: var(--fs-md); padding: 4px 8px; }
.compact .helperbar { gap: 6px; row-gap: 4px; }
.compact .main { padding: 12px 12px 72px; }
.compact .main h1 { font-size: var(--fs-2xl); margin-bottom: 8px; }

/* read + quick actions: dense tables become stacked cards, so nothing is
   squeezed into 55px columns and the actions stay reachable */
.compact .main table.sticky-first { display: block; }
.compact .main table.sticky-first tr:first-child { display: none; }   /* header row */
.compact .main table.sticky-first tr {
  display: block;
  border: 1px solid var(--hair);
  border-radius: var(--r-md);
  padding: 10px 12px;
  margin-bottom: var(--s2);
  background: var(--surface-soft);
}
.compact .main table.sticky-first td { display: block; border: none; padding: 1px 0; }
.compact .main table.sticky-first td:first-child { font-weight: 600; font-size: var(--fs-lg); }
.compact .main table.sticky-first td:empty { display: none; }

.compactnote {
  font-size: var(--fs-sm);
  color: var(--muted);
  border-top: 1px solid var(--hair);
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  text-align: center;
}

/* ---------- form fields: one width, and no scrolling inside a box ------------
   Two rules, both from real complaints:
   1. A field is as wide as its row allows, not as wide as its markup happened to
      make it - the document editor had seven different widths in one form.
   2. Nothing scrolls inside an input. A text box that hides its own content
      makes you scroll a 3-line window to read a paragraph; the page scrolls
      instead, which is the one scrollbar anyone should meet. */
.card input[type="text"], .card input[type="email"], .card input[type="search"],
.card input[type="number"], .card input[type="date"], .card select, .card textarea,
.modal input[type="text"], .modal input[type="email"], .modal input[type="search"],
.modal input[type="number"], .modal input[type="date"], .modal select, .modal textarea {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}
/* fields sharing a row split it evenly instead of each picking its own width */
.card .row > label, .modal .row > label { flex: 1 1 0; min-width: 0; }
/* textareas grow with their content (see autoGrow) and never scroll themselves */
textarea.grow { overflow-y: hidden; resize: vertical; }

/* ---------- lock: a state you can see, not a dialog you dismiss ------------- */
.lockbar { border: 1px solid var(--hair); border-radius: var(--r-md); padding: 8px 10px; margin-bottom: var(--s3); gap: var(--s2); }
input.is-locked, textarea.is-locked, select.is-locked {
  background: transparent;
  border-color: transparent;
  color: var(--muted);
  cursor: default;
}

/* Links inherit the app's ink. Until briefings there were no real <a href>
   elements in the SPA, so nothing had ever set this — and the browser's default
   blue/purple is invisible on the dark ground. Anchors used as rows or headings
   take the surrounding colour; only a genuine inline link is tinted. */
a { color: inherit; }
a.listrow, a.trow, a.faname, a.sctitle { color: var(--ink); text-decoration: none; }
a.listrow:hover, a.trow:hover { color: var(--ink); }
.hint a, p a { color: var(--accent); }
