/* ============================================================================
   CPMS · Construction Command Center — Design System
   A premium, decision-driven enterprise UI. Dark-first, fully themed.
   ========================================================================= */

/* ---- Design tokens ------------------------------------------------------- */
:root {
  /* Brand — "Chimbals Navy", pulled directly from the company mark (chimbals-logo.png
     samples to #02488f / #e3614a — this ramp and the accent ramp below are built from
     those two exact values, not a generic template blue, so the product reads as this
     company's rather than as any dashboard-kit default). */
  --brand-50:  #ebf2f9;
  --brand-100: #d6e5f5;
  --brand-200: #a8ccf0;
  --brand-300: #6cadef;
  --brand-400: #1684f3;
  --brand-500: #0565c7;
  --brand-600: #02488f;
  --brand-700: #03386d;
  --brand-800: #04294e;
  --brand-900: #04192f;

  /* Accent — "Brick" terracotta, the second colour in the mark. Used narrowly and at
     scale (a hero gradient, a badge, a glow) — never in a small inline pill, where it
     would sit too close in hue to --danger / --serious and read as a status rather
     than a brand flourish. */
  --accent-100: #fbe8e4;
  --accent-300: #efab9f;
  --accent-400: #e68270;
  --accent-500: #e3614a;
  --accent-600: #c73c23;

  /* Semantic status — untouched: these must stay clearly apart from both ramps above. */
  --success: #12b312;
  --warning: #f59e0b;
  --serious: #ef7f4e;
  --danger:  #e2413f;
  --info:    #2a86e0;

  /* Data-viz series (validated, colourblind-safe) */
  --series-1: #2a78d6;
  --series-2: #1baf7a;
  --series-3: #eda100;
  --series-4: #008300;
  --series-5: #7c5cff;
  --series-6: #e34948;
  --series-7: #e87ba4;
  --series-8: #eb6834;

  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 16px;
  --radius-xl: 22px;
  --radius-full: 999px;

  /* IBM Plex Sans / Mono — drawn as one coherent family (not two unrelated faces
     stitched together), with real character in its numerals and bowls so dense
     tables and hero rupee figures both read as considered rather than default. */
  --font-sans: "IBM Plex Sans", "IBM Plex Sans Variable", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;

  --shadow-xs: 0 1px 2px rgba(15, 20, 40, 0.06);
  --shadow-sm: 0 1px 3px rgba(15, 20, 40, 0.08), 0 2px 8px -2px rgba(15, 20, 40, 0.06);
  --shadow: 0 4px 14px -4px rgba(15, 20, 40, 0.12), 0 2px 6px -2px rgba(15, 20, 40, 0.08);
  --shadow-lg: 0 18px 48px -14px rgba(15, 20, 40, 0.28), 0 6px 16px -8px rgba(15, 20, 40, 0.16);
  --shadow-brand: 0 10px 30px -8px rgba(2, 72, 143, 0.45);

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 0.22s;
}

/* Light theme (default) — refined, airy, professional */
:root,
html[data-theme="light"] {
  --canvas: #f4f6fb;
  --canvas-2: #eef1f8;
  --surface: #ffffff;
  --surface-2: #f7f9fc;
  --elevated: #ffffff;
  --sunken: #eef1f7;
  --line: #e7eaf1;
  --line-strong: #d5dae6;
  --ink: #111725;
  --ink-muted: #59637a;
  --ink-subtle: #98a1b4;
  --brand: var(--brand-600);
  --brand-soft: #ebf2f9;
  --brand-ink: #ffffff;
  --ring: rgba(2, 72, 143, 0.24);
  --overlay: rgba(17, 23, 37, 0.32);
  --grid-line: rgba(17, 23, 37, 0.05);

  /* Elegant light sidebar */
  --sidebar-bg: #ffffff;
  --sidebar-fg: #111725;
  --sidebar-ink: #4a5468;
  --sidebar-ink-dim: #98a1b4;
  --sidebar-active: #eaf1fb;
  --sidebar-active-fg: var(--brand-700);
  --sidebar-hover: #f4f6fb;
  --sidebar-border: #e9ecf3;
  --sidebar-glow: rgba(2, 72, 143, 0.06);

  /* Softer, cooler elevation for light surfaces */
  --shadow-xs: 0 1px 2px rgba(17, 24, 45, 0.05);
  --shadow-sm: 0 1px 2px rgba(17, 24, 45, 0.04), 0 4px 12px -4px rgba(17, 24, 45, 0.07);
  --shadow: 0 2px 6px -2px rgba(17, 24, 45, 0.07), 0 14px 30px -10px rgba(17, 24, 45, 0.12);
  --shadow-lg: 0 24px 56px -18px rgba(17, 24, 45, 0.22), 0 10px 22px -12px rgba(17, 24, 45, 0.14);
  --scrim: rgba(255, 255, 255, 0.7);
  color-scheme: light;
}

/* Dark theme */
html[data-theme="dark"] {
  --canvas: #070a14;
  --canvas-2: #0a0e1a;
  --surface: #10141f;
  --surface-2: #141926;
  --elevated: #171d2b;
  --sunken: #0c1019;
  --line: #232a3b;
  --line-strong: #313a51;
  --ink: #eef1fa;
  --ink-muted: #9aa2ba;
  --ink-subtle: #6a7a99;
  --brand: var(--brand-400);
  --brand-soft: rgba(22, 132, 243, 0.14);
  --brand-ink: #0a0e1a;
  --ring: rgba(22, 132, 243, 0.5);
  --overlay: rgba(3, 5, 12, 0.66);
  --grid-line: rgba(255, 255, 255, 0.05);
  --sidebar-bg: #080b16;
  --sidebar-fg: #ffffff;
  --sidebar-ink: #c3c9dc;
  --sidebar-ink-dim: #767e99;
  --sidebar-active: rgba(22, 132, 243, 0.16);
  --sidebar-active-fg: #ffffff;
  --sidebar-hover: rgba(255, 255, 255, 0.05);
  --sidebar-border: rgba(255, 255, 255, 0.06);
  --sidebar-glow: rgba(22, 132, 243, 0.14);
  --scrim: rgba(8, 11, 22, 0.7);
  --shadow-lg: 0 18px 48px -14px rgba(0, 0, 0, 0.6), 0 6px 16px -8px rgba(0, 0, 0, 0.5);
  --shadow: 0 4px 14px -4px rgba(0, 0, 0, 0.5);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
  color-scheme: dark;
}

/* ---- Page-loading bar ----------------------------------------------------- */
.page-progress {
  position: fixed; top: 0; left: 0; z-index: 9999;
  width: 0%; height: 3px; opacity: 0; pointer-events: none;
  background: linear-gradient(90deg, var(--brand-400), var(--brand-600) 55%, var(--accent-500));
  box-shadow: 0 0 10px 1px color-mix(in srgb, var(--brand-500) 65%, transparent);
  border-radius: 0 2px 2px 0;
}
@media (prefers-reduced-motion: reduce) { .page-progress { box-shadow: none; } }

/* ---- Reset --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  font-family: var(--font-sans);
  background: var(--canvas);
  color: var(--ink);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: "cv02", "cv03", "cv04", "ss01";
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; }
ul { list-style: none; }
h1, h2, h3, h4 { line-height: 1.2; font-weight: 650; letter-spacing: -0.015em; }
::selection { background: var(--brand-400); color: #fff; }

/* Scrollbars */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 999px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--ink-subtle); background-clip: content-box; }

/* ---- Typography helpers -------------------------------------------------- */
.text-xs { font-size: 0.75rem; }
.text-sm { font-size: 0.8125rem; }
.text-md { font-size: 0.9375rem; }
.text-lg { font-size: 1.0625rem; }
.text-xl { font-size: 1.375rem; }
.text-2xl { font-size: 1.75rem; }
.text-3xl { font-size: 2.25rem; }
.muted { color: var(--ink-muted); }
.subtle { color: var(--ink-subtle); }
.tabular { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-mono); }
.uppercase { text-transform: uppercase; letter-spacing: 0.06em; }
.eyebrow { font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink-subtle); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.strong { font-weight: 650; }
.center { text-align: center; }

/* ---- Layout primitives --------------------------------------------------- */
.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; }
.between { display: flex; align-items: center; justify-content: space-between; }
.wrap { flex-wrap: wrap; }
.gap-1 { gap: 4px; } .gap-2 { gap: 8px; } .gap-3 { gap: 12px; }
.gap-4 { gap: 16px; } .gap-5 { gap: 20px; } .gap-6 { gap: 24px; } .gap-8 { gap: 32px; }
.grow { flex: 1 1 auto; min-width: 0; }
.grid { display: grid; gap: 20px; }
.grid-2 { display: grid; gap: 20px; grid-template-columns: repeat(2, 1fr); }
.grid-3 { display: grid; gap: 20px; grid-template-columns: repeat(3, 1fr); }
.grid-4 { display: grid; gap: 18px; grid-template-columns: repeat(4, 1fr); }
.grid-2-1 { display: grid; gap: 20px; grid-template-columns: 2fr 1fr; }
.grid-1-2 { display: grid; gap: 20px; grid-template-columns: 1fr 2fr; }
.grid-3-2 { display: grid; gap: 20px; grid-template-columns: 3fr 2fr; }
@media (max-width: 1100px) { .grid-2-1, .grid-1-2, .grid-3-2, .grid-3 { grid-template-columns: 1fr !important; } }
/* Finance summary cards — bold colored, vertical, equal-height. Each card is themed by --fc. */
.fcard-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(258px,1fr));gap:18px}
.card.fcard{--fc:var(--brand);display:flex;flex-direction:column;height:100%;color:#fff;border:0;
  background:linear-gradient(150deg, rgba(255,255,255,.16), rgba(0,0,0,.14)), var(--fc);
  box-shadow:0 10px 24px -12px rgba(17,24,45,.38);
  transition:box-shadow var(--dur), transform var(--dur)}
.card.fcard.hover{cursor:pointer}
.card.fcard.hover:hover{box-shadow:0 18px 38px -14px rgba(17,24,45,.5); transform:translateY(-3px)}
.fc-head{display:flex;align-items:center;gap:10px}
.fc-ic{width:36px;height:36px;border-radius:11px;display:grid;place-items:center;flex:none;
  background:rgba(255,255,255,.22);color:#fff}
.fc-ic svg{width:18px;height:18px}
.fc-eyebrow{font-size:.7rem;font-weight:700;letter-spacing:.6px;text-transform:uppercase;
  color:rgba(255,255,255,.85);line-height:1.25}
.fc-total{font-size:1.75rem;font-weight:800;letter-spacing:-.02em;line-height:1.1;margin-top:13px;
  font-variant-numeric:tabular-nums;color:#fff}
.stat-rows{margin-top:14px;border-top:1px solid rgba(255,255,255,.28)}
/* A long breakdown scrolls INSIDE the card instead of stretching the whole row — every
   tile keeps the same height and the grid stays calm. The mask fades the last row so it
   reads as "more below" rather than a hard cut. */
.stat-rows.scroll{max-height:236px;overflow-y:auto;overscroll-behavior:contain;
  -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 26px),transparent);
  mask-image:linear-gradient(to bottom,#000 calc(100% - 26px),transparent);
  padding-right:6px;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.45) transparent}
.stat-rows.scroll::-webkit-scrollbar{width:5px}
.stat-rows.scroll::-webkit-scrollbar-track{background:transparent}
.stat-rows.scroll::-webkit-scrollbar-thumb{background:rgba(255,255,255,.38);border-radius:99px}
.stat-rows.scroll:hover::-webkit-scrollbar-thumb{background:rgba(255,255,255,.6)}
.stat-row{position:relative;display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:8px 0;border-bottom:1px solid rgba(255,255,255,.16)}
.stat-row:last-child{border-bottom:0}
.stat-row .k{color:rgba(255,255,255,.82);font-size:.88rem;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;min-width:0}
.stat-row .k.strong{color:#fff;font-weight:650}
.stat-row .v{font-variant-numeric:tabular-nums;font-weight:650;white-space:nowrap;color:#fff}
/* Share-of-total bar, drawn as a soft underline beneath each row. */
.stat-row .bar{position:absolute;left:0;bottom:-1px;height:2px;border-radius:99px;
  background:rgba(255,255,255,.75);box-shadow:0 0 8px rgba(255,255,255,.45);
  transition:width var(--dur)}
.fc-count{margin-left:auto;flex:none;font-size:.68rem;font-weight:700;letter-spacing:.3px;
  padding:3px 8px;border-radius:99px;background:rgba(255,255,255,.22);color:#fff}
.fc-foot{margin-top:auto;padding-top:14px;color:rgba(255,255,255,.9);font-size:.82rem;display:flex;align-items:center;gap:5px;font-weight:600}

/* Drill-down rows */
[data-drill]{cursor:pointer}
[data-drill] .drill-chev{display:inline-block;width:14px;height:14px;transition:transform .15s;vertical-align:-2px;color:var(--ink-subtle)}
[data-drill].open > .drill-chev, [data-drill].open .drill-chev{transform:rotate(90deg)}
.drill-row{display:flex;justify-content:space-between;gap:12px;align-items:baseline;padding:7px 9px;border-radius:8px}
.drill-row:hover{background:var(--surface-2)}

/* Searchable select (type-to-filter combobox) — styled to match the native .select */
.ss{position:relative;display:block}
.ss-input{cursor:text;padding-right:30px}
.ss::after{content:'';position:absolute;right:13px;top:50%;width:7px;height:7px;border-right:2px solid var(--ink-subtle);border-bottom:2px solid var(--ink-subtle);transform:translateY(-70%) rotate(45deg);pointer-events:none}
.ss-panel{position:absolute;z-index:60;top:calc(100% + 4px);left:0;right:0;max-height:264px;overflow-y:auto;
  background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow-lg);padding:5px}
.ss-opt{padding:8px 11px;border-radius:7px;cursor:pointer;font-size:.88rem;color:var(--ink);line-height:1.35}
.ss-opt:hover,.ss-opt.active{background:var(--surface-2)}
.ss-empty{padding:11px;color:var(--ink-subtle);font-size:.85rem;text-align:center}
/* Chart-of-Accounts picker (select[data-head-tree]): groups as headings above their heads. */
.ss-panel--tree{max-height:380px}
/* Head picker one level at a time (select[data-head-steps]): main head › sub head › … */
.head-steps{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:6px}
/* select.select outranks the full-width rules a container sets on its own .select (e.g. .req-line) */
.head-steps > select.select{width:auto;min-width:190px;max-width:100%;flex:0 1 auto}
.head-steps__sep{color:var(--ink-subtle)}
.head-steps__or{display:block;margin:2px 0 4px}
.ss-head{padding:9px 11px 3px;font-size:.72rem;font-weight:650;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-subtle);cursor:default;line-height:1.3}

.mt-1{margin-top:4px}.mt-2{margin-top:8px}.mt-3{margin-top:12px}.mt-4{margin-top:16px}.mt-5{margin-top:20px}.mt-6{margin-top:24px}
.mb-1{margin-bottom:4px}.mb-2{margin-bottom:8px}.mb-3{margin-bottom:12px}.mb-4{margin-bottom:16px}.mb-5{margin-bottom:20px}.mb-6{margin-bottom:24px}
.full { width: 100%; }

/* ============================================================================
   App shell
   ========================================================================= */
.app { display: grid; grid-template-columns: var(--sidebar-w, 268px) 1fr; min-height: 100vh; transition: grid-template-columns var(--dur) var(--ease); }
.app.collapsed { --sidebar-w: 76px; }

/* Sidebar */
.sidebar {
  position: sticky; top: 0; height: 100vh; overflow: hidden;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--sidebar-border);
  display: flex; flex-direction: column; z-index: 40;
}
.sidebar::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 45% at 0% 0%, var(--sidebar-glow), transparent 60%);
}
.sidebar__brand { display: flex; align-items: center; gap: 12px; padding: 18px 20px 16px; position: relative; }
.brand-logo { height: 58px; width: auto; max-width: 190px; object-fit: contain; }
.brand-mark.brand-mark--mini { display: none; }
.app.collapsed .brand-logo { display: none; }
.app.collapsed .brand-mark.brand-mark--mini { display: grid; }
html[data-theme="dark"] .brand-logo { background: #fff; border-radius: 9px; padding: 6px 9px; }
.brand-mark {
  width: 38px; height: 38px; border-radius: 11px; flex: none;
  background: linear-gradient(135deg, #1684f3, #02488f 55%, #03386d);
  display: grid; place-items: center; color: #fff;
  box-shadow: 0 6px 18px -6px rgba(2,72,143,0.7), inset 0 1px 0 rgba(255,255,255,0.3);
}
.brand-mark svg { width: 21px; height: 21px; }
.brand-text { display: flex; flex-direction: column; line-height: 1.05; }
.brand-text b { color: var(--sidebar-fg); font-size: 1.02rem; letter-spacing: -0.02em; font-weight: 750; }
.brand-text span { color: var(--sidebar-ink-dim); font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 600; }
.app.collapsed .brand-text, .app.collapsed .nav__label, .app.collapsed .nav-link span, .app.collapsed .sidebar__foot .u-meta { display: none; }
.app.collapsed .sidebar__brand { justify-content: center; padding-inline: 0; }

/* Brand wordmark under the logo */
.brand-sub { display: flex; flex-direction: column; gap: 2px; padding: 0 20px 16px; margin-top: -6px; }
.brand-sub__eyebrow {
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-subtle); padding-left: 1px;
}
.brand-sub__title {
  position: relative; width: fit-content;
  font-size: 0.92rem; font-weight: 750; letter-spacing: 0.005em; line-height: 1.15;
  background: linear-gradient(92deg, var(--brand) 0%, var(--accent-500) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.brand-sub__title::after {
  content: ""; position: absolute; left: 0; bottom: -4px; width: 34px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--brand), var(--accent-500));
}
.app.collapsed .brand-sub { display: none; }

.sidebar__nav { flex: 1 1 auto; overflow-y: auto; padding: 6px 14px 20px; position: relative; }
.nav__group { margin-top: 18px; }
.nav__label { font-size: 0.66rem; font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase; color: var(--sidebar-ink-dim); padding: 0 12px 8px; }
.nav-link {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 11px;
  color: var(--sidebar-ink); font-size: 0.875rem; font-weight: 500; position: relative;
  transition: background var(--dur) var(--ease), color var(--dur); margin-bottom: 2px;
}
.nav-link svg { width: 19px; height: 19px; flex: none; opacity: 0.85; }
.nav-link:hover { background: var(--sidebar-hover); color: var(--sidebar-fg); }
.nav-link.active { background: var(--sidebar-active); color: var(--sidebar-active-fg); font-weight: 600; }
.nav-link.active::before {
  content: ""; position: absolute; left: -14px; top: 50%; transform: translateY(-50%);
  width: 4px; height: 22px; border-radius: 0 4px 4px 0; background: linear-gradient(var(--brand-400), var(--brand-600));
}
.nav-link.active svg { opacity: 1; color: var(--brand); }
.nav-badge { margin-left: auto; background: var(--accent-500); color: #241500; font-size: 0.68rem; font-weight: 800; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; display: grid; place-items: center; }
.app.collapsed .nav-link { justify-content: center; }
.app.collapsed .nav-badge { position: absolute; top: 4px; right: 6px; margin: 0; }

.sidebar__foot { padding: 14px; border-top: 1px solid var(--sidebar-border); position: relative; }
.u-card { display: flex; align-items: center; gap: 11px; padding: 8px; border-radius: 12px; transition: background var(--dur); }
.u-card:hover { background: var(--sidebar-hover); }
.u-meta { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.u-meta b { color: var(--sidebar-fg); font-size: 0.83rem; font-weight: 600; }
.u-meta span { color: var(--sidebar-ink-dim); font-size: 0.72rem; }

/* Main column */
/* grid-column: 2 is pinned explicitly rather than left to auto-placement. On the mobile
   breakpoint below, .sidebar switches to position:fixed to become an overlay — and an
   out-of-flow grid item is removed from auto-placement, so .main was left to fall back
   into track 1 (the sidebar's now-empty 0px column) instead of track 2 (1fr). The whole
   main content area computed to zero width because of it — invisible on most elements,
   which just overflow their box, but violently visible on the first thing that actually
   respects its containing width, like a flash message's text wrapping one word per line. */
.main { display: flex; flex-direction: column; grid-column: 2; min-width: 0; min-height: 100vh; background: var(--canvas); }

/* Topbar */
.topbar {
  position: sticky; top: 0; z-index: 30; height: 66px; display: flex; align-items: center; gap: 16px;
  padding: 0 26px; background: color-mix(in srgb, var(--canvas) 82%, transparent);
  backdrop-filter: saturate(160%) blur(14px); border-bottom: 1px solid var(--line);
}
.icon-btn {
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 11px; display: grid; place-items: center;
  color: var(--ink-muted); border: 1px solid transparent; position: relative; transition: all var(--dur) var(--ease);
}
.icon-btn:hover { background: var(--surface); color: var(--ink); border-color: var(--line); }
.icon-btn svg { width: 19px; height: 19px; }
.icon-btn .dot { position: absolute; top: 8px; right: 9px; width: 8px; height: 8px; border-radius: 999px; background: var(--danger); border: 2px solid var(--canvas); }

.searchbar {
  display: flex; align-items: center; gap: 10px; height: 40px; padding: 0 12px 0 14px; min-width: 260px;
  flex-shrink: 0; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; color: var(--ink-subtle);
  transition: all var(--dur) var(--ease); cursor: text;
}
.searchbar:hover { border-color: var(--line-strong); }
.searchbar svg { width: 17px; height: 17px; }
.searchbar .kbd { margin-left: auto; }
.kbd { font-family: var(--font-mono); font-size: 0.68rem; padding: 2px 6px; border-radius: 6px; background: var(--sunken); border: 1px solid var(--line); color: var(--ink-subtle); }

/* The topbar is a flex row shared by every page, and the page title varies in length —
   a long one used to have nowhere to go but to steal width from the icon buttons beside
   it (see .icon-btn's flex-shrink above), crushing a 40px tap target down to a couple of
   pixels. min-width: 0 lets THIS shrink instead of its siblings; the ellipsis is what
   makes shrinking look intentional rather than like text got cut off mid-word. */
.page-title-wrap { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.breadcrumb { display: flex; align-items: center; gap: 7px; font-size: 0.75rem; color: var(--ink-subtle); min-width: 0; }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb svg { width: 13px; height: 13px; flex-shrink: 0; }
.breadcrumb .strong, .breadcrumb > b {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}

/* Content */
.content { padding: 26px; max-width: 1600px; width: 100%; margin: 0 auto; animation: fadeUp 0.4s var(--ease); }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 22px; flex-wrap: wrap; }
.page-head h1 { font-size: 1.7rem; font-weight: 720; letter-spacing: -0.025em; }
.page-head p { color: var(--ink-muted); font-size: 0.9rem; margin-top: 4px; }

@keyframes fadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes scaleIn { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: none; } }
@keyframes pulseRing { 0% { box-shadow: 0 0 0 0 var(--ring); } 70% { box-shadow: 0 0 0 8px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
@keyframes shimmer { 100% { transform: translateX(100%); } }
@keyframes floaty { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ============================================================================
   Cards & surfaces
   ========================================================================= */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm); position: relative; min-width: 0;
  transition: border-color var(--dur), box-shadow var(--dur), transform var(--dur) var(--ease);
}
.pad, .card.pad { padding: 22px; }
.card.hover:hover { border-color: var(--line-strong); box-shadow: var(--shadow); transform: translateY(-2px); }
.project-hero__head { padding: 22px 24px 20px; }
.card__head { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 18px 22px; border-bottom: 1px solid var(--line); }
.card__head h3 { font-size: 1rem; font-weight: 640; }
.card__head p { font-size: 0.8rem; color: var(--ink-muted); margin-top: 2px; }
/* A real Chart.js canvas (responsive:true) redraws itself to fit once .card can no longer
   be stretched open by it (min-width: 0 above). This is the safety net for anything that
   doesn't: wide content scrolls inside its own card instead of dragging the page — and,
   critically, instead of dragging every OTHER card in the same grid row out of alignment
   with it, which is what actually produced the "sidebar missing, everything shifted"
   effect — the page was never missing its sidebar, it had grown wider than the screen and
   the browser was scrolled to a middle position. */
.card__body { padding: 22px; overflow-x: auto; }
.card__foot { padding: 14px 22px; border-top: 1px solid var(--line); }
.section-title { display: flex; align-items: center; gap: 10px; font-size: 1.02rem; font-weight: 640; margin-bottom: 2px; }
/* Give section headers a colourful leading icon by default (inline colours still win). */
.section-title > svg:first-child { color: var(--brand); flex: none; }

.glass {
  background: color-mix(in srgb, var(--surface) 72%, transparent);
  backdrop-filter: blur(16px) saturate(160%); border: 1px solid var(--line);
}

/* ============================================================================
   Buttons
   ========================================================================= */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 40px; padding: 0 16px; border-radius: 11px; font-size: 0.86rem; font-weight: 600;
  border: 1px solid transparent; transition: all var(--dur) var(--ease); white-space: nowrap; user-select: none;
}
.btn svg { width: 17px; height: 17px; }
.btn:active { transform: translateY(1px); }
.btn-primary { background: linear-gradient(180deg, var(--brand-500), var(--brand-600)); color: #fff; box-shadow: var(--shadow-brand); }
.btn-primary:hover { filter: brightness(1.07); box-shadow: 0 12px 34px -8px rgba(2,72,143,0.6); }
.btn-ghost { background: var(--surface); border-color: var(--line); color: var(--ink); box-shadow: var(--shadow-xs); }
.btn-ghost:hover { border-color: var(--line-strong); background: var(--surface-2); }
.btn-subtle { background: var(--sunken); color: var(--ink-muted); }
.btn-subtle:hover { color: var(--ink); background: var(--surface-2); }
.btn-success { background: var(--success); color: #fff; }
.btn-success:hover { filter: brightness(1.06); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { filter: brightness(1.06); }
.btn-danger-soft { background: color-mix(in srgb, var(--danger) 11%, transparent); color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 32%, transparent); }
.btn-danger-soft:hover { background: var(--danger); color: #fff; border-color: var(--danger);
  box-shadow: 0 8px 20px -8px color-mix(in srgb, var(--danger) 65%, transparent); }
.btn-danger-soft svg { color: currentColor; }

/* Danger zone — destructive action card (e.g. delete a client approval) */
.danger-card { border-color: color-mix(in srgb, var(--danger) 24%, var(--line));
  background: linear-gradient(180deg, color-mix(in srgb, var(--danger) 5%, var(--surface)), var(--surface));
  overflow: hidden; }
.danger-card__body { display: flex; align-items: center; gap: 18px; padding: 20px 22px; flex-wrap: wrap; }
.danger-card__icon { flex: none; width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center;
  color: #fff; background: linear-gradient(180deg, #f26b68, var(--danger));
  box-shadow: 0 8px 18px -7px color-mix(in srgb, var(--danger) 60%, transparent); }
.danger-card__icon svg { width: 22px; height: 22px; }
.danger-card__text { min-width: 220px; flex: 1 1 340px; }
.danger-card__eyebrow { display: inline-flex; align-items: center; gap: 6px; font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--danger); margin-bottom: 5px; }
.danger-card__eyebrow svg { width: 13px; height: 13px; }
.danger-card__text b { display: block; font-size: 1.02rem; color: var(--ink); letter-spacing: -0.01em; }
.danger-card__text p { margin: 4px 0 0; color: var(--ink-muted); font-size: 0.86rem; line-height: 1.55; }
.danger-card__text .mono { color: var(--ink); font-weight: 600; }
.danger-card__action { flex: none; margin-left: auto; }
@media (max-width: 620px) {
  .danger-card__action { margin-left: 0; width: 100%; }
  .danger-card__action .btn { width: 100%; }
}
.btn-accent { background: linear-gradient(180deg, var(--accent-400), var(--accent-600)); color: #2a1900; }
.btn-sm { height: 34px; padding: 0 12px; font-size: 0.8rem; border-radius: 9px; }
.btn-lg { height: 46px; padding: 0 22px; font-size: 0.94rem; }
.btn-icon { width: 40px; padding: 0; }
.btn[disabled] { opacity: 0.5; pointer-events: none; }
.btn-block { width: 100%; }

/* ============================================================================
   Badges, chips, pills, tones
   ========================================================================= */
.badge {
  display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px;
  border-radius: 999px; font-size: 0.72rem; font-weight: 650; letter-spacing: 0.01em;
  border: 1px solid transparent; white-space: nowrap;
}
.badge svg { width: 13px; height: 13px; }
.badge .tdot { width: 6px; height: 6px; border-radius: 999px; background: currentColor; }
.tone-brand { color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, transparent); border-color: color-mix(in srgb, var(--brand) 24%, transparent); }
.tone-success { color: #0f9b0f; background: color-mix(in srgb, var(--success) 13%, transparent); border-color: color-mix(in srgb, var(--success) 26%, transparent); }
.tone-warning { color: #b9770a; background: color-mix(in srgb, var(--warning) 15%, transparent); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
.tone-serious { color: #cf6234; background: color-mix(in srgb, var(--serious) 15%, transparent); border-color: color-mix(in srgb, var(--serious) 30%, transparent); }
.tone-danger { color: #d63a38; background: color-mix(in srgb, var(--danger) 13%, transparent); border-color: color-mix(in srgb, var(--danger) 26%, transparent); }
.tone-info { color: var(--info); background: color-mix(in srgb, var(--info) 12%, transparent); border-color: color-mix(in srgb, var(--info) 24%, transparent); }
.tone-neutral { color: var(--ink-muted); background: var(--sunken); border-color: var(--line); }
html[data-theme="dark"] .tone-success { color: #34d334; }
html[data-theme="dark"] .tone-warning { color: #fbbf3f; }
html[data-theme="dark"] .tone-serious { color: #f5a27a; }
html[data-theme="dark"] .tone-danger { color: #ff6b69; }

.chip {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px; border-radius: 999px;
  font-size: 0.82rem; font-weight: 550; color: var(--ink-muted); background: var(--surface);
  border: 1px solid var(--line); transition: all var(--dur) var(--ease);
}
.chip:hover { border-color: var(--line-strong); color: var(--ink); }
.chip.active { background: var(--brand); color: #fff; border-color: var(--brand); box-shadow: var(--shadow-brand); }
.chip svg { width: 15px; height: 15px; }

/* ============================================================================
   Avatars
   ========================================================================= */
.avatar {
  --sz: 38px; width: var(--sz); height: var(--sz); border-radius: 50%; flex: none;
  display: grid; place-items: center; color: #fff; font-weight: 700; font-size: calc(var(--sz) * 0.4);
  letter-spacing: 0.01em; box-shadow: inset 0 0 0 1px rgba(255,255,255,0.16); overflow: hidden;
}
.avatar.sm { --sz: 30px; } .avatar.lg { --sz: 48px; } .avatar.xl { --sz: 64px; }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar-stack { display: flex; }
.avatar-stack .avatar { margin-left: -10px; box-shadow: 0 0 0 2px var(--surface), inset 0 0 0 1px rgba(255,255,255,0.16); }
.avatar-stack .avatar:first-child { margin-left: 0; }
.avatar-more { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; background: var(--sunken); color: var(--ink-muted); font-size: 0.72rem; font-weight: 700; margin-left: -10px; box-shadow: 0 0 0 2px var(--surface); }

/* ============================================================================
   KPI / stat tiles
   ========================================================================= */
.kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.kpi {
  background:
    linear-gradient(152deg, color-mix(in srgb, var(--kpi-accent, var(--brand)) 9%, var(--surface)) 0%, var(--surface) 58%);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 20px; position: relative; overflow: hidden; box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur), border-color var(--dur);
}
/* A crisp colour bar across the top ties each card to its accent. */
.kpi::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, var(--kpi-accent, var(--brand)), color-mix(in srgb, var(--kpi-accent, var(--brand)) 15%, transparent));
}
.kpi:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow), 0 20px 38px -20px color-mix(in srgb, var(--kpi-accent, var(--brand)) 62%, transparent);
  border-color: color-mix(in srgb, var(--kpi-accent, var(--brand)) 38%, var(--line));
}
.kpi::after { content: ""; position: absolute; right: -34px; top: -30px; width: 128px; height: 128px; border-radius: 50%; background: radial-gradient(circle, color-mix(in srgb, var(--kpi-accent, var(--brand)) 22%, transparent), transparent 70%); }
.kpi__icon {
  width: 46px; height: 46px; border-radius: 14px; display: grid; place-items: center; color: #fff;
  background: linear-gradient(135deg, var(--kpi-accent, var(--brand)), color-mix(in srgb, var(--kpi-accent, var(--brand)) 74%, #101426));
  box-shadow: 0 8px 18px -7px color-mix(in srgb, var(--kpi-accent, var(--brand)) 72%, transparent), inset 0 1px 0 rgba(255,255,255,0.25);
  margin-bottom: 14px; position: relative; z-index: 1;
}
.kpi__icon svg { width: 22px; height: 22px; }
.kpi__label { font-size: 0.78rem; color: var(--ink-muted); font-weight: 600; position: relative; z-index: 1; }
.kpi__value { font-size: 1.95rem; font-weight: 760; letter-spacing: -0.03em; margin-top: 4px; line-height: 1; position: relative; z-index: 1; }
.kpi__value .unit { font-size: 0.95rem; color: var(--ink-subtle); font-weight: 600; margin-left: 3px; }
.kpi__foot { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 0.78rem; }
/* Clickable KPI / summary cards — drill into the page they summarise. */
a.kpi { display: block; text-decoration: none; color: inherit; cursor: pointer; }
a.kpi:hover { border-color: color-mix(in srgb, var(--kpi-accent, var(--brand)) 50%, var(--line)); }
.kpi__go { position: absolute; right: 16px; top: 18px; color: var(--kpi-accent, var(--ink-subtle)); opacity: 0; transform: translateX(-5px); transition: opacity var(--dur), transform var(--dur); z-index: 1; }
.kpi__go svg { width: 17px; height: 17px; }
a.kpi:hover .kpi__go { opacity: 0.9; transform: translateX(0); }
.card-link { text-decoration: none; color: inherit; cursor: pointer; display: block; transition: transform var(--dur) var(--ease), box-shadow var(--dur), border-color var(--dur); }
.card-link:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--line-strong); }
.delta { display: inline-flex; align-items: center; gap: 3px; font-weight: 700; padding: 2px 7px; border-radius: 999px; font-size: 0.72rem; }
.delta svg { width: 13px; height: 13px; }
.delta.up { color: #0f9b0f; background: color-mix(in srgb, var(--success) 13%, transparent); }
.delta.down { color: #d63a38; background: color-mix(in srgb, var(--danger) 13%, transparent); }
html[data-theme="dark"] .delta.up { color: #34d334; }
html[data-theme="dark"] .delta.down { color: #ff6b69; }

/* Stat strip (project detail hero) */
.kpi-strip { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--line); }
.kpi-stat { display: flex; align-items: center; gap: 14px; padding: 20px 24px; border-right: 1px solid var(--line); }
.kpi-stat:last-child { border-right: none; }
.kpi-stat b { font-weight: 640; }
@media (max-width: 900px) { .kpi-strip { grid-template-columns: repeat(2, 1fr); } .kpi-stat:nth-child(2) { border-right: none; } }

/* Project cards */
.project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 18px; }
.project-card { overflow: hidden; }
.project-card__body { display: flex; flex-direction: column; gap: 15px; padding: 20px; height: 100%; }
.proj-ic { width: 42px; height: 42px; border-radius: 12px; flex: none; display: grid; place-items: center; background: var(--brand-soft); color: var(--brand); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand) 14%, transparent); }
.proj-ic svg { width: 21px; height: 21px; }
.project-card__foot { margin-top: auto; padding-top: 15px; border-top: 1px solid var(--line); }

/* Every project card wears its status as a stripe along the top edge, so the grid is
   scannable by colour without reading a single badge. --status is set per card from the
   status tone (the project detail header paints its bar from the same token), and falls
   back to a plain rule for a status with no colour of its own. */
.project-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--status, var(--line-strong)); z-index: 1;
}

/* Completed is a terminal state, so it is called out well past its stripe: a solid badge
   that outranks the tinted risk pill beside it, a tinted card, and the type icon moved off
   brand-blue onto the green. The badge fill is darkened off --success because white text on
   the raw token is only 2.8:1. */
.badge.is-solid { border-color: transparent; }
.badge.tone-success.is-solid { background: color-mix(in srgb, var(--success) 70%, #000); color: #fff; }
.project-card.is-complete::before { height: 5px; }
.project-card.is-complete {
  border-color: color-mix(in srgb, var(--success) 48%, var(--line));
  background: color-mix(in srgb, var(--success) 7%, var(--surface));
}
/* The type icon is brand-blue on every other card; on a finished one it joins the green so
   the card reads as complete from its shape, not from one pill in the corner. */
.project-card.is-complete .proj-ic {
  background: color-mix(in srgb, var(--success) 15%, transparent);
  color: color-mix(in srgb, var(--success) 72%, #000);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--success) 30%, transparent);
}
.project-card.is-complete .project-card__foot { border-top-color: color-mix(in srgb, var(--success) 26%, var(--line)); }
html[data-theme="dark"] .project-card.is-complete .proj-ic { color: #34d334; }

/* Client-approval review console (PMTS-style) */
.review-console { overflow: hidden; }
.review-console__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 22px 24px; background: linear-gradient(120deg, #4a3aa7 0%, #6d5ef0 58%, #7c5cff 100%); flex-wrap: wrap; }
.review-console__head h3 { font-size: 1.18rem; color: #fff; }
.review-console__head p { font-size: 0.86rem; margin-top: 2px; }
.review-card { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 18px; border: 1px solid var(--line); border-left: 3px solid var(--brand); border-radius: 13px; margin-bottom: 12px; flex-wrap: wrap; transition: box-shadow var(--dur) var(--ease); }
.review-card:hover { box-shadow: var(--shadow-sm); }
.review-card:last-child { margin-bottom: 0; }
.review-card.done { border-left-color: var(--success); background: var(--surface); }
.review-console__done { padding: 20px 24px 24px; border-top: 1px solid var(--line); background: var(--surface-2); }
.review-console__actions { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 18px 24px; border-top: 1px solid var(--line); background: var(--surface-2); flex-wrap: wrap; }

/* Client-approval checklist slots */
.slot-row { display: flex; align-items: center; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--line); margin: 0; }
.slot-row:last-child { border-bottom: none; }
.slot-flag { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; flex: none; }
.slot-flag svg { width: 15px; height: 15px; }
.slot-flag.done { background: color-mix(in srgb, var(--success) 15%, transparent); color: var(--success); }
.slot-flag.missing { background: color-mix(in srgb, var(--warning) 16%, transparent); color: var(--warning); }
.slot-label { font-size: 0.88rem; font-weight: 550; }

/* Chart of Accounts */
table.data.coa td { padding-top: 9px; padding-bottom: 9px; }
table.data.coa tr.coa-d0 td { background: var(--sunken); border-top: 2px solid var(--line-strong); font-size: 0.9rem; }
table.data.coa tr.coa-d1 td { background: var(--surface-2); }

/* Project checklist (client assignment) */
.proj-checklist { max-height: 240px; overflow-y: auto; border: 1px solid var(--line); border-radius: 11px; padding: 6px; background: var(--surface); }
.proj-check { display: flex; align-items: center; gap: 11px; padding: 9px 11px; border-radius: 9px; cursor: pointer; font-size: 0.86rem; }
.proj-check:hover { background: var(--surface-2); }
.proj-check input { width: 16px; height: 16px; accent-color: var(--brand); flex: none; }

/* RBAC matrix */
.role-ic { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; flex: none; }
.role-ic svg { width: 16px; height: 16px; }
input.perm { width: 18px; height: 18px; accent-color: var(--brand); cursor: pointer; vertical-align: middle; }
table.data.matrix thead th { text-align: center; }
table.data.matrix thead th:first-child { text-align: left; }
table.data.matrix td, table.data.matrix th { padding-top: 11px; padding-bottom: 11px; }

/* Profile header */
.profile-card { overflow: hidden; }
.profile-cover { position: relative; height: 120px; background: linear-gradient(115deg, #03386d 0%, #0565c7 52%, #6cadef 100%); }
.profile-cover::before { content: ""; position: absolute; inset: 0; background: radial-gradient(130% 150% at 10% 0%, rgba(255,255,255,0.22), transparent 52%); }
.profile-cover::after { content: ""; position: absolute; inset: 0; background-image: linear-gradient(rgba(255,255,255,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.06) 1px, transparent 1px); background-size: 34px 34px; -webkit-mask-image: linear-gradient(105deg, #000, transparent 72%); mask-image: linear-gradient(105deg, #000, transparent 72%); }
.profile-actions { position: absolute; top: 16px; right: 18px; z-index: 2; }
.profile-head { display: flex; align-items: flex-end; gap: 20px; padding: 0 26px 22px; margin-top: -46px; position: relative; }
.profile-head .grow { padding-bottom: 6px; }
.profile-avatar { --sz: 94px; font-size: 1.9rem; box-shadow: 0 0 0 5px var(--surface), 0 10px 24px -10px rgba(17,24,45,0.4); }
@media (max-width: 640px) { .profile-head { flex-direction: column; align-items: flex-start; gap: 12px; } .profile-actions { top: 14px; right: 14px; } }

/* ============================================================================
   Progress bars & rings
   ========================================================================= */
.progress { height: 8px; border-radius: 999px; background: var(--sunken); overflow: hidden; position: relative; }
.progress__bar { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--brand-400), var(--brand-600)); transition: width 0.7s var(--ease); }
.progress.thin { height: 6px; }
.progress__bar.success { background: linear-gradient(90deg, #22c55e, var(--success)); }
.progress__bar.warning { background: linear-gradient(90deg, #fbbf24, var(--warning)); }
.progress__bar.danger { background: linear-gradient(90deg, #f87171, var(--danger)); }
.progress__bar.accent { background: linear-gradient(90deg, var(--accent-400), var(--accent-600)); }

.ring { --p: 0; --sz: 68px; --tw: 7px; width: var(--sz); height: var(--sz); border-radius: 50%; display: grid; place-items: center; flex: none;
  background: conic-gradient(var(--ring-color, var(--brand)) calc(var(--p) * 1%), var(--sunken) 0); position: relative; }
.ring::before { content: ""; position: absolute; inset: var(--tw); border-radius: 50%; background: var(--surface); }
.ring__val { position: relative; font-weight: 720; font-size: calc(var(--sz) * 0.24); letter-spacing: -0.02em; }
.ring__val small { font-size: 0.6em; color: var(--ink-subtle); }

/* ============================================================================
   Tables
   ========================================================================= */
.table-wrap { overflow-x: auto; border-radius: var(--radius-lg); }
table.data { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
table.data thead th {
  text-align: left; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-subtle); padding: 12px 16px; border-bottom: 1px solid var(--line); white-space: nowrap;
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
table.data tbody td { padding: 14px 16px; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.data tfoot td { padding: 13px 16px; }
/* Align table content with the card gutter (22px) so cells never touch the card edges. */
table.data th:first-child, table.data td:first-child { padding-left: 22px; }
table.data th:last-child,  table.data td:last-child  { padding-right: 22px; }
table.data tbody tr { transition: background var(--dur); }
table.data tbody tr:hover { background: var(--surface-2); }
table.data tbody tr:last-child td { border-bottom: none; }
/* Money never wraps. "Rs 240,000,000" breaking after "Rs" made a narrow table unreadable
   and, worse, crushed the name column next to it — the one that says WHICH project. */
table.data .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cell-primary { font-weight: 600; color: var(--ink); }
.cell-sub { font-size: 0.76rem; color: var(--ink-subtle); }

/* ============================================================================
   Forms
   ========================================================================= */
.field { display: flex; flex-direction: column; gap: 7px; }
.field label { font-size: 0.8rem; font-weight: 600; color: var(--ink-muted); }
.input, .select, textarea.input {
  height: 44px; padding: 0 14px; border-radius: 11px; background: var(--surface); border: 1px solid var(--line);
  color: var(--ink); font-size: 0.9rem; width: 100%; transition: border-color var(--dur), box-shadow var(--dur);
}
textarea.input { height: auto; padding: 12px 14px; resize: vertical; min-height: 90px; line-height: 1.5; }
.input::placeholder { color: var(--ink-subtle); }
.input:focus, .select:focus, textarea.input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 4px var(--ring); }
/* A field the form will refuse. Applied by script as the value is typed, so the problem
   is visible while it can still be fixed rather than only after a round trip. The focus
   ring is overridden too — a red border under a brand-coloured glow reads as neither. */
.input.is-invalid, .select.is-invalid { border-color: var(--danger); }
.input.is-invalid:focus, .select.is-invalid:focus {
  border-color: var(--danger); box-shadow: 0 0 0 4px color-mix(in srgb, var(--danger) 20%, transparent); }
.select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238a91a6' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; padding-right: 40px; }
.input-group { position: relative; display: flex; align-items: center; }
.input-group svg.lead { position: absolute; left: 14px; width: 18px; height: 18px; color: var(--ink-subtle); pointer-events: none; }
.input-group .input { padding-left: 42px; }

/* DD/MM/YYYY date field (static/js/date-field.js) — a native date input always shows in
   the BROWSER's own locale, not the page's, so this is a text field with a calendar
   button that opens a hidden native picker only to browse a month. */
.date-field-wrap { position: relative; display: flex; align-items: center; }
.date-field-text { padding-right: 42px; font-variant-numeric: tabular-nums; }
.date-field-btn {
  position: absolute; right: 6px; width: 32px; height: 32px; border-radius: 8px; border: 0;
  background: transparent; color: var(--ink-subtle); display: grid; place-items: center;
  cursor: pointer; transition: background var(--dur), color var(--dur);
}
.date-field-btn:hover { background: var(--surface-2); color: var(--ink); }
.date-field-btn svg { width: 17px; height: 17px; }
.date-field-native {
  position: absolute; right: 6px; top: 6px; width: 32px; height: 32px; opacity: 0;
  pointer-events: none; border: 0;
}
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.form-grid .col-span-2 { grid-column: 1 / -1; }
.hint { font-size: 0.74rem; color: var(--ink-subtle); }
.switch { --w: 44px; --h: 25px; width: var(--w); height: var(--h); border-radius: 999px; background: var(--line-strong); position: relative; transition: background var(--dur); flex: none; }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: calc(var(--h) - 6px); height: calc(var(--h) - 6px); border-radius: 50%; background: #fff; transition: transform var(--dur) var(--ease); box-shadow: var(--shadow-sm); }
.switch.on { background: var(--brand); }
.switch.on::after { transform: translateX(calc(var(--w) - var(--h))); }

/* ============================================================================
   Tabs
   ========================================================================= */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; }
.tabs::-webkit-scrollbar { width: 0; height: 0; display: none; }
.tab { padding: 12px 16px; font-size: 0.86rem; font-weight: 550; color: var(--ink-muted); position: relative; white-space: nowrap; transition: color var(--dur); display: inline-flex; align-items: center; gap: 8px; }
.tab:hover { color: var(--ink); }
.tab.active { color: var(--brand); font-weight: 650; }
.tab.active::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--brand); }
.tab .count { font-size: 0.7rem; background: var(--sunken); padding: 1px 7px; border-radius: 999px; color: var(--ink-subtle); }

/* ============================================================================
   Timeline / workflow / activity
   ========================================================================= */
.timeline { position: relative; padding-left: 8px; }
.tl-item { position: relative; padding: 0 0 22px 34px; }
.tl-item::before { content: ""; position: absolute; left: 12px; top: 22px; bottom: -4px; width: 2px; background: var(--line); }
.tl-item:last-child::before { display: none; }
.tl-dot { position: absolute; left: 3px; top: 2px; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; background: var(--surface); border: 2px solid var(--line-strong); color: var(--ink-subtle); z-index: 1; }
.tl-dot svg { width: 11px; height: 11px; }
.tl-dot.success { border-color: var(--success); color: var(--success); background: color-mix(in srgb, var(--success) 12%, var(--surface)); }
.tl-dot.danger { border-color: var(--danger); color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, var(--surface)); }
.tl-dot.brand { border-color: var(--brand); color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, var(--surface)); }
.tl-dot.warning { border-color: var(--warning); color: var(--warning); }
.tl-body b { font-size: 0.87rem; font-weight: 600; }
.tl-body p { font-size: 0.82rem; color: var(--ink-muted); margin-top: 2px; }
.tl-time { font-size: 0.72rem; color: var(--ink-subtle); margin-top: 3px; }

/* Approval chain (horizontal stepper) */
.chain { display: flex; align-items: stretch; gap: 0; overflow-x: auto; padding: 4px 0; }
.chain__step { flex: 1 1 0; min-width: 128px; position: relative; padding: 0 6px; text-align: center; }
.chain__node { width: 40px; height: 40px; border-radius: 50%; margin: 0 auto 10px; display: grid; place-items: center; background: var(--surface); border: 2px solid var(--line-strong); color: var(--ink-subtle); position: relative; z-index: 2; transition: all var(--dur) var(--ease); }
.chain__node svg { width: 18px; height: 18px; }
.chain__step::before { content: ""; position: absolute; top: 20px; left: -50%; width: 100%; height: 2px; background: var(--line); z-index: 1; }
.chain__step:first-child::before { display: none; }
.chain__step.done .chain__node { background: var(--success); border-color: var(--success); color: #fff; }
.chain__step.done::before { background: var(--success); }
.chain__step.current .chain__node { background: var(--brand); border-color: var(--brand); color: #fff; animation: pulseRing 2s infinite; }
.chain__step.rejected .chain__node { background: var(--danger); border-color: var(--danger); color: #fff; }
.chain__role { font-size: 0.76rem; font-weight: 600; }
.chain__who { font-size: 0.7rem; color: var(--ink-subtle); margin-top: 2px; }

/* ============================================================================
   Kanban
   ========================================================================= */
.kanban { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(280px, 1fr); gap: 16px; overflow-x: auto; padding-bottom: 8px; }
.kanban__col { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-lg); display: flex; flex-direction: column; max-height: 640px; }
.kanban__head { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border-bottom: 1px solid var(--line); font-size: 0.82rem; font-weight: 650; }
.kanban__head .count { margin-left: auto; background: var(--sunken); color: var(--ink-muted); font-size: 0.7rem; padding: 1px 9px; border-radius: 999px; font-weight: 700; }
.kanban__head .kdot { width: 8px; height: 8px; border-radius: 999px; }
.kanban__list { padding: 12px; display: flex; flex-direction: column; gap: 10px; overflow-y: auto; }
.kcard { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px; box-shadow: var(--shadow-xs); transition: all var(--dur) var(--ease); cursor: pointer; }
.kcard:hover { border-color: var(--brand); transform: translateY(-2px); box-shadow: var(--shadow); }

/* ============================================================================
   Dropdown / menu / popover
   ========================================================================= */
.pop { position: relative; }
.menu {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 230px; background: var(--elevated);
  border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-lg); padding: 7px; z-index: 60;
  animation: scaleIn 0.16s var(--ease); transform-origin: top right;
}
.menu.left { right: auto; left: 0; transform-origin: top left; }
.menu-item { display: flex; align-items: center; gap: 11px; padding: 9px 11px; border-radius: 9px; font-size: 0.85rem; color: var(--ink); width: 100%; text-align: left; transition: background var(--dur); }
.menu-item:hover { background: var(--surface-2); }
.menu-item svg { width: 17px; height: 17px; color: var(--ink-subtle); }
.menu-item.danger { color: var(--danger); } .menu-item.danger svg { color: var(--danger); }
.menu-sep { height: 1px; background: var(--line); margin: 6px 4px; }
.menu-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-subtle); padding: 8px 11px 5px; font-weight: 700; }
[hidden] { display: none !important; }

/* ============================================================================
   Modal
   ========================================================================= */
.modal-backdrop { position: fixed; inset: 0; background: var(--overlay); backdrop-filter: blur(4px); z-index: 90; display: grid; place-items: center; padding: 24px; animation: fadeIn 0.2s; }
.modal { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-xl); box-shadow: var(--shadow-lg); width: 100%; max-width: 540px; max-height: 90vh; overflow: hidden; display: flex; flex-direction: column; animation: scaleIn 0.22s var(--ease); }
.modal.wide { max-width: 820px; }
.modal__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 22px 24px 16px; border-bottom: 1px solid var(--line); }
.modal__head h3 { font-size: 1.15rem; font-weight: 680; }
.modal__body { padding: 22px 24px; overflow-y: auto; }
.modal__foot { padding: 16px 24px; border-top: 1px solid var(--line); display: flex; justify-content: flex-end; gap: 10px; background: var(--surface-2); }
/* Ad-hoc modals place their content directly inside .modal (no structured
   head/body/foot). Give them comfortable internal padding so the content never sits
   flush against the edges, matching the structured dialogs. */
.modal:not(.confirm-card):not(:has(.modal__body)) { padding: 24px; }

/* Attendance reminder — no close button, no Escape, so the page behind it must not scroll
   away underneath either. z-index sits above every other modal: it is the one dialog that
   is not allowed to end up behind something. */
[data-attendance-prompt] { z-index: 120; }
body:has([data-attendance-prompt]) { overflow: hidden; }
[data-attendance-prompt] .modal__foot { justify-content: space-between; }

/* Confirmation dialog */
.confirm-card { max-width: 428px; text-align: center; padding: 34px 30px 26px; }
.confirm-card__icon { width: 62px; height: 62px; border-radius: 50%; display: grid; place-items: center; margin: 0 auto 18px; background: var(--brand-soft); color: var(--brand); }
.confirm-card__icon svg { width: 28px; height: 28px; }
.confirm-card__icon.danger { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.confirm-card__icon.success { background: color-mix(in srgb, var(--success) 14%, transparent); color: var(--success); }
.confirm-card__icon.warning { background: color-mix(in srgb, var(--warning) 16%, transparent); color: var(--warning); }
.confirm-card h3 { font-size: 1.22rem; letter-spacing: -0.02em; margin-bottom: 8px; }
.confirm-card p { font-size: 0.9rem; line-height: 1.55; margin-bottom: 24px; max-width: 340px; margin-left: auto; margin-right: auto; }
.confirm-card__actions { display: flex; gap: 10px; }
.confirm-card__actions .btn { flex: 1; height: 44px; }

/* ============================================================================
   Command palette
   ========================================================================= */
.cmdk-backdrop { position: fixed; inset: 0; background: var(--overlay); backdrop-filter: blur(6px); z-index: 100; display: flex; justify-content: center; align-items: flex-start; padding-top: 12vh; animation: fadeIn 0.15s; }
.cmdk { width: 100%; max-width: 620px; background: var(--elevated); border: 1px solid var(--line-strong); border-radius: 18px; box-shadow: var(--shadow-lg); overflow: hidden; animation: scaleIn 0.18s var(--ease); }
.cmdk__input { display: flex; align-items: center; gap: 12px; padding: 18px 20px; border-bottom: 1px solid var(--line); }
.cmdk__input svg { width: 20px; height: 20px; color: var(--ink-subtle); }
.cmdk__input input { border: none; background: none; outline: none; font-size: 1.02rem; width: 100%; }
.cmdk__list { max-height: 52vh; overflow-y: auto; padding: 8px; }
.cmdk__group-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-subtle); padding: 10px 12px 6px; font-weight: 700; }
.cmdk__item { display: flex; align-items: center; gap: 13px; padding: 11px 12px; border-radius: 11px; cursor: pointer; font-size: 0.9rem; }
.cmdk__item .ic { width: 34px; height: 34px; border-radius: 9px; background: var(--sunken); display: grid; place-items: center; color: var(--ink-muted); flex: none; }
.cmdk__item .ic svg { width: 17px; height: 17px; }
.cmdk__item small { color: var(--ink-subtle); font-size: 0.75rem; }
.cmdk__item.active { background: var(--brand-soft); }
.cmdk__item.active .ic { background: var(--brand); color: #fff; }
.cmdk__foot { padding: 10px 16px; border-top: 1px solid var(--line); display: flex; gap: 16px; font-size: 0.72rem; color: var(--ink-subtle); }

/* ============================================================================
   Toast
   ========================================================================= */
.toast-wrap { position: fixed; bottom: 24px; right: 24px; z-index: 120; display: flex; flex-direction: column; gap: 10px; }
.toast { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: var(--elevated); border: 1px solid var(--line); border-left: 3px solid var(--brand); border-radius: 12px; box-shadow: var(--shadow-lg); min-width: 300px; animation: slideInRight 0.3s var(--ease); }
.toast.success { border-left-color: var(--success); } .toast.danger { border-left-color: var(--danger); } .toast.warning { border-left-color: var(--warning); }
.toast svg { width: 19px; height: 19px; }
@keyframes slideInRight { from { opacity: 0; transform: translateX(30px); } to { opacity: 1; transform: none; } }

/* Django messages */
.messages { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
.alert { display: flex; align-items: center; gap: 11px; padding: 13px 16px; border-radius: 12px; font-size: 0.86rem; border: 1px solid; }
.alert svg { width: 18px; height: 18px; flex: none; }
.alert.success { background: color-mix(in srgb, var(--success) 10%, var(--surface)); border-color: color-mix(in srgb, var(--success) 30%, transparent); color: #0f9b0f; }
.alert.error, .alert.danger { background: color-mix(in srgb, var(--danger) 10%, var(--surface)); border-color: color-mix(in srgb, var(--danger) 30%, transparent); color: #d63a38; }
.alert.warning { background: color-mix(in srgb, var(--warning) 10%, var(--surface)); border-color: color-mix(in srgb, var(--warning) 30%, transparent); color: #b9770a; }
.alert.info { background: var(--brand-soft); border-color: color-mix(in srgb, var(--brand) 24%, transparent); color: var(--brand); }

/* ============================================================================
   Misc: dividers, empty states, tooltips, skeleton
   ========================================================================= */
.divider { height: 1px; background: var(--line); border: none; }
.vr { width: 1px; align-self: stretch; background: var(--line); }
.empty { text-align: center; padding: 56px 24px; }
.empty__icon { width: 62px; height: 62px; border-radius: 18px; display: grid; place-items: center; margin: 0 auto 16px;
  color: var(--brand); background: linear-gradient(150deg, color-mix(in srgb, var(--brand) 16%, transparent), color-mix(in srgb, var(--brand) 5%, transparent));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand) 18%, transparent); }
.empty__icon svg { width: 26px; height: 26px; }
.empty h3 { font-size: 1.05rem; margin-bottom: 6px; }
.empty p { color: var(--ink-muted); font-size: 0.88rem; max-width: 380px; margin: 0 auto 18px; }

.dl { display: grid; grid-template-columns: 150px 1fr; gap: 4px 16px; font-size: 0.87rem; }
.dl dt { color: var(--ink-subtle); padding: 8px 0; }
.dl dd { color: var(--ink); font-weight: 550; padding: 8px 0; border-bottom: 1px solid var(--line); }

.meter-legend { display: flex; align-items: center; gap: 6px; font-size: 0.76rem; color: var(--ink-muted); }
.meter-legend .sw { width: 11px; height: 11px; border-radius: 3px; }

.stat-line { display: flex; align-items: baseline; gap: 8px; }
.stat-line b { font-size: 1.5rem; font-weight: 720; letter-spacing: -0.02em; }

/* ============================================================================
   Auth / login
   ========================================================================= */
.auth { display: grid; grid-template-columns: 1.05fr 0.95fr; min-height: 100vh; background: var(--canvas); }
.auth__showcase { position: relative; overflow: hidden; background: linear-gradient(158deg, #1a256b 0%, #16205e 42%, #0f1642 100%); display: flex; padding: 46px; color: #e8ecfb; }
.auth__aurora { position: absolute; inset: -20%; background:
    radial-gradient(42% 42% at 22% 24%, rgba(92,130,251,0.42), transparent 62%),
    radial-gradient(38% 38% at 84% 16%, rgba(245,153,11,0.24), transparent 60%),
    radial-gradient(50% 50% at 76% 84%, rgba(30,49,201,0.5), transparent 62%),
    radial-gradient(40% 40% at 40% 100%, rgba(124,92,255,0.28), transparent 60%);
  filter: blur(6px); animation: auroraPan 16s ease-in-out infinite alternate; }
@keyframes auroraPan { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(-3%, 2%) scale(1.08); } }
.auth__grid-overlay { position: absolute; inset: 0; background-image: linear-gradient(rgba(255,255,255,0.04) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.04) 1px, transparent 1px); background-size: 44px 44px; mask-image: radial-gradient(circle at 50% 40%, #000 30%, transparent 78%); }
.auth__showcase-inner { position: relative; z-index: 2; display: flex; flex-direction: column; gap: 30px; width: 100%; max-width: 540px; margin: auto; }
.auth__showcase-inner .brand-text b { color: #fff; }
.auth__showcase-inner .brand-text span { color: rgba(232,236,251,0.6); }

.auth__eyebrow { display: inline-flex; align-items: center; gap: 9px; font-size: 0.74rem; font-weight: 600; color: rgba(232,236,251,0.82); text-transform: uppercase; letter-spacing: 0.09em; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1); padding: 7px 14px; border-radius: 999px; width: fit-content; }
.pulse-dot { width: 8px; height: 8px; border-radius: 999px; background: #37f0a0; box-shadow: 0 0 0 0 rgba(55,240,160,0.6); animation: pulseDot 2s infinite; }
@keyframes pulseDot { 0% { box-shadow: 0 0 0 0 rgba(55,240,160,0.55); } 70% { box-shadow: 0 0 0 9px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
.auth__hero h1 { font-size: 2.65rem; font-weight: 760; letter-spacing: -0.035em; line-height: 1.08; margin-top: 16px; color: #fff; }
.auth__hero .grad { background: linear-gradient(100deg, #6cadef, #1684f3 45%, #e3614a); -webkit-background-clip: text; background-clip: text; color: transparent; }
.auth__hero p { color: rgba(232,236,251,0.72); font-size: 1rem; margin-top: 18px; max-width: 460px; line-height: 1.6; }

.auth__cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.auth__mcard { background: rgba(255,255,255,0.055); border: 1px solid rgba(255,255,255,0.1); border-radius: 16px; padding: 16px; backdrop-filter: blur(8px); animation: fadeUp 0.7s var(--ease) both; }
.mc-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.mc-ic { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; color: var(--c); background: color-mix(in srgb, var(--c) 20%, transparent); }
.mc-ic svg { width: 17px; height: 17px; }
.mc-val { font-size: 1.7rem; font-weight: 760; letter-spacing: -0.03em; color: #fff; line-height: 1; }
.mc-val span { font-size: 0.95rem; color: rgba(232,236,251,0.6); margin-left: 2px; }
.mc-lab { font-size: 0.72rem; color: rgba(232,236,251,0.62); margin-top: 7px; line-height: 1.3; }

.auth__trust { margin-top: 4px; }
.auth__trust > span { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.08em; color: rgba(232,236,251,0.45); }
.auth__trust-row { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 12px; }
.auth__trust-row span { display: inline-flex; align-items: center; gap: 8px; font-size: 0.82rem; color: rgba(232,236,251,0.8); }
.auth__trust-row svg { width: 16px; height: 16px; color: #6cadef; }

.auth__panel { display: flex; align-items: center; justify-content: center; padding: 40px 28px; }
.auth__form { width: 100%; max-width: 400px; animation: fadeUp 0.6s var(--ease); }
.auth-logo { height: 92px; width: auto; object-fit: contain; margin-bottom: 26px; }
.auth__demo { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--line); }
.auth__foot { margin-top: 26px; font-size: 0.72rem; color: var(--ink-subtle); text-align: center; }

@media (max-width: 940px) {
  .auth { grid-template-columns: 1fr; }
  .auth__showcase { display: none; }
  .auth .hide-desktop { display: flex !important; }
}

/* Responsive */
.hide-desktop { display: none !important; }
@media (max-width: 1180px) { .kpi-grid, .grid-4 { grid-template-columns: repeat(2, 1fr) !important; } .grid-3, .grid-2 { grid-template-columns: 1fr !important; } }
@media (max-width: 560px) { .kpi-grid, .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr !important; } }
@media (max-width: 900px) {
  .app { grid-template-columns: 0 1fr; }
  .sidebar { position: fixed; left: 0; top: 0; width: 268px; transform: translateX(-100%); transition: transform var(--dur) var(--ease); box-shadow: var(--shadow-lg); }
  .app.nav-open .sidebar { transform: none; }
  .content { padding: 18px; }
  .form-grid, .dl { grid-template-columns: 1fr; }
  .searchbar { min-width: 0; }
  .hide-mobile { display: none !important; }
  .hide-desktop { display: inline-flex !important; }
  .page-head { gap: 12px; }
  /* The Accounting GL sub-nav (_gl_bar.html) opts out of the standard .tabs horizontal
     scroll with an inline flex-wrap so its trailing export buttons can drop to their own
     line on a narrow desktop window. On an actual phone that trade only pays for itself
     on the Dashboard/Journal/Ledger/... row too: eight tabs wrapping one-per-line pushed
     the real page content down by several screens before a user reached it. Scrolling one
     compact strip is the shorter path to what they opened the page for. */
  .tabs[style*="flex-wrap"] { flex-wrap: nowrap !important; overflow-x: auto !important; }
}

/* ============================================================================
   Print — clean report output (hide chrome, keep the content)
   ========================================================================= */
@media print {
  .sidebar, .topbar, .no-print, .btn, .tabs, [data-confirm], .messages { display: none !important; }
  .app, .main, .content { display: block !important; margin: 0 !important; padding: 0 !important; }
  .content { padding: 0 !important; }
  body, .app { background: #fff !important; }
  .card { box-shadow: none !important; border: 1px solid #ddd !important; break-inside: avoid; }
  .card__head { border-bottom: 1px solid #ddd !important; }
  a { color: inherit !important; text-decoration: none !important; }
  table.data thead th { background: #f3f4f6 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  @page { margin: 14mm; }
}

/* A table row that is awaiting THIS user's action — subtle amber tint + left accent. */
tr.row-awaiting > td { background: rgba(234,179,8,.09); }
tr.row-awaiting:hover > td { background: rgba(234,179,8,.16); }
tr.row-awaiting > td:first-child { box-shadow: inset 3px 0 0 var(--warning); }

/* Numeric inputs — hide the browser spin-arrows so the full value is visible even in a
   tight column (the up/down stepper ate most of the narrow Qty box otherwise). */
input.num[type="number"]::-webkit-outer-spin-button,
input.num[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input.num[type="number"] { -moz-appearance: textfield; appearance: textfield; }

/* ============================================================================
   Financial presentation kit — gradient hero tiles, statement cards, section
   rows and total bands. Shared by the Chimbals Financials module + Dashboard.
   Row / band / section rules are scoped under `.fin` so the short class names
   never collide with the rest of the app. Theme-aware (light + dark).
   ========================================================================= */
.fin{--c-rev:#10b981;--c-mat:#f59e0b;--c-dir:#f97316;--c-ovh:#8b5cf6;
     --c-asset:#0ea5e9;--c-liab:#f43f5e;--c-eq:#8b5cf6;
     --pos:#059669;--neg:#e11d48;--band:rgba(148,163,184,.10);}
@media (prefers-color-scheme:dark){.fin{--band:rgba(148,163,184,.16)}}
:root[data-theme="dark"] .fin{--band:rgba(148,163,184,.16)}
:root[data-theme="light"] .fin{--band:rgba(148,163,184,.10)}

/* hero summary strip */
.fin-hero{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;margin-bottom:22px}
.fin-tile{position:relative;overflow:hidden;border-radius:18px;padding:18px 20px;color:#fff;text-decoration:none;display:block;
          background:linear-gradient(145deg,rgba(255,255,255,.18),rgba(0,0,0,.12)),var(--tc,#10b981);
          box-shadow:0 10px 26px -12px var(--tc,#10b981);isolation:isolate}
a.fin-tile{transition:transform .14s ease, box-shadow .14s ease}
a.fin-tile:hover{transform:translateY(-2px);box-shadow:0 16px 34px -12px var(--tc,#10b981)}
.fin-tile::after{content:"";position:absolute;right:-24px;top:-24px;width:110px;height:110px;border-radius:50%;background:rgba(255,255,255,.14);z-index:-1}
.fin-tile .ft-ic{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:11px;background:rgba(255,255,255,.22);margin-bottom:12px}
.fin-tile .ft-ic i{width:19px;height:19px}
.fin-tile .ft-lbl{font-size:.7rem;font-weight:700;letter-spacing:.7px;text-transform:uppercase;opacity:.92}
/* The value scales with the tile so a long money figure (Rs 51,543,391) stays on ONE line
   instead of breaking the currency onto its own row. */
.fin-tile .ft-val{font-size:clamp(1.24rem,1.55vw + .72rem,1.7rem);font-weight:800;line-height:1.15;
  margin-top:3px;font-variant-numeric:tabular-nums;letter-spacing:-.5px;
  white-space:nowrap;display:flex;align-items:baseline;gap:.3em;min-width:0}
/* Currency reads as a quiet prefix so the number itself carries the weight. */
.fin-tile .ft-cur{font-size:.6em;font-weight:700;opacity:.82;letter-spacing:.2px;flex:none}
.fin-tile .ft-num{overflow:hidden;text-overflow:ellipsis}
.fin-tile .ft-sub{font-size:.74rem;opacity:.92;margin-top:5px;display:flex;align-items:center;gap:5px}
.fin-tile .ft-go{position:absolute;right:16px;bottom:14px;opacity:.55}
.fin-tile .ft-go i{width:17px;height:17px}

/* statement / content cards */
.stmt-card{border-radius:20px;overflow:hidden;border:1px solid var(--line);background:var(--surface);box-shadow:0 14px 40px -26px rgba(15,23,42,.5)}
.stmt-cap{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:18px 22px 16px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.stmt-cap .tt{display:flex;align-items:center;gap:11px}
.stmt-cap .cap-ic{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:12px;color:#fff;background:var(--cap,#10b981);box-shadow:0 6px 16px -8px var(--cap,#10b981);flex:none}
.stmt-cap h3{margin:0;font-size:1.18rem;letter-spacing:-.3px}
.stmt-cap .cap-sub{font-size:.74rem;color:var(--ink-subtle)}
.stmt-body{padding:8px 22px 22px}

.fin .grp-h{display:flex;align-items:center;gap:9px;margin:20px 0 6px;font-size:.72rem;font-weight:800;letter-spacing:.7px;text-transform:uppercase;color:var(--ink-subtle)}
.fin .grp-h::before{content:"";width:10px;height:10px;border-radius:3px;background:var(--gc,var(--brand));flex:none}
.fin .grp-h:first-child{margin-top:6px}

.fin .r{display:flex;justify-content:space-between;gap:16px;align-items:baseline;padding:7px 10px;border-radius:9px;font-size:.9rem;transition:background .12s}
.fin .r:hover{background:var(--band)}
.fin .r .lbl{color:var(--ink-muted)}
.fin .r.child{padding-left:26px}
.fin .r.child .lbl{position:relative}
.fin .r.child .lbl::before{content:"";position:absolute;left:-14px;top:.55em;width:6px;height:1px;background:var(--line)}
.fin .r .num{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600;color:var(--ink)}
.fin .r.head{font-weight:700}.fin .r.head .lbl{color:var(--ink)}
.fin .num.neg{color:var(--neg)}.fin .num.pos{color:var(--pos)}
.fin .r.sub{margin-top:3px;background:var(--band);font-weight:750}
.fin .r.sub .lbl{color:var(--ink);font-weight:750}
.fin .r.sub .num{font-weight:800}

/* highlight bands */
.fin .band{display:flex;justify-content:space-between;align-items:center;gap:14px;margin:14px 0 4px;padding:14px 18px;border-radius:14px;font-weight:800}
.fin .band .bl{font-size:.96rem;letter-spacing:-.2px}
.fin .band .bn{font-size:1.28rem;font-variant-numeric:tabular-nums;letter-spacing:-.5px}
.fin .band.soft{background:var(--band)}
.fin .band.pos{background:linear-gradient(135deg,rgba(16,185,129,.16),rgba(5,150,105,.10));color:var(--pos);border:1px solid rgba(16,185,129,.30)}
.fin .band.neg{background:linear-gradient(135deg,rgba(244,63,94,.16),rgba(225,29,72,.10));color:var(--neg);border:1px solid rgba(244,63,94,.30)}
.fin .band.hero{padding:18px 20px;color:#fff;border:0}
.fin .band.hero.pos{background:linear-gradient(135deg,#10b981,#059669);box-shadow:0 12px 30px -14px #059669}
.fin .band.hero.neg{background:linear-gradient(135deg,#fb7185,#e11d48);box-shadow:0 12px 30px -14px #e11d48}
.fin .band.hero .bn{font-size:1.5rem}

.bal-pill{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:999px;font-size:.76rem;font-weight:800}
.bal-pill.ok{background:rgba(16,185,129,.16);color:var(--pos)}
.bal-pill.off{background:rgba(244,63,94,.16);color:var(--neg)}

@media print{
  .fin-tile{color:#111 !important;background:#fff !important;border:1px solid #ddd;box-shadow:none !important}
  .fin-tile .ft-ic,.fin-tile .ft-go{display:none}
  .stmt-card{box-shadow:none !important;border:1px solid #ddd !important}
  .fin .band.hero{color:#111 !important;background:#fff !important;border:1px solid #ddd !important;box-shadow:none !important}
}

/* ---------------------------------------------------------------------------
   Composition donut — the client invoice's breakdown chart, reused in-app.
   Plain SVG plus a legend: no chart library, prints as it renders, and reads
   as a ranking because the largest slice always leads.
   --------------------------------------------------------------------------- */
.fd-wrap { display: flex; gap: 22px; align-items: center; flex-wrap: wrap; }
.fd-ring { flex: none; }
.fd-ring .fd-v { font-size: 12px; font-weight: 800; fill: var(--ink); }
.fd-ring .fd-l { font-size: 6px; fill: var(--ink-subtle); font-weight: 700; letter-spacing: .5px; }
.fd-legend { flex: 1; min-width: 240px; }
.fd-row {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto 44px;
  align-items: center;
  gap: 9px;
  padding: 4px 0;
  font-size: .82rem;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.fd-row:last-child { border-bottom: 0; }
.fd-dot { width: 10px; height: 10px; border-radius: 3px; }
.fd-nm { color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-amt { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.fd-pc { text-align: right; font-weight: 700; color: var(--ink-subtle); font-variant-numeric: tabular-nums; }
@media (max-width: 560px) {
  .fd-wrap { gap: 14px; }
  .fd-row { grid-template-columns: 10px minmax(0, 1fr) auto; }
  .fd-pc { display: none; }
}

/* Treasury — the per-account rows behind the headline figures. */
.tr-accts { display: grid; gap: 6px; margin-top: 16px; padding-top: 14px; border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
.tr-acct {
  display: grid; grid-template-columns: 26px minmax(0, 1fr) auto;
  align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 10px; text-decoration: none;
  transition: background .14s ease;
}
.tr-acct:hover { background: color-mix(in srgb, var(--brand) 8%, transparent); }
.tr-ic { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; background: color-mix(in srgb, var(--brand) 12%, transparent); color: var(--brand); }
.tr-nm { min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.tr-nm b { font-size: .84rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tr-bal { font-size: .9rem; font-variant-numeric: tabular-nums; color: var(--ink); }

/* ============================================================================
   Requisition forms — shared between the project and Head-Office requisition.

   Both forms ask exactly one question at the top ("is this a purchase or a cash
   advance?") and then let the LINES decide what kind of purchase it is. The type
   is shown back as a derived summary, never as a second control, so nothing is
   asked for twice.
   ========================================================================= */
.req-mode { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.req-mode__opt { position: relative; cursor: pointer; margin: 0; }
.req-mode__opt input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.req-mode__body {
  display: block;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.req-mode__body svg { width: 18px; height: 18px; color: var(--ink-subtle); }
.req-mode__body b { display: block; margin: 6px 0 2px; color: var(--ink); }
.req-mode__opt input:checked + .req-mode__body {
  border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 7%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 14%, transparent);
}
.req-mode__opt input:checked + .req-mode__body svg { color: var(--brand); }
.req-mode__opt input:focus-visible + .req-mode__body { outline: 2px solid var(--brand); outline-offset: 2px; }
@media (max-width: 620px) { .req-mode { grid-template-columns: 1fr; } }

/* The requisition type, shown back as a read-only summary of what the lines say. */
.req-derived {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px;
  border: 1px solid color-mix(in srgb, var(--brand) 22%, var(--line));
  border-radius: 12px;
  background: linear-gradient(145deg, color-mix(in srgb, var(--brand-soft) 75%, var(--surface)), var(--surface));
}
.req-derived__meta { display: flex; align-items: center; gap: 10px; min-width: 0; font-weight: 600; color: var(--ink); }
.req-derived__meta svg { width: 16px; height: 16px; }
.req-derived__icon {
  width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--brand) 18%, transparent); color: var(--brand); flex: none;
}
.req-derived .badge { flex: none; }

/* ============================================================================
   Chart of Accounts — drag & drop.

   The grip is the only drag surface, so selecting text, ticking checkboxes and
   clicking links inside a row all still behave normally.
   ========================================================================= */
.coa-grip {
  cursor: grab; color: var(--ink-subtle); text-align: center;
  padding-left: 6px; padding-right: 0; touch-action: none; user-select: none;
  border-radius: 7px; transition: color .14s ease, background .14s ease;
}
.coa-grip:hover { color: var(--brand); background: color-mix(in srgb, var(--brand) 10%, transparent); }
.coa-grip:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; color: var(--brand); }
body.coa-dragging { cursor: grabbing; user-select: none; }
body.coa-dragging .coa-grip { cursor: grabbing; }
/* The handle reads as a handle: a small raised pill, not a faint glyph. Hovering a row
   lights its handle, so it is clear WHICH part of the row picks it up. */
.coa-grip__pill {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 26px; border-radius: 7px;
  border: 1px dashed var(--line-strong); background: var(--surface);
  transition: border-color .14s ease, background .14s ease, color .14s ease;
}
.coa-row:hover .coa-grip { color: var(--brand); }
.coa-row:hover .coa-grip__pill, .coa-grip:focus-visible .coa-grip__pill {
  border-style: solid; border-color: color-mix(in srgb, var(--brand) 55%, var(--line));
  background: color-mix(in srgb, var(--brand) 8%, var(--surface));
}
.coa-grip:active .coa-grip__pill { background: color-mix(in srgb, var(--brand) 18%, var(--surface)); }
.coa-row:hover > td { background-color: color-mix(in srgb, var(--brand) 4%, transparent); }
body.coa-dragging .coa-row:hover > td { background-color: transparent; }

/* The instructions, where the eye is when it reaches the chart. */
.coa-hint {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 12px 22px; padding: 8px 12px; border-radius: 10px; font-size: .8rem;
  background: color-mix(in srgb, var(--brand) 7%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--brand) 22%, var(--line)); color: var(--ink);
}
.coa-hint kbd {
  font: 600 .72rem ui-monospace, SFMono-Regular, Menlo, monospace;
  padding: 1px 6px; border-radius: 5px; border: 1px solid var(--line-strong); background: var(--surface);
}

/* The heading a head would be filed INSIDE — the main head it will belong to. */
.coa-row.is-drop-into > td {
  background: color-mix(in srgb, var(--brand) 14%, var(--surface)) !important;
  box-shadow: inset 0 2px 0 var(--brand), inset 0 -2px 0 var(--brand);
}
.coa-row.is-drop-into.is-drop-blocked > td {
  background: color-mix(in srgb, var(--danger) 12%, var(--surface)) !important;
  box-shadow: inset 0 2px 0 var(--danger), inset 0 -2px 0 var(--danger);
}

/* The lifted rows stay in place, faded, so the chart keeps its shape while you carry
   the head around — losing the row you dragged from is disorienting. */
.coa-row.is-lifted > td { opacity: .35; }
.coa-row.is-source > td { opacity: .3; }

/* What you are carrying. */
.coa-ghost {
  position: fixed; top: 0; left: 0; z-index: 90; pointer-events: none;
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px; border-radius: 11px;
  background: var(--surface); color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--brand) 45%, var(--line));
  box-shadow: 0 12px 30px rgba(0, 0, 0, .22), 0 0 0 4px color-mix(in srgb, var(--brand) 14%, transparent);
  font-size: .84rem; max-width: 60vw;
  transform: translate(-9999px, -9999px);
}
.coa-ghost__code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 700; color: var(--brand); }
.coa-ghost__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.coa-ghost__n {
  flex: none; font-size: .72rem; font-weight: 700; padding: 2px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand);
}
.coa-ghost__hint { flex: none; font-size: .7rem; color: var(--ink-subtle); }
/* Off the chart: releasing here cancels, and the card says so. */
.coa-ghost.is-cancel { border-color: var(--line-strong); box-shadow: 0 12px 30px rgba(0, 0, 0, .22); opacity: .75; }
.coa-ghost.is-cancel .coa-ghost__hint { color: var(--danger); font-weight: 700; }

/* Where it will land. The bar is inset to the target INDENT, so the level it will sit at
   is visible before the drop — that is the difference between "somewhere near here" and
   "inside this heading". */
.coa-bar { position: fixed; z-index: 89; pointer-events: none; height: 0; }
.coa-bar::before {
  content: ''; position: absolute; left: var(--coa-indent, 0); right: 0; top: -1px; height: 2px;
  background: var(--brand); border-radius: 2px;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent);
}
.coa-bar::after {
  content: ''; position: absolute; left: var(--coa-indent, 0); top: -5px;
  width: 10px; height: 10px; border-radius: 50%; background: var(--brand);
  transform: translateX(-4px);
}
.coa-bar__tip {
  position: absolute; left: var(--coa-indent, 0); top: 8px;
  background: var(--ink); color: var(--surface);
  padding: 5px 11px; border-radius: 8px; font-size: .76rem; font-weight: 600;
  white-space: nowrap; max-width: 84vw; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .2);
}
.coa-bar.is-blocked::before, .coa-bar.is-blocked::after { background: var(--danger); box-shadow: none; }
.coa-bar.is-blocked .coa-bar__tip { background: var(--danger); }

/* Landing, and being renumbered, both get a moment so the change is seen. */
@keyframes coa-settle { from { background: color-mix(in srgb, var(--brand) 22%, transparent); } to { background: transparent; } }
@keyframes coa-reject { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
.coa-row.is-settling > td { animation: coa-settle .7s ease-out; }
.coa-row.is-rejected > td { animation: coa-reject .3s ease-in-out 2; background: color-mix(in srgb, var(--danger) 12%, transparent); }
.coa-row.is-recoded [data-code-text] {
  animation: coa-settle 1.2s ease-out; border-radius: 5px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 16%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .coa-row.is-settling > td, .coa-row.is-rejected > td, .coa-row.is-recoded [data-code-text] { animation: none; }
}

.coa-toast {
  position: fixed; left: 50%; bottom: 26px; z-index: 95;
  transform: translate(-50%, 14px); opacity: 0; pointer-events: none;
  background: var(--ink); color: var(--surface);
  padding: 10px 18px; border-radius: 999px; font-size: .82rem; font-weight: 600;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .24); max-width: 90vw; text-align: center;
  transition: opacity .18s ease, transform .18s ease;
}
.coa-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
.coa-toast.is-bad { background: var(--danger); color: #fff; }

/* Visually hidden, still announced — used for live regions that narrate an action
   (a chart-of-accounts move) to a screen reader without putting text on the page. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ============================================================================
   Vendor invoice — the money block in the header.

   A part-paid invoice raises a question that a single "Total Payable" cannot answer, so
   this reads as a small statement: what was billed, what has been paid, what is left.
   ========================================================================= */
.bill-sum {
  padding: 14px 16px; border-radius: 14px;
  border: 1px solid var(--line); background: var(--surface-2);
}
.bill-sum__row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.bill-sum__row + .bill-sum__row { margin-top: 7px; }
.bill-sum__row--head {
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line);
  align-items: center; font-weight: 700;
}
.bill-sum__big { font-size: 1.6rem; font-weight: 740; letter-spacing: -.02em; line-height: 1.05; }

/* The stored figure and the ledger have parted company — say so where it is seen. */
.bill-drift {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 12px 14px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--warning) 45%, var(--line));
  background: color-mix(in srgb, var(--warning) 8%, transparent);
}
.bill-drift svg { width: 17px; height: 17px; color: var(--warning); flex: none; margin-top: 2px; }

/* Pay-invoice modal — the three figures the person paying is deciding between. */
.pay-figures {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 2px;
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--line);
}
.pay-figures > div { background: var(--surface-2); padding: 11px 14px; display: flex; flex-direction: column; gap: 3px; }
.pay-figures b { font-size: 1.05rem; }
.pay-figures__due { background: color-mix(in srgb, var(--brand) 9%, var(--surface)) !important; }
.pay-figures__due b { font-size: 1.3rem; font-weight: 740; letter-spacing: -.02em; color: var(--brand); }

/* A file field that looks like the rest of the form, instead of the browser's grey
   "Choose file / No file chosen" control. */
.filedrop {
  display: flex; align-items: center; gap: 11px; cursor: pointer;
  padding: 11px 13px; border: 1px dashed var(--line-strong); border-radius: 11px;
  background: var(--surface-2); transition: border-color .15s ease, background .15s ease;
}
.filedrop:hover { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 6%, var(--surface-2)); }
.filedrop svg { width: 17px; height: 17px; color: var(--ink-subtle); flex: none; }
.filedrop__text { flex: 1; min-width: 0; font-size: .85rem; color: var(--ink-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filedrop:focus-within { outline: 2px solid var(--brand); outline-offset: 2px; }
.filedrop.has-file { border-style: solid; border-color: var(--brand); background: color-mix(in srgb, var(--brand) 7%, var(--surface)); }
.filedrop.has-file .filedrop__text { color: var(--ink); font-weight: 600; }
.filedrop.has-file svg { color: var(--brand); }

/* ============================================================================
   "Awaiting your review" rows.

   A wrapping flex row put the action wherever the text happened to leave room, so the
   Review button sat mid-row on long titles and hard right on short ones — the eye had to
   hunt for it on every line. A grid fixes the three zones: badge, content, action. The
   action column is sized to its content and pinned right, so every button lands in the
   same place no matter how long the title is.
   ========================================================================= */
.review-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  padding: 15px 22px;
  border-bottom: 1px solid var(--line);
  transition: background var(--dur);
}
.review-row:last-child { border-bottom: 0; }
.review-row:hover { background: var(--surface-2); }
.review-row__body { min-width: 0; }
.review-row__title {
  display: block; font-weight: 650; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.review-row__meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  margin-top: 4px; font-size: 0.78rem; color: var(--ink-subtle); min-width: 0;
}
.review-row__meta .sep { color: var(--line-strong); }
/* The status chips ride with the content, not with the button — they describe the item. */
.review-row__tags { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 7px; }
.review-row__act {
  display: flex; align-items: center; gap: 12px; flex: none;
  justify-self: end; white-space: nowrap;
}
.review-row__age { font-size: 0.76rem; color: var(--ink-subtle); }

@media (max-width: 760px) {
  .review-row { grid-template-columns: auto minmax(0, 1fr); row-gap: 12px; }
  .review-row__act { grid-column: 2; justify-self: start; }
}

/* ============================================================================
   Document attachments — the supporting files that make up one submission
   (a BOQ with its measurement sheet and bar-bending schedule).
   ========================================================================= */
.attach-list { display: grid; gap: 8px; margin-top: 10px; }
.attach-row {
  display: grid; grid-template-columns: auto minmax(0, 1.4fr) minmax(0, 1fr) auto auto;
  align-items: center; gap: 10px;
  padding: 9px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface-2);
}
.attach-row > svg { width: 16px; height: 16px; color: var(--ink-subtle); }
.attach-row__name { font-size: .84rem; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-row__label { height: 32px; font-size: .8rem; }
.attach-row__size { font-size: .75rem; color: var(--ink-subtle); font-variant-numeric: tabular-nums; }
@media (max-width: 720px) {
  .attach-row { grid-template-columns: auto minmax(0, 1fr) auto; }
  .attach-row__label { grid-column: 2 / -1; }
}

/* On the document page: the whole submission, each part openable on its own. */
.att-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.att-card {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 13px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); transition: border-color .15s ease, box-shadow .15s ease;
  min-width: 0;
}
.att-card:hover { border-color: var(--brand); box-shadow: 0 3px 12px rgba(0, 0, 0, .07); }
.att-card__ic {
  width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center; flex: none;
  background: color-mix(in srgb, var(--brand) 12%, transparent); color: var(--brand);
  font-size: .62rem; font-weight: 800; letter-spacing: .02em;
}
.att-card__body { min-width: 0; flex: 1; }
.att-card__name { display: block; font-size: .83rem; font-weight: 640; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-card__meta { font-size: .72rem; color: var(--ink-subtle); }
.att-card__act { display: flex; gap: 2px; flex: none; }
.att-card.is-primary { border-color: color-mix(in srgb, var(--brand) 40%, var(--line));
  background: color-mix(in srgb, var(--brand) 5%, var(--surface)); }

/* ============================================================================
   Upload progress.

   A large file needs to show that it is moving, how fast, and how much longer —
   otherwise it is indistinguishable from a hang.
   ========================================================================= */
.up-panel {
  margin-top: 16px; padding: 14px 16px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--brand) 30%, var(--line));
  background: color-mix(in srgb, var(--brand) 6%, var(--surface));
}
.up-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.up-title { font-weight: 650; color: var(--ink); font-size: .92rem; }
.up-track {
  height: 8px; border-radius: 999px; margin: 11px 0 9px;
  background: color-mix(in srgb, var(--ink) 10%, transparent); overflow: hidden;
}
.up-bar {
  height: 100%; border-radius: 999px; background: var(--brand);
  transition: width .2s ease;
  background-image: linear-gradient(90deg,
    color-mix(in srgb, var(--brand) 78%, white) 0%, var(--brand) 60%);
}
.up-meta {
  display: flex; flex-wrap: wrap; gap: 4px 16px;
  font-size: .78rem; color: var(--ink-muted); font-variant-numeric: tabular-nums;
}
.up-meta > span:first-child { font-weight: 700; color: var(--ink); }
.up-note { margin: 8px 0 0; font-size: .76rem; color: var(--ink-subtle); }

/* All bytes sent, server still writing — a barber-pole says "working", not "stuck". */
.up-panel.is-finishing .up-bar {
  background-image: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--brand) 70%, white) 0 10px, var(--brand) 10px 20px);
  animation: up-stripe 1s linear infinite;
}
@keyframes up-stripe { from { background-position: 0 0; } to { background-position: 28px 0; } }

.up-panel.is-error {
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 7%, var(--surface));
}
.up-panel.is-error .up-bar { background: var(--danger); background-image: none; animation: none; }
.up-panel.is-error .up-note { color: var(--danger); }
@media (prefers-reduced-motion: reduce) {
  .up-bar { transition: none; }
  .up-panel.is-finishing .up-bar { animation: none; }
}

/* ============================================================================
   Risk matrix — probability (rows, most likely at the top) × impact (columns).
   The colour IS the score, so the shape of the portfolio's risk reads before any
   number is looked at.
   ========================================================================= */
.rmx { display: grid; grid-template-columns: 34px repeat(5, 1fr); gap: 5px; }
.rmx__ax {
  display: grid; place-items: center; font-size: .7rem; font-weight: 700;
  color: var(--ink-subtle); font-variant-numeric: tabular-nums;
}
.rmx__cell {
  min-height: 54px; border-radius: 9px; display: flex; flex-wrap: wrap; gap: 4px;
  align-items: center; justify-content: center; padding: 6px;
  border: 1px solid var(--line);
}
.rmx__cell.t-success { background: color-mix(in srgb, var(--success) 12%, transparent); }
.rmx__cell.t-warning { background: color-mix(in srgb, var(--warning) 16%, transparent); }
.rmx__cell.t-danger  { background: color-mix(in srgb, var(--danger) 18%, transparent); }
.rmx__dot {
  font-size: .68rem; font-weight: 800; letter-spacing: .02em;
  padding: 3px 7px; border-radius: 999px;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line-strong);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
}
@media (max-width: 620px) { .rmx__cell { min-height: 42px; } }


/* ---- requisition line-item table ---- */
/* One definition for BOTH requisition forms. The project form had drifted into a
   fixed 1040px table that squeezed its own controls until "Material" read "Mate";
   the head-office form already had this treatment. Sharing it is what stops them
   diverging again. */
  .req-items-wrap { overflow-x: clip; }
  .req-items { width: 100%; table-layout: fixed; }
  .req-items thead th {
    position: static;
    white-space: normal;
    line-height: 1.25;
    padding: 11px 6px;
  }
  .req-items tbody td,
  .req-items tfoot td { padding: 10px 6px; }
  .req-items th:first-child,
  .req-items td:first-child { padding-left: 12px; }
  /* The remove column is a fixed 46px — keep the trash button fully inside the card. */
  .req-items th:last-child,
  .req-items td:last-child { padding-left: 2px; padding-right: 8px; }
  .req-items td[data-cell="remove"] { text-align: center; }
  .req-items td[data-cell="remove"] .icon-btn { margin: 0 auto; }
  .req-items .input,
  .req-items .select {
    width: 100%;
    min-width: 0;
    height: 38px;
    font-size: 0.84rem;
  }
  .req-items [data-po-amount] { white-space: nowrap; }
  .req-actions { justify-content: flex-end; }

  @media (max-width: 1100px) {
    .req-form .form-grid { grid-template-columns: 1fr; }
    .req-form .form-grid .field,
    .req-form .form-grid .col-span-2 { grid-column: auto; }
    .req-items-wrap { overflow: visible; }
    .req-items thead { display: none; }
    .req-items,
    .req-items tbody,
    .req-items tr,
    .req-items td,
    .req-items tfoot { display: block; width: 100%; }
    .req-items tbody tr {
      border: 1px solid var(--line);
      border-radius: 14px;
      padding: 12px;
      margin-bottom: 10px;
      background: var(--surface);
    }
    .req-items tbody td {
      border: 0;
      padding: 0;
      margin-bottom: 10px;
    }
    .req-items tbody td:last-child { margin-bottom: 0; }
    .req-items tbody td[data-label]::before {
      content: attr(data-label);
      display: block;
      font-size: 0.68rem;
      text-transform: uppercase;
      letter-spacing: 0.06em;
      color: var(--ink-subtle);
      margin-bottom: 6px;
      font-weight: 700;
    }
    .req-items td[data-cell="amount"] {
      text-align: left;
      font-size: 0.94rem;
    }
    .req-items td[data-cell="remove"] {
      display: flex;
      justify-content: flex-end;
    }
    .req-items tfoot {
      margin-top: 12px;
      border-top: 1px solid var(--line);
      padding-top: 10px;
    }
    .req-items tfoot tr {
      display: grid;
      grid-template-columns: 1fr auto;
      gap: 10px;
      align-items: center;
    }
    .req-items tfoot td {
      border: 0;
      padding: 0;
    }
    .req-items tfoot td:last-child { display: none; }
    .req-actions { flex-wrap: wrap; }
    .req-actions .btn { width: 100%; justify-content: center; }
  }



/* ---- requisition lines: a card per line, not a spreadsheet row ---- */
/* Eight controls will never sit comfortably in one table row: at any realistic width the
   columns squeeze until "Material" reads "Mate" and "— unit —" reads "— un". A line is
   given its own card instead, with every field labelled and full-size, and the grid wraps
   rather than truncating. */
.req-lines { display: flex; flex-direction: column; gap: 14px; }

.req-line {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface);
  padding: 16px 56px 16px 18px;
  display: grid;
  gap: 14px 16px;
  grid-template-columns: minmax(150px, 0.8fr) minmax(230px, 1.6fr) minmax(190px, 1.1fr);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.req-line:hover { border-color: var(--line-strong); }
.req-line:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 12%, transparent);
}

.req-line__f { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.req-line__f > label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-subtle);
}
.req-line .input,
.req-line .select {
  width: 100%;
  min-width: 0;
  height: 44px;
  font-size: 0.92rem;
  padding-inline: 13px;
}
.req-line .select { padding-right: 34px; }

/* The money row sits on its own line so qty / unit / rate / amount all stay legible. */
.req-line__money {
  grid-column: 1 / -1;
  display: grid;
  gap: 14px 16px;
  grid-template-columns: minmax(96px, .5fr) minmax(140px, .7fr) minmax(120px, .6fr) minmax(130px, .7fr);
  align-items: end;
  border-top: 1px dashed var(--line);
  padding-top: 14px;
}
.req-line__amount {
  display: flex; flex-direction: column; gap: 6px;
  justify-content: flex-end; min-width: 0;
}
.req-line__amount b {
  font-size: 1.18rem;
  font-variant-numeric: tabular-nums;
  line-height: 44px;
  white-space: nowrap;
}
.req-line__no {
  position: absolute; top: 16px; left: -1px;
  width: 4px; height: 26px; border-radius: 0 4px 4px 0;
  background: var(--brand); opacity: .5;
}
.req-line__del {
  position: absolute; top: 12px; right: 12px;
}

.req-lines__foot {
  display: flex; justify-content: flex-end; align-items: baseline; gap: 14px;
  padding: 16px 18px 2px; border-top: 1px solid var(--line); margin-top: 4px;
}
.req-lines__foot b { font-size: 1.3rem; font-variant-numeric: tabular-nums; }

@media (max-width: 900px) {
  .req-line { grid-template-columns: 1fr; padding-right: 18px; }
  .req-line__del { position: static; align-self: flex-end; }
  .req-line__money { grid-template-columns: 1fr 1fr; }
}
