/* ======================================================================
   PropLens — the whole design system, one file, no build step.

   Six palettes on one axis, light / dark / system on the other. Every
   colour in the sheet comes from a token, so a palette is a block of
   custom properties and nothing else. Forest is the default: warm
   off-white ground, deep green accent.

   Structure never varies between themes — 10px cards, hairline rules,
   one soft shadow, IBM Plex Sans for text and JetBrains Mono for
   figures.
   ====================================================================== */

/* ---- Self-hosted faces. No network call, no layout shift. ---- */
@font-face{font-family:"IBM Plex Sans";src:url("../fonts/IBMPlexSans-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Sans";src:url("../fonts/IBMPlexSans-500.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Sans";src:url("../fonts/IBMPlexSans-600.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url("../fonts/JetBrainsMono-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url("../fonts/JetBrainsMono-500.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}

/* ======================================================================
   Tokens
   ====================================================================== */

:root{--rowpad:11px;--navw:236px;--canvas:#f4f4f1;--surface:#ffffff;--surface-alt:#fafaf8;--sunken:#eeeeea;--ink:#141715;--ink-soft:#3a3f3c;--ink-muted:#6c7370;--ink-faint:#9aa19d;--line:#e2e3de;--line-strong:#cfd1cb;--accent:#1f4b43;--accent-ink:#ffffff;--accent-soft:#e8efec;--ok:#1a7a3c;--ok-bg:#eaf4ed;--warn:#9a6206;--warn-bg:#fbf2e3;--danger:#b3261e;--danger-bg:#fbecea;--info:#2b5c8f;--info-bg:#eaf1f8;--shadow:0 1px 2px rgba(20,23,21,.07)}

:root[data-theme="forest"]{--canvas:#f4f4f1;--surface:#ffffff;--surface-alt:#fafaf8;--sunken:#eeeeea;--ink:#141715;--ink-soft:#3a3f3c;--ink-muted:#6c7370;--ink-faint:#9aa19d;--line:#e2e3de;--line-strong:#cfd1cb;--accent:#1f4b43;--accent-ink:#ffffff;--accent-soft:#e8efec;--ok:#1a7a3c;--ok-bg:#eaf4ed;--warn:#9a6206;--warn-bg:#fbf2e3;--danger:#b3261e;--danger-bg:#fbecea;--info:#2b5c8f;--info-bg:#eaf1f8;--shadow:0 1px 2px rgba(20,23,21,.07)}
:root[data-theme="graphite"]{--canvas:#f4f4f4;--surface:#ffffff;--surface-alt:#fafafa;--sunken:#efefef;--ink:#000000;--ink-soft:#333333;--ink-muted:#6b6b6b;--ink-faint:#9a9a9a;--line:#e0e0e0;--line-strong:#cccccc;--accent:#1a1a1a;--accent-ink:#ffffff;--accent-soft:#f0f0f0;--ok:#1b8a2a;--ok-bg:#eef7ef;--warn:#c77d00;--warn-bg:#fbf3e6;--danger:#c62828;--danger-bg:#fbeded;--info:#2b5c8f;--info-bg:#edf2f8;--shadow:0 1px 2px rgba(0,0,0,.07)}
:root[data-theme="slate"]{--canvas:#f2f5f8;--surface:#ffffff;--surface-alt:#f6f8fa;--sunken:#eceff3;--ink:#10151b;--ink-soft:#2c3742;--ink-muted:#5f6c7b;--ink-faint:#93a1b0;--line:#dfe5ec;--line-strong:#c3ccd6;--accent:#2b5c8f;--accent-ink:#ffffff;--accent-soft:#e9f1f8;--ok:#1b7f3b;--ok-bg:#edf6f0;--warn:#b06f00;--warn-bg:#fbf3e4;--danger:#c02b2b;--danger-bg:#fbecec;--info:#2b5c8f;--info-bg:#e9f1f8;--shadow:0 1px 2px rgba(16,21,27,.08)}
:root[data-theme="sand"]{--canvas:#f6f3ec;--surface:#fffdf9;--surface-alt:#f3efe7;--sunken:#ebe6da;--ink:#221d16;--ink-soft:#4a4238;--ink-muted:#7a7060;--ink-faint:#a79c8a;--line:#e3ddd0;--line-strong:#cfc7b5;--accent:#8a5a2b;--accent-ink:#ffffff;--accent-soft:#f2e9dd;--ok:#4a7c2f;--ok-bg:#eef4e8;--warn:#a06a00;--warn-bg:#f9f0de;--danger:#a83224;--danger-bg:#f9eae7;--info:#3f6b7d;--info-bg:#eaf1f4;--shadow:0 1px 2px rgba(34,29,22,.08)}
:root[data-theme="forest"][data-mode="dark"]{--canvas:#0e1110;--surface:#161a19;--surface-alt:#1b201e;--sunken:#101413;--ink:#e9ebe9;--ink-soft:#c2c7c4;--ink-muted:#8a918d;--ink-faint:#636a66;--line:#262b29;--line-strong:#353b38;--accent:#6fc0ae;--accent-ink:#0e1110;--accent-soft:#17251f;--ok:#54b072;--ok-bg:#152218;--warn:#d29b3a;--warn-bg:#241d10;--danger:#e0736a;--danger-bg:#251715;--info:#7fb0dd;--info-bg:#141f29;--shadow:0 1px 2px rgba(0,0,0,.35)}
:root[data-theme="graphite"][data-mode="dark"]{--canvas:#131313;--surface:#191919;--surface-alt:#1f1f1f;--sunken:#101010;--ink:#ededed;--ink-soft:#c9c9c9;--ink-muted:#8f8f8f;--ink-faint:#666666;--line:#2c2c2c;--line-strong:#3d3d3d;--accent:#ededed;--accent-ink:#131313;--accent-soft:#252525;--ok:#4faf63;--ok-bg:#1a271d;--warn:#d99a2b;--warn-bg:#2a2417;--danger:#e56b6b;--danger-bg:#2a1c1c;--info:#7fb0dd;--info-bg:#161f27;--shadow:0 1px 2px rgba(0,0,0,.4)}
:root[data-theme="slate"][data-mode="dark"]{--canvas:#0f151b;--surface:#151d25;--surface-alt:#1b242e;--sunken:#101820;--ink:#e4eaf0;--ink-soft:#bcc7d3;--ink-muted:#8494a3;--ink-faint:#5d6b79;--line:#26313c;--line-strong:#354350;--accent:#7fb3e0;--accent-ink:#0f151b;--accent-soft:#1c2833;--ok:#4fae6c;--ok-bg:#16261c;--warn:#d09a3c;--warn-bg:#28231a;--danger:#e0706f;--danger-bg:#2a1c1e;--info:#7fb3e0;--info-bg:#16232e;--shadow:0 1px 2px rgba(0,0,0,.38)}
:root[data-theme="sand"][data-mode="dark"]{--canvas:#14110d;--surface:#1b1712;--surface-alt:#221d16;--sunken:#100d09;--ink:#ece5d8;--ink-soft:#c8bfae;--ink-muted:#948a78;--ink-faint:#6b6355;--line:#2a251c;--line-strong:#3a3428;--accent:#d9a066;--accent-ink:#14110d;--accent-soft:#241d14;--ok:#79b061;--ok-bg:#1a2415;--warn:#d2a03c;--warn-bg:#282014;--danger:#e0806f;--danger-bg:#2a1a16;--info:#8fb8c9;--info-bg:#16222a;--shadow:0 1px 2px rgba(0,0,0,.4)}
:root[data-theme="black"]{--canvas:#ffffff;--surface:#ffffff;--surface-alt:#f7f7f7;--sunken:#ededed;--ink:#000000;--ink-soft:#2b2b2b;--ink-muted:#606060;--ink-faint:#909090;--line:#dcdcdc;--line-strong:#bdbdbd;--accent:#000000;--accent-ink:#ffffff;--accent-soft:#ececec;--ok:#1b7a2e;--ok-bg:#eff6f0;--warn:#8a5a00;--warn-bg:#f7f1e4;--danger:#b02318;--danger-bg:#f9ebe9;--info:#20406b;--info-bg:#eceff4;--shadow:0 1px 2px rgba(0,0,0,.09)}
:root[data-theme="blue"]{--canvas:#eef3fb;--surface:#ffffff;--surface-alt:#f5f8fd;--sunken:#e4ebf7;--ink:#0d1b2e;--ink-soft:#26364f;--ink-muted:#5a6b85;--ink-faint:#8d9cb4;--line:#d9e2f0;--line-strong:#bcc9de;--accent:#1d4ed8;--accent-ink:#ffffff;--accent-soft:#e5ecfd;--ok:#12784a;--ok-bg:#e8f5ef;--warn:#a35d00;--warn-bg:#fbf1e2;--danger:#bc2b26;--danger-bg:#fbeceb;--info:#1d4ed8;--info-bg:#e5ecfd;--shadow:0 1px 2px rgba(13,27,46,.09)}
:root[data-theme="black"][data-mode="dark"]{--canvas:#000000;--surface:#0c0c0c;--surface-alt:#141414;--sunken:#080808;--ink:#f2f2f2;--ink-soft:#cfcfcf;--ink-muted:#8d8d8d;--ink-faint:#5e5e5e;--line:#222222;--line-strong:#333333;--accent:#ffffff;--accent-ink:#000000;--accent-soft:#1c1c1c;--ok:#54b26a;--ok-bg:#132015;--warn:#d59c34;--warn-bg:#241d10;--danger:#e0685f;--danger-bg:#251512;--info:#89aede;--info-bg:#131b26;--shadow:0 1px 2px rgba(0,0,0,.6)}
:root[data-theme="blue"][data-mode="dark"]{--canvas:#08101f;--surface:#0e1829;--surface-alt:#142136;--sunken:#0a1322;--ink:#e6ecf7;--ink-soft:#bcc9de;--ink-muted:#8496b3;--ink-faint:#5b6c8a;--line:#1e2c45;--line-strong:#2c3d5c;--accent:#7ba7f5;--accent-ink:#08101f;--accent-soft:#16253c;--ok:#4fb07d;--ok-bg:#12241b;--warn:#d3a044;--warn-bg:#251f12;--danger:#e0736d;--danger-bg:#271719;--info:#7ba7f5;--info-bg:#16253c;--shadow:0 1px 2px rgba(0,0,0,.45)}

@media (prefers-color-scheme: dark) {
  :root[data-theme="forest"][data-mode="system"]{--canvas:#0e1110;--surface:#161a19;--surface-alt:#1b201e;--sunken:#101413;--ink:#e9ebe9;--ink-soft:#c2c7c4;--ink-muted:#8a918d;--ink-faint:#636a66;--line:#262b29;--line-strong:#353b38;--accent:#6fc0ae;--accent-ink:#0e1110;--accent-soft:#17251f;--ok:#54b072;--ok-bg:#152218;--warn:#d29b3a;--warn-bg:#241d10;--danger:#e0736a;--danger-bg:#251715;--info:#7fb0dd;--info-bg:#141f29;--shadow:0 1px 2px rgba(0,0,0,.35)}
  :root[data-theme="graphite"][data-mode="system"]{--canvas:#131313;--surface:#191919;--surface-alt:#1f1f1f;--sunken:#101010;--ink:#ededed;--ink-soft:#c9c9c9;--ink-muted:#8f8f8f;--ink-faint:#666666;--line:#2c2c2c;--line-strong:#3d3d3d;--accent:#ededed;--accent-ink:#131313;--accent-soft:#252525;--ok:#4faf63;--ok-bg:#1a271d;--warn:#d99a2b;--warn-bg:#2a2417;--danger:#e56b6b;--danger-bg:#2a1c1c;--info:#7fb0dd;--info-bg:#161f27;--shadow:0 1px 2px rgba(0,0,0,.4)}
  :root[data-theme="slate"][data-mode="system"]{--canvas:#0f151b;--surface:#151d25;--surface-alt:#1b242e;--sunken:#101820;--ink:#e4eaf0;--ink-soft:#bcc7d3;--ink-muted:#8494a3;--ink-faint:#5d6b79;--line:#26313c;--line-strong:#354350;--accent:#7fb3e0;--accent-ink:#0f151b;--accent-soft:#1c2833;--ok:#4fae6c;--ok-bg:#16261c;--warn:#d09a3c;--warn-bg:#28231a;--danger:#e0706f;--danger-bg:#2a1c1e;--info:#7fb3e0;--info-bg:#16232e;--shadow:0 1px 2px rgba(0,0,0,.38)}
  :root[data-theme="sand"][data-mode="system"]{--canvas:#14110d;--surface:#1b1712;--surface-alt:#221d16;--sunken:#100d09;--ink:#ece5d8;--ink-soft:#c8bfae;--ink-muted:#948a78;--ink-faint:#6b6355;--line:#2a251c;--line-strong:#3a3428;--accent:#d9a066;--accent-ink:#14110d;--accent-soft:#241d14;--ok:#79b061;--ok-bg:#1a2415;--warn:#d2a03c;--warn-bg:#282014;--danger:#e0806f;--danger-bg:#2a1a16;--info:#8fb8c9;--info-bg:#16222a;--shadow:0 1px 2px rgba(0,0,0,.4)}
  :root[data-theme="black"][data-mode="system"]{--canvas:#000000;--surface:#0c0c0c;--surface-alt:#141414;--sunken:#080808;--ink:#f2f2f2;--ink-soft:#cfcfcf;--ink-muted:#8d8d8d;--ink-faint:#5e5e5e;--line:#222222;--line-strong:#333333;--accent:#ffffff;--accent-ink:#000000;--accent-soft:#1c1c1c;--ok:#54b26a;--ok-bg:#132015;--warn:#d59c34;--warn-bg:#241d10;--danger:#e0685f;--danger-bg:#251512;--info:#89aede;--info-bg:#131b26;--shadow:0 1px 2px rgba(0,0,0,.6)}
  :root[data-theme="blue"][data-mode="system"]{--canvas:#08101f;--surface:#0e1829;--surface-alt:#142136;--sunken:#0a1322;--ink:#e6ecf7;--ink-soft:#bcc9de;--ink-muted:#8496b3;--ink-faint:#5b6c8a;--line:#1e2c45;--line-strong:#2c3d5c;--accent:#7ba7f5;--accent-ink:#08101f;--accent-soft:#16253c;--ok:#4fb07d;--ok-bg:#12241b;--warn:#d3a044;--warn-bg:#251f12;--danger:#e0736d;--danger-bg:#271719;--info:#7ba7f5;--info-bg:#16253c;--shadow:0 1px 2px rgba(0,0,0,.45)}
  :root[data-theme="forest"][data-mode="system"]{--canvas:#0e1110;--surface:#161a19;--surface-alt:#1b201e;--sunken:#101413;--ink:#e9ebe9;--ink-soft:#c2c7c4;--ink-muted:#8a918d;--ink-faint:#636a66;--line:#262b29;--line-strong:#353b38;--accent:#6fc0ae;--accent-ink:#0e1110;--accent-soft:#17251f;--ok:#54b072;--ok-bg:#152218;--warn:#d29b3a;--warn-bg:#241d10;--danger:#e0736a;--danger-bg:#251715;--info:#7fb0dd;--info-bg:#141f29;--shadow:0 1px 2px rgba(0,0,0,.35)}
  :root[data-theme="graphite"][data-mode="system"]{--canvas:#131313;--surface:#191919;--surface-alt:#1f1f1f;--sunken:#101010;--ink:#ededed;--ink-soft:#c9c9c9;--ink-muted:#8f8f8f;--ink-faint:#666666;--line:#2c2c2c;--line-strong:#3d3d3d;--accent:#ededed;--accent-ink:#131313;--accent-soft:#252525;--ok:#4faf63;--ok-bg:#1a271d;--warn:#d99a2b;--warn-bg:#2a2417;--danger:#e56b6b;--danger-bg:#2a1c1c;--info:#7fb0dd;--info-bg:#161f27;--shadow:0 1px 2px rgba(0,0,0,.4)}
  :root[data-theme="slate"][data-mode="system"]{--canvas:#0f151b;--surface:#151d25;--surface-alt:#1b242e;--sunken:#101820;--ink:#e4eaf0;--ink-soft:#bcc7d3;--ink-muted:#8494a3;--ink-faint:#5d6b79;--line:#26313c;--line-strong:#354350;--accent:#7fb3e0;--accent-ink:#0f151b;--accent-soft:#1c2833;--ok:#4fae6c;--ok-bg:#16261c;--warn:#d09a3c;--warn-bg:#28231a;--danger:#e0706f;--danger-bg:#2a1c1e;--info:#7fb3e0;--info-bg:#16232e;--shadow:0 1px 2px rgba(0,0,0,.38)}
  :root[data-theme="sand"][data-mode="system"]{--canvas:#14110d;--surface:#1b1712;--surface-alt:#221d16;--sunken:#100d09;--ink:#ece5d8;--ink-soft:#c8bfae;--ink-muted:#948a78;--ink-faint:#6b6355;--line:#2a251c;--line-strong:#3a3428;--accent:#d9a066;--accent-ink:#14110d;--accent-soft:#241d14;--ok:#79b061;--ok-bg:#1a2415;--warn:#d2a03c;--warn-bg:#282014;--danger:#e0806f;--danger-bg:#2a1a16;--info:#8fb8c9;--info-bg:#16222a;--shadow:0 1px 2px rgba(0,0,0,.4)}
  :root[data-theme="black"][data-mode="system"]{--canvas:#000000;--surface:#0c0c0c;--surface-alt:#141414;--sunken:#080808;--ink:#f2f2f2;--ink-soft:#cfcfcf;--ink-muted:#8d8d8d;--ink-faint:#5e5e5e;--line:#222222;--line-strong:#333333;--accent:#ffffff;--accent-ink:#000000;--accent-soft:#1c1c1c;--ok:#54b26a;--ok-bg:#132015;--warn:#d59c34;--warn-bg:#241d10;--danger:#e0685f;--danger-bg:#251512;--info:#89aede;--info-bg:#131b26;--shadow:0 1px 2px rgba(0,0,0,.6)}
  :root[data-theme="blue"][data-mode="system"]{--canvas:#08101f;--surface:#0e1829;--surface-alt:#142136;--sunken:#0a1322;--ink:#e6ecf7;--ink-soft:#bcc9de;--ink-muted:#8496b3;--ink-faint:#5b6c8a;--line:#1e2c45;--line-strong:#2c3d5c;--accent:#7ba7f5;--accent-ink:#08101f;--accent-soft:#16253c;--ok:#4fb07d;--ok-bg:#12241b;--warn:#d3a044;--warn-bg:#251f12;--danger:#e0736d;--danger-bg:#271719;--info:#7ba7f5;--info-bg:#16253c;--shadow:0 1px 2px rgba(0,0,0,.45)}
}

:root {
  --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  --font-mono: 'JetBrains Mono', Consolas, 'Courier New', monospace;
}

/* ====================================================================
   Base
   ==================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; padding: 0; height: 100%; }

body {
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--ink); text-decoration: underline; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 4px; }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 3px solid var(--canvas);
  border-radius: 6px;
}

/* Numbers only line up when the glyphs are the same width. */
.num, .mono, td.num, th.num, input.num, .stat__value, .kbd {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.muted   { color: var(--ink-muted); }
.faint   { color: var(--ink-faint); }
.soft    { color: var(--ink-soft); }
.right   { text-align: right; }
.center  { text-align: center; }
.nowrap  { white-space: nowrap; }
.ok-text { color: var(--ok); }
.warn-text { color: var(--warn); }
.danger-text { color: var(--danger); }

.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;
}

.skip-link {
  position: absolute; left: -9999px; top: 8px; z-index: 100;
  background: var(--accent); color: var(--accent-ink);
  padding: 8px 14px; border-radius: 7px; font-weight: 500;
}
.skip-link:focus { left: 8px; }

@keyframes pl-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

/* ====================================================================
   Shell — topbar across the top, nav rail on the left, page to the right
   ==================================================================== */

.shell {
  display: grid;
  grid-template-columns: var(--navw) 1fr;
  grid-template-rows: 53px 1fr;
  height: 100vh;
}
.shell--wide { grid-template-columns: 0 1fr; }

.topbar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 18px 0 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  z-index: 5;
}
.topbar__brand { display: flex; align-items: center; gap: 9px; flex: none; }
.topbar__mark {
  width: 24px; height: 24px; border-radius: 6px;
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center; flex: none;
}
.topbar__name {
  font-size: 15px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink);
}
.topbar__version {
  font-family: var(--font-mono); font-size: 10px; line-height: 1;
  color: var(--ink-faint); padding-top: 3px;
}
.topbar__spacer { flex: 1; }

/* History controls. The application is server-rendered so the browser's own
   buttons already work — these are the canvas's, wired to the same history,
   for people who never look at the chrome. */
.topbar__history { display: flex; align-items: center; gap: 4px; flex: none; }

/* The command palette's resting state: a search field that is really a button. */
.omni {
  display: flex; align-items: center; gap: 8px;
  width: 100%; min-width: 0; max-width: 380px; height: 29px;
  padding: 0 10px;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface-alt);
  color: var(--ink-faint); cursor: text; overflow: hidden;
}
.omni:hover { border-color: var(--line-strong); }
.omni__label {
  flex: 1; min-width: 0; font-size: 12.5px; line-height: 29px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.omni__key {
  font-family: var(--font-mono); font-size: 10px;
  border: 1px solid var(--line); border-radius: 4px;
  padding: 1px 4px; flex: none; white-space: nowrap;
}
.topbar__search { flex: 1; min-width: 0; display: flex; justify-content: center; }

/* Who is signed in: name over role, then initials. */
.topbar__who {
  display: flex; align-items: center; gap: 8px;
  padding-left: 10px; border-left: 1px solid var(--line); flex: none;
}
.topbar__names {
  display: flex; flex-direction: column; line-height: 1.2; text-align: right;
}
.topbar__user { font-size: 12px; font-weight: 500; color: var(--ink); white-space: nowrap; }
.topbar__role { font-size: 10.5px; color: var(--ink-muted); white-space: nowrap; }
.topbar__avatar {
  width: 27px; height: 27px; border-radius: 50%; flex: none;
  background: var(--sunken); color: var(--ink-soft);
  font-size: 11px; font-weight: 600; line-height: 27px; text-align: center;
}

.icon-btn {
  width: 27px; height: 27px; flex: none;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface); color: var(--ink-muted);
  display: grid; place-items: center; cursor: pointer;
}
.icon-btn:hover { border-color: var(--line-strong); color: var(--ink); }

/* Company switcher and the financial-year selector share a shape. */
.switcher {
  display: flex; align-items: center; gap: 7px;
  padding: 4px 9px 4px 7px;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface-alt);
  flex: none;
}
/* Name over role, the way the canvas has it — the role is what tells you what
   you can do here, and it was only in the far corner of the bar. */
.switcher__lines { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.switcher__name { font-size: 12.5px; font-weight: 500; color: var(--ink); white-space: nowrap; }
.switcher__sub { font-size: 10.5px; color: var(--ink-muted); white-space: nowrap; }
/* The select sits invisibly over the two-line label so the whole block is the
   control, and it still works with no JavaScript at all. */
.switcher--overlay { position: relative; }
.switcher--overlay select {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
}
.switcher__caret { color: var(--ink-muted); flex: none; margin-left: 2px; }
.switcher:hover { border-color: var(--line-strong); }
.switcher__badge {
  width: 20px; height: 20px; border-radius: 5px;
  background: var(--accent-soft); color: var(--accent);
  font-family: var(--font-mono); font-size: 10px; font-weight: 600;
  line-height: 20px; text-align: center; flex: none;
}
.switcher select, .switcher__select {
  border: 0; background: none; color: var(--ink);
  font-size: 12.5px; padding: 2px 2px; max-width: 210px; cursor: pointer;
}
/* The financial-year control is a bordered mono select of its own, not a
   switcher — it names a period, it does not change who you are. */
.fy-select {
  font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-muted);
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 6px; white-space: nowrap; flex: none; cursor: pointer;
}
.switcher select:focus { outline: none; }

.readonly-flag {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 3px 7px; border-radius: 5px;
  background: var(--warn-bg); color: var(--warn); white-space: nowrap;
}

/* ---- nav rail ---- */

.nav {
  background: var(--surface);
  border-right: 1px solid var(--line);
  padding: 12px 10px;
  overflow: hidden auto;
}
.shell--wide .nav { display: none; }
.nav__section { margin-bottom: 14px; }
.nav__label {
  padding: 4px 10px 6px;
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-faint);
}
.nav__link {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: 6px;
  font-size: 13px; color: var(--ink-soft); text-decoration: none;
}
.nav__link:hover { background: var(--surface-alt); color: var(--ink); text-decoration: none; }
.nav__link.is-active { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.nav__bar { width: 3px; height: 15px; border-radius: 2px; background: transparent; flex: none; }
.nav__link.is-active .nav__bar { background: var(--accent); }
.nav__text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav__count {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-faint); flex: none;
}
.nav__link.is-active .nav__count { color: var(--accent); }
.nav__note {
  margin: 18px 10px 8px; padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 10.5px; line-height: 1.5; color: var(--ink-faint);
}

/* ---- page ---- */

.main { overflow: auto; padding: 18px 28px 48px; }
/* The canvas caps the reading column. Past about 1280px a dense table stops
   being easier to read and starts making the eye travel. */
.main > * { max-width: 1280px; }

/* Main column plus a 300px rail, the canvas's standing two-column page. */
.split2 {
  display: grid; grid-template-columns: minmax(0, 1fr) 300px;
  gap: 18px; align-items: start; max-width: 1280px;
}
.split2__main, .split2__rail { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
@media (max-width: 1080px) { .split2 { grid-template-columns: 1fr; } }
.main > * { animation: pl-in 140ms ease both; }

.page-head {
  display: flex; align-items: flex-start; gap: 14px;
  margin-bottom: 16px; flex-wrap: wrap;
}
.page-head__text { flex: 1; min-width: 240px; }
.page-head h1 { font-size: 19px; }
.page-head__sub { margin: 3px 0 0; font-size: 12.5px; color: var(--ink-muted); max-width: 78ch; }
.page-head__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.section-title {
  margin: 22px 0 10px;
  font-size: 11px; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-faint);
}

/* ====================================================================
   Cards
   ==================================================================== */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 14px;
}
.card--flush { overflow: visible; }
.card__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 16px; border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.card__title { font-size: 13.5px; font-weight: 600; flex: 1; min-width: 0; white-space: nowrap; }
.card__sub { font-size: 11.5px; color: var(--ink-muted); }
/* The quiet right-hand caption the canvas puts on a card header — it says how
   to read what is underneath, which a bare heading never does. */
.card__note {
  font-size: 11px; color: var(--ink-faint); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; flex: none; max-width: 55%;
}
.card__body { padding: 16px; }
.card__foot {
  padding: 11px 16px; border-top: 1px solid var(--line);
  background: var(--surface-alt);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}

.grid { display: grid; gap: 14px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid--side { grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }

/* ====================================================================
   Stat tiles
   ==================================================================== */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 13px 15px;
}
.stat__label {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-faint);
}
.stat__value {
  margin-top: 4px;
  font-size: 22px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink);
}
.stat__note { margin-top: 3px; font-size: 11.5px; color: var(--ink-muted); }

/* ====================================================================
   Tables
   ==================================================================== */

.table-wrap { overflow-x: auto; }

/* The card is the frame; the table scrolls inside it.

   Both axes, and the card itself does not grow — a 400-row register used to
   push the page to 12,000 pixels and take the header off the top of the screen
   with it. Held at 520px the frame stays put, the header stays visible, and
   both scrollbars belong to the table rather than the document. Matches the
   canvas exactly: overflow:auto, max-height:520px, sticky header. */
.card > .table-wrap {
  border-radius: 0;
  overflow: auto;
  max-height: 520px;
  overscroll-behavior: contain;
}

/* A short table should not be padded out to 520px of empty card. */
.card > .table-wrap.is-short { max-height: none; overflow-x: auto; overflow-y: visible; }

/* Sticky through a vertical scroll. It needs its own background or the rows
   show through it, and a z-index or the cell borders paint over it. */
.card > .table-wrap .table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface);
  box-shadow: inset 0 -1px 0 var(--line);
}
/* A footer that totals the column is worth pinning too. */
.card > .table-wrap .table tfoot td {
  position: sticky;
  bottom: 0;
  z-index: 2;
  box-shadow: inset 0 1px 0 var(--line-strong);
}

.table { width: 100%; border-collapse: collapse; }
.table thead th {
  text-align: left;
  padding: 8px 12px;
  font-size: 10px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-muted);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--surface);
}
.table thead th:first-child, .table tbody td:first-child { padding-left: 16px; }
.table thead th:last-child,  .table tbody td:last-child  { padding-right: 16px; }
.table thead th.num { text-align: right; }

.table tbody td {
  padding: var(--rowpad) 12px;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 340px;
}
.table tbody td.num { text-align: right; font-size: 12px; color: var(--ink); }
.table tbody td.wrap { white-space: normal; max-width: none; }

/* Long text reads on hover instead of staying cut off.

   The cell clips; the span inside it slides. At rest the span carries the
   ellipsis, so nothing about the resting row changes — put the cursor on a
   truncated cell and the text travels far enough to finish, then returns. The
   span is added by app.js on first hover, and only to cells that actually
   overflow, so a hundred-row table costs nothing until someone points at it. */
.cellscroll {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: transform 0s linear;
  will-change: transform;
}
.cellscroll.is-scrolling {
  overflow: visible;
  text-overflow: clip;
}
td:has(> .cellscroll) { cursor: default; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-alt); }
.table tbody tr.is-linked { cursor: pointer; }

.table tfoot td {
  padding: 10px 12px;
  border-top: 1px solid var(--line-strong);
  background: var(--surface-alt);
  font-size: 12.5px; font-weight: 600; color: var(--ink);
  white-space: nowrap;
}
.table tfoot td.num { text-align: right; font-family: var(--font-mono); }

.table .actions { text-align: right; white-space: nowrap; }
.table .lead { font-weight: 500; color: var(--ink); }
.table .sub { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }

.empty {
  padding: 28px 16px;
  text-align: center;
  color: var(--ink-muted);
  font-size: 12.5px;
  white-space: normal;
}

.pager { display: flex; gap: 6px; align-items: center; margin-top: 12px; font-size: 12.5px; }

/* ====================================================================
   Buttons
   ==================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 13px;
  border: 1px solid var(--accent); border-radius: 7px;
  background: var(--accent); color: var(--accent-ink);
  font-family: inherit; font-size: 12.5px; font-weight: 500;
  cursor: pointer; white-space: nowrap;
  text-decoration: none;
}
.btn:hover { opacity: 0.9; color: var(--accent-ink); text-decoration: none; }
.btn:disabled, .btn[disabled] { opacity: 0.5; cursor: not-allowed; }

.btn--ghost {
  background: var(--surface); color: var(--ink-soft); border-color: var(--line);
}
.btn--ghost:hover { background: var(--surface-alt); color: var(--ink); border-color: var(--line-strong); opacity: 1; }

.btn--danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn--danger:hover { color: #fff; }

.btn--sm { padding: 4px 9px; font-size: 11.5px; border-radius: 6px; }
.btn--block { width: 100%; }

.btn-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
/* Controls inside a button row are part of the row, not a stacked form: the
   global 100% width made a select-plus-input-plus-button take three lines
   wherever there was room for one. They still wrap when there is not. */
.btn-row > select,
.btn-row > input[type="text"],
.btn-row > input[type="search"],
.btn-row > input[type="date"],
.btn-row > input[type="number"] { width: auto; flex: 1 1 150px; min-width: 130px; max-width: 320px; }
.btn-row > input[type="file"] { width: auto; flex: 0 1 auto; }

/* ====================================================================
   Pills — state, said in a word
   ==================================================================== */

.pill {
  display: inline-block;
  padding: 3px 8px; border-radius: 5px;
  font-size: 11px; font-weight: 500; white-space: nowrap;
  background: var(--accent-soft); color: var(--accent);
}
.pill--ok     { background: var(--ok-bg);     color: var(--ok); }
.pill--warn   { background: var(--warn-bg);   color: var(--warn); }
.pill--danger { background: var(--danger-bg); color: var(--danger); }
.pill--info   { background: var(--info-bg);   color: var(--info); }
.pill--muted  { background: var(--sunken);    color: var(--ink-muted); }
.pill--sm     { padding: 2px 6px; font-size: 10px; }

/* ====================================================================
   Forms
   ==================================================================== */

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 13px;
}
.form-grid--wide { grid-template-columns: 1fr; }
.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.field--full { grid-column: 1 / -1; }
.field__label { font-size: 11.5px; font-weight: 500; color: var(--ink-soft); }
.field__hint { font-size: 11px; color: var(--ink-faint); }

input[type="text"], input[type="email"], input[type="password"], input[type="date"],
input[type="number"], input[type="search"], input[type="file"], select, textarea {
  width: 100%;
  padding: 7px 9px;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface); color: var(--ink);
  font-family: inherit; font-size: 12.5px; line-height: 1.35;
  -webkit-appearance: none; appearance: none;
}
input:hover, select:hover, textarea:hover { border-color: var(--line-strong); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
input:disabled, select:disabled, textarea:disabled,
input[readonly] { background: var(--sunken); color: var(--ink-muted); cursor: not-allowed; }
textarea { min-height: 66px; resize: vertical; line-height: 1.5; }

/* Fields read left to right while they are being typed. Amount COLUMNS are
   right-aligned — that is a display rule for a ledger, not an entry rule. */
input[type="number"], input.num, td input.num, textarea.num, select.num {
  font-family: var(--font-mono);
  text-align: left;
  font-variant-numeric: tabular-nums;
}
.table input.num, .table td input, .table td select { text-align: left; }

select {
  padding-right: 26px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-muted) 50%),
    linear-gradient(135deg, var(--ink-muted) 50%, transparent 50%);
  background-position: calc(100% - 14px) 55%, calc(100% - 9px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.check { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-soft); }
.check input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--accent); flex: none; cursor: pointer; }

.filters {
  display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: var(--shadow);
  margin-bottom: 14px;
}
.filters .field { min-width: 150px; }

/* A filter bar is a row of controls, not a stack. Views put several
   label + control pairs inside one .field, so inside .filters the group
   lays out horizontally and wraps. */
.filters .field {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  flex: 1 1 auto;
}
.filters .field label { font-size: 11.5px; font-weight: 500; color: var(--ink-soft); white-space: nowrap; }
.filters .field select,
.filters .field input { width: auto; min-width: 130px; max-width: 260px; }
.filters .field .btn { margin-left: 2px; }

.field-error { font-size: 11.5px; color: var(--danger); }

/* ====================================================================
   Notices
   ==================================================================== */

.notice {
  padding: 10px 14px;
  border: 1px solid var(--line); border-left: 3px solid var(--info);
  border-radius: 8px;
  background: var(--info-bg); color: var(--ink-soft);
  font-size: 12.5px;
  margin-bottom: 14px;
}
.notice--ok    { border-left-color: var(--ok);     background: var(--ok-bg); }
.notice--warn  { border-left-color: var(--warn);   background: var(--warn-bg); }
.notice--error { border-left-color: var(--danger); background: var(--danger-bg); }
.notice strong { color: var(--ink); }
.notice ul { margin: 6px 0 0; padding-left: 18px; }

.toast {
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  max-width: 380px;
  padding: 11px 15px;
  border: 1px solid var(--line); border-left: 3px solid var(--ok);
  border-radius: 8px;
  background: var(--surface); color: var(--ink);
  box-shadow: 0 6px 20px rgba(0,0,0,.14);
  font-size: 12.5px;
  animation: pl-in 160ms ease both;
}
.toast--error { border-left-color: var(--danger); }

/* ====================================================================
   Tabs
   ==================================================================== */

.tabs {
  display: flex; gap: 2px; flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
  margin-bottom: 14px;
}
.tab {
  padding: 8px 13px;
  font-size: 12.5px; color: var(--ink-muted);
  border-bottom: 2px solid transparent;
  text-decoration: none;
}
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; }

/* ====================================================================
   Stage rail — the eight stages of a process
   ==================================================================== */

.rail { display: flex; flex-direction: column; }
.rail__row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--line);
  text-decoration: none; color: inherit;
}
.rail__row:last-child { border-bottom: 0; }
.rail__row:hover { background: var(--surface-alt); text-decoration: none; }
.rail__seq {
  width: 24px; height: 24px; flex: none;
  border-radius: 6px;
  font-family: var(--font-mono); font-size: 10px; font-weight: 600;
  line-height: 24px; text-align: center;
  background: var(--sunken); color: var(--ink-muted);
}
.rail__row.is-done    .rail__seq { background: var(--ok-bg);   color: var(--ok); }
.rail__row.is-running .rail__seq { background: var(--warn-bg); color: var(--warn); }
.rail__name { flex: 1; font-size: 13px; font-weight: 500; color: var(--ink); min-width: 0; }
.rail__meta { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); white-space: nowrap; }

.meter { height: 5px; border-radius: 3px; background: var(--sunken); overflow: hidden; }
.meter__fill { height: 100%; background: var(--accent); border-radius: 3px; }
.meter__fill--warn { background: var(--warn); }
.meter__fill--danger { background: var(--danger); }

/* Gantt: planned above, actual below, one scale. */
.gantt__track { position: relative; height: 8px; background: var(--sunken); border-radius: 4px; }
.gantt__bar { position: absolute; top: 0; height: 8px; border-radius: 4px; background: var(--accent-soft); }
.gantt__bar--actual { background: var(--accent); }
.gantt__bar--over { background: var(--danger); }

/* ====================================================================
   Definition lists — a record's own facts
   ==================================================================== */

.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px 18px; margin: 0; }
.facts > div { min-width: 0; }
.facts dt { font-size: 10px; font-weight: 500; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-faint); }
.facts dd {
  margin: 3px 0 0;
  font-size: 13px;
  color: var(--ink);
  /* One line, like every other value in the tool. It was overflow-wrap:anywhere,
     which broke a RERA registration number across two lines mid-token — the one
     place a value must stay whole to be readable at all. Truncated instead, and
     hovering it slides the rest into view. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.facts dd.num { font-size: 13px; }
.facts dd.wrap { white-space: normal; overflow: visible; }

.kbd {
  padding: 1px 5px; border: 1px solid var(--line); border-radius: 4px;
  background: var(--surface-alt); font-size: 11px; color: var(--ink-soft);
}

/* ====================================================================
   Appearance picker
   ==================================================================== */

.picker { position: relative; }
.picker__toggle {
  display: flex; align-items: center; gap: 7px;
  padding: 4px 9px;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface-alt); color: var(--ink-soft);
  font-family: inherit; font-size: 12.5px; cursor: pointer;
  list-style: none;
}
.picker__toggle::-webkit-details-marker { display: none; }
.picker__toggle:hover { border-color: var(--line-strong); color: var(--ink); }
.picker__swatch { width: 14px; height: 14px; border-radius: 4px; border: 1px solid var(--line-strong); flex: none; }
.picker__label { white-space: nowrap; }
.picker__caret { color: var(--ink-faint); flex: none; }
.picker[open] .picker__caret { transform: rotate(180deg); }
.picker__panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  width: 326px; padding: 16px;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.16);
  animation: pl-in 120ms ease both;
}
.picker__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 8px;
}
.picker__head + .picker__themes { margin-bottom: 0; }
.picker__legend {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-faint);
}
.picker__close {
  border: 0; background: none; color: var(--ink-faint); cursor: pointer;
  font-size: 17px; line-height: 1; padding: 0 2px; font-family: inherit;
}
.picker__close:hover { color: var(--ink); }

/* Three equal buttons, because there are exactly three modes and they are a
   single choice — not a list that might grow. */
.picker__modes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 16px; }
.picker__mode {
  padding: 8px 6px;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface); color: var(--ink-soft);
  font-family: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer;
}
.picker__mode:hover { border-color: var(--line-strong); }
.picker__mode[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* The palettes as a list, not a grid of tiles: the name has to be readable
   beside its colours, and six names in three columns are not. */
.picker__themes { display: flex; flex-direction: column; gap: 2px; }
.picker__theme {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 8px 10px;
  border: 1px solid transparent; border-radius: 8px;
  background: none; color: var(--ink-soft);
  font-family: inherit; font-size: 13px; cursor: pointer; text-align: left;
}
.picker__theme:hover { background: var(--surface-alt); }
.picker__theme[aria-pressed="true"] { background: var(--accent-soft); color: var(--ink); }

/* Accent, soft tint, ground — the three that make a palette recognisable. */
.picker__chip { display: flex; gap: 3px; flex: none; }
.picker__chip > span {
  display: block; width: 13px; height: 13px; border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, .12);
}
.picker__name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Only the palette in force says so. */
.picker__current { font-size: 11px; color: var(--ink-muted); white-space: nowrap; display: none; }
.picker__theme[aria-pressed="true"] .picker__current { display: block; }

.picker__note {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 11px; line-height: 1.55; color: var(--ink-faint);
}

/* ====================================================================
   Sign-in — brand panel beside the form
   ==================================================================== */

.login { display: grid; grid-template-columns: 1fr 420px; min-height: 100vh; }
.login__brand {
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 44px; background: var(--accent); color: var(--accent-ink);
}
.login__mark { display: flex; align-items: center; gap: 10px; font-size: 16px; font-weight: 600; }
.login__mark span {
  width: 26px; height: 26px; border-radius: 7px;
  background: var(--accent-ink); display: grid; place-items: center; flex: none;
}
.login__pitch { font-size: 26px; font-weight: 600; line-height: 1.28; letter-spacing: -0.02em; max-width: 20ch; }
.login__lede { margin-top: 12px; font-size: 13.5px; opacity: 0.86; max-width: 46ch; line-height: 1.6; }
.login__foot { font-size: 11.5px; opacity: 0.72; }
.login__panel {
  display: flex; flex-direction: column; justify-content: center;
  padding: 44px 40px; background: var(--surface);
}
.login__form { display: flex; flex-direction: column; gap: 13px; max-width: 340px; }
.login__accounts {
  margin-top: 26px; padding-top: 16px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--ink-muted);
}
.login__accounts table { border-collapse: collapse; margin-top: 8px; }
.login__accounts td { padding: 3px 12px 3px 0; font-family: var(--font-mono); font-size: 11px; }

/* ====================================================================
   Print — an invoice leaves the building on paper
   ==================================================================== */

.paper {
  background: #ffffff; color: #111;
  border: 1px solid var(--line); border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 38px 40px;
  max-width: 860px; margin: 0 auto;
}
.paper__head { display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.paper__draft {
  font-size: 30px; font-weight: 700; letter-spacing: 0.08em;
  color: var(--danger); text-transform: uppercase;
}
.paper table { width: 100%; border-collapse: collapse; margin-top: 22px; }
.paper th {
  text-align: left; padding: 7px 8px; font-size: 10px; letter-spacing: 0.06em;
  text-transform: uppercase; color: #555; border-bottom: 1px solid #ddd;
}
.paper td { padding: 8px; border-bottom: 1px solid #eee; font-size: 12px; }
.paper .num { text-align: right; }

@media print {
  .topbar, .nav, .page-head__actions, .no-print { display: none !important; }
  .shell { display: block; height: auto; }
  .main { overflow: visible; padding: 0; }
  .paper { border: 0; box-shadow: none; padding: 0; max-width: none; }
  body { background: #fff; }
}

/* ====================================================================
   Narrow screens
   ==================================================================== */

@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; grid-template-rows: 52px auto 1fr; }
  .nav { border-right: 0; border-bottom: 1px solid var(--line); max-height: 190px; }
  .grid--side { grid-template-columns: 1fr; }
  .login { grid-template-columns: 1fr; }
  .login__brand { display: none; }
  .main { padding: 16px 14px 40px; }
}

/* ======================================================================
   Odds and ends the views ask for by name
   ====================================================================== */

/* A footer row is already styled through <tfoot>; the class is the hook a
   view uses to say "this row is the total" without changing the markup. */
.total-row td { font-weight: 600; color: var(--ink); }

.small { font-size: 11.5px; color: var(--ink-muted); }
.stack { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.gantt { display: flex; flex-direction: column; gap: 10px; }

.paper__ref { font-family: var(--font-mono); font-size: 12px; color: #444; }
.paper__who { font-size: 12.5px; line-height: 1.6; color: #333; max-width: 40ch; }
.paper__words { margin-top: 14px; font-size: 12px; color: #444; font-style: italic; }
.paper__sign { margin-top: 42px; padding-top: 6px; border-top: 1px solid #bbb; width: 210px; font-size: 11px; color: #555; }

/* ======================================================================
   Loose blocks sit on a card too

   Most screens are cards already. A bare form or fact list on the canvas
   reads as an unfinished page next to them, so anything that is a direct
   child of .main gets the same surface. .filters and .paper bring their
   own and are left alone.
   ====================================================================== */

.main > form:not(.filters):not(.paper):not(.bare),
.main > dl.facts,
.main > .btn-row {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 16px;
  margin-bottom: 14px;
}
.main > form:not(.filters) > .form-grid:last-child { margin-bottom: 0; }

/* ======================================================================
   Additions for the feature-parity round (v1.6.0)
   ====================================================================== */

/* A payload someone has to read. Monospace, scrollable in its own box —
   never widening the page, per the no-sideways-scroll rule. */
.code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px 14px;
  margin: 0 0 14px;
  max-height: 460px;
  overflow: auto;
  white-space: pre;
  tab-size: 2;
}

/* The nav rail toggle. Collapsing hides the rail rather than shrinking it
   to icons: these links are words, and a 48px rail of clipped words is
   worse than no rail plus a button that brings it straight back. */
.navtoggle { margin-right: 2px; }
.shell--narrow { grid-template-columns: 0 1fr; }
.shell--narrow .nav { display: none; }

/* An inline edit that lives inside the row it edits. <details> because it
   must survive with no JS — the arrow is the browser's own. */
.rowedit { font-size: 12px; }
.rowedit > summary {
  cursor: pointer; color: var(--ink-muted); list-style: none;
  padding: 2px 0; white-space: nowrap;
}
.rowedit > summary::-webkit-details-marker { display: none; }
.rowedit > summary::before { content: "Edit"; }
.rowedit[open] > summary::before { content: "Cancel"; }
.rowedit > summary:hover { color: var(--ink); text-decoration: underline; }
.rowedit__body {
  display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap;
  padding: 10px 0 4px;
}
.rowedit__body .field { margin: 0; min-width: 0; }
.rowedit__body input { max-width: 130px; }
.rowedit__body input[name="notes"] { max-width: 240px; }

/* A cell holding two or three controls should not wrap them onto stacked
   lines and stretch every row in the table. */
td .btn-row { display: flex; gap: 6px; align-items: center; flex-wrap: nowrap; }

/* A filter that is four choices is a row of chips, not a dropdown plus a
   button: one click instead of three, and the current choice is readable
   without opening anything. Links, not script — each state has a URL. */
.chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.chips__label {
  font-size: 9.5px; font-weight: 500; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-faint); margin-right: 2px;
}
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink-soft);
  font-size: 12px; text-decoration: none; white-space: nowrap;
}
.chip:hover { border-color: var(--line-strong); color: var(--ink); text-decoration: none; }
.chip.is-active {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 500;
}
.chip__count {
  font-family: var(--font-mono); font-size: 10.5px;
  color: var(--ink-faint);
}
.chip.is-active .chip__count { color: var(--accent-ink); opacity: .8; }

/* The lifecycle pip strip: eight stages as eight marks, so a register row
   shows how far along a project is without opening it. */
.pips { display: inline-flex; gap: 2px; align-items: center; }
.pip { width: 8px; height: 8px; border-radius: 2px; background: var(--line-strong); flex: none; }
.pip--done { background: var(--ok); }
.pip--now  { background: var(--warn); }

/* ======================================================================
   The command palette
   ====================================================================== */

.palette {
  width: min(560px, calc(100vw - 32px));
  max-height: 60vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .18);
  color: var(--ink);
  overflow: hidden;
}
/* Near the top rather than dead centre: the eye is already up there, and a
   centred box jumps as results change its height. */
.palette::backdrop { background: rgba(20, 23, 21, .28); }
.palette[open] { display: flex; flex-direction: column; margin: 12vh auto auto; }

.palette__head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  flex: none;
}
.palette__icon { color: var(--ink-faint); flex: none; }
.palette__input {
  flex: 1; min-width: 0;
  border: 0; background: none; color: var(--ink);
  font-size: 14px; padding: 0;
}
.palette__input:focus { outline: none; }
.palette__input::-webkit-search-cancel-button { display: none; }

.palette__body { overflow: auto; padding: 6px; }
.palette__hint, .palette__empty {
  margin: 0; padding: 14px; font-size: 12.5px; color: var(--ink-muted);
}
.palette__group {
  padding: 8px 10px 4px;
  font-size: 9.5px; font-weight: 500; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-faint);
}
.palette__hit {
  display: flex; align-items: baseline; gap: 10px;
  padding: 7px 10px; border-radius: 7px;
  color: var(--ink-soft); text-decoration: none;
}
.palette__hit:hover, .palette__hit.is-active {
  background: var(--accent-soft); color: var(--accent); text-decoration: none;
}
.palette__label {
  flex: 1; min-width: 0; font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.palette__meta {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-faint);
  white-space: nowrap; flex: none;
}
.palette__hit.is-active .palette__meta { color: var(--accent); opacity: .75; }

/* ======================================================================
   The canvas's list row

   A table is right when every row answers the same narrow question in the
   same column. It is wrong for a stage, a parcel-scoped stage or an item
   needing attention, where each row carries a name, a qualifier, a measure
   of progress, a figure and a state — a table forces those into columns of
   equal weight and the row stops reading as one thing.
   ====================================================================== */

.rows { display: block; }

.row {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 142px 104px 78px;
  align-items: center;
  gap: 12px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--line);
  color: inherit;
  text-decoration: none;
}
.row:last-child { border-bottom: 0; }
a.row:hover, .row.is-link:hover { background: var(--surface-alt); text-decoration: none; }

/* A leading counter, or a coloured rule for rows that are not numbered. */
.row__seq {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--sunken); color: var(--ink-faint);
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  line-height: 22px; text-align: center; flex: none;
}
.row__seq--done { background: var(--accent); color: var(--accent-ink); }
.row__seq--now  { background: var(--warn-bg); color: var(--warn); }

.row__body { min-width: 0; }
.row__name { display: flex; align-items: center; gap: 7px; min-width: 0; }
.row__title {
  font-size: 13px; font-weight: 500; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.row__sub {
  margin-top: 2px; font-size: 11.5px; color: var(--ink-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.row__days {
  text-align: right; font-family: var(--font-mono); font-size: 12px;
  color: var(--ink-soft); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.row__end { text-align: right; white-space: nowrap; }

/* A tag on the row's title: what makes this row unlike its neighbours. */
.tag {
  font-size: 10px; font-weight: 500; padding: 2px 6px; border-radius: 4px;
  background: var(--sunken); color: var(--ink-muted); white-space: nowrap; flex: none;
}
.tag--info { background: var(--info-bg); color: var(--info); }
.tag--warn { background: var(--warn-bg); color: var(--warn); }
.tag--ok   { background: var(--ok-bg); color: var(--ok); }

/* Checklist progress, inline in the row rather than a column of fractions. */
.meter { display: flex; align-items: center; gap: 7px; }
.meter__track {
  flex: 1; height: 4px; border-radius: 2px;
  background: var(--sunken); overflow: hidden; display: block;
}
.meter__fill { display: block; height: 4px; background: var(--accent); }
.meter__fill--part { background: var(--warn); }
.meter__label {
  font-family: var(--font-mono); font-size: 11px; color: var(--ink-soft);
  white-space: nowrap; flex: none; min-width: 26px; text-align: right;
}

/* A row that is a notice rather than a record: a coloured rule down the left,
   a title, an explanation, and the figure it concerns. */
.row--flag { grid-template-columns: 3px minmax(0, 1fr) auto; gap: 14px; align-items: start; }
.row__rule { width: 3px; align-self: stretch; border-radius: 2px; background: var(--line-strong); }
.row__rule--warn   { background: var(--warn); }
.row__rule--danger { background: var(--danger); }
.row__rule--ok     { background: var(--ok); }
.row__rule--info   { background: var(--info); }
.row--flag .row__sub { white-space: normal; font-size: 11.5px; line-height: 1.5; }
.row__figure {
  text-align: right; font-family: var(--font-mono); font-size: 12.5px;
  color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.row__go { display: block; margin-top: 3px; font-size: 11px; color: var(--ink-muted); }
a.row:hover .row__go { color: var(--accent); }

@media (max-width: 860px) {
  .row { grid-template-columns: 28px minmax(0, 1fr) auto; }
  .row__days, .row .meter { display: none; }
}

/* ======================================================================
   Key-figure strip

   The figures a record is judged on, across the top, in bordered cells.
   The canvas uses it wherever the answer is "these six numbers" — stacking
   them into cards down a rail buries the comparison the strip exists for.
   ====================================================================== */

.strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 18px;
}
.strip__cell {
  padding: 12px 16px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  min-width: 0;
}
.strip__label {
  font-size: 10px; font-weight: 500; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.strip__value {
  margin-top: 4px; font-family: var(--font-mono); font-size: 13px; color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.strip__value--text { font-family: var(--font-sans); }
/* What the figure above it means, where the label alone does not say. */
.strip__note {
  margin-top: 3px; font-size: 11px; color: var(--ink-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ======================================================================
   Progress stepper — draft, approved, posted, paid
   ====================================================================== */

.steps {
  display: flex; align-items: flex-start;
  padding: 16px; gap: 0;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); box-shadow: var(--shadow);
  margin-bottom: 18px; overflow-x: auto;
}
.step { display: flex; align-items: flex-start; gap: 10px; flex: 1; min-width: 150px; }
.step__dot {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  background: var(--sunken); color: var(--ink-faint);
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  line-height: 22px; text-align: center;
}
.step.is-done .step__dot { background: var(--accent); color: var(--accent-ink); }
.step__text { min-width: 0; }
.step__label {
  display: block; font-size: 12.5px; font-weight: 500; color: var(--ink-faint);
  white-space: nowrap;
}
.step.is-done .step__label { color: var(--ink); }
.step__note {
  display: block; font-size: 11px; color: var(--ink-muted); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.step__line { flex: 1; height: 1px; background: var(--line); margin: 11px 12px 0; min-width: 20px; }
.step.is-done + .step__line { background: var(--accent); }

/* ======================================================================
   Page head: breadcrumb, title with its inline facts, descriptive sub-line
   ====================================================================== */

.crumb {
  display: flex; align-items: center; gap: 7px;
  margin-bottom: 6px; font-size: 11.5px; color: var(--ink-muted);
  white-space: nowrap; overflow: hidden;
}
.crumb a { color: var(--ink-muted); }
.crumb a:hover { color: var(--accent); }
.crumb__sep { color: var(--ink-faint); }

.page-head__line { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; min-width: 0; }
/* The facts that belong to the title rather than under it — a code, a state. */
.page-head__meta {
  font-family: var(--font-mono); font-size: 12px; color: var(--ink-muted); white-space: nowrap;
}

/* A table cell that carries a name and its qualifier. */
.cell2__main { font-size: 12.5px; font-weight: 500; color: var(--ink); }
.cell2__sub { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }

/* Totals as label/value pairs in a rail card, not a full-width table. */
.tot { display: flex; flex-direction: column; }
.tot__row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 7px 0; border-bottom: 1px solid var(--line);
}
.tot__row:last-child { border-bottom: 0; }
.tot__row--rule { border-top: 1px solid var(--line-strong); margin-top: 2px; }
.tot__label { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.tot__value {
  font-family: var(--font-mono); font-size: 12.5px; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tot__row--strong .tot__label { font-weight: 600; color: var(--ink); }
.tot__row--strong .tot__value { font-weight: 600; }

/* A stacked proportion bar with a legend beneath — how a total splits. */
.split-bar { display: flex; height: 8px; border-radius: 3px; overflow: hidden; background: var(--sunken); }
.split-bar span { display: block; height: 8px; }
.legend { margin-top: 12px; display: flex; flex-direction: column; gap: 7px; }
.legend__row { display: flex; align-items: center; gap: 8px; }
.legend__dot { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.legend__label {
  flex: 1; min-width: 0; font-size: 12px; color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.legend__value {
  font-family: var(--font-mono); font-size: 12px; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* ======================================================================
   Register toolbar: the search, the chips and the sort note on one line
   ====================================================================== */

/* A register does not need a bordered filter panel above it. One row: the
   search box, the chips that narrow it, and — pushed to the far right — a
   note saying how the rows below are ordered. */
.toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px; min-width: 0;
}
.toolbar .chips { margin-bottom: 0; }
.toolbar__note {
  margin-left: auto; font-size: 11.5px; color: var(--ink-faint);
  white-space: nowrap; padding-left: 12px;
}

/* The search field, with the magnifier inside the box. Enter submits, so
   there is no Filter button; emptying the field and pressing Enter is the
   reset, so there is no Reset button either. */
.seek { position: relative; flex: none; width: 278px; max-width: 100%; }
.seek__icon {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  color: var(--ink-faint); pointer-events: none;
}
.seek input[type="search"] {
  height: 30px; padding: 0 10px 0 30px; border-radius: 7px;
  background: var(--surface);
}
/* The browser's own clear button sits where our padding does not allow. */
.seek input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }

/* Days a project is past its planned window, beside the lifecycle pips. */
.over {
  font-family: var(--font-mono); font-size: 11px; color: var(--danger);
  white-space: nowrap; margin-left: 8px; font-variant-numeric: tabular-nums;
}

/* A stage past its planned window says so in the rail's day column. */
.row__days--over { color: var(--warn); }

/* A checklist row: the tick, the item, who ticked it. Three columns, not the
   stage rail's five. */
.row--check { grid-template-columns: auto minmax(0, 1fr) 140px; }
.row--check .row__days { text-align: right; font-family: var(--font-sans); }

/* A form declared only so controls in other columns can name it. It holds the
   CSRF token and nothing visible, so it must not draw a surface of its own. */
.bare { display: none; }

/* A filter set that is not the common case. Closed it costs one line; open it
   is the same row of controls the toolbar would have carried. */
.disclose { margin: -6px 0 14px; }
.disclose > summary { display: inline-flex; list-style: none; cursor: pointer; }
.disclose > summary::-webkit-details-marker { display: none; }

/* A horizontal bar chart made of rows: label, proportion, figure. The shape a
   projection wants — every window comparable at a glance, and the number still
   exact beside it. */
.bars { display: block; }
.bar {
  display: grid; grid-template-columns: 132px minmax(0, 1fr) 132px;
  align-items: center; gap: 14px;
  padding: 10px 16px; border-bottom: 1px solid var(--line);
}
.bar:last-child { border-bottom: 0; }
.bar__label {
  font-size: 12.5px; color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bar__track { display: block; height: 12px; border-radius: 3px; background: var(--sunken); overflow: hidden; }
.bar__fill { display: block; height: 12px; background: var(--accent); }
.bar__fill--warn   { background: var(--warn); }
.bar__fill--danger { background: var(--danger); }
.bar__fill--ok     { background: var(--accent); }
.bar__fill--muted  { background: var(--line-strong); }
.bar__value {
  text-align: right; font-family: var(--font-mono); font-size: 12.5px; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* The row whose detail is open in the rail beside the register. */
.table tbody tr.is-selected > td { background: var(--accent-soft); }

/* A file input in a dense register is a button, not a path display. */
.table input[type="file"] { max-width: 136px; font-size: 11px; }

@media (max-width: 860px) {
  .bar { grid-template-columns: 100px minmax(0, 1fr) 96px; gap: 10px; }
}

/* Four counts in a square. Pipeline against ongoing is a comparison, and a
   stacked list turns a glance into a scan. */
.quad { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 14px; }
.quad__cell { min-width: 0; }
.quad__label {
  font-size: 10px; font-weight: 500; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.quad__value {
  margin-top: 3px; font-family: var(--font-mono); font-size: 21px; line-height: 1.1;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.quad__note {
  margin-top: 2px; font-size: 11px; color: var(--ink-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* A state belonging to one window of the projection: its own line under the
   bar, so a long sentence is not squeezed into the label column. */
.bar__note {
  grid-column: 2 / -1; margin-top: 6px;
  display: flex; align-items: center; gap: 7px;
  font-size: 11px; color: var(--ink-muted);
}

/* ======================================================================
   Error pages

   A code on its own tells the reader nothing they can act on. These say what
   happened, why it is likely to have happened, and what to do next — in the
   application's own type and palette, so it does not read as having fallen out
   of the product.
   ====================================================================== */

.errpage {
  min-height: 100vh; margin: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 32px 20px;
  background: var(--canvas); color: var(--ink);
  font-family: var(--font-sans);
}
.errpage__box {
  width: 100%; max-width: 620px;
  padding: 32px 34px 28px;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow);
}
.errpage__code {
  font-family: var(--font-mono); font-size: 12px; font-weight: 500;
  letter-spacing: .12em; color: var(--ink-faint);
}
.errpage__title { margin: 8px 0 16px; font-size: 22px; line-height: 1.25; }
.errpage__body { font-size: 13.5px; line-height: 1.65; color: var(--ink-soft); }
.errpage__body p { margin: 0 0 12px; }
.errpage__body ul { margin: 0 0 12px; padding-left: 18px; }
.errpage__body li { margin-bottom: 7px; }
.errpage__body code {
  font-family: var(--font-mono); font-size: 12px;
  background: var(--sunken); padding: 1px 4px; border-radius: 3px;
}
/* The machine's own words, kept but demoted — useful to whoever is asked for
   help, noise to everybody else. */
.errpage__detail {
  margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.55;
  color: var(--ink-faint); overflow-wrap: anywhere;
}
.errpage__actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 20px; }
