/* ============================================================
   Reaction ERP — Theme
   Modern visual system on the corporate palette (spec 13.2.3)
   ============================================================ */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/inter-var.woff2') format('woff2');
}
@font-face {
  font-family: 'Noto Sans Thai';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/noto-sans-thai-var.woff2') format('woff2');
}

:root {
  /* Core palette */
  --c-main: #0070C0;
  --c-main-deep: #005A9E;
  --c-menu: #23374B;
  --c-menu-deep: #1A2A3B;
  --c-accent: #F6C02A;
  --c-navy: #387491;
  --c-blue: #0070C0;
  --c-green: #00B050;
  --c-yellow: #F6C02A;
  --c-orange: #FF964F;
  --c-red: #F05A5A;
  --c-purple: #7030A0;
  --c-grey: #919191;
  --c-bluegrey: #7B8189;
  --c-darknavy: #23374B;

  /* Surfaces & text */
  color-scheme: light;
  --bg: #f4f6fa;
  --surface: #ffffff;
  --surface-2: #fafbfd;        /* barely raised: table heads, code, footers */
  --surface-3: #eef2f7;        /* fills: secondary buttons, bars, chips     */
  --surface-3-hover: #e5ebf3;
  --row-hover: #f2f7fc;
  --input-bg: #ffffff;
  --border: #e5eaf1;
  --border-strong: #d5dde8;
  --border-hover: #b9c6d6;
  --text: #1c2733;
  --text-dim: #68788d;
  --heading: #23374B;
  --star-off: #d8dee8;
  --topbar-bg: rgba(255, 255, 255, .85);

  /* ---------- names that were used before they existed ----------
     Six variables were referenced across the stylesheet — --muted 23 times,
     --danger 19, --accent 17 — and none of them was ever defined. CSS does not
     complain: `color: var(--muted)` with no --muted simply inherits, so a
     caption came out the same colour as body text and a stage badge came out
     white on white. They are aliases of the real tokens, defined in BOTH
     themes so nothing inherits the light palette in the dark one. */
  --accent: var(--c-main);
  --danger: var(--danger-strong);
  --muted: var(--text-dim);
  --success-text: var(--ok-fg);
  --warning-text: var(--warn-fg);
  --font-mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;

  /* State colours as text/background, tuned per theme for contrast */
  --ok-strong: #068348;   --ok-fg: #077a41;
  --danger-strong: #d33f3f; --danger-fg: #b93a3a;
  --warn-strong: #e0762d;  --warn-fg: #9c4e14;
  --gold-strong: #b28908;
  --info-fg: #0b5e9b;
  --pill-pending-fg: #9c4e08;
  --pill-active-fg: #05703d;
  --pill-inactive-fg: #5d6874;
  --pill-cancelled-fg: #b53434;
  --pill-blue-fg: #005A9E;
  --note-warm-bg: #fff8ec; --note-warm-border: #f0dcb4;
  --note-ok-bg: #f1f9f4;   --note-ok-border: #cfe8d8;
  --radius: 14px;
  --radius-sm: 9px;
  --shadow-sm: 0 1px 2px rgba(28, 39, 51, .05), 0 1px 6px rgba(28, 39, 51, .04);
  --shadow: 0 10px 34px rgba(28, 39, 51, .14);
  --shadow-lg: 0 24px 70px rgba(16, 26, 36, .28);
  --font: 'Inter', 'Noto Sans Thai', 'Leelawadee UI', 'Segoe UI', Tahoma, sans-serif;

  /* Single stacking scale — every layered element takes its z-index from here
     so nothing can ever be accidentally covered (spec 13.3.7). */
  --z-sticky: 2;      /* sticky table headers                */
  --z-topbar: 100;    /* topbar above the scrolling view     */
  --z-dropdown: 1800; /* in-form dropdown lists — above modals */
  --z-modal: 800;     /* modal dialogs + backdrop            */
  --z-loader: 1500;   /* full-screen loading curtain         */
  --z-popover: 1900;  /* notifications & quick search        */
  --z-tooltip: 2000;  /* mouse-following tooltip             */
  --z-toast: 2147483000; /* status toasts — always on top    */
}

/* ============================================================
   Dark theme. Same components, same geometry — only the tokens
   move. html[data-theme] is set before first paint (js/i18n.js),
   so there is never a white flash.
   ============================================================ */
[data-theme="dark"] {

  /* ---------- names that were used before they existed ----------
     Six variables were referenced across the stylesheet — --muted 23 times,
     --danger 19, --accent 17 — and none of them was ever defined. CSS does not
     complain: `color: var(--muted)` with no --muted simply inherits, so a
     caption came out the same colour as body text and a stage badge came out
     white on white. They are aliases of the real tokens, defined in BOTH
     themes so nothing inherits the light palette in the dark one. */
  --accent: var(--c-main);
  --danger: var(--danger-strong);
  --muted: var(--text-dim);
  --success-text: var(--ok-fg);
  --warning-text: var(--warn-fg);
  --font-mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
  color-scheme: dark;
  --bg: #10161d;
  --surface: #1a232e;
  --surface-2: #202b38;
  --surface-3: #263344;
  --surface-3-hover: #2e3d51;
  --row-hover: #212e3d;
  --input-bg: #141c25;
  --border: #2a3646;
  --border-strong: #38475c;
  --border-hover: #4a5e77;
  --text: #dde6f0;
  --text-dim: #93a3b8;
  --heading: #dbe7f4;
  --star-off: #3a4a5e;
  --topbar-bg: rgba(19, 27, 36, .85);
  --c-menu: #1d2b3a;
  --c-menu-deep: #131e2a;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3), 0 1px 6px rgba(0, 0, 0, .22);
  --shadow: 0 10px 34px rgba(0, 0, 0, .5);
  --shadow-lg: 0 24px 70px rgba(0, 0, 0, .62);

  --ok-strong: #37c584;   --ok-fg: #64d8a4;
  --danger-strong: #ff7d75; --danger-fg: #ff9b94;
  --warn-strong: #ffa161;  --warn-fg: #ffb27f;
  --gold-strong: #ffd34d;
  --info-fg: #7cc4ff;
  --pill-pending-fg: #ffb27a;
  --pill-active-fg: #56d698;
  --pill-inactive-fg: #a8b5c4;
  --pill-cancelled-fg: #ff9d9d;
  --pill-blue-fg: #6fc0ff;
  --note-warm-bg: #2b2517; --note-warm-border: #52431f;
  --note-ok-bg: #16281f;   --note-ok-border: #29523f;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; }
body {
  font-family: var(--font);
  font-size: 13.5px;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.011em;
}
.hidden { display: none !important; }
button { font-family: inherit; }
input, select, textarea { font-family: inherit; }
::selection { background: rgba(0, 112, 192, .18); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 15px; border: none; border-radius: 10px;
  font-size: 13px; font-weight: 600; cursor: pointer; letter-spacing: -0.006em;
  color: #fff;
  background: linear-gradient(180deg, var(--c-main), var(--c-main-deep));
  box-shadow: 0 1px 2px rgba(0, 90, 158, .35), inset 0 1px 0 rgba(255,255,255,.16);
  transition: transform .06s, box-shadow .15s, filter .15s;
}
.btn:hover { filter: brightness(1.07); box-shadow: 0 4px 14px rgba(0, 112, 192, .35); }
.btn:active { transform: translateY(1px); }
.btn:disabled { background: var(--c-grey); cursor: not-allowed; filter: none; box-shadow: none; }
.btn.secondary { background: var(--surface-3); color: var(--text); box-shadow: inset 0 0 0 1px var(--border-strong); }
.btn.secondary:hover { background: var(--surface-3-hover); }
.btn.success { background: linear-gradient(180deg, #06bd5c, #049a4b); box-shadow: 0 1px 2px rgba(4,154,75,.35); }
.btn.danger { background: linear-gradient(180deg, #f2685f, #e04c48); box-shadow: 0 1px 2px rgba(224,76,72,.35); }
.btn.warning { background: linear-gradient(180deg, #ff9d58, #f07f33); }
.btn.ghost { background: transparent; color: var(--c-main); box-shadow: inset 0 0 0 1.5px rgba(0,112,192,.4); }
.btn.ghost:hover { background: rgba(0,112,192,.06); }
.btn.small { padding: 5px 11px; font-size: 12.5px; border-radius: 8px; }
.btn .icon { width: 15px; height: 15px; }

/* Icon-only row action buttons */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border: none; border-radius: 8px;
  background: transparent; cursor: pointer; color: var(--c-bluegrey);
  transition: background .12s, color .12s;
}
.icon-btn:hover { background: rgba(0, 112, 192, .1); color: var(--c-main); }
.icon-btn.danger:hover { background: rgba(240, 90, 90, .12); color: var(--c-red); }
.icon-btn svg { width: 16px; height: 16px; }

/* ---------- Inputs ---------- */
.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 12px; font-weight: 600; color: var(--text-dim); letter-spacing: .01em; }
.field label .req { color: var(--c-red); margin-left: 2px; }
/* A required field the person left empty. Marked on the field itself, because
   a banner at the top of a long form is invisible to somebody who scrolled. */
.field.invalid > label { color: var(--c-red); }
.field.invalid .input,
.field.invalid textarea.input,
.field.invalid select.input { border-color: var(--c-red); background: rgba(240, 90, 90, .05); }
.input, textarea.input, select.input {
  padding: 8.5px 11px; border: 1.5px solid var(--border-strong);
  border-radius: 10px; font-size: 13.5px; background: var(--input-bg);
  color: var(--text); outline: none; width: 100%;
  transition: border-color .12s, box-shadow .12s;
}
.input:hover { border-color: var(--border-hover); }
.input:focus { border-color: var(--c-main); box-shadow: 0 0 0 3.5px rgba(0, 112, 192, .14); }
textarea.input { resize: vertical; min-height: 72px; line-height: 1.5; }

/* ---------- Table ---------- */
.table-wrap {
  overflow: auto; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface);
  box-shadow: var(--shadow-sm);
}
table.data { border-collapse: collapse; width: 100%; min-width: 600px; }
table.data thead th {
  position: sticky; top: 0; z-index: var(--z-sticky);
  background: var(--surface-2); color: var(--text-dim);
  text-align: left; font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  padding: 10px 14px; white-space: nowrap; cursor: pointer; user-select: none;
  border-bottom: 1px solid var(--border-strong);
}
table.data thead th:hover { color: var(--c-main); }
table.data thead th .sort-ind { opacity: .9; font-size: 9px; margin-left: 4px; color: var(--c-main); }
table.data tbody td {
  padding: 9.5px 14px; border-top: 1px solid var(--border);
  font-size: 13px; vertical-align: middle; white-space: nowrap;
  max-width: 340px; overflow: hidden; text-overflow: ellipsis;
}
table.data tbody tr:first-child td { border-top: none; }
table.data tbody tr { transition: background .1s; }
table.data tbody tr:hover { background: var(--row-hover); }
table.data tbody tr.clickable { cursor: pointer; }
table.data .empty-row td { text-align: center; color: var(--text-dim); padding: 34px; white-space: normal; }
/* The row that adds the table up. It matched no padding rule at all — only
   `table.data tbody td` had one — so a total sat jammed against the edge in
   type smaller than the figures above it. A total is the line people read
   first; it gets the same gutters and a little more weight. */
table.data tfoot td {
  padding: 12px 14px; font-size: 13.5px; font-weight: 700;
  color: var(--heading); background: var(--surface-2);
  border-top: 2px solid var(--border-strong); white-space: nowrap;
}
table.data tfoot td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tfoot tr:last-child td:first-child { border-bottom-left-radius: 10px; }
table.data tfoot tr:last-child td:last-child { border-bottom-right-radius: 10px; }

/* ---------- Status pills & badges ---------- */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2.5px 10px; border-radius: 999px; font-size: 11.5px; font-weight: 600;
  letter-spacing: 0;
}
.pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .75; }
.pill.pending  { background: rgba(255, 150, 79, .16); color: var(--pill-pending-fg); }
.pill.active   { background: rgba(0, 176, 80, .13); color: var(--pill-active-fg); }
.pill.inactive { background: rgba(123, 129, 137, .14); color: var(--pill-inactive-fg); }
.pill.cancelled{ background: rgba(240, 90, 90, .13); color: var(--pill-cancelled-fg); }
.pill.blue     { background: rgba(0, 112, 192, .1); color: var(--pill-blue-fg); }
.pill.purple   { background: rgba(112, 48, 160, .1); color: var(--c-purple); }
/* Status is carried by SHAPE as well as colour, so the four lifecycle states
   stay distinguishable without colour vision: ring = pending, solid = active,
   dash = inactive, diamond = cancelled. */
.pill.pending::before   { background: transparent; box-shadow: inset 0 0 0 2px currentColor; opacity: 1; }
.pill.inactive::before  { width: 9px; height: 2.5px; border-radius: 2px; }
.pill.cancelled::before { border-radius: 1px; transform: rotate(45deg); }

/* ---------- Modal (spec 13.3.4: rounded, dark header + white body) ---------- */
#modal-root { position: fixed; inset: 0; z-index: var(--z-modal); pointer-events: none; }
.modal-backdrop {
  position: absolute; inset: 0; background: rgba(16, 26, 36, .5);
  backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  pointer-events: auto; padding: 24px;
}
.modal {
  background: var(--surface); border-radius: 18px; overflow: hidden;
  width: 660px; max-width: 96vw; max-height: 92vh;
  display: flex; flex-direction: column; box-shadow: var(--shadow-lg);
  animation: modal-in .18s cubic-bezier(.2, .9, .3, 1.1);
}
.modal.wide { width: 1000px; }
.modal-head {
  background: linear-gradient(180deg, var(--c-menu), var(--c-menu-deep));
  color: #fff; padding: 14px 20px; font-size: 14.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.modal-head .icon-btn { color: #b9c6d3; }
.modal-head .icon-btn:hover { background: rgba(255,255,255,.12); color: #fff; }
/* flex:1 with min-height:0 is what keeps the footer on screen: without it a
   long form grows the body past the modal's max-height and pushes the Save
   button off the bottom of the window. */
.modal-body { padding: 20px; overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.modal-foot {
  padding: 13px 20px; border-top: 1px solid var(--border);
  display: flex; justify-content: flex-end; gap: 9px; background: var(--surface-2);
}
@keyframes modal-in { from { transform: translateY(16px) scale(.98); opacity: 0; } to { transform: none; opacity: 1; } }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 13px 18px; }
.form-grid .span2 { grid-column: span 2; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } .form-grid .span2 { grid-column: span 1; } }

/* ---------- Alert boxes (Success / Error / Warning / Info) ---------- */
.alert {
  display: flex; gap: 10px; align-items: flex-start;
  border-radius: 11px; padding: 11px 13px; font-size: 13px;
  border: 1px solid transparent; margin-bottom: 10px; line-height: 1.45;
}
.alert svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }
.alert:last-child { margin-bottom: 0; }
.alert.success { background: rgba(0,176,80,.08);  border-color: rgba(0,176,80,.3);  color: var(--ok-fg); }
.alert.error   { background: rgba(240,90,90,.08);  border-color: rgba(240,90,90,.35);  color: var(--danger-fg); }
.alert.warning { background: rgba(255,150,79,.10);  border-color: rgba(255,150,79,.45); color: var(--warn-fg); }
.alert.info    { background: rgba(0,112,192,.07);  border-color: rgba(0,112,192,.3); color: var(--info-fg); }

/* ---------- Toast (spec 13.3.7: bottom-right, stacked, above everything) ---------- */
#toast-root {
  position: fixed; right: 18px; bottom: 18px; z-index: var(--z-toast);
  display: flex; flex-direction: column-reverse; gap: 10px; pointer-events: none;
}
.toast {
  display: flex; align-items: flex-start; gap: 10px;
  min-width: 270px; max-width: 390px;
  background: var(--surface); border-radius: 13px; padding: 13px 15px;
  box-shadow: 0 10px 36px rgba(16,26,36,.24), 0 2px 8px rgba(16,26,36,.12);
  border: 1px solid var(--border);
  border-left: 4px solid var(--c-blue);
  pointer-events: auto; animation: toast-in .2s cubic-bezier(.2,.9,.3,1.1);
  font-size: 13px;
}
.toast.success { border-left-color: var(--ok-strong); }
.toast.error { border-left-color: var(--danger-strong); }
.toast.warning { border-left-color: var(--warn-strong); }
.toast svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }
.toast.success svg { color: var(--ok-strong); }
.toast.error svg { color: var(--danger-strong); }
.toast.warning svg { color: var(--warn-strong); }
.toast.info svg { color: var(--info-fg); }
/* The title repeats the state in words, so colour is never the only cue */
.toast .t-kind { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .09em; }
.toast.success .t-kind { color: var(--ok-strong); }
.toast.error   .t-kind { color: var(--danger-strong); }
.toast.warning .t-kind { color: var(--warn-strong); }
.toast.info    .t-kind { color: var(--info-fg); }
.toast .t-close { margin-left: 6px; align-self: flex-start; width: 22px; height: 22px; }
.toast .t-close svg { width: 13px; height: 13px; color: var(--c-grey); }
.toast .t-title { font-weight: 700; margin-bottom: 2px; }
.toast.leaving { animation: toast-out .25s ease-in forwards; }
@keyframes toast-in { from { transform: translateX(32px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes toast-out { to { transform: translateX(40px); opacity: 0; } }

/* ---------- Full-screen loader (spec 13.3.8) ---------- */
#loader-root { position: fixed; inset: 0; z-index: var(--z-loader); pointer-events: none; }
.loader-screen {
  position: absolute; inset: 0;
  background: linear-gradient(150deg, rgba(35,55,75,.96), rgba(20,32,45,.97));
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 20px; color: #fff; pointer-events: auto;
}
.spinner {
  width: 46px; height: 46px; border-radius: 50%;
  border: 4px solid rgba(255,255,255,.18); border-top-color: var(--c-accent);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loader-text {
  font-size: 14.5px; letter-spacing: .01em; opacity: .92;
  white-space: pre-line; text-align: center; line-height: 1.7; max-width: 460px;
}
.loader-text::first-line { font-weight: 600; }

/* ---------- Custom tooltip (spec 13.3.9: instant, follows mouse) ---------- */
#tooltip-root {
  position: fixed; z-index: var(--z-tooltip); pointer-events: none;
  background: var(--c-menu-deep); color: #fff;
  padding: 6px 11px; border-radius: 8px; font-size: 12px;
  box-shadow: 0 6px 18px rgba(0,0,0,.3);
  max-width: 300px; display: none; white-space: pre-line; line-height: 1.45;
}

/* ---------- Searchable dropdown (spec 13.3.5) ---------- */
.sdd { position: relative; }
/* The list is moved into #popover-root and positioned against the window, so
   no dialog, sticky header or scrollbox can clip it. */
.sdd-list {
  position: fixed; z-index: var(--z-dropdown);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: 11px;
  box-shadow: var(--shadow); max-height: 224px; overflow-y: auto; padding: 4px;
  pointer-events: auto;
}
.sdd-list .sdd-item { padding: 7.5px 10px; cursor: pointer; font-size: 13px; border-radius: 7px; }
.sdd-list .sdd-item:hover, .sdd-list .sdd-item.hl { background: rgba(0,112,192,.09); color: var(--c-main); }
.sdd-list .sdd-item.none { color: var(--text-dim); cursor: default; }
.sdd-list .sdd-item.none:hover { background: transparent; color: var(--text-dim); }
/* The "clear the field" row is a real choice, so it stays clickable */
.sdd-list .sdd-item.clear { cursor: pointer; font-style: italic; }
.sdd-list .sdd-item.clear:hover { background: rgba(0,112,192,.07); color: var(--c-main); }
/* Name first, then what identifies it. The box itself only ever shows the
   name, so a long one is readable; the id lives on the second line here and
   in the caption under the field. */
.sdd-list .sdd-item.two-line { display: flex; flex-direction: column; gap: 1px; padding: 6px 10px; }
.sdd-list .sdd-item .sdd-t { font-weight: 600; }
.sdd-list .sdd-item .sdd-s { font-size: 11px; color: var(--text-dim); }
.sdd-list .sdd-item:hover .sdd-s, .sdd-list .sdd-item.hl .sdd-s { color: var(--c-main); opacity: .8; }
/* The chosen record's id/code, under the field. Empty until something is
   chosen, and it takes no room while it is empty. */
.field .sdd-caption { display: block; font-size: 11.5px; color: var(--text-dim); margin-top: 4px; line-height: 1.4; }
.field .sdd-caption:empty { display: none; }
.field .sdd-caption .mono { font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); }

/* ---------- Chips (multi-select values) ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(0,112,192,.09); color: var(--c-main);
  border-radius: 999px; padding: 3px 7px 3px 11px; font-size: 12.5px; font-weight: 600;
}
.chip button {
  border: none; background: none; color: var(--c-main); cursor: pointer;
  font-size: 14px; line-height: 1; padding: 0 4px; border-radius: 50%;
}
.chip button:hover { color: var(--c-red); }

/* ---------- Login screen ---------- */
.login-screen {
  position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(900px 500px at 85% -10%, rgba(0,112,192,.35), transparent 60%),
    radial-gradient(700px 500px at -10% 110%, rgba(246,192,42,.14), transparent 55%),
    linear-gradient(150deg, #1d2f42 0%, #16232f 60%, #101a24 100%);
  padding: 20px;
}
.login-card {
  width: 404px; max-width: 94vw; background: var(--surface); border-radius: 22px;
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.login-head {
  background: linear-gradient(160deg, var(--c-main) 0%, var(--c-main-deep) 100%);
  color: #fff; padding: 28px 28px 22px;
  display: flex; flex-direction: column; gap: 5px;
}
.login-head .logo { display: flex; align-items: center; gap: 11px; font-size: 21px; font-weight: 800; letter-spacing: -.02em; }
.login-head .logo .mark {
  width: 38px; height: 38px; border-radius: 12px; flex: none;
  background: rgba(255,255,255,.16); display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25);
}
.login-head .logo .mark svg { width: 22px; height: 22px; color: var(--c-accent); }
.login-head .sub { font-size: 12.5px; opacity: .82; }
.login-body { padding: 26px 28px 28px; display: flex; flex-direction: column; gap: 14px; }
.login-body .btn { justify-content: center; padding: 11px; font-size: 14px; border-radius: 12px; }
.login-alt { text-align: center; font-size: 13px; color: var(--text-dim); }
.login-alt a { color: var(--c-main); font-weight: 600; cursor: pointer; text-decoration: none; }
.login-alt a:hover { text-decoration: underline; }

/* ---------- Toolbar ---------- */
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.toolbar .spacer { flex: 1; }
.search-box { position: relative; }
.search-box input { padding-left: 32px; width: 250px; }
.search-box svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--c-grey); }
.muted { color: var(--text-dim); }
.mono { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12px; letter-spacing: 0; }

/* ---------- Tabs ---------- */
.tabs { display: flex; gap: 3px; border-bottom: 1.5px solid var(--border-strong); margin-bottom: 16px; flex-wrap: wrap; }
.tab {
  padding: 9px 15px; cursor: pointer; font-weight: 600; font-size: 13px;
  color: var(--text-dim); border-bottom: 2.5px solid transparent; margin-bottom: -1.5px;
  display: inline-flex; align-items: center; gap: 7px; background: none;
  border-top: none; border-left: none; border-right: none;
  border-radius: 8px 8px 0 0; transition: color .12s, background .12s;
}
.tab svg { width: 15px; height: 15px; }
.tab.on { color: var(--c-main); border-bottom-color: var(--c-main); }
.tab:hover { color: var(--c-main); background: rgba(0,112,192,.05); }

/* ---------- the second tier ----------
   Fifteen tabs across the top made a person read a list before they could
   read a project. The top row is now six groups and this is what is inside
   the one they chose — visually lighter than the row above it, because it is
   subordinate to it and must never be mistaken for another set of top tabs. */
.tabs.grouped { margin-bottom: 0; }
.subtabs { margin: 10px 0 16px; display: flex; flex-direction: column; gap: 9px; }
.subtabs:empty { margin: 0 0 16px; }
.subtab-row { display: flex; gap: 6px; flex-wrap: wrap; }
.subtab {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface);
  font-family: inherit; font-size: 12.5px; font-weight: 600; color: var(--text-dim);
  transition: background .12s, color .12s, border-color .12s;
}
.subtab svg { width: 14px; height: 14px; }
.subtab:hover { color: var(--c-main); border-color: var(--c-main); }
.subtab.on { background: var(--c-main); border-color: var(--c-main); color: #fff; }
.subtab:focus-visible { outline: 2px solid var(--c-main); outline-offset: 2px; }

/* Why this group exists, in one line. The distinction it draws — pages you
   keep against pages that only read what you kept — is the whole reason the
   grouping is worth having, so it is said in words rather than implied. */
.tab-note {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 8px 11px; border-radius: var(--radius); border: 1px solid var(--border);
  background: var(--surface-2); font-size: 11.5px; line-height: 1.5; color: var(--text-dim);
}
.tab-note svg { width: 14px; height: 14px; flex: none; margin-top: 1.5px; }
.tab-note b { color: var(--heading); font-weight: 700; }
.tab-note.keep { border-left: 3px solid var(--c-main); }
.tab-note.keep svg { color: var(--c-main); }
.tab-note.tool { border-left: 3px solid var(--c-purple); }
.tab-note.tool svg { color: var(--c-purple); }

/* A chart keeps its natural size and scrolls rather than shrinking: an axis
   label at 5px is not a smaller chart, it is a chart with no axis. */
.chart-scroll { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; }
.chart-scroll::-webkit-scrollbar { height: 6px; }

/* Something inside this group wants a person's attention. Amber rather than
   red: work nobody has picked up yet is a nudge, not a fault. A mark on a tab
   always means "there IS something in here" — never the reverse. */
.tab-dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--warn-strong);
  flex: none; margin-left: 1px; align-self: flex-start; margin-top: 3px;
}

/* How many records are filed under a group. Quiet by design: it is a fact
   about the register, not a summons. Hidden entirely at zero. */
.tab-count {
  flex: none; margin-left: 2px; padding: 0 6px; min-width: 18px;
  border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border);
  font-size: 10.5px; font-weight: 700; line-height: 16px; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.tab.on .tab-count { background: rgba(0,112,192,.1); border-color: rgba(0,112,192,.25); color: var(--c-main); }

/* ---------- Cards ---------- */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 14px; }
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px;
  box-shadow: var(--shadow-sm);
}
.card h3 {
  font-size: 12px; color: var(--text-dim); font-weight: 700; margin-bottom: 10px;
  display: flex; align-items: center; gap: 8px; text-transform: uppercase; letter-spacing: .05em;
}
.card h3 .chip-ic {
  width: 26px; height: 26px; border-radius: 8px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(0,112,192,.1); color: var(--c-main);
}
.card h3 .chip-ic svg { width: 15px; height: 15px; }
.card h3 > svg { width: 15px; height: 15px; color: var(--c-main); }
.card h3 .chip-ic.green { background: rgba(0,176,80,.1); color: var(--c-green); }
.card h3 .chip-ic.orange { background: rgba(255,150,79,.12); color: var(--warn-strong); }
.card h3 .chip-ic.red { background: rgba(240,90,90,.1); color: var(--c-red); }
.card h3 .chip-ic.purple { background: rgba(112,48,160,.1); color: var(--c-purple); }
.card h3 .chip-ic.yellow { background: rgba(246,192,42,.16); color: var(--gold-strong); }
.card .big { font-size: 27px; font-weight: 800; color: var(--heading); letter-spacing: -.02em; }
.card .sub { font-size: 12.5px; color: var(--text-dim); margin-top: 3px; }

/* ---------- Detail page header (personnel / project / meeting) ---------- */
.detail-head {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 20px; margin-bottom: 16px;
  box-shadow: var(--shadow-sm);
  display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
}
.detail-avatar {
  width: 58px; height: 58px; border-radius: 18px; flex: none;
  background: linear-gradient(150deg, var(--c-main), var(--c-navy));
  color: #fff; font-weight: 800; font-size: 21px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 18px rgba(0,112,192,.3);
}
.detail-avatar.project { background: linear-gradient(150deg, var(--c-purple), #4a1f6e); box-shadow: 0 6px 18px rgba(112,48,160,.3); }
.detail-avatar.meeting { background: linear-gradient(150deg, var(--c-orange), #d96a22); box-shadow: 0 6px 18px rgba(255,150,79,.3); }
.detail-avatar svg { width: 26px; height: 26px; }
.detail-title { flex: 1; min-width: 240px; }
.detail-title h1 { font-size: 20px; font-weight: 800; letter-spacing: -.02em; color: var(--heading); }
.detail-title .sub { color: var(--text-dim); font-size: 13px; margin-top: 3px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.detail-actions { display: flex; gap: 8px; align-items: flex-start; flex-wrap: wrap; }
.info-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-3); border-radius: 999px; padding: 4px 12px;
  font-size: 12.5px; color: var(--text);
}
.info-chip svg { width: 13px; height: 13px; color: var(--c-bluegrey); }

/* Read-only field display grid on detail pages */

/* ---------- Entity page: LinkedIn-style two-panel layout ---------- */
.entity-grid { display: grid; grid-template-columns: 330px minmax(0, 1fr); gap: 16px; align-items: start; }
/* One column on a narrow screen — and the tabs go FIRST. The identity panel
   is reference (a phone number, a blood group); the tabs are what somebody
   opened the record to read. Stacked in source order a person scrolls past
   twenty rows of "—" to reach their own work. */
@media (max-width: 900px) {
  .entity-grid { grid-template-columns: 1fr; }
  .entity-right { order: 1; }
  .entity-left { order: 2; }
}
.entity-left { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.entity-right { min-width: 0; }

.kv-line { display: flex; justify-content: space-between; gap: 14px; padding: 6.5px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.kv-line:last-child { border-bottom: none; }
.kv-line .k { color: var(--text-dim); flex: none; }
.kv-line .v { text-align: right; font-weight: 550; overflow-wrap: anywhere; min-width: 0; }

.stars { letter-spacing: 2px; color: var(--star-off); font-size: 13px; }
.stars .on { color: var(--c-accent); text-shadow: 0 1px 3px rgba(246,192,42,.4); }

/* ---------- Gamified primitives ---------- */
.progress { height: 8px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.progress-fill {
  height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, var(--c-main), #38a1e8);
  transition: width .4s ease;
}
.progress.green .progress-fill { background: linear-gradient(90deg, #049a4b, #2fd57f); }
.progress.orange .progress-fill { background: linear-gradient(90deg, #f07f33, #ffb066); }
.progress.red .progress-fill { background: linear-gradient(90deg, #e04c48, #ff8a80); }

.ring { --p: 0; --ring-c: var(--c-accent);
  width: 84px; height: 84px; border-radius: 50%; flex: none; position: relative;
  background: conic-gradient(var(--ring-c) calc(var(--p) * 1%), rgba(255,255,255,.18) 0);
  display: flex; align-items: center; justify-content: center;
}
.ring::before { content: ''; position: absolute; inset: 8px; border-radius: 50%; background: var(--surface); }
.ring .ring-hole {
  position: absolute; inset: 8px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-weight: 800; font-size: 17px;
}

/* Hero panel (dashboard greeting) */
.hero {
  border-radius: 18px; padding: 22px 24px; color: #fff; margin-bottom: 16px;
  background:
    radial-gradient(600px 300px at 90% -40%, rgba(246,192,42,.25), transparent 60%),
    linear-gradient(140deg, var(--c-main) 0%, var(--c-main-deep) 45%, var(--c-menu) 100%);
  box-shadow: 0 14px 40px rgba(0, 90, 158, .3);
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
}
.hero .ring { background: conic-gradient(var(--ring-c) calc(var(--p) * 1%), rgba(255,255,255,.15) 0); }
.hero .ring::before { background: rgba(0, 62, 105, .6); backdrop-filter: blur(2px); }
.hero .ring .ring-hole { color: #fff; }
.hero .ring .ring-hole small { font-size: 9.5px; font-weight: 600; opacity: .8; }
.hero-avatar {
  width: 56px; height: 56px; border-radius: 18px; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 21px; color: #fff;
  box-shadow: 0 6px 18px rgba(0,0,0,.25), inset 0 1px 0 rgba(255,255,255,.25);
}
.hero .who { flex: 1; min-width: 200px; }
.hero .who h1 { font-size: 20px; font-weight: 800; letter-spacing: -.02em; }
.hero .who .sub { font-size: 12.5px; opacity: .8; margin-top: 2px; }
.hero-stats { display: flex; gap: 26px; flex-wrap: wrap; align-items: center; }
.hero-stat { min-width: 74px; }
.hero-stat .n { font-size: 24px; font-weight: 800; letter-spacing: -.02em; }
.hero-stat .l { font-size: 11px; opacity: .78; margin-top: 1px; }

/* Quest cards (my tasks) */
.quest {
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px;
  background: var(--surface); transition: box-shadow .15s, transform .1s, border-color .15s;
  cursor: pointer;
}
.quest:hover { box-shadow: var(--shadow); transform: translateY(-1px); border-color: rgba(0,112,192,.35); }
.quest .q-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.quest .q-title { font-weight: 650; font-size: 13px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.quest .q-meta { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-dim); flex-wrap: wrap; }
.quest .q-meta .pct { margin-left: auto; font-weight: 700; color: var(--c-main); }

/* Section container (replaces scattered boxes) */
.section {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px 18px; box-shadow: var(--shadow-sm);
  min-width: 0;
}
.section > h2 {
  font-size: 13px; font-weight: 750; color: var(--heading);
  display: flex; align-items: center; gap: 9px; margin-bottom: 12px; letter-spacing: -.01em;
}
.section > h2 .chip-ic { width: 26px; height: 26px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; background: rgba(0,112,192,.1); color: var(--c-main); }
.section > h2 .chip-ic svg { width: 15px; height: 15px; }
.section > h2 .more { margin-left: auto; font-size: 11.5px; color: var(--c-main); cursor: pointer; font-weight: 600; }
.mini-stats { display: flex; gap: 0; flex-wrap: wrap; }
.mini-stat { display: flex; align-items: center; gap: 10px; padding: 6px 18px 6px 0; margin-right: 18px; border-right: 1px solid var(--border); }
.mini-stat:last-child { border-right: none; }
.mini-stat .ic { width: 32px; height: 32px; border-radius: 10px; display: flex; align-items: center; justify-content: center; }
.mini-stat .ic svg { width: 16px; height: 16px; }
.mini-stat .n { font-size: 17px; font-weight: 800; line-height: 1.1; }
.mini-stat .l { font-size: 11px; color: var(--text-dim); }

/* Finance bars */
.money-bar { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.money-bar .row { display: flex; justify-content: space-between; font-size: 12px; gap: 10px; }
.money-bar .row b { white-space: nowrap; }

/* Empty state */
.empty {
  text-align: center; color: var(--text-dim); padding: 26px 10px; font-size: 13px;
}
.empty svg { width: 30px; height: 30px; opacity: .4; margin-bottom: 6px; }

/* ---------- Agenda cards + voting ---------- */
.agenda-card {
  border: 1px solid var(--border); border-radius: 14px; background: var(--surface);
  padding: 16px 18px; margin-bottom: 12px; box-shadow: var(--shadow-sm);
}
.agenda-card .a-head { display: flex; align-items: flex-start; gap: 12px; }
.agenda-no {
  width: 30px; height: 30px; border-radius: 10px; flex: none;
  background: rgba(0,112,192,.1); color: var(--c-main);
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 13px;
}
.agenda-card .a-title { font-weight: 700; font-size: 14px; flex: 1; min-width: 0; }
.agenda-card .a-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.minutes {
  margin-top: 12px; border-left: 3px solid var(--c-accent);
  background: rgba(246,192,42,.07); border-radius: 0 10px 10px 0;
  padding: 10px 13px; font-size: 13px; white-space: pre-line;
}
.minutes .m-label { font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .07em; color: var(--gold-strong); margin-bottom: 3px; }
.vote-row { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.vote-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1.5px solid var(--border-strong); background: var(--surface); border-radius: 999px;
  padding: 5px 13px; font-size: 12.5px; font-weight: 650; cursor: pointer;
  color: var(--text-dim); transition: all .12s;
}
.vote-btn svg { width: 14px; height: 14px; }
.vote-btn:hover { border-color: var(--c-main); color: var(--c-main); }
.vote-btn.approve.sel { background: rgba(0,176,80,.12); border-color: var(--c-green); color: var(--ok-strong); }
.vote-btn.reject.sel { background: rgba(240,90,90,.12); border-color: var(--c-red); color: var(--danger-strong); }
.vote-btn.abstain.sel { background: rgba(123,129,137,.15); border-color: var(--c-bluegrey); color: var(--pill-inactive-fg); }
.vote-tally { display: flex; height: 8px; border-radius: 99px; overflow: hidden; background: var(--surface-3); margin-top: 10px; }
.vote-tally .t-a { background: var(--c-green); }
.vote-tally .t-r { background: var(--c-red); }
.vote-tally .t-x { background: var(--c-bluegrey); }

/* ---------- Global quick search (topbar) ---------- */
.gsearch { position: relative; }
.gsearch input { width: 250px; padding-left: 32px; height: 34px; border-radius: 10px; }
.gsearch > svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--c-grey); }
.gsearch-panel {
  position: absolute; top: calc(100% + 8px); right: 0; width: 380px; max-width: 84vw;
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: 14px;
  box-shadow: var(--shadow-lg); padding: 6px; max-height: 420px; overflow-y: auto;
}
.gsearch-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px;
  border-radius: 9px; cursor: pointer;
}
.gsearch-item:hover { background: rgba(0,112,192,.08); }
.gsearch-item .ic { width: 28px; height: 28px; border-radius: 9px; flex: none; display: flex; align-items: center; justify-content: center; background: rgba(0,112,192,.1); color: var(--c-main); }
.gsearch-item .ic svg { width: 14px; height: 14px; }
.gsearch-item .tx { min-width: 0; flex: 1; }
.gsearch-item .t1 { display: block; font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gsearch-item .t2 { display: block; font-size: 11px; color: var(--text-dim); line-height: 1.45; }
/* Notification text may wrap over two lines; search results stay single-line */
.notif-item .t1 { white-space: normal; }

/* ---------- Notification bell ---------- */
.bell { position: relative; }
/* A three-character badge ('99+') sat on top of the bell and hid the thing it
   was a badge for. It now hangs off the corner instead of covering it. */
.bell .badge {
  position: absolute; top: -6px; right: -8px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px; background: var(--c-red); color: #fff;
  font-size: 10px; font-weight: 800; line-height: 17px; text-align: center;
  box-shadow: 0 0 0 2px var(--surface); pointer-events: none;
}
.notif-panel { width: 420px; }
.notif-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px 6px; font-size: 13px;
}
.notif-head .more { border: none; background: none; color: var(--c-main); font-size: 12px; font-weight: 600; cursor: pointer; }
.notif-item.read { opacity: .62; }
/* Repeated headlines collapse into one openable line */
.notif-roll { cursor: pointer; }
.notif-roll .pill { font-size: 10.5px; font-weight: 800; padding: 1px 7px; border-radius: 999px;
  background: var(--c-red); color: #fff; flex: none; }
.notif-roll.open .ic { background: rgba(0,112,192,.2); }
.notif-roll-body { padding-left: 14px; border-left: 2px solid var(--border); margin-left: 16px; }
.notif-roll-body[hidden] { display: none; }

.notif-item .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--c-main); flex: none; }

/* ---------- Change history diffs ---------- */
.diff-list { display: flex; flex-direction: column; gap: 4px; }
.diff-row {
  display: flex; align-items: center; gap: 8px; font-size: 12.5px;
  padding: 4px 8px; background: var(--surface-2); border-radius: 8px; flex-wrap: wrap;
}
.diff-row svg { width: 12px; height: 12px; color: var(--c-grey); flex: none; }
.diff-field { font-weight: 700; color: var(--heading); min-width: 110px; }
.diff-before { color: var(--c-red); text-decoration: line-through; overflow-wrap: anywhere; }
.diff-after { color: var(--ok-strong); font-weight: 600; overflow-wrap: anywhere; }

/* ---------- Gantt chart ---------- */
/* The chart scrolls sideways; the names do not. Everything in the first
   column is pinned to the left edge of the scroller, so a long project can be
   read across without losing track of which row is which. */
.sched-scroll { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; }
.gantt { display: grid; grid-template-columns: 200px 1fr; gap: 0; font-size: 12px; }
.gantt .g-row, .gantt-months .g-scale { position: relative; }
.gantt .g-label {
  padding: 7px 10px 7px 0; border-bottom: 1px solid var(--border);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  position: sticky; left: 0; z-index: 3; background: var(--surface);
  box-shadow: 1px 0 0 var(--border);
}
.gantt .g-label.sc-axis { padding: 0; overflow: visible; border-bottom: none; }
.gantt .g-row { position: relative; border-bottom: 1px solid var(--border); min-height: 30px; }
.gantt .g-grid { position: absolute; top: 0; bottom: 0; border-left: 1px dashed var(--border); }
.gantt .g-bar {
  position: absolute; top: 7px; height: 16px; border-radius: 4px;
  background: var(--surface-3); overflow: hidden; min-width: 4px;
}
.gantt .g-fill { height: 100%; border-radius: 4px 0 0 4px; }
.gantt .g-bar.done .g-fill { background: var(--c-green); }
.gantt .g-bar.active .g-fill { background: var(--c-main); }
.gantt .g-bar.late .g-fill { background: var(--c-red); }
.gantt .g-today { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--c-accent); z-index: 2; }
.gantt-months {
  display: grid; grid-template-columns: 200px 1fr; margin-bottom: 4px;
  position: sticky; top: 0; z-index: 4; background: var(--surface); padding-bottom: 2px;
}
.gantt-months .g-head {
  position: sticky; left: 0; z-index: 5; background: var(--surface);
  font-size: 11px; align-self: end; padding-bottom: 2px; box-shadow: 1px 0 0 var(--border);
}
.gantt-months .g-scale { position: relative; height: 20px; border-bottom: 1px solid var(--border); }
/* Each label owns exactly one month column and is centred in it, so however
   long the project runs the months read cleanly instead of overlapping. */
.gantt-months .g-m {
  position: absolute; top: 3px; font-size: 10px; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: .04em; font-weight: 600;
  text-align: center; overflow: hidden; white-space: nowrap;
  border-left: 1px solid var(--border); padding-left: 4px; box-sizing: border-box;
}
.gantt .g-ms { position: absolute; top: 9px; width: 12px; height: 12px; transform: translateX(-6px) rotate(45deg); background: var(--c-purple); border-radius: 2px; }
.chart-legend { display: flex; gap: 16px; align-items: center; font-size: 12px; color: var(--text-dim); margin-top: 10px; flex-wrap: wrap; }
.chart-legend .key { display: inline-flex; align-items: center; gap: 6px; }
.chart-legend .sw { width: 14px; height: 4px; border-radius: 2px; display: inline-block; }
.chart-legend .sw.dot { width: 10px; height: 10px; border-radius: 50%; }

/* ---------- Icon chips (global) ---------- */
.chip-ic {
  width: 26px; height: 26px; border-radius: 8px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(0,112,192,.1); color: var(--c-main);
}
.chip-ic svg { width: 15px; height: 15px; }
.chip-ic.green { background: rgba(0,176,80,.1); color: var(--c-green); }
.chip-ic.orange { background: rgba(255,150,79,.12); color: var(--warn-strong); }
.chip-ic.red { background: rgba(240,90,90,.1); color: var(--c-red); }
.chip-ic.purple { background: rgba(112,48,160,.1); color: var(--c-purple); }
.chip-ic.yellow { background: rgba(246,192,42,.16); color: var(--gold-strong); }

/* ---------- Popover layer (notifications, quick search) ----------
   Panels are moved into #popover-root so no page content, sticky table
   header or modal can ever cover or clip them. */
#popover-root { position: fixed; inset: 0; z-index: var(--z-popover); pointer-events: none; }
#popover-root > .popover { position: fixed; pointer-events: auto; }

/* ---------- Modal tone (spec keeps the dark header; tone adds a colour cue) ---------- */
.modal-head { position: relative; }
.modal.tone-warning .modal-head::after,
.modal.tone-danger .modal-head::after,
.modal.tone-success .modal-head::after,
.modal.tone-info .modal-head::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
}
.modal.tone-warning .modal-head::after { background: var(--c-orange); }
.modal.tone-danger  .modal-head::after { background: var(--c-red); }
.modal.tone-success .modal-head::after { background: var(--c-green); }
.modal.tone-info    .modal-head::after { background: var(--c-main); }
.modal-head .head-ic { width: 26px; height: 26px; border-radius: 8px; flex: none;
  display: inline-flex; align-items: center; justify-content: center; background: rgba(255,255,255,.13); }
.modal-head .head-ic svg { width: 15px; height: 15px; }
.modal.tone-warning .modal-head .head-ic { background: rgba(255,150,79,.25); color: #ffc999; }
.modal.tone-danger  .modal-head .head-ic { background: rgba(240,90,90,.25); color: #ffb3b3; }
.modal.tone-success .modal-head .head-ic { background: rgba(0,176,80,.25); color: #9de9c1; }
.modal-head .head-tx { flex: 1; min-width: 0; }

/* ---------- Skill catalog & skill page ---------- */
.face {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; color: #fff; border: 2px solid var(--surface);
  margin-left: -7px; box-shadow: 0 1px 3px rgba(16,26,36,.18);
}
.face:first-child { margin-left: 0; }
.face.more { background: var(--surface-3); color: var(--text-dim); }

/* Level distribution bars (skill page left panel) */
.lvl-dist { display: flex; flex-direction: column; gap: 6px; }
.lvl-row { display: flex; align-items: center; gap: 9px; font-size: 12px; }
.lvl-row .lv-name { width: 78px; flex: none; color: var(--text-dim); }
.lvl-row .lv-bar { flex: 1; height: 7px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.lvl-row .lv-fill { height: 100%; border-radius: 99px; background: linear-gradient(90deg, var(--c-main), #45a9ec); }
.lvl-row .lv-n { width: 18px; text-align: right; font-weight: 700; color: var(--heading); flex: none; }

/* Holder rows on a skill page */
.holder {
  display: flex; align-items: center; gap: 12px; padding: 11px 13px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--surface); margin-bottom: 8px;
  transition: box-shadow .15s, border-color .15s;
}
.holder:hover { box-shadow: var(--shadow-sm); border-color: rgba(0,112,192,.3); }
.holder .h-av { width: 38px; height: 38px; border-radius: 12px; flex: none; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; font-size: 14px; }
.holder .h-tx { flex: 1; min-width: 0; }
.holder .h-name { font-weight: 650; font-size: 13.5px; cursor: pointer; }
.holder .h-name:hover { color: var(--c-main); text-decoration: underline; }
.holder .h-sub { font-size: 11.5px; color: var(--text-dim); display: flex; gap: 7px; flex-wrap: wrap; align-items: center; }
.holder .h-lvl { text-align: right; flex: none; min-width: 116px; }
.holder .h-lvl .lv-label { font-size: 11px; color: var(--text-dim); margin-top: 2px; }
.holder .h-acts { display: flex; gap: 3px; flex: none; }

/* ---------- Star picker (assessment form) ---------- */
.star-pick { display: flex; align-items: center; gap: 10px; }
.star-pick .sp-stars { display: flex; gap: 3px; }
.star-pick .sp-star {
  border: none; background: none; cursor: pointer; padding: 2px; line-height: 0;
  color: var(--star-off); transition: transform .08s, color .12s;
}
.star-pick .sp-star svg { width: 26px; height: 26px; }
.star-pick .sp-star:hover { transform: scale(1.12); }
.star-pick .sp-star.on { color: var(--c-accent); }
.star-pick .sp-star.on svg { fill: var(--c-accent); }
.star-pick .sp-label { font-size: 13px; font-weight: 700; color: var(--heading); }
.star-pick .sp-hint { font-size: 11.5px; color: var(--text-dim); }

/* Segmented control (person / stakeholder toggle, holder filter) */
.seg { display: inline-flex; background: var(--surface-3); border-radius: 10px; padding: 3px; gap: 3px; }
.seg button {
  border: none; background: none; cursor: pointer; padding: 6px 13px; border-radius: 8px;
  font-size: 12.5px; font-weight: 650; color: var(--text-dim); font-family: inherit;
  display: inline-flex; align-items: center; gap: 6px;
}
.seg button svg { width: 14px; height: 14px; }
.seg button.on { background: var(--surface); color: var(--c-main); box-shadow: var(--shadow-sm); }

/* Related-records links on a generic record page */
.rel-link {
  display: flex; align-items: flex-start; gap: 9px; padding: 8px 10px; border-radius: 9px;
  cursor: pointer; border: 1px solid var(--border); margin-bottom: 6px; background: var(--surface);
}
.rel-link:hover { border-color: rgba(0,112,192,.4); background: rgba(0,112,192,.04); }
/* The name wraps rather than being cut off or running out of the card. These
   are spans, so the old `text-overflow: ellipsis` never applied to them — an
   inline box does not clip — and a long project name simply left the box.
   A truncated project name is no use to anybody anyway: half of them here
   differ only in the last few words. */
.rel-link .chip-ic, .rel-link > svg, .rel-link > i { margin-top: 1px; }
.rel-link .rl-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.rel-link .rl-t1 { display: block; font-size: 13px; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.rel-link .rl-t2 { display: block; font-size: 11px; color: var(--text-dim); line-height: 1.4; overflow-wrap: anywhere; }
.rel-link > svg, .rel-link > b { flex: none; }

/* S-curve sharing the Gantt timeline */
.sc-head {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  margin: 18px 0 4px; padding-top: 14px; border-top: 1px solid var(--border);
  font-size: 13px;
}
.sc-head .muted { font-size: 11.5px; }

/* ---------- Portraits ---------- */
/* An avatar keeps its gradient + initials until a photo arrives, so the
   layout never jumps and people without a portrait still look deliberate. */
.has-photo { background-size: cover !important; background-position: center; color: transparent !important; }
.avatar-edit { position: relative; display: inline-flex; }
.avatar-edit .cam {
  position: absolute; right: -4px; bottom: -4px; width: 26px; height: 26px;
  border-radius: 50%; border: 2px solid var(--surface); background: var(--c-main);
  color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.avatar-edit .cam svg { width: 13px; height: 13px; }
.avatar-edit .cam:hover { filter: brightness(1.1); }

/* Photo gallery (project photos) */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }
.gallery .shot {
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--surface);
  cursor: pointer; transition: box-shadow .15s, transform .1s;
}
.gallery .shot:hover { box-shadow: var(--shadow); transform: translateY(-1px); }
.gallery .shot img { width: 100%; height: 118px; object-fit: cover; display: block; background: var(--surface-3); }
.gallery .shot .cap { padding: 8px 10px; font-size: 12px; }
.gallery .shot .cap .t2 { font-size: 11px; color: var(--text-dim); }
.lightbox-img { max-width: 100%; max-height: 72vh; display: block; margin: 0 auto; border-radius: 10px; }

/* ---------- Standard-WBS branch picker ---------- */
/* Its own class: this used to be `.wbs-pick`, which the cascading picker in
   the task form also uses — so this box's scrollbar appeared inside that form
   as well. Neither needs one: the dialog body already scrolls, and a panel
   that scrolls inside a page that scrolls is a trap for the reader. */
.wbs-branches { display: flex; flex-direction: column; gap: 6px; }
.wbs-branch {
  display: flex; align-items: flex-start; gap: 11px; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: 10px; cursor: pointer; background: var(--surface);
}
.wbs-branch:hover { border-color: rgba(0,112,192,.4); background: rgba(0,112,192,.03); }
.wbs-branch input { margin-top: 3px; accent-color: var(--c-main); width: 15px; height: 15px; }
.wbs-branch .wb-tx { flex: 1; min-width: 0; }
.wbs-branch .wb-name { display: block; font-size: 13px; }
.wbs-branch .wb-sub { display: block; font-size: 11.5px; color: var(--text-dim); margin-top: 1px; }
.wbs-branch .wb-pct { flex: none; font-size: 12px; font-weight: 700; color: var(--c-main); }

/* Inline "what changed" panel inside an approval card */
.ap-diff { margin-top: 11px; padding-top: 11px; border-top: 1px dashed var(--border-strong); }

/* ---------- Collapsible form sections ---------- */
/* A heading inside the form grid: groups the fields under it without hiding
   them, so a long form reads as three short ones. */
.form-head {
  grid-column: 1 / -1; display: flex; align-items: baseline; gap: 9px;
  margin: 6px 0 -2px; padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
.form-head:first-child { margin-top: 0; }
.form-head span { font-size: 12px; font-weight: 700; color: var(--heading); letter-spacing: .02em; text-transform: uppercase; }
.form-head em { font-style: normal; font-size: 11.5px; color: var(--text-dim); }
@media (max-width: 640px) { .form-head { grid-column: 1 / -1; } }

.form-section { grid-column: 1 / -1; margin-top: 14px; border-top: 1px solid var(--border); padding-top: 12px; }
.form-section .fs-head {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 2px;
  border: none; background: none; cursor: pointer; font-family: inherit;
  font-size: 12.5px; font-weight: 700; color: var(--heading); text-align: left;
}
.form-section .fs-head svg { width: 15px; height: 15px; color: var(--c-bluegrey); transition: transform .14s; }
.form-section .fs-head.open svg { transform: rotate(90deg); }
.form-section .fs-head:hover { color: var(--c-main); }
.form-section .fs-hint { margin-left: auto; font-size: 11px; font-weight: 500; color: var(--text-dim); }
.form-section .fs-body { margin-top: 10px; }

/* Money reads as money: tabular figures so columns of amounts line up */
.num { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* "Show more" strip under a long table */
.table-more { padding: 12px; text-align: center; border-top: 1px solid var(--border); background: var(--surface-2); }
.table-more .btn { gap: 6px; }

/* Why people voted the way they did — the reason matters more than the tally */
.vote-notes { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.vote-notes .vn-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12.5px; background: var(--surface-2); border-radius: 8px; padding: 6px 10px;
}

/* ---------- Photo albums ---------- */
.photo-folder { margin-bottom: 20px; }
.photo-folder .pf-head {
  display: flex; align-items: center; gap: 9px; margin-bottom: 10px;
  font-size: 13px; color: var(--heading);
}
.photo-folder .pf-head svg { width: 16px; height: 16px; color: var(--c-purple); }
.photo-folder .pf-head .muted { font-size: 11.5px; margin-left: 2px; }

/* The schedule is a wide view: give it every pixel the window has, and let it
   scroll only when the project is genuinely longer than the screen. */
.gantt-months, .gantt { min-width: 0; }

/* ---------- Cash flow summary strip ---------- */
.cf-stats { display: flex; flex-wrap: wrap; gap: 0; margin: -2px 0 14px; }
.cf-stat { padding: 4px 20px 4px 0; margin-right: 20px; border-right: 1px solid var(--border); }
.cf-stat:last-child { border-right: none; }
.cf-stat .l { display: block; font-size: 11px; color: var(--text-dim); }
.cf-stat .v { display: block; font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.cf-stat .v.big { font-size: 18px; }

/* ---------- Submitting and reviewing work ---------- */
.cbx { display: flex; align-items: center; gap: 9px; font-size: 13px; cursor: pointer; color: var(--text); }
.cbx input { width: 16px; height: 16px; accent-color: var(--c-main); }

.rv-head { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.rv-task { font-size: 15px; font-weight: 700; color: var(--heading); }
.rv-facts { margin-left: auto; display: flex; gap: 10px; flex-wrap: wrap; }
.rv-fact { background: var(--surface-3); border-radius: 10px; padding: 7px 12px; min-width: 130px; }
.rv-fact .l { display: block; font-size: 10.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .05em; }
.rv-fact .v { display: block; font-size: 13px; font-weight: 700; }
.rv-fact.late .v { color: var(--c-red); }
.rv-fact.ontime .v { color: var(--ok-strong); }
.rv-summary { background: var(--surface-2); border-left: 3px solid var(--c-main); border-radius: 0 8px 8px 0;
  padding: 9px 12px; font-size: 13px; white-space: pre-line; }

.rv-dim { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.rv-dim-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 9px; font-size: 13px; }
.rv-dim-head .muted { font-size: 11.5px; }
.rv-scale { display: flex; flex-direction: column; gap: 4px; }
/* Each level shows what it actually means, so two supervisors mean the same
   thing by "4" — that is the whole point of an anchored scale. */
.rv-level {
  display: flex; align-items: flex-start; gap: 10px; text-align: left; width: 100%;
  border: 1px solid var(--border); border-radius: 9px; background: var(--surface); cursor: pointer;
  padding: 7px 11px; font-family: inherit; font-size: 12.5px; color: var(--text);
  transition: border-color .12s, background .12s;
}
.rv-level:hover { border-color: rgba(0,112,192,.45); background: rgba(0,112,192,.03); }
.rv-level .n {
  flex: none; width: 22px; height: 22px; border-radius: 7px; background: var(--surface-3);
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 12px;
  color: var(--text-dim);
}
.rv-level.on { border-color: var(--c-main); background: rgba(0,112,192,.07); box-shadow: 0 0 0 2px rgba(0,112,192,.12); }
.rv-level.on .n { background: var(--c-main); color: #fff; }
.rv-running {
  margin-top: 14px; padding: 9px 12px; background: var(--surface-3); border-radius: 10px;
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-size: 12.5px;
}
.rv-running b { font-size: 15px; color: var(--heading); }
.rv-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.rv-chip { background: var(--surface); border: 1px solid var(--border); border-radius: 999px;
  padding: 2px 10px; font-size: 11.5px; }
.rv-chip b { color: var(--c-main); }

/* ---------- Measured work rates ---------- */
.nm-head { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.nm-title { font-size: 14px; font-weight: 700; color: var(--heading); }
.nm-rates { display: flex; flex-wrap: wrap; gap: 0; margin-top: 12px; }
.nm-rate { padding: 4px 22px 4px 0; margin-right: 22px; border-right: 1px solid var(--border); }
.nm-rate:last-child { border-right: none; }
.nm-rate .l { display: block; font-size: 11px; color: var(--text-dim); }
.nm-rate .v { display: block; font-size: 20px; font-weight: 800; color: var(--heading);
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.nm-rate .v small { font-size: 11.5px; font-weight: 600; color: var(--text-dim); }
.nm-obs { margin-top: 12px; }
.nm-obs .more { border: none; background: none; color: var(--c-main); font-size: 12px;
  font-weight: 600; cursor: pointer; padding: 0; }
.nm-card { padding: 14px 0; border-top: 1px solid var(--border); }
.nm-card:first-child { border-top: none; padding-top: 6px; }
.nm-act { margin-left: auto; align-self: center; }

/* A table wider than its panel scrolls inside its own box; the page never
   scrolls sideways to reach a column. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll table.data { min-width: 520px; }

/* ---------- Cash flow period picker ---------- */
.cf-range {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: -2px 0 14px; padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.cf-dates { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-dim); }
.cf-dates .input { width: 152px; padding: 5px 9px; font-size: 12px; }
.cf-grain { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-dim); }

/* ---------- Total-cash banner on the accounts list ---------- */
.total-wallet {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: linear-gradient(135deg, var(--c-darknavy), #35516d);
  color: #fff; border-radius: var(--radius); padding: 16px 20px; margin-bottom: 14px;
}
.total-wallet .tw-ic {
  width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center;
  background: rgba(255,255,255,.14);
}
.total-wallet .tw-ic i { width: 21px; height: 21px; }
.total-wallet .tw-tx { flex: 1; min-width: 200px; }
.total-wallet .tw-l { font-size: 11.5px; opacity: .8; text-transform: uppercase; letter-spacing: .05em; }
.total-wallet .tw-v { font-size: 27px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.total-wallet .tw-s { font-size: 11.5px; opacity: .82; }
.total-wallet .btn.secondary { background: rgba(255,255,255,.15); border-color: rgba(255,255,255,.3); color: #fff; }
.total-wallet .btn.secondary:hover { background: rgba(255,255,255,.25); }

/* ---------- Fee-share calculator on a WBS line ---------- */
.fee-calc {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  margin-top: 12px; padding: 10px 12px; background: var(--surface-3); border-radius: 10px; font-size: 12.5px;
}
.fee-calc label { color: var(--text-dim); }
.fee-calc .input { width: 160px; padding: 5px 9px; font-size: 12.5px; }
.fee-calc b { font-size: 15px; color: var(--heading); font-variant-numeric: tabular-nums; }

/* Notification groups: unread first, under their own heading */
.notif-group {
  padding: 9px 14px 5px; font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--c-main);
  background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.notif-group.muted { color: var(--text-dim); }

/* ============ Rich content: agenda papers ============ */
.rich { font-size: 13px; line-height: 1.62; color: var(--text); }
.rich > *:first-child { margin-top: 0; }
.rich > *:last-child { margin-bottom: 0; }
.rich p { margin: 0 0 9px; }
.rich h3 { font-size: 15px; font-weight: 700; color: var(--heading); margin: 16px 0 7px; letter-spacing: -.01em; }
.rich h4 { font-size: 13.5px; font-weight: 700; color: var(--heading); margin: 14px 0 6px; }
.rich ul, .rich ol { margin: 0 0 9px; padding-left: 22px; }
.rich li { margin: 2px 0; }
.rich blockquote {
  margin: 10px 0; padding: 7px 13px; border-left: 3px solid var(--c-main);
  background: var(--surface-2); border-radius: 0 8px 8px 0; color: var(--text-dim);
}
.rich code { background: var(--surface-2); border-radius: 4px; padding: 1px 5px; font-size: 12px; }
.rich pre { background: var(--surface-2); border-radius: 8px; padding: 10px 12px; overflow-x: auto; font-size: 12px; }
.rich a { color: var(--c-main); text-decoration: underline; }
.rich hr { border: none; border-top: 1px solid var(--border); margin: 14px 0; }
.rich figure { margin: 12px 0; }
.rich figure img { display: block; max-width: 100%; height: auto; border-radius: 10px; border: 1px solid var(--border); }
.rich figcaption { margin-top: 5px; font-size: 11.5px; color: var(--text-dim); text-align: center; }
.rich img { max-width: 100%; height: auto; border-radius: 8px; }
.rich table {
  border-collapse: collapse; margin: 11px 0; font-size: 12.5px;
  width: 100%; max-width: 100%; display: block; overflow-x: auto;
}
.rich table th, .rich table td { border: 1px solid var(--border-strong); padding: 6px 9px; vertical-align: top; min-width: 60px; }
.rich table th { background: var(--surface-3); font-weight: 700; text-align: left; color: var(--heading); }
.rich table tr:nth-child(even) td { background: var(--surface-2); }

/* ============ The editor ============ */
.rte { border: 1px solid var(--border-strong); border-radius: 10px; overflow: hidden; background: var(--input-bg); }
.rte-bar {
  display: flex; align-items: center; gap: 2px; flex-wrap: wrap;
  padding: 5px 7px; background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.rte-btn {
  width: 28px; height: 28px; border: none; background: none; border-radius: 7px;
  display: grid; place-items: center; cursor: pointer; color: var(--text-dim);
}
.rte-btn:hover { background: rgba(0,112,192,.12); color: var(--c-main); }
.rte-btn i { width: 15px; height: 15px; }
.rte-sep { width: 1px; height: 18px; background: var(--border-strong); margin: 0 5px; }
.rte-body { padding: 12px 14px; max-height: 46vh; overflow-y: auto; outline: none; }
.rte-body:empty::before, .rte-body > p:only-child:empty::before {
  content: attr(data-placeholder); color: var(--text-dim);
}
.rte-body:focus { box-shadow: inset 0 0 0 2px rgba(0,112,192,.12); }
.rte-body table th, .rte-body table td { min-width: 48px; }
.rte-foot {
  display: flex; gap: 10px; align-items: center; justify-content: space-between;
  padding: 5px 10px; background: var(--surface-2); border-top: 1px solid var(--border); font-size: 11px;
}
.rte-uploading { color: var(--text-dim); font-style: italic; }
.rte-tablepick .field { margin-bottom: 10px; }

/* ============ Agenda: closed items you open ============ */
.agenda-card.collapsible { padding: 0; overflow: hidden; }
.a-toggle {
  width: 100%; display: flex; align-items: center; gap: 12px; text-align: left;
  padding: 12px 14px; background: none; border: none; cursor: pointer; font: inherit;
}
.a-toggle:hover { background: var(--surface-2); }
.a-tx { flex: 1; min-width: 0; }
.a-tx .a-title { display: block; }
.a-tx .a-sub { display: block; }
.a-chev { width: 16px; height: 16px; color: var(--c-grey); transition: transform .15s; flex: none; }
.agenda-card.collapsible.open .a-chev { transform: rotate(180deg); }
.agenda-card.collapsible.open .a-toggle { border-bottom: 1px solid var(--border); background: var(--surface-2); }
.a-body:not(:empty) { padding: 13px 14px 14px; }
.a-lead { font-size: 12.5px; color: var(--text-dim); margin-bottom: 10px; }
.a-content:not(:empty) { margin-bottom: 12px; }

/* ============ Invitations, replies and the register ============ */
.rsvp-banner { display: flex; align-items: center; gap: 12px; }
.rsvp-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.rsvp-bar { display: flex; height: 9px; border-radius: 999px; overflow: hidden; background: var(--border); margin: 2px 0 9px; }
.rsvp-bar span { display: block; }
.s-a { background: var(--ok-strong); } .s-x { background: var(--c-orange); }
.s-w { background: var(--c-bluegrey, #7d93a8); } .s-r { background: var(--danger-strong); }
.s-u { background: var(--border-strong); }
.rsvp-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11px; color: var(--text-dim); margin-bottom: 10px; }
.rsvp-legend .sw { display: inline-block; width: 9px; height: 9px; border-radius: 3px; margin-right: 5px; }
.chk {
  width: 26px; height: 26px; border-radius: 8px; border: 1px solid var(--border-strong);
  background: var(--surface); cursor: pointer; display: grid; place-items: center; color: var(--c-grey);
}
.chk i { width: 14px; height: 14px; }
.chk.on { background: var(--ok-strong); border-color: var(--ok-strong); color: #fff; }
.chk:hover { border-color: var(--c-main); }
.chip .x {
  border: none; background: none; cursor: pointer; color: var(--text-dim);
  font-size: 14px; line-height: 1; padding: 0 0 0 4px;
}
.chip .x:hover { color: var(--c-red); }

/* ---------- Choosing a piece of work, one level at a time ---------- */
/* Deliberately unbounded: it grows to whatever the choice needs and the form
   around it scrolls, exactly like every other field. */
.wbs-pick { display: grid; gap: 8px; }
.wbs-lvl { display: grid; grid-template-columns: 150px 1fr; gap: 10px; align-items: center; }
.wbs-lvl > label { font-size: 12px; font-weight: 600; color: var(--heading); }
.wbs-lvl > label .muted { display: block; font-size: 10.5px; font-weight: 500; }
.wbs-trail {
  margin-top: 2px; padding: 8px 11px; background: var(--surface-3); border-radius: 9px;
  font-size: 12px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.wbs-trail .mono { font-weight: 700; color: var(--heading); }
.sw-dot { display: inline-block; width: 11px; height: 11px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; }
@media (max-width: 720px) { .wbs-lvl { grid-template-columns: 1fr; } }

/* ---------- How work flows here ---------- */
.flow-stage { display: flex; gap: 14px; padding: 14px 0; border-top: 1px solid var(--border);
  /* `empty` here only dims the stage (below); it must NOT borrow the centred
     text-align of the global .empty placeholder — the stage still holds real
     left-reading description text whether or not any records exist yet. */
  text-align: left; }
.flow-stage:first-child { border-top: none; }
.flow-stage.empty { opacity: .72; }
.fs-n { flex: none; }
.fs-n span {
  width: 30px; height: 30px; border-radius: 10px; display: grid; place-items: center;
  background: var(--c-menu); color: #fff; font-weight: 800; font-size: 13px;
}
.flow-stage.empty .fs-n span { background: var(--c-grey); }
.fs-body { flex: 1; min-width: 0; }
.fs-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.fs-head b { font-size: 14px; color: var(--heading); }
.fs-head .muted { font-size: 11.5px; }
.fs-head .spacer { flex: 1; }
.fs-what { font-size: 12.5px; color: var(--text); margin: 6px 0 7px; }
.fs-does { margin: 0 0 9px; padding-left: 18px; font-size: 12px; color: var(--text-dim); }
.fs-does li { margin: 2px 0; }
/* The money map: one line per fact, the count on the right, a lock under
   the level saying what it may not change. */
.mm-rows { display: grid; gap: 2px; margin: 8px 0 10px; }
.mm-row {
  display: flex; align-items: center; gap: 12px; padding: 7px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface); font-size: 12.5px;
}
.mm-row .mm-l { flex: 1; min-width: 0; }
.mm-row .mm-v { flex: none; font-variant-numeric: tabular-nums; white-space: nowrap; }
.mm-row .mm-v.none { color: var(--warn-strong); font-weight: 600; }
.mm-row .mm-v b { font-size: 14px; }
.mm-frozen {
  display: flex; gap: 9px; align-items: flex-start; padding: 9px 11px; border-radius: 8px;
  background: var(--surface-2); border-left: 3px solid var(--c-purple); font-size: 12px; line-height: 1.5;
}
.mm-frozen svg { width: 14px; height: 14px; flex: none; margin-top: 2px; color: var(--c-purple); }
@media (max-width: 640px) {
  .mm-row { flex-wrap: wrap; }
  .mm-row .mm-l { flex-basis: 100%; }
}

.fs-foot { display: flex; gap: 7px; align-items: center; flex-wrap: wrap; font-size: 11.5px; }

/* ---------- What happens next, on a project ---------- */
.ns-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; cursor: pointer; border-radius: 8px; }
.ns-head:hover .ns-chev { color: var(--c-main); }
.ns-head:focus-visible { outline: 2px solid var(--c-main); outline-offset: 3px; }
.ns-head .ns-chev { width: 16px; height: 16px; color: var(--text-dim); flex: none; }
.ns-body[hidden] { display: none; }
.ns-bar { flex: 1; height: 7px; border-radius: 999px; background: var(--border); overflow: hidden; }
.ns-bar span { display: block; height: 100%; background: var(--ok-strong); border-radius: 999px; }
.ns-next {
  display: flex; align-items: center; gap: 11px; padding: 11px 13px;
  background: var(--note-warm-bg); border: 1px solid var(--note-warm-border); border-radius: 10px; font-size: 12.5px;
}
.ns-next.done { background: var(--note-ok-bg); border-color: var(--note-ok-border); }
.ns-next .muted { font-size: 11.5px; }
.ns-next .btn { margin-left: auto; }
.ns-list { display: grid; gap: 2px; margin-top: 11px; }
.ns-row {
  display: flex; align-items: center; gap: 8px; font-size: 12.5px;
  padding: 4px 0; color: var(--text-dim);
}
.ns-row i { width: 15px; height: 15px; color: var(--c-grey); flex: none; }
.ns-row.done { color: var(--text); }
.ns-row.done i { color: var(--ok-strong); }
.ns-row .more { margin-left: auto; }

/* ---------- Quotations ---------- */
/* The money, laid out so the eye lands on the total payable and the net —
   the two figures a client and an accountant respectively look for. */
.qt-totals { padding: 16px 18px; }
.qt-sum { display: flex; flex-wrap: wrap; gap: 10px 26px; align-items: flex-end; }
.qt-cell { display: flex; flex-direction: column; gap: 3px; min-width: 128px; }
.qt-lab { font-size: 11.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .3px; }
.qt-val { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }
.qt-cell.minus .qt-val { color: var(--c-orange); }
.qt-cell.strong .qt-val { font-size: 17px; }
.qt-cell.grand { padding-left: 20px; border-left: 2px solid var(--c-main); }
.qt-cell.grand .qt-val { font-size: 21px; color: var(--c-main); }
.qt-cell.note .qt-val { font-size: 13px; font-weight: 500; color: var(--text-dim); }
.qt-group td { background: var(--bg); font-weight: 600; font-size: 12px;
  text-transform: uppercase; letter-spacing: .3px; color: var(--heading); }
.qt-group .muted { float: right; font-weight: 600; text-transform: none; letter-spacing: 0; }
.qt-optional td { opacity: .72; }
/* the shared `table.data tfoot td` rule now carries this */
td.row-actions { white-space: nowrap; text-align: right; }

/* A hint under any form field, not only the star picker */
.field .sp-hint { display: block; font-size: 11.5px; color: var(--text-dim); margin-top: 4px; line-height: 1.4; }
/* A yes/no that reads as a sentence rather than a bare box */
label.check { display: flex; align-items: flex-start; gap: 8px; font-size: 13px;
  line-height: 1.45; cursor: pointer; padding-top: 6px; }
label.check input { margin-top: 2px; accent-color: var(--c-main); flex: none; }

/* ---------- "Open" buttons ----------
   The small jump from a summary row to the record itself. One component,
   used by the clause map, project checklists and section footers — it was a
   bare native <button> before, which is why it looked like Windows 95. */
.more {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px; border: none; border-radius: 999px;
  background: rgba(0, 112, 192, .09); color: var(--c-main);
  font-family: inherit; font-size: 12px; font-weight: 650; letter-spacing: -.005em;
  line-height: 1.45; cursor: pointer; white-space: nowrap;
  transition: background .13s, color .13s, box-shadow .13s, transform .1s;
}
.more svg { width: 12.5px; height: 12.5px; flex: none; transition: transform .13s; }
.more:hover { background: var(--c-main); color: #fff; box-shadow: 0 3px 10px rgba(0, 112, 192, .35); }
.more:hover svg { transform: translate(1.5px, -1.5px); }
.more:active { transform: translateY(1px); }
.more:focus-visible { outline: 2px solid var(--c-main); outline-offset: 2px; }
[data-theme="dark"] .more { background: rgba(90, 176, 255, .13); color: #6fc0ff; }
[data-theme="dark"] .more:hover { background: var(--c-main); color: #fff; }

/* ---------- Theme & language switches (topbar) ---------- */
.tb-switches { display: flex; align-items: center; gap: 7px; }
.lang-seg {
  display: inline-flex; background: var(--surface-3); border-radius: 9px;
  padding: 2.5px; gap: 2px;
}
.lang-seg button {
  border: none; background: none; cursor: pointer; padding: 3.5px 9px;
  border-radius: 7px; font-size: 11.5px; font-weight: 700; color: var(--text-dim);
  font-family: inherit; letter-spacing: .01em; line-height: 1.5;
  transition: background .12s, color .12s;
}
.lang-seg button.on { background: var(--surface); color: var(--c-main); box-shadow: var(--shadow-sm); }
.lang-seg button:focus-visible { outline: 2px solid var(--c-main); outline-offset: 1px; }

/* The same switches on the login screen, floating on its dark backdrop */
.login-switches {
  position: absolute; top: 16px; right: 18px;
  display: flex; align-items: center; gap: 7px;
}
.login-switches .icon-btn { color: #cdd7e1; background: rgba(255, 255, 255, .08); width: 32px; height: 32px; }
.login-switches .icon-btn:hover { background: rgba(255, 255, 255, .16); color: #fff; }
.login-switches .lang-seg { background: rgba(255, 255, 255, .1); }
.login-switches .lang-seg button { color: #b9c6d3; }
.login-switches .lang-seg button.on { background: rgba(255, 255, 255, .92); color: var(--c-main-deep); }

/* Login screen needs its own positioning context for the switches */
.login-screen { position: fixed; }

/* ---------- Risk register: score chip ---------- */
.risk-score {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; height: 22px; padding: 0 8px; border-radius: 7px;
  font-weight: 800; font-size: 12px; font-variant-numeric: tabular-nums;
}
.risk-score.low    { background: rgba(0, 176, 80, .14);  color: var(--pill-active-fg); }
.risk-score.medium { background: rgba(246, 192, 42, .2); color: var(--gold-strong); }
.risk-score.high   { background: rgba(255, 150, 79, .18); color: var(--pill-pending-fg); }
.risk-score.extreme{ background: rgba(240, 90, 90, .16);  color: var(--pill-cancelled-fg); }

/* ---------- Live estimate panel inside a form ---------- */
.form-note {
  background: var(--surface-3); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 13px; font-size: 12.5px; line-height: 1.55;
}
.form-note b { color: var(--heading); }
.form-note .est-figure { font-size: 15px; font-weight: 800; color: var(--c-main); font-variant-numeric: tabular-nums; }
.form-note .muted { display: block; margin-top: 3px; }

/* ---------- "There is more to the right" ----------
   Wide tables scroll inside their own box, but macOS hides scrollbars until
   the moment you scroll — so a clipped last column reads as a broken layout
   rather than as something you can reach. These shadows appear only while
   there is content beyond the edge, and fade out as you arrive at it. */
.table-wrap, .table-scroll, .sched-scroll {
  background-image:
    linear-gradient(to right, var(--surface) 30%, rgba(0, 0, 0, 0)),
    linear-gradient(to left,  var(--surface) 30%, rgba(0, 0, 0, 0)),
    radial-gradient(farthest-side at 0 50%, rgba(16, 26, 36, .16), rgba(0, 0, 0, 0)),
    radial-gradient(farthest-side at 100% 50%, rgba(16, 26, 36, .16), rgba(0, 0, 0, 0));
  background-position: 0 0, 100% 0, 0 0, 100% 0;
  background-repeat: no-repeat;
  background-size: 42px 100%, 42px 100%, 15px 100%, 15px 100%;
  background-attachment: local, local, scroll, scroll;
  background-color: var(--surface);
}
[data-theme="dark"] .table-wrap,
[data-theme="dark"] .table-scroll,
[data-theme="dark"] .sched-scroll {
  background-image:
    linear-gradient(to right, var(--surface) 30%, rgba(0, 0, 0, 0)),
    linear-gradient(to left,  var(--surface) 30%, rgba(0, 0, 0, 0)),
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0)),
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0));
}
/* The sticky header must not let the shadow bleed over it */
table.data thead th { background-clip: padding-box; }

/* ---------- Password field with a reveal button ---------- */
.pw-field { position: relative; display: flex; }
.pw-field .input { padding-right: 40px; }
.pw-eye {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; border: none; background: none; cursor: pointer;
  display: grid; place-items: center; border-radius: 8px;
  color: var(--text-dim); transition: color .12s, background .12s;
}
.pw-eye:hover { color: var(--c-main); background: rgba(0, 112, 192, .09); }
.pw-eye:focus-visible { outline: 2px solid var(--c-main); outline-offset: 1px; }
.pw-eye svg { width: 16px; height: 16px; }

/* ---------- Record page: the facts, laid out to be read ----------
   The wide column gets the full field list in a responsive grid, grouped
   exactly as the form groups it, so a record reads like the form that made
   it rather than like a column of a hundred rows. */
.rec-group + .rec-group { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.rec-group-h {
  font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .07em;
  color: var(--c-main); margin-bottom: 10px;
}
.rec-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 12px 20px; }
.rec-cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rec-cell .k { font-size: 11px; color: var(--text-dim); }
.rec-cell .v { font-size: 13.5px; font-weight: 550; overflow-wrap: anywhere; }
.rec-long { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.rec-remarks {
  margin-top: 10px; padding: 8px 11px; background: var(--surface-2);
  border-radius: 8px; font-size: 12.5px; white-space: pre-line;
}

/* ---------- One timeline: what was done, and what changed ---------- */
.tl-item { display: flex; gap: 12px; padding: 12px 0; border-top: 1px solid var(--border); }
.tl-item:first-child { border-top: none; }
.tl-ic {
  width: 30px; height: 30px; border-radius: 10px; flex: none; display: grid; place-items: center;
  background: rgba(0, 112, 192, .1); color: var(--c-main);
}
.tl-ic svg { width: 15px; height: 15px; }
.tl-ic.move { background: rgba(255, 150, 79, .14); color: var(--warn-strong); }
.tl-ic.change { background: rgba(123, 129, 137, .14); color: var(--text-dim); }
.tl-body { flex: 1; min-width: 0; }
.tl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.tl-head b { font-weight: 650; }
.tl-when { margin-left: auto; font-size: 11.5px; color: var(--text-dim); white-space: nowrap; }
.tl-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; }

/* ---------- The total line of a roll-up ----------
   A total that touches the last row reads as one more row; and sitting on the
   scroller's own edge it collided with the scrollbar. It gets a rule above it,
   a little air, and its own background so it stays readable while the table
   scrolls sideways underneath. */
.rollup-scroll { padding-bottom: 10px; }
table.data.rollup tfoot td {
  border-top: 2px solid var(--border-strong);
  padding-top: 13px; padding-bottom: 13px;
  background: var(--surface-2);
  position: relative;
}
table.data.rollup tfoot tr td:first-child { border-bottom-left-radius: 10px; }
table.data.rollup tfoot tr td:last-child { border-bottom-right-radius: 10px; }
/* A real gap, not padding inside the last row: with collapsed borders the
   total otherwise sits directly on the last line of data and reads as one
   more row of it. */
table.data.rollup tbody tr.rollup-gap td { height: 14px; padding: 0; border: none; }

/* A unit sitting inside a number box: % or a currency, so the figure and what
   it means are read together rather than from a label three inches away. */
.in-suffix {
  position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  font-size: 12px; color: var(--text-dim); pointer-events: none;
}
.pw-field .input[type="number"] { padding-right: 42px; }

/* ============================================================
   Project controls — the programme, the network, the site record
   ============================================================ */
:root {
  --link: #7B8189;            /* dependency arrows: present, never shouting  */
  --wknd: rgba(123,129,137,.07);
  --bar-tx: #ffffff;
  --pill-orange-fg: #9c4e14;
  --pill-green-fg: #05703d;
  --pill-red-fg: #b53434;
}
[data-theme="dark"] {
  --link: #7f8a99;
  --wknd: rgba(255,255,255,.035);
  --bar-tx: #0d1520;
  --pill-orange-fg: #ffb877;
  --pill-green-fg: #6ede9f;
  --pill-red-fg: #ff9a9a;
}

.pill.orange { background: rgba(255,150,79,.16); color: var(--pill-orange-fg); }
.pill.green  { background: rgba(0,176,80,.13);   color: var(--pill-green-fg); }
.pill.red    { background: rgba(240,90,90,.13);  color: var(--pill-red-fg); }

/* Dense card row for the control dashboards: more of them, smaller */
.cards.tight { grid-template-columns: repeat(auto-fill, minmax(184px, 1fr)); gap: 11px; }
.cards.tight .card .big { font-size: 22px; }
.cards.evm-cards { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 11px; }
.evm-card h3 { font-size: 11.5px; letter-spacing: .04em; }
.evm-card .big { font-size: 19px; }
.evm-card .sub { font-size: 11px; line-height: 1.35; }

/* Compact report table — denser than the module list, and it carries totals */
table.table { border-collapse: collapse; width: 100%; background: var(--surface); }
table.table thead th {
  position: sticky; top: 0; z-index: var(--z-sticky);
  background: var(--surface-2); color: var(--text-dim);
  text-align: left; font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; padding: 8px 11px; white-space: nowrap;
  border-bottom: 1px solid var(--border-strong);
}
table.table tbody td { padding: 7.5px 11px; border-top: 1px solid var(--border); font-size: 12.5px; vertical-align: middle; }
table.table tbody tr:hover { background: var(--row-hover); }
table.table td.num, table.table th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.table tfoot td {
  padding: 9px 11px; border-top: 2px solid var(--border-strong);
  background: var(--surface-2); font-size: 12.5px;
}
table.table tfoot td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.cert-table td { border-top: 1px solid var(--border); }
table.cert-table tr.total td { border-top: 2px solid var(--border-strong); font-size: 14px; }

/* Key/value grid used by the dialogs */
.detail-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 9px 18px; }
.detail-grid .dk { display: block; font-size: 11px; font-weight: 700; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: .05em; }
.detail-grid .dv { display: block; font-size: 13px; color: var(--text); margin-top: 1px; }

/* Popover menu (export, and anything else offered from a button) */
.pop-menu { background: var(--surface); border: 1px solid var(--border-strong); border-radius: 12px;
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(20,32,48,.18)); padding: 6px; min-width: 288px; overflow: auto; }
.pop-item { display: flex; gap: 10px; align-items: flex-start; width: 100%; text-align: left;
  padding: 9px 10px; border: none; background: none; border-radius: 9px; cursor: pointer; color: var(--text); }
.pop-item:hover { background: var(--row-hover); }
.pop-item svg { width: 17px; height: 17px; color: var(--c-main); flex: none; margin-top: 1px; }
.pop-item b { display: block; font-size: 13px; font-weight: 650; }
.pop-item small { display: block; font-size: 11.5px; color: var(--text-dim); line-height: 1.35; margin-top: 1px; }

/* ---------- Gantt ---------- */
.sched .gt-toolbar { display: flex; flex-direction: column; gap: 9px; margin-bottom: 10px; }
.gt-tools { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; }
.gt-toggles { display: flex; gap: 5px; flex-wrap: wrap; }
.gt-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; cursor: pointer; color: var(--text-dim);
  background: var(--surface-3); border: 1px solid transparent;
}
.gt-chip svg { width: 12px; height: 12px; }
.gt-chip.on { background: rgba(0,112,192,.1); color: var(--c-main); border-color: rgba(0,112,192,.3); }
.gt-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.btn.sm { padding: 5px 11px; font-size: 12px; border-radius: 9px; }
.btn.sm svg { width: 13px; height: 13px; }

.gt-wrap {
  display: grid;
  grid-template-columns: var(--label-w) var(--chart-w);
  grid-template-rows: auto auto;
  width: max-content; min-width: 100%;
  border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;
  background: var(--surface);
}
.gt-corner {
  position: sticky; left: 0; z-index: 4; background: var(--surface-2);
  border-right: 1px solid var(--border-strong); border-bottom: 1px solid var(--border-strong);
  padding: 7px 10px; display: flex; flex-direction: column; justify-content: center; gap: 1px;
  font-size: 11.5px; font-weight: 700; color: var(--text-dim); text-transform: uppercase; letter-spacing: .05em;
}
.gt-corner-sub { font-size: 10.5px; font-weight: 500; text-transform: none; letter-spacing: 0; }
.gt-headwrap { border-bottom: 1px solid var(--border-strong); background: var(--surface-2); }
.gt-head { position: relative; height: 40px; }
.gt-band, .gt-ticks { position: relative; height: 20px; }
.gt-band span {
  position: absolute; top: 0; height: 20px; line-height: 20px; padding-left: 6px;
  font-size: 11px; font-weight: 700; color: var(--heading);
  border-left: 1px solid var(--border-strong); overflow: hidden; white-space: nowrap;
}
.gt-ticks span {
  position: absolute; top: 0; height: 20px; line-height: 20px; text-align: center;
  font-size: 10px; color: var(--text-dim); border-left: 1px solid var(--border);
  overflow: hidden; white-space: nowrap;
}
.gt-ticks span.wknd { background: var(--wknd); }
.gt-ticks span i { font-style: normal; opacity: .55; margin-left: 2px; font-size: 9px; }

.gt-labels { position: sticky; left: 0; z-index: 3; background: var(--surface); border-right: 1px solid var(--border-strong); }
.gt-label {
  height: 30px; display: flex; align-items: center; gap: 6px; padding: 0 8px;
  border-bottom: .5px solid var(--border); font-size: 12px; cursor: pointer; overflow: hidden;
}
.gt-label:hover { background: var(--row-hover); }
.gt-wbs { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 10px; color: var(--text-dim); flex: none; }
.gt-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gt-name.late { color: var(--danger-fg); font-weight: 600; }
.gt-who { margin-left: auto; font-size: 10.5px; color: var(--text-dim); flex: none; }
.gt-dia { width: 9px; height: 9px; background: var(--c-purple); transform: rotate(45deg); border-radius: 1.5px; flex: none; }
.gt-chart { position: relative; }
.gt-barg:hover rect { filter: brightness(1.08); }

/* the S-curve reuses the same two-column frame */
.gt-wrap.sc { grid-template-rows: auto; margin-top: 10px; }
.gt-labels.sc-axis { border-right: 1px solid var(--border-strong); }

/* ---------- AON network ---------- */
.aon-scroll {
  overflow: auto; max-height: 62vh; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface); margin-top: 12px;
}
.aon-node:hover rect:first-of-type { stroke-width: 2.4; }

/* ---------- Weather strip ---------- */
.wx-strip {
  display: flex; gap: 2px; align-items: flex-end; overflow-x: auto; padding: 8px 2px 4px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
}
.wx-day {
  position: relative; width: 15px; min-width: 15px; height: 46px; border-radius: 4px;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  cursor: pointer; background: var(--surface-3);
}
.wx-day.ok { background: rgba(0,176,80,.16); }
.wx-day.partial { background: rgba(255,150,79,.22); }
.wx-day.stopped { background: rgba(240,90,90,.22); }
.wx-day.none { background: var(--surface-3); opacity: .55; cursor: default; }
.wx-day:hover { outline: 1.5px solid var(--c-main); }
.wx-ic { font-size: 9px; line-height: 12px; }
.wx-rain { position: absolute; bottom: 0; width: 7px; border-radius: 2px 2px 0 0; background: var(--c-main); opacity: .75; }
.wx-eot { position: absolute; top: 1px; right: 1px; width: 4px; height: 4px; border-radius: 50%; background: var(--warn-strong); }
.chart-legend .sw.wx-sw { width: 12px; height: 12px; border-radius: 3px; }
.chart-legend .sw.wx-sw.ok { background: rgba(0,176,80,.4); }
.chart-legend .sw.wx-sw.partial { background: rgba(255,150,79,.5); }
.chart-legend .sw.wx-sw.stopped { background: rgba(240,90,90,.5); }
.chart-legend .sw.wx-sw.none { background: var(--surface-3); }

/* ---------- The earned-value verdict ---------- */
.evm-verdict { margin-top: 8px; }
.evm-big {
  display: flex; gap: 12px; align-items: center; padding: 13px 15px; border-radius: 12px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.evm-big svg { width: 26px; height: 26px; flex: none; }
.evm-big b { display: block; font-size: 15px; }
.evm-big span { display: block; font-size: 12.5px; color: var(--text-dim); margin-top: 2px; line-height: 1.45; }
.evm-big.ok { border-color: rgba(0,176,80,.4); } .evm-big.ok svg { color: var(--c-green); }
.evm-big.warn { border-color: rgba(255,150,79,.5); } .evm-big.warn svg { color: var(--warn-strong); }
.evm-big.bad { border-color: rgba(240,90,90,.45); } .evm-big.bad svg { color: var(--c-red); }

/* ---------- Print ----------
   The browser is the PDF writer. What it prints is the report, not the
   application around it — and never the dark theme, which is a screen
   choice, not a paper one. */
@media print {
  .sidebar, .topbar, .tabs, .nav-scrim, .gt-toolbar, .detail-actions,
  .btn, .icon-btn, .table-more, .toolbar { display: none !important; }
  #app-root { display: block !important; height: auto !important; }
  .main, .view { display: block !important; overflow: visible !important; padding: 0 !important; }
  .section, .card, .gt-wrap, .table-scroll { break-inside: avoid; box-shadow: none !important; }
  .sched-scroll, .aon-scroll, .table-scroll, .table-wrap {
    overflow: visible !important; max-height: none !important;
  }
  .gt-labels, .gt-corner { position: static !important; }
}
}

/* A progress photograph carries what it is evidence of, on the picture */
.shot { position: relative; }
.shot-pct {
  position: absolute; top: 7px; right: 7px; z-index: 1;
  padding: 2px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 700; color: #fff;
  background: var(--c-main); box-shadow: 0 1px 4px rgba(0,0,0,.25);
}
.shot-pct.done { background: var(--c-green); }
.shot-pct.mid { background: var(--c-main); }
.shot-pct.early { background: var(--warn-strong); }
.shot .cap .t2 { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.shot .cap .t2 svg { width: 11px; height: 11px; }
.shot-task { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

/* ---------- Portfolio health: one bar, two facts ----------
   The fill is the work actually done; the notch is where the plan says it
   should be. The gap between them is the whole message. */
.ph-bar { position: relative; height: 8px; border-radius: 999px; background: var(--surface-3); overflow: visible; }
.ph-fill { height: 100%; border-radius: 999px; background: var(--c-green); transition: width .25s; }
.ph-fill.warn { background: var(--warn-strong); }
.ph-fill.bad { background: var(--c-red); }
.ph-mark { position: absolute; top: -3px; width: 2px; height: 14px; background: var(--heading); border-radius: 1px; }
[data-theme="dark"] .ph-mark { background: #e7edf6; }

/* ---------- Earned value: the reading, and the arithmetic ---------- */
.evm-actions { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.evm-actions li { display: flex; gap: 8px; align-items: flex-start; font-size: 12.5px; line-height: 1.5; color: var(--text); }
.evm-actions svg { width: 14px; height: 14px; flex: none; margin-top: 2px; color: var(--c-main); opacity: .8; }
.evm-card { cursor: pointer; transition: box-shadow .12s, transform .12s; }
.evm-card:hover { box-shadow: 0 0 0 2px rgba(0,112,192,.25); }
.evm-card:focus-visible { outline: 2px solid var(--c-main); outline-offset: 2px; }
.evm-formula {
  display: inline-block; font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 11.5px;
  background: var(--surface-3); padding: 3px 7px; border-radius: 6px; color: var(--heading);
  white-space: normal; line-height: 1.6;
}
.evm-formula.block { display: block; padding: 9px 11px; font-size: 12px; }
.evm-verdict-line {
  font-size: 12.5px; line-height: 1.5; margin-top: 5px; padding: 6px 9px; border-radius: 8px;
  border-left: 3px solid var(--border-strong); background: var(--surface-2);
}
.evm-verdict-line.ok { border-left-color: var(--c-green); }
.evm-verdict-line.warn { border-left-color: var(--warn-strong); }
.evm-verdict-line.bad { border-left-color: var(--c-red); }
table.evm-method tbody td { vertical-align: top; padding: 11px; }
.evm-metric-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.evm-metric-value { font-size: 26px; font-weight: 800; color: var(--heading); }

/* The approval row: what it is on the left, what you can do on the right.
   The stacking below 680px is in responsive.css. */
.agenda-card .a-body { flex: 1; min-width: 0; }
.agenda-card .a-actions { display: flex; gap: 7px; flex-wrap: wrap; align-items: center; }

/* ============================================================
   The progress report — a document, not a screen
   ------------------------------------------------------------
   Deliberately its own visual language: white paper, black text, thin rules,
   no rounded cards. It is read on paper or as a PDF by somebody who is not a
   user of this system, so it borrows nothing from the interface except the
   data. Always light, whatever the reader's theme.
   ============================================================ */
.report-root {
  position: fixed; inset: 0; z-index: 200; overflow: auto;
  background: #6b7684;
  color: #1c2733;
  -webkit-font-smoothing: antialiased;
}
body.reporting { overflow: hidden; }

.rp-bar {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 18px; background: var(--c-menu); color: #fff; font-weight: 600; font-size: 13.5px;
}
.rp-bar svg { width: 16px; height: 16px; vertical-align: -3px; margin-right: 6px; }
.rp-bar-actions { display: flex; gap: 8px; }

.report-sheet {
  background: #fff; color: #1c2733;
  width: 297mm; max-width: 100%; min-height: 210mm;
  margin: 18px auto 40px; padding: 16mm 14mm;
  box-shadow: 0 12px 40px rgba(0,0,0,.35);
  font-size: 11px; line-height: 1.5;
}
.report-sheet h1 { font-size: 22px; margin: 2px 0 2px; letter-spacing: -.02em; color: #23374B; }
.report-sheet h2 {
  font-size: 13px; margin: 20px 0 8px; color: #23374B;
  border-bottom: 1.5px solid #23374B; padding-bottom: 4px; letter-spacing: -.01em;
}
.report-sheet h3 { font-size: 11.5px; margin: 12px 0 5px; color: #3d4d60; }
.rp-head { display: flex; justify-content: space-between; gap: 24px; align-items: flex-start;
  border-bottom: 2.5px solid #23374B; padding-bottom: 10px; }
.rp-org { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #0070C0; }
.rp-project { font-size: 13px; color: #3d4d60; }
.rp-meta { border-collapse: collapse; font-size: 10.5px; min-width: 260px; }
.rp-meta td { padding: 2px 0; }
.rp-meta td:first-child { color: #68788d; padding-right: 14px; white-space: nowrap; }

.rp-verdict { border-left: 4px solid #068348; padding: 8px 12px; background: #f5f8fb; margin-bottom: 10px; }
.rp-verdict.warn { border-left-color: #e0762d; }
.rp-verdict.bad { border-left-color: #d33f3f; }
.rp-verdict b { display: block; font-size: 13px; }
.rp-verdict span { display: block; color: #3d4d60; margin-top: 2px; }

.rp-kpis { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin: 10px 0; }
.rp-kpi { border: 1px solid #d7dee8; border-top: 3px solid #9aa7b6; padding: 7px 9px; }
.rp-kpi.ok { border-top-color: #068348; } .rp-kpi.warn { border-top-color: #e0762d; }
.rp-kpi.bad { border-top-color: #d33f3f; }
.rp-kpi-l { font-size: 9px; text-transform: uppercase; letter-spacing: .06em; color: #68788d; font-weight: 700; }
.rp-kpi-v { font-size: 17px; font-weight: 800; color: #23374B; margin: 1px 0; }
.rp-kpi-s { font-size: 9.5px; color: #68788d; }

.rp-actions { margin: 8px 0 0 16px; padding: 0; }
.rp-actions li { margin-bottom: 3px; }
.rp-lead { margin: 4px 0 8px; color: #3d4d60; }
.rp-note { margin: 6px 0; padding: 5px 9px; background: #fff8ec; border-left: 3px solid #e0762d; font-size: 10.5px; }
.rp-source { font-size: 9.5px; color: #68788d; margin-top: 4px; }

table.rp-table { width: 100%; border-collapse: collapse; font-size: 10px; margin: 6px 0 4px; }
table.rp-table th {
  text-align: left; padding: 5px 6px; border-bottom: 1.5px solid #23374B;
  font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: #3d4d60;
}
table.rp-table td { padding: 4px 6px; border-bottom: 1px solid #e5eaf1; vertical-align: top; }
table.rp-table td.num, table.rp-table th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.rp-table .mono { font-family: ui-monospace, Menlo, monospace; font-size: 9px; color: #3d4d60; }

.rp-chart { display: block; width: 100%; margin: 6px 0; }
.rp-legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 9.5px; color: #68788d; margin-bottom: 6px; }
.rp-legend i { display: inline-block; width: 12px; height: 4px; border-radius: 2px; margin-right: 4px; vertical-align: 2px; }
.rp-foot {
  display: flex; justify-content: space-between; gap: 16px; margin-top: 22px; padding-top: 8px;
  border-top: 1px solid #d7dee8; font-size: 9.5px; color: #68788d;
}

/* The paginator table and the running head it repeats. Screen hides the
   head entirely — the preview already opens on the full title block. */
table.rp-pages { width: 100%; border-collapse: collapse; }
table.rp-pages > thead > tr > td, table.rp-pages > tbody > tr > td,
table.rp-pages > tfoot > tr > td { padding: 0; border: 0; }
table.rp-pages > thead { display: none; }
.rp-runhead { display: flex; justify-content: space-between; gap: 16px; align-items: baseline;
  font-size: 9px; color: #68788d; border-bottom: 1px solid #d7dee8;
  padding-bottom: 3px; margin-bottom: 12px; }
.rp-runhead b { color: #23374B; font-size: 10px; }

/* A module whose name no longer says what it covers explains itself, in the
   authority table where the question is actually being asked. */
.am-mod .am-note { display: block; font-size: 10.5px; color: var(--text-dim);
  line-height: 1.4; margin-top: 2px; max-width: 46ch; }

/* The งวด's actions: one line, equal widths, in the order the paperwork
   happens. Buttons that size themselves to their label make a ragged column
   that reads as three unrelated controls rather than one row of choices. */
/* Thirteen columns do not fit a laptop, and the one that gets pushed past the
   edge is the last one — which is where Certify lives, the button that starts
   the whole certify → invoice → receipt run. An action you cannot see is an
   action nobody takes, so the column stays pinned to the right-hand edge and
   the rest of the table scrolls underneath it. */
td.pay-actions, th.pay-actions {
  position: sticky; right: 0; background: var(--surface); z-index: 2;
  box-shadow: -10px 0 10px -10px rgba(16, 26, 36, .35);
}
td.pay-actions { white-space: nowrap; text-align: right; }
td.pay-actions .pay-btn {
  min-width: 108px; justify-content: center; white-space: nowrap;
}
td.pay-actions .pay-btn + .pay-btn { margin-left: 6px; }

/* ---------- Papers for the client ---------- */
/* Four cards, because a paper is a thing you send rather than a row action
   hiding at the right-hand end of a thirteen-column table. */
.paper-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; }
.paper-card {
  display: flex; align-items: center; gap: 11px; text-align: left; width: 100%;
  padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface); color: var(--text); cursor: pointer;
  transition: border-color .12s, background .12s, transform .08s;
}
.paper-card:hover:not(.empty) { border-color: var(--c-main); background: var(--row-hover); }
.paper-card:active:not(.empty) { transform: translateY(1px); }
.paper-card.empty { cursor: default; opacity: .62; }
.paper-ic { display: flex; align-items: center; justify-content: center; flex: none;
  width: 34px; height: 34px; border-radius: 10px; background: rgba(112,48,160,.12); color: var(--c-purple); }
.paper-ic svg { width: 17px; height: 17px; }
.paper-card.empty .paper-ic { background: var(--surface-2); color: var(--text-dim); }
.paper-tx { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.paper-tx b { font-size: 13.5px; color: var(--heading); }
.paper-tx span { font-size: 11.5px; color: var(--text-dim); line-height: 1.35; }
.paper-n { flex: none; font-size: 12px; font-weight: 700; color: var(--c-purple);
  background: rgba(112,48,160,.12); border-radius: 999px; padding: 1px 9px; }

/* Choosing which งวด a paper is for */
.pick-list { display: flex; flex-direction: column; gap: 7px; }
.pick-row { display: grid; grid-template-columns: 1fr auto; gap: 2px 14px; width: 100%;
  text-align: left; padding: 10px 13px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); color: var(--text); cursor: pointer; }
.pick-row:hover { border-color: var(--c-main); background: var(--row-hover); }
.pick-row b { font-size: 13px; color: var(--heading); }
.pick-row span { font-size: 11.5px; color: var(--text-dim); }
.pick-row .num { grid-row: 1 / 3; align-self: center; font-size: 14px; font-weight: 700;
  color: var(--heading); font-variant-numeric: tabular-nums; }

/* ---------- The organisation page's live preview ---------- */
/* What is being typed, drawn the way the client will read it — the same block
   the papers print, so a missing field is visible as a missing field. */
.org-preview { border: 1px solid var(--border); border-radius: 11px; padding: 16px 18px;
  background: var(--surface-2); max-width: 460px; }
.org-role { font-size: 9.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-dim); }
.org-name { font-weight: 700; font-size: 15px; color: var(--heading); margin-top: 2px; }
.org-party { font-size: 12.5px; line-height: 1.6; }
.org-gap { color: var(--warn-strong); font-style: italic; }

/* ---------- How much room there is to bargain ---------- */
/* The margin is the only part of the price the practice can give away, so it
   is drawn as a quantity that gets used up rather than described in prose. */
.qt-bargain {
  display: flex; gap: 11px; align-items: flex-start; margin-top: 12px;
  padding: 11px 13px; border-radius: 11px; font-size: 12.5px; line-height: 1.5;
  background: rgba(0,176,80,.07); border: 1px solid rgba(0,176,80,.3); color: var(--ok-fg);
}
.qt-bargain svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }
.qt-bargain b { display: block; font-size: 13.5px; }
.qt-bargain span { color: var(--text-dim); }
.qt-bargain.spent { background: rgba(240,90,90,.08); border-color: rgba(240,90,90,.35); color: var(--danger-fg); }
.qt-bargain.none { background: var(--surface-2); border-color: var(--border); color: var(--text); }
.qt-bargain-bar { height: 5px; border-radius: 3px; background: rgba(0,0,0,.10); margin: 6px 0 5px; overflow: hidden; }
.qt-bargain-bar span { display: block; height: 100%; background: currentColor; opacity: .55; }

/* ---------- The personnel summary's figure grid ---------- */
.report-sheet .rp-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 8px 0 4px; }
.report-sheet .rp-stat { border: 1px solid #e5eaf1; border-radius: 8px; padding: 8px 10px; }
.report-sheet .rp-stat-k { font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: #68788d; }
.report-sheet .rp-stat-v { font-size: 16px; font-weight: 700; color: #23374B; margin-top: 1px; }
.report-sheet .rp-stat-n { font-size: 9.5px; color: #68788d; margin-top: 1px; line-height: 1.35; }

/* ---------- The commercial papers: quotation, billing note, invoice, receipt ---------- */
/* Who is issuing and who is receiving, side by side — a tax document is
   read by checking those two blocks before anything else. */
.rp-parties { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; margin: 14px 0 4px; }
.rp-party { font-size: 10.5px; line-height: 1.55; }
.rp-party-role { font-size: 9px; text-transform: uppercase; letter-spacing: .06em;
  color: #68788d; margin-bottom: 2px; }
.rp-party-name { font-weight: 700; color: #23374B; font-size: 12px; }
/* A field the practice has not configured is NAMED, never left as a gap that
   reads like a complete document. */
.rp-missing { margin-top: 4px; padding: 3px 7px; background: #fff8ec;
  border-left: 3px solid #e0762d; font-size: 9.5px; color: #8a5a20; }
/* ...but the client is not the person who can fix it. A note telling OUR
   staff to go and set the tax number has no business on the paper we hand
   over, so it is on screen only and never on the printed copy. */
@media print { .rp-missing { display: none !important; } }
.rp-doc-th { font-size: 13px; color: #3d4d60; margin-top: -1px; }
.rp-th { font-weight: 400; color: #68788d; font-size: 11px; }
table.rp-table tr.sect td { background: #f2f5f9; font-weight: 700; color: #23374B; }
table.rp-table tfoot td { border-bottom: 0; padding-top: 5px; }
table.rp-table tfoot tr.grand td { border-top: 2px solid #23374B; font-size: 11.5px; }
.rp-amount-words { margin-top: 6px; padding: 6px 9px; background: #f2f5f9; font-size: 10.5px; }
.rp-stamp { float: right; border: 2px solid #068348; color: #068348; border-radius: 6px;
  padding: 4px 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; font-size: 12px; }
@media (max-width: 640px) { .rp-parties { grid-template-columns: 1fr; } }

/* The project brief is a portrait paper — it is read, not scanned across */
.brief-root .report-sheet { width: 210mm; min-height: 297mm; }
.rb-signs { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin-top: 26px; }
.rb-sign { display: flex; flex-direction: column; gap: 2px; font-size: 10.5px; }
.rb-sign-line { height: 44px; border-bottom: 1px solid #23374B; margin-bottom: 6px; }
.rb-sign-hint { color: #68788d; font-size: 9.5px; }

/* On paper: the sheet IS the page */
@media print {
  @page { size: A4 landscape; margin: 10mm; }
  /* The id selector on the generic print rules (#app-root) outguns a bare
     child-combinator hider, so the application printed as three junk pages
     in front of every report. Name it explicitly. */
  body.reporting > *:not(.report-root), body.reporting #app-root { display: none !important; }
  .report-root { position: static; overflow: visible; background: #fff; }
  .rp-bar, .no-print { display: none !important; }
  .report-sheet { width: auto; margin: 0; padding: 0; box-shadow: none; min-height: 0; }
  .rp-section { break-inside: avoid-page; }
  .rp-break { break-before: page; }
  table.rp-table { break-inside: auto; }
  table.rp-table tr { break-inside: avoid; }
  table.rp-pages > thead { display: table-header-group; }
  table.rp-pages > tfoot { display: table-footer-group; }
  .rp-foot { margin-top: 10px; }
}

/* ---------- Workload grid: people down, weeks across ---------- */
table.wl-grid td, table.wl-grid th { padding: 5px 7px; }
.wl-person { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.wl-face {
  width: 24px; height: 24px; border-radius: 8px; flex: none; color: #fff;
  display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700;
}
.wl-cell { cursor: pointer; font-variant-numeric: tabular-nums; min-width: 40px; text-align: center !important; }
.wl-cell.under { background: rgba(0,176,80,.13); color: var(--pill-green-fg); }
.wl-cell.fit   { background: rgba(0,112,192,.14); color: var(--pill-blue-fg); }
.wl-cell.over  { background: rgba(240,90,90,.20); color: var(--pill-red-fg); font-weight: 800; }
.wl-cell:hover { outline: 2px solid var(--c-main); outline-offset: -2px; }
b.under { background: rgba(0,176,80,.13); color: var(--pill-green-fg); }
b.fit   { background: rgba(0,112,192,.14); color: var(--pill-blue-fg); }
b.over  { background: rgba(240,90,90,.20); color: var(--pill-red-fg); }
.chart-legend .sw.wl-sw { width: 14px; height: 12px; border-radius: 3px; }
.chart-legend .sw.wl-sw.under { background: rgba(0,176,80,.4); }
.chart-legend .sw.wl-sw.fit { background: rgba(0,112,192,.4); }
.chart-legend .sw.wl-sw.over { background: rgba(240,90,90,.5); }
.wl-cell.unknown { background: repeating-linear-gradient(135deg, var(--surface-3) 0 5px, transparent 5px 10px); }
.wl-unknown { font-size: 9px; color: var(--warn-strong); font-weight: 800; margin-left: 2px; }

/* ---------- what somebody wrote when they handed work in ---------- */
/* Label above value, wrapping into as many columns as the width allows. All
   of this was captured and then never shown to anybody, which is how a form
   teaches people that filling it in does not matter. */
.sub-detail {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px 18px; margin: 10px 0 4px; padding: 10px 0; border-top: 1px solid var(--border);
}
.sub-detail .dk { display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-dim); }
.sub-detail .dv { font-size: 13px; font-weight: 600; }
.agenda-card .a-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }

/* Earlier attempts, folded away. A reviewer about to write the same comment
   for the third time should be able to see that they are. */
.rv-earlier { margin-top: 10px; }
.rv-earlier > summary {
  cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--c-main); padding: 4px 0;
}
.rv-earlier > summary:hover { text-decoration: underline; }
.rv-earlier-row {
  padding: 8px 11px; margin-top: 6px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--border); font-size: 12.5px;
}

/* ---------- recovery instructions ---------- */
/* Numbered, spaced, with the command on its own line. Somebody reading this
   is having a bad day and should not have to parse a paragraph. */
.recover { margin: 12px 0 0; padding-left: 22px; font-size: 12.5px; line-height: 1.6; }
.recover li { margin-bottom: 10px; }
.recover code.block {
  display: block; margin-top: 6px; padding: 8px 11px; border-radius: 8px;
  background: var(--surface-3); border: 1px solid var(--border);
  font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 11.5px;
  overflow-x: auto; white-space: nowrap;
}

/* ---------- the periodic evaluation ---------- */
/* The judgement questions are sentences, not a scale. A radio row of numbers
   invites the middle answer; a row of statements makes somebody pick the one
   that is actually true, which is the whole point of asking this way. */
.ev-q { padding: 11px 0; border-bottom: 1px solid var(--border); }
.ev-q:last-child { border-bottom: none; }
.ev-q-head { display: flex; align-items: center; gap: 7px; font-size: 13px; margin-bottom: 8px; }
.ev-q-head svg { width: 15px; height: 15px; color: var(--c-main); }
.ev-q-head .muted { font-size: 11px; font-weight: 500; margin-left: auto; }
.ev-opts { display: flex; flex-direction: column; gap: 5px; }
.ev-opt {
  display: flex; align-items: center; gap: 10px; text-align: left; width: 100%;
  padding: 8px 11px; border-radius: 9px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface);
  font-family: inherit; font-size: 12.5px; color: var(--text);
  transition: border-color .12s, background .12s;
}
.ev-opt:hover { border-color: var(--c-main); }
.ev-opt:focus-visible { outline: 2px solid var(--c-main); outline-offset: 2px; }
.ev-opt.on { border-color: var(--c-main); background: rgba(0,112,192,.07); font-weight: 600; }
.ev-opt.clear { opacity: .72; font-style: italic; }
.ev-pts {
  flex: none; width: 22px; height: 22px; border-radius: 6px; display: grid; place-items: center;
  background: var(--surface-3); font-weight: 800; font-size: 11.5px; color: var(--text-dim);
}
.ev-opt.on .ev-pts { background: var(--c-main); color: #fff; }

.ev-mix { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; font-size: 12.5px; }
.ev-mix input[type=range] { flex: 1; min-width: 160px; accent-color: var(--c-main); }
.ev-mix b { font-variant-numeric: tabular-nums; min-width: 40px; }

.ev-result {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 13px 15px; border-radius: var(--radius);
  border: 1px solid var(--border); background: var(--surface-2);
}
.ev-big { display: flex; align-items: center; gap: 11px; }
.ev-num { font-size: 30px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.ev-parts { display: flex; gap: 22px; flex-wrap: wrap; margin-left: auto; }
.ev-parts .dk { display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-dim); }
.ev-parts .dv { font-size: 13px; font-weight: 600; }
.ev-split { display: flex; gap: 24px; flex-wrap: wrap; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.ev-split .dk { display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-dim); }
.ev-split .dv { font-size: 13px; font-weight: 600; }
.ev-summary { cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--c-main); }
.ev-summary:hover { text-decoration: underline; }

@media (max-width: 680px) {
  .ev-parts, .ev-split { margin-left: 0; gap: 14px; }
  .ev-num { font-size: 25px; }
}

/* ---------- choosing a colour ---------- */
/* Big enough to see the colour and to hit with a thumb; the tick appears on
   the chosen one rather than a border, because a border changes the swatch's
   apparent colour and this field is about judging colours. */
.colorpick { display: flex; flex-direction: column; gap: 10px; }
.cp-grid { display: grid; grid-template-columns: repeat(10, 1fr); gap: 6px; }
.cp-sw {
  position: relative; aspect-ratio: 1; min-height: 30px; border-radius: 8px; cursor: pointer;
  border: 1px solid rgba(0,0,0,.18); background: var(--sw, var(--surface-3));
  display: flex; align-items: center; justify-content: center; padding: 0;
  transition: transform .1s, box-shadow .1s;
}
.cp-sw:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.cp-sw:focus-visible { outline: 2px solid var(--c-main); outline-offset: 2px; }
.cp-sw svg { width: 15px; height: 15px; color: #fff; opacity: 0; filter: drop-shadow(0 1px 2px rgba(0,0,0,.55)); }
.cp-sw.on svg { opacity: 1; }
.cp-sw.none { background: var(--surface-2); border-style: dashed; aspect-ratio: auto; width: 34px; height: 30px; flex: none; }
.cp-sw.none svg { color: var(--text-dim); opacity: .8; }
.cp-sw.none.on { border-color: var(--c-main); }
.cp-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cp-name { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600; }
.cp-hexwrap { display: inline-flex; align-items: center; gap: 7px; margin-left: auto; font-size: 11.5px; }
.cp-hex { width: 104px; font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12px; text-transform: uppercase; }
@media (max-width: 680px) {
  .cp-grid { grid-template-columns: repeat(5, 1fr); gap: 8px; }
  .cp-hexwrap { margin-left: 0; width: 100%; }
}

/* A candidate for a piece of work. The tint is the verdict, so a planner
   scanning the list sees who is worth reading before reading anybody. */
tr.cand.ok  td:first-child { box-shadow: inset 3px 0 0 var(--c-green); }
tr.cand.warn td:first-child { box-shadow: inset 3px 0 0 var(--warn-strong); }
tr.cand.bad td:first-child { box-shadow: inset 3px 0 0 var(--border-strong); }
tr.cand.bad { opacity: .72; }
tr.cand:hover { background: var(--row-hover); }
tr.cand td { vertical-align: middle; }

/* The period bar sits above a page rather than inside a panel, so it needs
   its own breathing room where .cf-range alone would sit flush. */
.period-bar { flex-wrap: wrap; row-gap: 8px; }
.chart-legend .sw.wl-sw.unknown { background: repeating-linear-gradient(135deg, var(--surface-3) 0 4px, transparent 4px 8px); box-shadow: inset 0 0 0 1px var(--border-strong); }

/* ---------- What needs attention ---------- */
.att-list { display: flex; flex-direction: column; gap: 7px; }
.att-item {
  display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px;
  border: 1px solid var(--border); border-left-width: 3px; border-radius: 10px;
  background: var(--surface); cursor: pointer; transition: background .12s;
}
.att-item:hover { background: var(--row-hover); }
.att-item.bad { border-left-color: var(--c-red); }
.att-item.warn { border-left-color: var(--warn-strong); }
.att-item.info { border-left-color: var(--c-bluegrey); }
.att-ic { width: 26px; height: 26px; border-radius: 8px; flex: none; display: inline-flex;
  align-items: center; justify-content: center; background: var(--surface-3); color: var(--text-dim); }
.att-item.bad .att-ic { background: rgba(240,90,90,.12); color: var(--c-red); }
.att-item.warn .att-ic { background: rgba(255,150,79,.14); color: var(--warn-strong); }
.att-ic svg { width: 14px; height: 14px; }
.att-tx { flex: 1; min-width: 0; }
.att-main { display: block; font-size: 13px; line-height: 1.45; }
.att-hint { display: block; font-size: 11.5px; color: var(--text-dim); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-go { width: 15px; height: 15px; color: var(--text-dim); flex: none; margin-top: 5px; }

/* ---------- The daily site report: one sheet, filled in standing up ---------- */
.dsr-h { font-size: 12.5px; font-weight: 700; color: var(--heading); margin: 16px 0 8px;
  display: flex; align-items: baseline; gap: 8px; }
.dsr-h .muted { font-size: 11.5px; font-weight: 500; }
.dsr-weather { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.dsr-wx {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 8px 10px; min-width: 74px; border-radius: 11px; cursor: pointer;
  border: 1.5px solid var(--border); background: var(--surface);
  font-size: 11px; color: var(--text-dim); font-weight: 600;
}
.dsr-wx:hover { border-color: var(--border-hover); }
.dsr-wx.on { border-color: var(--c-main); background: rgba(0,112,192,.07); color: var(--c-main); }
.dsr-wx-ic { font-size: 20px; line-height: 1.1; }
.dsr-lines input.sm, .dsr-lines select.sm { height: 32px; padding: 4px 8px; font-size: 12.5px; }
.dsr-lines input.num { text-align: right; }
.dsr-lines td { padding: 4px 6px; }
@media (max-width: 680px) {
  .dsr-wx { min-width: 62px; padding: 7px 6px; }
  .dsr-lines { min-width: 520px; }
}

/* ---------- Look-ahead: the three weeks in front of the site ---------- */
.la-weeks { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.la-week { border: 1px solid var(--border); border-radius: 12px; padding: 10px; background: var(--surface); }
.la-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid var(--border); font-size: 12.5px; }
.la-head .muted { font-size: 11px; }
.la-item { display: flex; gap: 8px; align-items: flex-start; padding: 7px 8px; border-radius: 9px;
  cursor: pointer; border-left: 3px solid var(--border-strong); margin-bottom: 6px; background: var(--surface-2); }
.la-item:hover { background: var(--row-hover); }
.la-item.late { border-left-color: var(--c-red); }
.la-item.blocked { border-left-color: var(--warn-strong); }
.la-item.milestone { border-left-color: var(--c-purple); }
.la-ic { width: 22px; height: 22px; border-radius: 7px; flex: none; display: inline-flex;
  align-items: center; justify-content: center; background: var(--surface-3); color: var(--text-dim); }
.la-ic svg { width: 12px; height: 12px; }
.la-tx { min-width: 0; flex: 1; }
.la-title { display: block; font-size: 12.5px; font-weight: 600; }
.la-sub { display: block; font-size: 11px; color: var(--text-dim); margin-top: 1px; }
.la-block { display: block; font-size: 11px; color: var(--warn-fg); margin-top: 3px; }
.la-empty { font-size: 11.5px; color: var(--text-dim); padding: 8px 4px; }
@media (max-width: 900px) { .la-weeks { grid-template-columns: 1fr; } }

/* ---------- the offer, checked against the work behind it ---------- */
.qt-undercost { display: flex; gap: 10px; align-items: flex-start; margin-top: 12px;
  padding: 12px 14px; border-radius: 10px;
  background: color-mix(in srgb, var(--danger) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--danger) 35%, var(--border)); }
.qt-undercost > i { flex: none; width: 18px; height: 18px; color: var(--danger); margin-top: 2px; }
.qt-undercost b { display: block; font-size: 13.5px; color: var(--danger); margin-bottom: 3px; }
.qt-undercost span { font-size: 12px; color: var(--text); line-height: 1.5; }
.qt-undercost-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.qt-undercost-list span { font-size: 11.5px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 20px; padding: 2px 9px; }
.qt-lines tbody tr.qt-below { box-shadow: inset 3px 0 0 var(--danger); }
.qt-lines td.qt-cost { color: var(--muted); }
.qt-short { font-size: 10.5px; font-weight: 700; color: var(--danger); }
.qt-gapblock { margin-bottom: 14px; }
.qt-gapblock b { display: block; font-size: 13px; color: var(--heading); }
.qt-gapblock > .muted { font-size: 11.5px; line-height: 1.45; display: block; margin-bottom: 5px; }
.qt-gapblock ul { margin: 0; padding-left: 18px; font-size: 12px; line-height: 1.7; }
.qt-workbar { height: 4px; border-radius: 3px; background: var(--surface-3, var(--border));
  overflow: hidden; margin-top: 5px; max-width: 130px; }
.qt-workbar span { display: block; height: 100%; background: var(--accent); }

/* ---------- which work a งวด bills ---------- */
.alloc-note { display: flex; gap: 9px; align-items: flex-start; margin-bottom: 12px;
  font-size: 12px; color: var(--muted); line-height: 1.5; }
.alloc-note i { flex: none; width: 16px; height: 16px; margin-top: 1px; color: var(--accent); }
.alloc-table tbody tr.alloc-full { opacity: .55; }
.alloc-table input.alloc-pct { width: 84px; text-align: right; padding: 4px 8px; }
.alloc-table td.alloc-amt { font-weight: 600; }

/* ---------- how work is priced ---------- */
.cost-rule { padding: 12px 14px; border-radius: 10px; background: var(--surface-2);
  border: 1px solid var(--border); }
.cost-rule b { display: block; font-size: 13.5px; color: var(--heading); margin-bottom: 4px; }
.cost-rule span { font-size: 12px; color: var(--muted); line-height: 1.55; }
.cost-input { display: flex; align-items: center; gap: 7px; }
.cost-input input { flex: 1 1 auto; text-align: right; }
.cost-input span { font-size: 12.5px; color: var(--muted); min-width: 34px; }
.cost-chain { display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px; margin-top: 16px; }
.cost-chain > div { background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 9px; padding: 9px 13px; display: flex; flex-direction: column; gap: 1px; min-width: 132px; }
.cost-chain > div.op { background: none; border: none; align-items: center; justify-content: center;
  min-width: 0; padding: 0 3px; font-size: 13px; font-weight: 700; color: var(--muted); }
.cost-chain span { font-size: 11.5px; color: var(--muted); }
.cost-chain b { font-size: 16px; color: var(--heading); }
.cost-chain em { font-size: 10.5px; color: var(--muted); font-style: normal; }
.cost-chain .grand { border-color: var(--accent); }
.cost-chain .grand b { color: var(--accent); }
.cost-chain .bargain { margin-left: auto; border-style: dashed; }
.qt-lines td.qt-kind { font-size: 12px; color: var(--muted); max-width: 260px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qt-lines td.qt-kind .mono { color: var(--text); }

/* ============================================================
   The service catalogue: the WBS read commercially.

   The stage headings used to sit directly on top of their table, so a
   fifteen-stage page read as one long list with words in it. Each stage is
   now a card with a banner of its own, a clear gap between it and the next,
   and the table inset inside it — so the eye lands on "which stage am I in"
   before it lands on a row.
   ============================================================ */
.cat-head { padding-bottom: 18px; }
.cat-strip { display: flex; flex-wrap: wrap; gap: 10px; }
.cat-stat { flex: 1 1 170px; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 14px; display: flex; flex-direction: column; gap: 2px; }
.cat-stat .cat-num { font-size: 28px; font-weight: 700; color: var(--heading); line-height: 1.05; }
.cat-stat .cat-lab { font-size: 12.5px; font-weight: 600; color: var(--text); }
.cat-stat .cat-sub { font-size: 11.5px; color: var(--muted); line-height: 1.35; }

.cat-formula { margin-top: 16px; padding: 14px 16px; border-radius: 12px;
  background: var(--surface-2); border: 1px solid var(--border); }
.cat-formula-lead { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 14px; }
.cat-formula-lead i { flex: none; width: 18px; height: 18px; color: var(--accent); margin-top: 2px; }
.cat-formula-lead b { display: block; font-size: 13.5px; color: var(--heading); margin-bottom: 3px; }
.cat-formula-lead span { font-size: 12px; color: var(--muted); line-height: 1.55; }
.cat-chain { display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px; }
.cat-chain > div { background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 9px 13px; display: flex; flex-direction: column;
  gap: 2px; min-width: 128px; justify-content: center; }
.cat-chain > div.op { background: none; border: none; align-items: center; justify-content: center;
  min-width: 0; padding: 0 2px; font-size: 15px; font-weight: 700; color: var(--muted); }
.cat-chain span { font-size: 11.5px; color: var(--muted); }
.cat-chain b { font-size: 16px; color: var(--heading); }
.cat-chain .grand { border-color: var(--accent); }
.cat-chain .grand b { color: var(--accent); font-size: 18px; }
.cat-chain em { font-size: 10.5px; color: var(--muted); font-style: normal; }
.cat-pct > div { display: flex; align-items: baseline; gap: 3px; }
.cat-pct input { width: 74px; padding: 3px 6px; font-size: 16px; font-weight: 700;
  text-align: right; border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface-2); color: var(--heading); }
.cat-pct input:disabled { background: none; border-color: transparent; padding-left: 0; }
.cat-pct em { font-size: 13px; font-style: normal; color: var(--muted); }
.cat-save { background: none !important; border: none !important; flex-direction: row !important;
  align-items: center; gap: 9px !important; margin-left: auto; }
.cat-save .muted { font-size: 11.5px; max-width: 240px; line-height: 1.4; }

.cat-controls { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.cat-controls #cat-q { min-width: 260px; flex: 1 1 260px; }
.cat-controls select { max-width: 220px; }

.cat-body { display: flex; flex-direction: column; gap: 18px; margin-top: 18px; }
.cat-stage { background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; overflow: hidden; box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.04)); }
.cat-stage-head { display: flex; align-items: center; gap: 12px; cursor: pointer;
  padding: 14px 18px; background: var(--surface-2);
  border-bottom: 1px solid var(--border); user-select: none; }
.cat-stage-head:hover { background: color-mix(in srgb, var(--accent) 6%, var(--surface-2)); }
.cat-stage-head:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.cat-stage-no { flex: none; min-width: 30px; height: 30px; padding: 0 8px; border-radius: 8px;
  background: var(--accent); color: #fff; font-weight: 700; font-size: 14px;
  display: flex; align-items: center; justify-content: center; }
.cat-stage-name { font-size: 15px; font-weight: 700; color: var(--heading); }
.cat-stage-meta { margin-left: auto; text-align: right; display: flex; flex-direction: column; gap: 1px; }
.cat-stage-meta b { font-size: 12.5px; color: var(--text); }
.cat-stage-meta span { font-size: 11.5px; color: var(--muted); }
.cat-stage-chev { flex: none; width: 18px; height: 18px; color: var(--muted); transition: transform .15s; }
.cat-stage.shut .cat-stage-chev { transform: rotate(-90deg); }
.cat-stage.shut .cat-stage-head { border-bottom: none; }
.cat-stage.shut .cat-stage-body { display: none; }
.cat-stage-body { padding: 4px 6px 6px; }
.cat-table tbody tr { cursor: pointer; }
.cat-table tbody tr.cat-below { box-shadow: inset 3px 0 0 var(--danger); }
.cat-grade { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.cat-set { font-size: 10.5px; color: var(--accent); font-weight: 600; }
.cat-loss { color: var(--danger); font-weight: 700; }
.cat-gap { display: flex; align-items: center; gap: 4px; font-size: 11px;
  color: var(--warning-text, #a86400); margin-top: 3px; }
.cat-gap i { width: 12px; height: 12px; }
.cat-drift { font-size: 11px; font-weight: 700; }
.cat-drift.over { color: var(--danger); }
.cat-drift.under { color: var(--success-text, #17794f); }

/* ---------- one service, priced ---------- */
.pricing { display: flex; flex-direction: column; gap: 14px; }
/* Two panels side by side while there is room for both, stacked when there is
   not. The old rule asked the VIEWPORT how wide it was — but this grid usually
   renders inside a dialog, which is far narrower than the window, so on a
   1400px laptop the right-hand panel (the whole price build-up, including the
   control that adopts a price) sat past the edge of a box that scrolls
   sideways without saying so. auto-fit asks the container instead. */
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 14px; }
.pricing-box { min-width: 0; }
.pricing-box table.pricing-parts { width: 100%; }
/* The build-up table has six columns and lives in one half of a grid. When
   the box is narrower than the table, the table has to scroll INSIDE it —
   left to itself it simply drew past the groupbox border, which reads as a
   broken panel rather than as content continuing. */
.pricing-box .parts-scroll { overflow-x: auto; max-width: 100%; }
/* `table.data` carries min-width:600px and nowrap cells — right for a register
   that owns a whole page, wrong for a build-up table sharing a row with the
   price panel. In a ~510px box it was cut off mid-column: the Rate header read
   "R.", the amounts were sliced down the middle, and the total lost its
   figure. It reads as a table drawn past its own groupbox, which is what it
   was. Here the table fits the box: descriptions wrap, the numbers stay whole,
   and the padding tightens rather than the content disappearing. */
.pricing-box .parts-scroll table.pricing-parts { min-width: 0; width: 100%; }
.pricing-box .pricing-parts thead th,
.pricing-box .pricing-parts tbody td,
.pricing-box .pricing-parts tfoot td { padding-left: 8px; padding-right: 8px; }
.pricing-box .pricing-parts tbody td { white-space: normal; max-width: none; overflow-wrap: anywhere; }
.pricing-box .pricing-parts thead th { white-space: normal; }
.pricing-box .pricing-parts td.num, .pricing-box .pricing-parts th.num { white-space: nowrap; }
.pricing-box .pricing-parts td.row-actions { padding-left: 2px; padding-right: 4px; }
/* The Kind cell holds one short word beside an icon. Left to wrap-anywhere it
   broke "Material" into "Materia/l", which looks like a rendering fault. */
.pricing-box .pricing-parts tbody td:first-child { white-space: nowrap; overflow-wrap: normal; }
.pricing-box { background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 12px; padding: 14px 16px; }
.pricing-box h3 { display: flex; align-items: center; gap: 7px; margin: 0 0 10px;
  font-size: 13px; color: var(--heading); }
.pricing-box h3 i { width: 15px; height: 15px; color: var(--accent); }
.pricing-box h3 .muted { font-weight: 400; font-size: 11.5px; margin-left: auto; }
.pricing-parts { background: var(--surface); }
.pricing-parts td i { width: 13px; height: 13px; vertical-align: -2px; margin-right: 4px; color: var(--muted); }
.pricing-add { display: flex; gap: 8px; margin-top: 11px; flex-wrap: wrap; }
.ask-build { display: flex; flex-wrap: wrap; align-items: stretch; gap: 6px; margin-bottom: 14px; }
.ask-build > div { background: var(--surface); border: 1px solid var(--border);
  border-radius: 9px; padding: 8px 11px; display: flex; flex-direction: column; gap: 1px; flex: 1 1 auto; }
.ask-build > div.op { background: none; border: none; align-items: center; justify-content: center;
  flex: 0 0 auto; padding: 0; font-size: 14px; color: var(--muted); }
.ask-build span { font-size: 11px; color: var(--muted); line-height: 1.3; }
.ask-build b { font-size: 15px; color: var(--heading); }
.ask-build .built { border-color: var(--accent); }
.ask-build .built b { color: var(--accent); }
.ask-mode { display: flex; align-items: center; gap: 8px; font-size: 12.5px;
  color: var(--text); margin-bottom: 9px; cursor: pointer; }
.ask-own, .ask-hours { display: flex; flex-direction: column; gap: 6px; }
.ask-hours { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.ask-hours > label { font-size: 12px; font-weight: 600; color: var(--text); }
.ask-verdict { display: flex; gap: 6px; align-items: flex-start; font-size: 12px; line-height: 1.45; }
.ask-verdict i { flex: none; width: 14px; height: 14px; margin-top: 2px; }
.ask-verdict.ok { color: var(--success-text, #17794f); }
.ask-verdict.thin { color: var(--warning-text, #a86400); }
.ask-verdict.bad { color: var(--danger); font-weight: 600; }
.ask-actions { display: flex; gap: 8px; margin-top: 14px; }
.pricing-measured { display: flex; gap: 9px; align-items: center; padding: 11px 14px;
  border-radius: 10px; background: var(--surface-2); border: 1px solid var(--border);
  font-size: 12.5px; line-height: 1.5; }
.pricing-measured i { flex: none; width: 16px; height: 16px; color: var(--accent); }
.pricing-measured.thin { color: var(--muted); }
.pricing-measured.thin i { color: var(--muted); }

/* ---------- a rate, and every version of it ---------- */
.rate-used { display: flex; gap: 9px; align-items: flex-start; margin-bottom: 12px;
  font-size: 12px; color: var(--muted); line-height: 1.5; }
.rate-used i { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--accent); }
.rate-hist tbody tr.rate-now { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.rate-delta { font-weight: 600; }
.rate-delta.up { color: var(--danger); }
.rate-delta.down { color: var(--success-text, #17794f); }
.rate-delta div { font-size: 10.5px; font-weight: 400; opacity: .8; }
.rate-actions { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.measured-lead { display: flex; gap: 10px; align-items: center; padding: 11px 14px;
  margin-bottom: 12px; border-radius: 10px; font-size: 12.5px; line-height: 1.5;
  background: var(--surface); border: 1px solid var(--border); }
.measured-lead i { flex: none; width: 16px; height: 16px; }
.measured-lead > div { flex: 1 1 auto; }
.measured-lead.ok i { color: var(--success-text); }
.measured-lead.over i { color: var(--danger); }
.measured-lead.under i { color: var(--warning-text); }
.measured-lead.thin { color: var(--muted); }
.measured-lead.thin i { color: var(--muted); }
.pricing-parts td.row-actions { white-space: nowrap; text-align: right; }
.pricing-parts td.row-actions .muted i { width: 13px; height: 13px; opacity: .5; }

/* ---------- Date-range narrowing on a register toolbar ---------- */
.date-range { display: inline-flex; align-items: center; gap: 5px; }
.date-range .input[type="date"] { width: 140px; padding: 5px 7px; font-size: 12px; }
.date-range .dash { color: var(--text-dim); }
@media (max-width: 760px) {
  .date-range { flex-wrap: wrap; }
  .date-range .input[type="date"] { width: calc(50% - 10px); }
}

/* An inline "use this number" offer inside a field hint */
.linkish { border: none; background: none; padding: 0; font: inherit; color: var(--c-main);
  font-weight: 600; cursor: pointer; text-decoration: underline dotted; }
.linkish:hover { text-decoration: underline solid; }
