/* =====================================================================
   SJ NEX — shared stylesheet
   =====================================================================
   Every color in the application comes from a variable defined below.
   A theme is nothing more than a different set of those values, so adding
   one means adding a block here and a line to THEMES in app.js — no other
   file changes.

   The active theme is written to <html data-theme="..."> by boot.js before
   anything renders, so switching never flashes the wrong colors.
   ===================================================================== */

/* =====================================================================
   THE FIVE THEMES. Professional Light is the default; Graphite Gray,
   Dark, Navy Enterprise and Luxury Gold beside it. Every color is
   MEASURED: the generator asserts WCAG AA on every text-bearing pair in
   every theme. Gold is an ACCENT in Luxury Gold, never a background.
   Old stored names map to the nearest theme in boot.js and S.theme. */
/* ---------------- PROFESSIONAL LIGHT (default) ---------------- */
:root,
[data-theme="prolight"]{
  --side:#ffffff; --side-2:#f1f5f9; --side-3:#e2e8f0;   /* sidebar, hero */
  --side-ink:#111827; --side-nav:#3f4c63; --side-dim:#64748b;
  --side-label:#64748b; --side-label-hi:#334155;
  --side-hover:#eff3f9; --side-line:#e5e7eb; --side-ring:rgba(37,99,235,.35);
  --avatar-bg:#2563eb; --avatar-ink:#ffffff;
  --amber:#2563eb; --amber-ink:#ffffff; --amber-soft:#eff6ff;   /* the ACTION color */
  --make:#1d4ed8; --make-ink:#ffffff;                           /* the CREATE color */
  --side-accent:#1d4ed8; --code-bg:#e0ecfd; --code-ink:#1d4ed8;   /* accent ON the sidebar/hero, and the code chip */
  --pick-bg:#eff6ff; --pick-line:#6294d9; --pick-icon:#1d4ed8;   /* the branch picker, measured ON the top bar */
  --ink:#030712; --muted:#646e7c; --faint:#75808f;   /* muted reads AA on --panel too: the neutral pill's ground */
  --line:#e5e7eb; --bg:#f8fafc; --card:#ffffff;
  --panel:#f3f6fa;
  --input-bg:#ffffff; --input-line:#e5e7eb;
  --ok:#107a3b; --ok-soft:#e7f6ee; --ok-ink:#ffffff;
  --red:#c81e1e; --red-soft:#fdecec; --red-ink:#ffffff;
  --warn:#8a5a00; --warn-soft:#fdf3de;
  --blue:#2563eb; --blue-soft:#eff6ff; --blue-line:#c7dbf8; --blue-ink:#ffffff;
  --purple:#6d3fa6; --teal:#0c6cb3;
  /* THE SPEED TEST'S TWO DIRECTIONS: the arrows are tinted, the figures
     stay ink and bold. Not green, amber or red — those mean connection
     health here, and a speed has no threshold to judge. Measured on --card. */
  --spd-dn:#0c6cb3; --spd-up:#6d3fa6;
  --ghost-ink:#1f2937; --ghost-line:#64748b; --danger-line:#f1b5b5;
  --btn-bg:#334155; --btn-ink:#ffffff;
  --accent-ink:#ffffff;
  /* The action accent — rooted once; each theme's --blue carries it. */
  --accent:var(--blue);
  --r:12px;
  --shadow:0 1px 2px rgba(17,24,39,.05);
  --shadow-lg:0 24px 60px rgba(0,0,0,.28);
  /* grid */
  --grid-head:#eef2f7; --grid-head-ink:#3d4a5c; --grid-head-hi:rgba(255,255,255,.65);
  --grid-row-line:#e5e9f0;     /* between rows */
  --grid-col-line:#e2e7ef;     /* between columns */
  --grid-odd:#f1f5f9; --grid-hover:#e4eefb;
  --grid-net:rgba(37,99,235,.07);   /* the Net columns' faint ground */
  --grid-new:rgba(138,90,0,.08);    /* the three New price columns' ground: amber, the pending colour */
  /* SEMANTIC STATUS TOKENS (2 Aug 2026) — screens say WHAT a thing is,
     never what color it is. Every pair below is MEASURED at AA. */
  --st-success:#107a3b; --st-success-soft:#e7f6ee;
  --st-warning:#8a5a00; --st-warning-soft:#fdf3de;
  --st-danger:#b91c1c; --st-danger-soft:#fdecec;
  --st-info:#0c6cb3; --st-info-soft:#e6f3fd;
  --st-pending:#8a5a00; --st-pending-soft:#fff1da;
  --st-processing:#2563eb; --st-processing-soft:#eff6ff;
  --st-approved:#107a3b; --st-approved-soft:#e7f6ee;
  --st-rejected:#b91c1c; --st-rejected-soft:#fdecec;
  --st-cancelled:#8b3a3a; --st-cancelled-soft:#f7ecec;
  --st-draft:#5b6472; --st-draft-soft:#eef1f5;
  --st-completed:#0b6b57; --st-completed-soft:#e4f3ef;
  --st-inactive:#5b6472; --st-inactive-soft:#eef1f5;
  --st-hold:#be185d; --st-hold-soft:#fce7f3;
  --st-memo:#4338ca; --st-memo-soft:#e4e8fa;
  --st-sold:#b91c1c; --st-sold-soft:#fdecec;
  --st-cert:#0c6cb3; --st-cert-soft:#e6f3fd;
  --st-wroff:#374151; --st-wroff-soft:#e8eaed;
  color-scheme:light;
}

/* ---------------- GRAPHITE GRAY ---------------- */
[data-theme="graphite"]{
  --side:#374151; --side-2:#414b5c; --side-3:#4c5769;   /* sidebar, hero */
  --side-ink:#ffffff; --side-nav:rgba(255,255,255,.8); --side-dim:rgba(255,255,255,.42);
  --side-label:rgba(255,255,255,.4); --side-label-hi:rgba(255,255,255,.7);
  --side-hover:rgba(255,255,255,.07); --side-line:rgba(255,255,255,.1); --side-ring:rgba(255,255,255,.28);
  --avatar-bg:#374151; --avatar-ink:#ffffff;
  --amber:#2563eb; --amber-ink:#ffffff; --amber-soft:#eef4fe;   /* the ACTION color */
  --make:#1d4ed8; --make-ink:#ffffff;                           /* the CREATE color */
  --side-accent:#bfdbfe; --code-bg:#e8eefb; --code-ink:#1d4ed8;   /* accent ON the sidebar/hero, and the code chip */
  --pick-bg:#eef4fe; --pick-line:#6294d9; --pick-icon:#1d4ed8;   /* the branch picker, measured ON the top bar */
  --ink:#030712; --muted:#646e7c; --faint:#75808f;
  --line:#d1d5db; --bg:#f3f4f6; --card:#ffffff;
  --panel:#f5f6f8;
  --input-bg:#ffffff; --input-line:#d1d5db;
  --ok:#107a3b; --ok-soft:#e6f5ed; --ok-ink:#ffffff;
  --red:#c81e1e; --red-soft:#fcebeb; --red-ink:#ffffff;
  --warn:#8a5a00; --warn-soft:#fcf2dd;
  --blue:#2563eb; --blue-soft:#eef4fe; --blue-line:#c5d9f7; --blue-ink:#ffffff;
  --purple:#6d3fa6; --teal:#0c6cb3;
  /* THE SPEED TEST'S TWO DIRECTIONS: the arrows are tinted, the figures
     stay ink and bold. Not green, amber or red — those mean connection
     health here, and a speed has no threshold to judge. Measured on --card. */
  --spd-dn:#0c6cb3; --spd-up:#6d3fa6;
  --ghost-ink:#374151; --ghost-line:#6b7280; --danger-line:#efb3b3;
  --btn-bg:#374151; --btn-ink:#ffffff;
  --accent-ink:#ffffff;
  --shadow:0 1px 2px rgba(55,65,81,.07);
  --shadow-lg:0 24px 60px rgba(0,0,0,.3);
  /* grid */
  --grid-head:#e7eaef; --grid-head-ink:#3b4453; --grid-head-hi:rgba(255,255,255,.6);
  --grid-row-line:#dfe3e9;     /* between rows */
  --grid-col-line:#dce0e7;     /* between columns */
  --grid-odd:#f0f2f5; --grid-hover:#e8eaee;
  --grid-net:rgba(59,68,83,.08);
  --grid-new:rgba(138,90,0,.08);
  /* SEMANTIC STATUS TOKENS (2 Aug 2026) — screens say WHAT a thing is,
     never what color it is. Every pair below is MEASURED at AA. */
  --st-success:#107a3b; --st-success-soft:#e7f6ee;
  --st-warning:#8a5a00; --st-warning-soft:#fdf3de;
  --st-danger:#b91c1c; --st-danger-soft:#fdecec;
  --st-info:#0c6cb3; --st-info-soft:#e6f3fd;
  --st-pending:#8a5a00; --st-pending-soft:#fff1da;
  --st-processing:#2563eb; --st-processing-soft:#eff6ff;
  --st-approved:#107a3b; --st-approved-soft:#e7f6ee;
  --st-rejected:#b91c1c; --st-rejected-soft:#fdecec;
  --st-cancelled:#8b3a3a; --st-cancelled-soft:#f7ecec;
  --st-draft:#5b6472; --st-draft-soft:#eef1f5;
  --st-completed:#0b6b57; --st-completed-soft:#e4f3ef;
  --st-inactive:#5b6472; --st-inactive-soft:#eef1f5;
  --st-hold:#be185d; --st-hold-soft:#fce7f3;
  --st-memo:#4338ca; --st-memo-soft:#e4e8fa;
  --st-sold:#b91c1c; --st-sold-soft:#fdecec;
  --st-cert:#0c6cb3; --st-cert-soft:#e6f3fd;
  --st-wroff:#374151; --st-wroff-soft:#e8eaed;
  color-scheme:light;
}

/* ---------------- DARK ---------------- */
[data-theme="dark"]{
  --side:#111827; --side-2:#1b2436; --side-3:#253049;   /* sidebar, hero */
  /* OFF-WHITE INK ON THE DARK THEMES (his report and choice, 19 Sep 2026:
     near-white at 14–17:1 was eye strain at night). Ink 9.1:1 on the
     card, 11.1:1 on the page; sidebar name, avatar and grid headings one
     step down with it; muted unchanged at 5.7:1. Every pair still AA. */
  --side-ink:#d3dae4; --side-nav:rgba(255,255,255,.66); --side-dim:rgba(255,255,255,.4);
  --side-label:rgba(255,255,255,.38); --side-label-hi:rgba(255,255,255,.68);
  --side-hover:rgba(255,255,255,.06); --side-line:rgba(255,255,255,.09); --side-ring:rgba(255,255,255,.28);
  --avatar-bg:#253049; --avatar-ink:#d3dae4;
  --amber:#60a5fa; --amber-ink:#0f172a; --amber-soft:#16283f;   /* the ACTION color */
  --make:#3b82f6; --make-ink:#0f172a;                           /* the CREATE color */
  --side-accent:#60a5fa; --code-bg:#1e3252; --code-ink:#93c5fd;   /* accent ON the sidebar/hero, and the code chip */
  --pick-bg:#16283f; --pick-line:#4f7cae; --pick-icon:#7fb3fa;   /* the branch picker, measured ON the top bar */
  --ink:#c4cdd9; --muted:#94a3b8; --faint:#8290a6;
  --line:#334155; --bg:#0f172a; --card:#1e293b;
  --panel:#243349;
  --input-bg:#16213a; --input-line:#3a4a63;
  --ok:#22c55e; --ok-soft:#12301f; --ok-ink:#04200f;
  --red:#f47171; --red-soft:#3a1618; --red-ink:#2d0707;
  --warn:#fbbf24; --warn-soft:#332b12;
  --blue:#7fb3fa; --blue-soft:#152c4a; --blue-line:#2c4a74; --blue-ink:#0f172a;
  --purple:#b79be8; --teal:#45c3cf;
  /* THE SPEED TEST'S TWO DIRECTIONS: the arrows are tinted, the figures
     stay ink and bold. Not green, amber or red — those mean connection
     health here, and a speed has no threshold to judge. Measured on --card. */
  --spd-dn:#45c3cf; --spd-up:#b79be8;
  --ghost-ink:#c4cdd9; --ghost-line:#6e7f9b; --danger-line:#7d3a40;
  --btn-bg:#e2e8f0; --btn-ink:#0f172a;
  --accent-ink:#0f172a;
  --shadow:0 1px 2px rgba(0,0,0,.4);
  --shadow-lg:0 24px 60px rgba(0,0,0,.6);
  /* grid */
  --grid-head:#2b3a52; --grid-head-ink:#b3c0d2; --grid-head-hi:rgba(255,255,255,.08);
  --grid-row-line:#2e3b52;     /* between rows */
  --grid-col-line:#2e3b52;     /* between columns */
  --grid-odd:#22304a; --grid-hover:#2a3d5c;
  --grid-net:rgba(255,255,255,.07);
  --grid-new:rgba(251,191,36,.10);
  /* SEMANTIC STATUS TOKENS (2 Aug 2026) — screens say WHAT a thing is,
     never what color it is. Every pair below is MEASURED at AA. */
  --st-success:#4ade80; --st-success-soft:#12301f;
  --st-warning:#fbbf24; --st-warning-soft:#332b12;
  --st-danger:#f87171; --st-danger-soft:#3a1618;
  --st-info:#5ec9f8; --st-info-soft:#102b3c;
  --st-pending:#fbbf24; --st-pending-soft:#3a2f10;
  --st-processing:#7fb3fa; --st-processing-soft:#152c4a;
  --st-approved:#4ade80; --st-approved-soft:#12301f;
  --st-rejected:#f87171; --st-rejected-soft:#3a1618;
  --st-cancelled:#e0a6a6; --st-cancelled-soft:#331d1d;
  --st-draft:#a8b4c6; --st-draft-soft:#232e42;
  --st-completed:#43c6a8; --st-completed-soft:#0e2c26;
  --st-inactive:#a8b4c6; --st-inactive-soft:#232e42;
  --st-hold:#f9a8d4; --st-hold-soft:#38152b;
  --st-memo:#a5b4fc; --st-memo-soft:#1d2147;
  --st-sold:#f87171; --st-sold-soft:#3a1618;
  --st-cert:#5ec9f8; --st-cert-soft:#102b3c;
  --st-wroff:#b6c0cf; --st-wroff-soft:#242d3d;
  color-scheme:dark;
}

/* Navy Enterprise retired on his order, 23 Aug 2026 — saved choices
   open as Diamond Blue through the theme map. */

/* ---------------- PLATINUM (his palette, 23 Aug 2026) ---------------- */
[data-theme="platinum"]{
  --side:#2b3038; --side-2:#363c46; --side-3:#424a55;
  --side-ink:#ffffff; --side-nav:rgba(255,255,255,.80); --side-dim:rgba(255,255,255,.42);
  --side-label:rgba(255,255,255,.40); --side-label-hi:rgba(255,255,255,.72);
  --side-hover:rgba(255,255,255,.08); --side-line:rgba(255,255,255,.10); --side-ring:rgba(180,190,205,.40);
  --avatar-bg:#596273; --avatar-ink:#ffffff;
  --amber:#4f647b; --amber-ink:#ffffff; --amber-soft:#eef2f6;
  --make:#3a4b5e; --make-ink:#ffffff;                           /* the CREATE color */
  --side-accent:#d5dce5; --code-bg:#edf1f5; --code-ink:#405166;
  --pick-bg:#f0f3f6; --pick-line:#8494a6; --pick-icon:#4f647b;
  --ink:#161b22; --muted:#606c7e; --faint:#71808f;
  --line:#dfe3e8; --bg:#f7f7f5; --card:#ffffff;
  --panel:#f0f1ef;
  --input-bg:#ffffff; --input-line:#d7dce2;
  --ok:#237a52; --ok-soft:#e8f5ee; --ok-ink:#ffffff;
  --red:#c92a2a; --red-soft:#fdecec; --red-ink:#ffffff;
  --warn:#8a6200; --warn-soft:#faf2df;
  --blue:#4f647b; --blue-soft:#eef2f6; --blue-line:#cdd6df; --blue-ink:#ffffff;
  --purple:#7356a5; --teal:#287a82;
  --spd-dn:#287a82; --spd-up:#7356a5;
  --ghost-ink:#303946; --ghost-line:#7c8795; --danger-line:#efb5b5;
  --btn-bg:#303946; --btn-ink:#ffffff;
  --accent-ink:#ffffff; --accent:var(--blue);
  --r:12px;
  --shadow:0 1px 2px rgba(30,35,42,.06);
  --shadow-lg:0 24px 60px rgba(30,35,42,.24);
  --grid-head:#e9ebed; --grid-head-ink:#3e4754; --grid-head-hi:rgba(255,255,255,.70);
  --grid-row-line:#e1e3e5; --grid-col-line:#dde0e3;
  --grid-odd:#f6f6f4; --grid-hover:#e9edf0;
  --grid-net:rgba(90,80,40,.08);
  --grid-new:rgba(138,98,0,.09);
  --st-success:#237a52; --st-success-soft:#e8f5ee;
  --st-warning:#8a6200; --st-warning-soft:#faf2df;
  --st-danger:#b91c1c; --st-danger-soft:#fdecec;
  --st-info:#426f95; --st-info-soft:#e8f0f7;
  --st-pending:#8a6200; --st-pending-soft:#fff1da;
  --st-processing:#4f647b; --st-processing-soft:#eef2f6;
  --st-approved:#237a52; --st-approved-soft:#e8f5ee;
  --st-rejected:#b91c1c; --st-rejected-soft:#fdecec;
  --st-cancelled:#8b3a3a; --st-cancelled-soft:#f7ecec;
  --st-draft:#626b77; --st-draft-soft:#eef0f2;
  --st-completed:#197263; --st-completed-soft:#e3f3ef;
  --st-inactive:#626b77; --st-inactive-soft:#eef0f2;
  --st-hold:#a33b6d; --st-hold-soft:#fae8f0;
  --st-memo:#554cc7; --st-memo-soft:#e9e9ff;
  --st-sold:#b91c1c; --st-sold-soft:#fdecec;
  --st-cert:#426f95; --st-cert-soft:#e8f0f7;
  --st-wroff:#374151; --st-wroff-soft:#e8eaed;
  color-scheme:light;
}

/* ------------- MIDNIGHT SAPPHIRE (his palette, 23 Aug 2026) ---------- */
[data-theme="midnight-sapphire"]{
  --side:#070d18; --side-2:#0c1728; --side-3:#11223a;
  /* off-white ink, his choice of 19 Sep 2026 (see Dark): 10.5:1 on the card */
  --side-ink:#d2dce8; --side-nav:rgba(230,240,255,.80); --side-dim:rgba(190,210,235,.42);
  --side-label:rgba(143,177,218,.46); --side-label-hi:rgba(190,215,245,.76);
  --side-hover:rgba(70,145,235,.13); --side-line:rgba(180,210,255,.09); --side-ring:rgba(62,139,235,.48);
  --avatar-bg:#1769c2; --avatar-ink:#ffffff;
  --amber:#55a6ff; --amber-ink:#07111f; --amber-soft:#102b4b;
  --make:#2b8cff; --make-ink:#07111f;                           /* the CREATE color */
  --side-accent:#72b7ff; --code-bg:#102b4a; --code-ink:#8ec5ff;
  --pick-bg:#102942; --pick-line:#3f76ad; --pick-icon:#78b8ff;
  --ink:#c3cedb; --muted:#9aabc0; --faint:#73869f;
  --line:#26384f; --bg:#091321; --card:#101e31;
  --panel:#14263d;
  --input-bg:#0d1a2b; --input-line:#2b415c;
  --ok:#45d38a; --ok-soft:#0d3023; --ok-ink:#041b11;
  --red:#f27b83; --red-soft:#35171d; --red-ink:#25070b;
  --warn:#f6bf4f; --warn-soft:#342a12;
  --blue:#55a6ff; --blue-soft:#102d50; --blue-line:#275888; --blue-ink:#07111f;
  --purple:#b49aff; --teal:#4fd1c5;
  --spd-dn:#4fd1c5; --spd-up:#b49aff;
  --ghost-ink:#c3cedb; --ghost-line:#627995; --danger-line:#783841;
  --btn-bg:#dceaff; --btn-ink:#091321;
  --accent-ink:#07111f; --accent:var(--blue);
  --r:12px;
  --shadow:0 1px 3px rgba(0,0,0,.42);
  --shadow-lg:0 24px 70px rgba(0,0,0,.68);
  --grid-head:#182b44; --grid-head-ink:#b5c4d7; --grid-head-hi:rgba(255,255,255,.07);
  --grid-row-line:#22354d; --grid-col-line:#22354d;
  --grid-odd:#0e1d31; --grid-hover:#173252;
  --grid-net:rgba(255,255,255,.07);
  --grid-new:rgba(246,191,79,.10);
  --st-success:#45d38a; --st-success-soft:#0d3023;
  --st-warning:#f6bf4f; --st-warning-soft:#342a12;
  --st-danger:#f27b83; --st-danger-soft:#35171d;
  --st-info:#61b8ff; --st-info-soft:#0d2944;
  --st-pending:#f6bf4f; --st-pending-soft:#382d10;
  --st-processing:#72b7ff; --st-processing-soft:#102d50;
  --st-approved:#45d38a; --st-approved-soft:#0d3023;
  --st-rejected:#f27b83; --st-rejected-soft:#35171d;
  --st-cancelled:#dfa5ac; --st-cancelled-soft:#301c24;
  --st-draft:#a4b3c7; --st-draft-soft:#1a293b;
  --st-completed:#4fd1b0; --st-completed-soft:#0c2b28;
  --st-inactive:#a4b3c7; --st-inactive-soft:#1a293b;
  --st-hold:#f19ac8; --st-hold-soft:#38152b;
  --st-memo:#a9b8ff; --st-memo-soft:#1b214b;
  --st-sold:#f27b83; --st-sold-soft:#35171d;
  --st-cert:#61b8ff; --st-cert-soft:#0d2944;
  --st-wroff:#bac6d6; --st-wroff-soft:#1d2a3a;
  color-scheme:dark;
}

/* ---------------- LUXURY GOLD ---------------- */
[data-theme="gold"]{
  --side:#0b1120; --side-2:#151f33; --side-3:#1f2b45;   /* sidebar, hero */
  /* off-white ink, his choice of 19 Sep 2026 (see Dark): 9.1:1 on the
     card; muted brought under the ink, 5.9:1 */
  --side-ink:#d3dae4; --side-nav:rgba(255,255,255,.78); --side-dim:rgba(255,255,255,.4);
  --side-label:rgba(212,175,55,.55); --side-label-hi:rgba(212,175,55,.85);
  --side-hover:rgba(255,255,255,.06); --side-line:rgba(255,255,255,.09); --side-ring:rgba(212,175,55,.4);
  --avatar-bg:#d4af37; --avatar-ink:#10141f;
  --amber:#d4af37; --amber-ink:#10141f; --amber-soft:#2c2614;   /* the ACTION color */
  --make:#92701f; --make-ink:#ffffff;                           /* the CREATE color - deep bronze */
  --side-accent:#d4af37; --code-bg:#332c17; --code-ink:#e3c257;   /* accent ON the sidebar/hero, and the code chip */
  --pick-bg:#2c2614; --pick-line:#8d793a; --pick-icon:#d4af37;   /* the branch picker, measured ON the top bar */
  --ink:#c4cdd9; --muted:#9aa6b6; --faint:#9aa7bc;
  --line:#374151; --bg:#111827; --card:#1f2937;
  --panel:#263246;
  --input-bg:#182233; --input-line:#40506a;
  --ok:#10b981; --ok-soft:#0f2b22; --ok-ink:#03251b;
  --red:#f47171; --red-soft:#3a1618; --red-ink:#2d0707;
  --warn:#fbbf24; --warn-soft:#322a14;
  --blue:#d3ab4f; --blue-soft:#2a2517; --blue-line:#584a24; --blue-ink:#10141f;
  --purple:#b79be8; --teal:#45c3cf;
  /* THE SPEED TEST'S TWO DIRECTIONS: the arrows are tinted, the figures
     stay ink and bold. Not green, amber or red — those mean connection
     health here, and a speed has no threshold to judge. Measured on --card. */
  --spd-dn:#45c3cf; --spd-up:#b79be8;
  --ghost-ink:#c4cdd9; --ghost-line:#71809c; --danger-line:#7d3a40;
  --btn-bg:#c8a14d; --btn-ink:#10141f;
  --accent-ink:#10141f;
  --shadow:0 1px 2px rgba(0,0,0,.45);
  --shadow-lg:0 24px 60px rgba(0,0,0,.65);
  /* grid */
  --grid-head:#2a3549; --grid-head-ink:#b3bdcb; --grid-head-hi:rgba(255,255,255,.07);
  --grid-row-line:#3a4559;     /* between rows */
  --grid-col-line:#3a4559;     /* between columns */
  --grid-odd:#242f44; --grid-hover:#2e3b55;
  --grid-net:rgba(255,255,255,.07);
  --grid-new:rgba(251,191,36,.10);
  /* SEMANTIC STATUS TOKENS (2 Aug 2026) — screens say WHAT a thing is,
     never what color it is. Every pair below is MEASURED at AA. */
  --st-success:#4ade80; --st-success-soft:#12301f;
  --st-warning:#fbbf24; --st-warning-soft:#332b12;
  --st-danger:#f87171; --st-danger-soft:#3a1618;
  --st-info:#5ec9f8; --st-info-soft:#102b3c;
  --st-pending:#fbbf24; --st-pending-soft:#3a2f10;
  --st-processing:#7fb3fa; --st-processing-soft:#152c4a;
  --st-approved:#4ade80; --st-approved-soft:#12301f;
  --st-rejected:#f87171; --st-rejected-soft:#3a1618;
  --st-cancelled:#e0a6a6; --st-cancelled-soft:#331d1d;
  --st-draft:#a8b4c6; --st-draft-soft:#232e42;
  --st-completed:#43c6a8; --st-completed-soft:#0e2c26;
  --st-inactive:#a8b4c6; --st-inactive-soft:#232e42;
  --st-hold:#f9a8d4; --st-hold-soft:#38152b;
  --st-memo:#a5b4fc; --st-memo-soft:#1d2147;
  --st-sold:#f87171; --st-sold-soft:#3a1618;
  --st-cert:#5ec9f8; --st-cert-soft:#102b3c;
  --st-wroff:#b6c0cf; --st-wroff-soft:#242d3d;
  color-scheme:dark;
}

/* ---------------- DIAMOND BLUE (his palette, 23 Aug 2026) ------------ */
[data-theme="diamond-blue"]{
  --side:#10243e; --side-2:#183452; --side-3:#214464;
  --side-ink:#f8fbff; --side-nav:rgba(248,251,255,.78); --side-dim:rgba(248,251,255,.42);
  --side-label:rgba(173,205,235,.48); --side-label-hi:rgba(206,227,248,.82);
  --side-hover:rgba(110,185,255,.10); --side-line:rgba(255,255,255,.09); --side-ring:rgba(66,153,225,.42);
  --avatar-bg:#2383d6; --avatar-ink:#ffffff;
  --amber:#166bc3; --amber-ink:#ffffff; --amber-soft:#eaf4ff;
  --make:#0f4c8a; --make-ink:#ffffff;                           /* the CREATE color */
  --side-accent:#72b9f2; --code-bg:#e5f2ff; --code-ink:#1466b8;
  --pick-bg:#edf6ff; --pick-line:#5b97d3; --pick-icon:#166bc3;
  --ink:#0b1623; --muted:#5e6e85; --faint:#6f7d90;
  --line:#dbe5ef; --bg:#f5f8fc; --card:#ffffff;
  --panel:#eef4f9;
  --input-bg:#ffffff; --input-line:#d5e1ec;
  --ok:#11794a; --ok-soft:#e5f7ee; --ok-ink:#ffffff;
  --red:#c92a2a; --red-soft:#fdecec; --red-ink:#ffffff;
  --warn:#966000; --warn-soft:#fff3dc;
  --blue:#166bc3; --blue-soft:#eaf4ff; --blue-line:#bfdcf7; --blue-ink:#ffffff;
  --purple:#7651b5; --teal:#087f8c;
  --spd-dn:#087f8c; --spd-up:#7651b5;
  --ghost-ink:#243447; --ghost-line:#71839a; --danger-line:#efb5b5;
  --btn-bg:#10243e; --btn-ink:#ffffff;
  --accent-ink:#ffffff; --accent:var(--blue);
  --r:12px;
  --shadow:0 1px 3px rgba(15,35,58,.07);
  --shadow-lg:0 24px 60px rgba(10,30,55,.22);
  --grid-head:#e8f0f8; --grid-head-ink:#34465a; --grid-head-hi:rgba(255,255,255,.70);
  --grid-row-line:#e1e8f0; --grid-col-line:#dce5ee;
  --grid-odd:#f4f7fb; --grid-hover:#e4f1ff;
  --grid-net:rgba(37,99,235,.07);
  --grid-new:rgba(150,96,0,.08);
  --st-success:#11794a; --st-success-soft:#e5f7ee;
  --st-warning:#966000; --st-warning-soft:#fff3dc;
  --st-danger:#b91c1c; --st-danger-soft:#fdecec;
  --st-info:#0973ab; --st-info-soft:#e4f4ff;
  --st-pending:#966000; --st-pending-soft:#fff1da;
  --st-processing:#166bc3; --st-processing-soft:#eaf4ff;
  --st-approved:#11794a; --st-approved-soft:#e5f7ee;
  --st-rejected:#b91c1c; --st-rejected-soft:#fdecec;
  --st-cancelled:#8b3a3a; --st-cancelled-soft:#f7ecec;
  --st-draft:#5b6472; --st-draft-soft:#eef1f5;
  --st-completed:#087564; --st-completed-soft:#e1f5f0;
  --st-inactive:#5b6472; --st-inactive-soft:#eef1f5;
  --st-hold:#b42367; --st-hold-soft:#fde7f2;
  --st-memo:#4f46c8; --st-memo-soft:#e9e9ff;
  --st-sold:#b91c1c; --st-sold-soft:#fdecec;
  --st-cert:#0973ab; --st-cert-soft:#e4f4ff;
  --st-wroff:#374151; --st-wroff-soft:#e8eaed;
  color-scheme:light;
}

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

/* =====================================================================
   THE TYPEFACE AND ITS SIZE
   =====================================================================
   ONE number, --fs-base, sizes the whole application; every other size
   is a multiple of it. --font-stack is the typeface. Both are chosen on
   a screen; the database stores the CHOICE, the measurements live here.
   Two things do not scale: the 16px phone typing boxes (smaller and the
   phone zooms) and px-sized icon glyphs. Bold is never switchable — it
   carries meaning. A new typeface needs a file in vendor/fonts/, an
   @font-face, a [data-font] block and the database's allowed code. */

/* ---- the families held inside the project (rule 21: no internet) ----
   Every face is SIL Open Font License. local() is tried first; swap keeps
   text readable from first paint. */
@font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:swap;
  src:local("Inter"),url("../vendor/fonts/Inter-Regular.woff2") format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:700;font-display:swap;
  src:local("Inter Bold"),url("../vendor/fonts/Inter-Bold.woff2") format("woff2")}
@font-face{font-family:"Roboto";font-style:normal;font-weight:400;font-display:swap;
  src:local("Roboto"),url("../vendor/fonts/Roboto-Regular.woff2") format("woff2")}
@font-face{font-family:"Roboto";font-style:normal;font-weight:700;font-display:swap;
  src:local("Roboto Bold"),url("../vendor/fonts/Roboto-Bold.woff2") format("woff2")}
@font-face{font-family:"Source Sans 3";font-style:normal;font-weight:400;font-display:swap;
  src:local("Source Sans 3"),url("../vendor/fonts/SourceSans3-Regular.woff2") format("woff2")}
@font-face{font-family:"Source Sans 3";font-style:normal;font-weight:700;font-display:swap;
  src:local("Source Sans 3 Bold"),url("../vendor/fonts/SourceSans3-Bold.woff2") format("woff2")}

/* ---- the choice, on <html>, exactly like the theme ----
   No attribute at all is today's look, so a page that never reaches the
   database still opens readable rather than blank (rule 22). */
:root{
  --font-stack:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --fs-base:17.5px;
}

/* THE HEADING BAND ON EVERY SPREADSHEET WE HAND OUT. A variable because
   rule 27 says every color is one — but NOT a themed one: the bytes are
   opened in Excel, which knows no theme. One value, every theme, every
   branch, declared where all the other colors live. */
:root{
  --sheet-head-bg:#1F3864;      /* the navy band */
  --sheet-head-ink:#FFFFFF;     /* bold white on it */
  --sheet-fault-bg:#FFC7CE;     /* a marked cell on a fault file */
  --sheet-fault-ink:#9C0006;    /* its ink */
  --sheet-note-bg:#FFFFE1;      /* the note box behind a marked cell */
}

/* THE DIAMOND MARKS (his drawings, 21 Oct 2026) — the stone and bulk
   icons, the same in every theme, on a white chip as he drew them. */
:root{
  --gem-gold:#D4A23A;           /* the outline */
  --gem-ice:#A9D6EE;            /* a small stone's centre */
  --gem-body:#FFFFFF;           /* the stone and its chip */
  --gem-pen:#2F6FB0;            /* a revision's pencil */
  --gem-pen-cap:#9CB9D8;        /* its cap */
  --gem-pen-wood:#F2D5A0;       /* its sharpened wood */
  --gem-pen-lead:#333333;       /* its point */
}
.s1gem .gm.rg{fill:none}
.s1gem .pn .pb{fill:var(--gem-body)}
.s1gem .pn .pw{fill:var(--gem-pen)}
.s1gem .pn .pc{fill:var(--gem-pen-cap)}
.s1gem .pn .pt{fill:var(--gem-pen-wood)}
.s1gem .pn .pp{fill:var(--gem-pen-lead)}
.s1gem{display:block;overflow:visible}
.s1gem .gm{stroke:var(--gem-gold);fill:var(--gem-body);stroke-linejoin:round;stroke-linecap:round}
.s1gem .gm .ln{fill:none}
.s1gem .gm .ice{fill:var(--gem-ice);stroke:none}
nav a .ic .s1gem{width:24px;height:24px}
aside.mini nav a .ic .s1gem{width:21px;height:21px}
nav a .ic:has(.s1gem), nav a:hover .ic:has(.s1gem), nav a.on .ic:has(.s1gem){background:var(--gem-body)}
.pin .pic .s1gem{width:15px;height:15px}
.pinbar.icons .pin .pic .s1gem{width:18px;height:18px}
.pinmenu .pinrow .pic .s1gem{width:17px;height:17px}
.qtile .qi .s1gem{width:1.4em;height:1.4em}
html[data-font="system"]     {--font-stack:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
html[data-font="inter"]      {--font-stack:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif}
html[data-font="roboto"]     {--font-stack:"Roboto",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif}
html[data-font="source_sans"]{--font-stack:"Source Sans 3",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif}

/* The five steps. Compact is 9% below today, Extra large 26% above. A
   free number was rejected: somebody types 40 and every screen breaks,
   and a refusal is a worse experience than five steps that all fit. */
html[data-fs="compact"]    {--fs-base:16px}
html[data-fs="normal"]     {--fs-base:17.5px}
html[data-fs="comfortable"]{--fs-base:19px}
html[data-fs="large"]      {--fs-base:20.5px}
html[data-fs="xlarge"]     {--fs-base:22px}

/* One number sizes the whole application. The scroll bar's lane is
   reserved whether or not the bar shows, so the page width never changes
   as it comes and goes. */
html{font-size:var(--fs-base);scrollbar-gutter:stable}
body{
  font-family:var(--font-stack); font-size:1rem; line-height:1.55;
  background:var(--bg); color:var(--ink); -webkit-text-size-adjust:100%;
}
[x-cloak]{display:none!important}
h1,h2,h3,h4{margin:0 0 .4rem;line-height:1.25}
h1{font-size:1.3rem} h2{font-size:1.05rem} h3{font-size:.92rem} h4{font-size:.8rem}
p{margin:.3rem 0}
a{color:var(--blue)}
svg{flex:none}

/* ================= LOGIN ================= */
/* The ground carries two line-drawn diamonds and sparkles, all in code —
   nothing fetched (rule 21). The page shows before anyone's look is
   known, so the ground wears ONE dress in every theme; the card stays on
   the theme's tokens. The reset page shares this id. */
#login{min-height:100%;display:flex;align-items:center;justify-content:center;padding:1.5rem;
  position:relative;overflow:hidden;
  --login-bg-1:#0b1630; --login-bg-2:#16294d; --login-bg-3:#1d3a63;
  --login-gem:#8fb3e8; --login-dot:rgba(207,225,255,.6);
  --gem:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 92'%3E%3Cg fill='none' stroke='white' stroke-width='1.1'%3E%3Cpath d='M30 10 L70 10 L90 32 L50 85 L10 32 Z'/%3E%3Cpath d='M10 32 L90 32'/%3E%3Cpath d='M30 10 L42 32 L50 85'/%3E%3Cpath d='M70 10 L58 32 L50 85'/%3E%3Cpath d='M42 32 L50 10 L58 32'/%3E%3C/g%3E%3C/svg%3E");
  background:
    radial-gradient(circle at 18% 22%,var(--login-dot) 0 1.5px,transparent 3px),
    radial-gradient(circle at 30% 64%,var(--login-dot) 0 1px,transparent 2.5px),
    radial-gradient(circle at 64% 18%,var(--login-dot) 0 1px,transparent 2.5px),
    radial-gradient(circle at 76% 70%,var(--login-dot) 0 1.5px,transparent 3px),
    radial-gradient(circle at 52% 82%,var(--login-dot) 0 1px,transparent 2.5px),
    radial-gradient(circle at 86% 38%,var(--login-dot) 0 1px,transparent 2.5px),
    linear-gradient(150deg,var(--login-bg-1) 0%,var(--login-bg-2) 55%,var(--login-bg-3) 100%)}
/* The two diamonds. Decoration only: no pointer events, clipped by the
   page, and kept under the card (the card is lifted one layer so the
   lines can never show through it). */
#login::before,#login::after{content:"";position:absolute;z-index:0;pointer-events:none;
  background:var(--login-gem);
  -webkit-mask:var(--gem) center/contain no-repeat;mask:var(--gem) center/contain no-repeat}
#login::before{width:520px;height:478px;left:-120px;top:38%;opacity:.16}
#login::after{width:420px;height:386px;right:-60px;top:-90px;transform:rotate(18deg);opacity:.12}
#login .box{background:var(--card);border-radius:16px;padding:2rem 1.6rem;width:100%;max-width:370px;
  box-shadow:var(--shadow-lg);position:relative;z-index:1}
/* The icon above the name, and the name drawn in its own letters: "SJ"
   in the page ink and "NEX" in the theme's blue, so both read on every
   theme's card. The words stay readable by a screen reader. */
#login .mark{width:72px;height:72px;border-radius:16px;overflow:hidden;margin:0 auto .9rem;
  box-shadow:var(--shadow)}
#login h1{text-align:center;font-size:1.25rem;margin-bottom:.15rem}
#login h1 .wm{height:26px;width:auto;display:block;margin:0 auto}
#login h1 .wm-sj{fill:currentColor}
#login h1 .wm-nex{fill:var(--blue)}
#login .sub{text-align:center;color:var(--muted);font-size:.78rem;margin:.55rem 0 1.5rem;letter-spacing:.02em}
#login .field{margin-bottom:.75rem}
/* THE ONE EXCEPTION TO THE BOX SIZE, deliberate: two boxes on a wide
   empty card are not a dense screen, and a 26px box floating in a 370px
   card reads as broken. */
#login input{padding:.5rem .55rem}
#login button{width:100%;margin-top:.6rem}

/* Show-password toggle. The eye sits INSIDE the box at its right edge;
   the input gains right padding so typing never runs under it.
   currentColor follows the theme. The #login .pweye line exists because
   `#login button` sets every button full width at ID strength. */
.pwbox{position:relative}
.pwbox input{padding-right:2.4rem}
.pweye{position:absolute;top:0;right:0;height:100%;width:2.2rem;display:flex;align-items:center;
  justify-content:center;background:none;border:0;color:var(--muted);cursor:pointer;
  border-radius:0 8px 8px 0}
#login .pweye{width:2.2rem;margin-top:0}
.pweye:hover{color:var(--ink)}
.pweye:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.pweye svg{width:18px;height:18px}

/* ================= SHELL ================= */
.shell{display:flex;min-height:100%}
aside{width:236px;flex:none;background:var(--side);color:var(--side-ink);display:flex;flex-direction:column;
  position:fixed;inset:0 auto 0 0;z-index:40;transform:translateX(-100%);transition:transform .22s ease}
aside.open{transform:none}
@media(min-width:940px){ aside{position:sticky;top:0;height:100vh;transform:none} }

.brandbar{padding:1.1rem 1rem;border-bottom:1px solid var(--side-line);
  display:flex;gap:.6rem;align-items:center}
/* The mark is the SJ NEX icon itself; its faint ring keeps a navy icon
   from sinking into a navy sidebar, and follows each theme's sidebar. */
.brandbar .mark{width:36px;height:36px;border-radius:9px;overflow:hidden;flex:none;
  box-shadow:0 0 0 1px var(--side-ring)}
.brandbar .mark img,#login .mark img{width:100%;height:100%;display:block}
.brandbar .n1{font-weight:600;font-size:.92rem}
.brandbar .n2{font-size:.62rem;color:var(--side-accent);letter-spacing:.14em;font-weight:600}
/* The running build's date (31 July 2026) — quiet support detail, not
   branding. Hidden with the rest of .txt when the sidebar is mini. */
.brandbar .n3{font-size:.6rem;color:var(--side-dim);margin-top:.15rem;
  white-space:nowrap}

.navwrap{flex:1;overflow-y:auto;overflow-x:hidden;padding:.7rem 0 1.2rem}
/* THE SCROLLBAR WEARS ITS SURFACE (his go, 19 Sep 2026). The browser's
   grey bar cut the menu's paper at the hero card's edge. Everywhere: a
   thin bar, no track, the thumb in the surface's own muted ink. On the
   menu alone the thumb shows only while the pointer is over the menu,
   so the column reads as paper until it is wanted. */
*{scrollbar-width:thin;scrollbar-color:var(--faint) transparent}
*::-webkit-scrollbar{width:8px;height:8px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--faint);border-radius:4px}
*::-webkit-scrollbar-thumb:hover{background:var(--muted)}
*::-webkit-scrollbar-corner{background:transparent}
.navwrap{scrollbar-color:transparent transparent}
.navwrap:hover{scrollbar-color:var(--side-dim) transparent}
.navwrap::-webkit-scrollbar{width:6px}
.navwrap::-webkit-scrollbar-thumb{background:transparent;border-radius:3px}
.navwrap:hover::-webkit-scrollbar-thumb{background:var(--side-dim)}
.navwrap:hover::-webkit-scrollbar-thumb:hover{background:var(--side-ink)}
.navlabel{font-size:.6rem;letter-spacing:.16em;color:var(--side-label);
  padding:.9rem 1rem .35rem;font-weight:700;white-space:nowrap}
nav a{width:100%;display:flex;align-items:center;gap:.7rem;color:var(--side-nav);
  padding:.42rem .8rem;font-size:.86rem;text-decoration:none;border-left:3px solid transparent}
nav a:hover{background:var(--side-hover);color:var(--side-ink)}
nav a.on{background:var(--side-2);color:var(--side-ink);border-left-color:var(--side-accent);font-weight:600}
/* Pale chip: white laid over the module color. The sidebar is dark in every
   theme, and most emoji are dark glyphs, so a tinted chip leaves them
   invisible — 👥 and 💱 worst of all. This keeps the color coding and the
   contrast at the same time. */
nav a .ic{width:30px;height:30px;border-radius:9px;flex:none;font-size:16px;line-height:1;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(0deg,rgba(255,255,255,.84),rgba(255,255,255,.84)),var(--c);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.06);
  transition:background .15s,box-shadow .15s}
nav a:hover .ic{background:linear-gradient(0deg,rgba(255,255,255,.92),rgba(255,255,255,.92)),var(--c)}
nav a.on .ic{
  background:linear-gradient(0deg,rgba(255,255,255,.95),rgba(255,255,255,.95)),var(--c);
  box-shadow:0 0 0 2px var(--side-ring), inset 0 0 0 1px rgba(0,0,0,.06)}
nav a .lb{white-space:nowrap;overflow:hidden}
/* THE PIN STAR. Right edge of the row, faint until hovered or pinned,
   gold when pinned. A tap target for phones, where drag does not work.
   Hidden with the label when the sidebar collapses to icons. */
nav a .star{margin-left:auto;flex:none;cursor:pointer;font-size:15px;line-height:1;
  color:var(--side-nav);opacity:.45;padding:0 .1rem;transition:opacity .12s,color .12s}
nav a .star:hover{opacity:1;color:var(--side-accent)}
nav a .star.on{opacity:1;color:var(--side-accent)}
nav a:hover .star{opacity:.85}

/* COLLAPSED SIDEBAR — a 50px rail. Each number is what makes 50px fit:
   the brand square is 30px inside .4rem (44px); a nav row's 3px accent
   border sits inside its width, leaving 36.5px for a 26px chip; the
   emoji drops to 20px so it stays inside the tint, at a specificity
   (0,2,3) that beats `nav a .ic` (0,1,2). Below 940px the sidebar is a
   full-width drawer and none of this applies. */
@media(min-width:940px){
  aside.mini{width:50px}
  aside.mini .brandbar{padding:1.1rem .4rem;justify-content:center}
  aside.mini .brandbar .mark{width:30px;height:30px;border-radius:8px}
  aside.mini .brandbar .txt{display:none}
  aside.mini .navlabel{opacity:0;height:.9rem;padding:.5rem 0 0}
  aside.mini nav a{justify-content:center;padding:.42rem .3rem;gap:0}
  aside.mini nav a .ic{width:26px;height:26px;border-radius:8px;font-size:20px}
  aside.mini nav a .lb{display:none}
  aside.mini nav a .star{display:none}
  /* THE COLLAPSED RAIL SPEAKS SOFTLY: icons drain to a quiet grey, shapes
     intact, and color returns on the row you are ON and under the hand.
     Short transition so hover feels instant. */
  aside.mini nav a .ic{filter:grayscale(.85) opacity(.65);transition:filter .12s ease}
  aside.mini nav a:hover .ic,
  aside.mini nav a.on .ic{filter:none}
}
/* There is no sidebar foot: the signed-in name sits beside the avatar in
   the top bar (.who) and the dot on the avatar's corner. */
.scrim{position:fixed;inset:0;background:rgba(10,16,28,.5);z-index:35;display:none}
.scrim.on{display:block}
@media(min-width:940px){ .scrim{display:none!important} }

.main{flex:1;min-width:0;display:flex;flex-direction:column}
/* THE BAR IS 42 px, NOT 55 (his go, 18 Sep 2026, "the page to also
   having some space"): padding .25rem, the burger and theme button
   .3rem, the branch and currency pickers .1rem — every item at 32 or
   under, so the bar sits at the tallest of them plus its padding. */
.topbar{background:var(--card);border-bottom:1px solid var(--line);padding:.25rem .8rem;display:flex;
  align-items:center;gap:.6rem;position:sticky;top:0;z-index:30;flex-wrap:wrap}
/* ABOVE 900px THE BAR IS ONE ROW. A wrapping flex row wraps BEFORE it
   shrinks, so wrapping is off wherever the pin strip shows; the strip is
   the only item that gives up width. Below 900px the strip hides and
   wrapping serves the small-screen stack. */
@media (min-width:901px){ .topbar{flex-wrap:nowrap} }
.burger{background:var(--card);border:1px solid var(--line);border-radius:9px;padding:.3rem .5rem;
  /* --ink, NOT --side: the icon strokes with currentColor and sits on
     the TOPBAR card, not the sidebar. Borrowing the sidebar's own
     BACKGROUND as its ink drew white-on-white the day a light
     sidebar arrived (Professional Light — the business, 2 Aug 2026). */
  cursor:pointer;display:flex;align-items:center;color:var(--ink)}
.burger:hover{background:var(--blue-soft);border-color:var(--blue-line)}
/* The title's margin-right:auto sweeps the pins and the right cluster to
   the RIGHT edge. Nothing in the bar gives up width except the crumb —
   every other item is flex:none — and the crumb's min-width is 110px
   because fitPins() plans the strip around that minimum; zero would let
   the title vanish before a chip did. */
.crumb{font-size:.82rem;color:var(--muted);font-weight:500;margin-right:auto;
  flex:0 1 auto;min-width:110px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.crumb b{color:var(--ink)}
/* Under 1200px the application's own name goes and the module name stays.
   You always know which system you are in; the module is the part that
   changes, and dropping the prefix buys roughly five more chips on a
   laptop (the business's pick, 4 Aug 2026). */
@media (max-width:1199px){.crumb{min-width:72px}.crumb .cpre{display:none}}
/* THE ONE-ROW BAR, ITEM BY ITEM. A default flex item shrinks; that is how
   fifteen pins pushed the branch picker's select from 260px to 146px at
   1366px. These are the controls, and a control is not negotiable. */
.topbar>.burger,.topbar>.pinwrap,.topbar>.branchpick,.topbar>.themepick,
.topbar>.whomenu{flex:none}
/* THE PINS (3 Aug 2026). Small chips on the RIGHT of the bar, first in
   the right cluster — just left of the branch picker. */
/* A FIXED FOOTPRINT. A shrinkable strip still asks for its natural width
   and every neighbour pays. So this block is flex:none and fitPins() in
   app.js measures what the bar has left and fits the chips in three
   steps: icon + label, icon only, then the tail into an overflow menu.
   position:relative because that menu hangs off this block. */
.pinwrap{position:relative;display:flex;align-items:center;gap:.3rem;flex:none}
.pinbar{display:flex;align-items:center;gap:.3rem;flex-wrap:nowrap}
/* A chip is never squeezed thinner than its own text: the strip is fitted
   by hiding WHOLE chips, never by slicing one. */
.pin{flex:none}
.pin{display:flex;align-items:center;gap:.32rem;text-decoration:none;white-space:nowrap;
  background:var(--card);border:1px solid var(--line);border-radius:8px;
  padding:.22rem .5rem;color:var(--ink);font-size:.78rem;cursor:grab}
.pin:hover{background:var(--blue-soft);border-color:var(--blue-line)}
.pin.on{background:var(--amber-soft);border-color:var(--amber)}
.pin .pic{font-size:13px;line-height:1;flex:none}
.pin .plb{font-weight:600}
.pin:active{cursor:grabbing}
/* A chip fitPins() could not fit. display:none, so it leaves the layout
   AND the tab order together — it is reached from the overflow menu, and
   a keyboard must not stop at something nobody can see. */
.pin.gone{display:none}
/* ICON MODE. The label goes and the emoji becomes a 22px tile tinted with
   the module's color, as the sidebar rows do — untinted dark glyphs read
   as a smudge. The screen you are ON keeps its word. */
.pinbar.icons .pin{padding:.2rem .3rem;gap:0}
.pinbar.icons .pin .plb{display:none}
.pinbar.icons .pin.on .plb{display:inline;margin-left:.34rem}
.pinbar.icons .pin .pic{width:22px;height:22px;border-radius:6px;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(0deg,rgba(255,255,255,.84),rgba(255,255,255,.84)),var(--c);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.06)}
/* THE OVERFLOW CHIP AND ITS MENU. A hidden sideways scroll has no
   affordance; the chip counts what is hidden and the menu is the same
   dropdown shape as the theme and account menus — one behaviour. */
.pinmore{flex:none;display:none;align-items:center;gap:.22rem;background:var(--card);
  border:1px solid var(--line);border-radius:8px;padding:.22rem .42rem;
  color:var(--muted);font:inherit;font-size:.75rem;font-weight:700;cursor:pointer}
.pinmore.show{display:flex}
.pinmore:hover{background:var(--blue-soft);border-color:var(--blue-line);color:var(--blue)}
.pinmenu{position:absolute;right:0;top:calc(100% + .4rem);z-index:60;min-width:200px;max-width:290px;
  background:var(--card);border:1px solid var(--line);border-radius:11px;
  box-shadow:0 12px 34px rgba(0,0,0,.18);padding:.3rem}
/* The menu rows carry the FULL name — there is room here, and this is
   where somebody goes precisely when they could not tell what an icon
   meant. */
.pinmenu .pinrow{display:flex;align-items:center;gap:.55rem;padding:.42rem .5rem;
  border-radius:7px;text-decoration:none;color:var(--ink);font-size:.84rem}
.pinmenu .pinrow:hover{background:var(--blue-soft)}
.pinmenu .pinrow .pic{font-size:15px;line-height:1;flex:none}
.pinmenu .pinrow .plb{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:900px){.pinwrap{display:none}}
/* THE BRANCH PICKER WEARS ITS THEME, NOT BLUE. The name is ordinary ink
   at full weight; the box says it can be clicked and is drawn from the
   theme's tokens. Measured ON THE TOP BAR: the fill nearly matches the
   bar, so the BORDER draws the boundary, tuned to 3.1-3.5:1 in every
   theme. */
/* A PLACE YOU STAND IN (his go, design A, 19 Sep 2026): a solid pill in
   the blue pair, which reads AA in all seven themes (the avatar pair does
   not in Diamond Blue, 3.97:1) — the one control that changes every
   screen behind it wears fill, round ends and a pin, so it can never
   read as the currency lens's twin. The lens keeps the light box. */
.branchpick{display:flex;align-items:center;gap:.4rem;background:var(--blue);
  border:1px solid var(--blue);border-radius:999px;padding:.1rem .5rem;position:relative}
.branchpick svg{color:var(--blue-ink)}
/* The box's content is a BUTTON now (22 Aug 2026) — the list it opens is
   the application's own, because the browser's popup could not be
   dressed, grouped or ticked. The box keeps its chrome; only the control
   inside changed. */
.branchpick .bpbtn{display:flex;align-items:center;gap:.4rem;background:none;border:0;
  padding:.05rem .1rem;cursor:pointer;font:inherit;font-size:.84rem;color:var(--blue-ink)}
/* the NAME reads bold, the code small after it (his go, 19 Sep 2026);
   both in the pill's own ink. 200px comfortable / 120 narrow is the
   name span's budget. */
.branchpick .bpc{font-weight:500;font-size:.76rem}
.branchpick .bpn{font-weight:700;max-width:200px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.branchpick .bpbtn > svg:last-child{color:var(--blue-ink)}
/* the hairline between where you stand and how money reads */
.barsep{width:1px;height:22px;background:var(--line);flex:none;margin:0 .1rem}
@media(max-width:720px){ .branchpick .bpn{max-width:120px} }
/* The list is OURS — the browser's popup draws pale-on-pale on dark
   themes. Paper and letters are set TOGETHER from the theme's card/ink
   pair, never one without the other. */
.branchmenu{position:absolute;left:0;top:calc(100% + .4rem);z-index:60;min-width:230px;
  max-width:300px;background:var(--card);color:var(--ink);border:1px solid var(--line);
  border-radius:11px;box-shadow:0 12px 34px rgba(0,0,0,.18);padding:.3rem;
  max-height:60vh;overflow:auto}
.branchmenu .bm{width:100%;display:flex;align-items:center;gap:.5rem;background:none;
  border:0;padding:.42rem .5rem;border-radius:7px;cursor:pointer;font:inherit;
  font-size:.84rem;color:var(--ink);text-align:left;white-space:nowrap}
.branchmenu .bm:hover{background:var(--blue-soft)}
.branchmenu .bm.on{background:var(--blue-soft);font-weight:650}
.branchmenu .bmc{font-weight:700;min-width:2.2rem}
.branchmenu .bmn{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis}
.branchmenu .bmr{font-size:.76rem;color:var(--muted)}
.branchmenu .bm .tick{color:var(--accent);font-weight:700}
.branchmenu .bm.off,.branchmenu .bm.off .bmc{color:var(--muted)}
.branchmenu .bmlock{display:inline-flex;align-items:center}   /* read only (0804) */
/* the button's white icon rule (.branchpick svg) reaches into the list;
   the lock wears its row's muted ink instead — found rendered, 30 Sep */
.branchmenu .bmlock svg{color:inherit}
.branchmenu .bmg{font-size:.68rem;letter-spacing:.5px;text-transform:uppercase;
  color:var(--muted);padding:.35rem .5rem .15rem;border-top:1px solid var(--line);
  margin-top:.25rem}
/* The hover note — OUR note, never the browser's tooltip (his standing
   rule), paper and ink painted together like the list above. */
.bnote{position:absolute;left:0;top:calc(100% + .4rem);z-index:59;width:max-content;
  max-width:280px;background:var(--card);color:var(--ink);border:1px solid var(--line);
  border-radius:9px;box-shadow:0 8px 22px rgba(0,0,0,.14);padding:.45rem .6rem;
  font-size:.78rem;line-height:1.45}
.bnote b{display:block;font-size:.8rem}
.bnote span{display:block;color:var(--muted)}
/* Who is signed in — name and avatar together, top right. The name is
   quiet weight so the branch picker stays loudest, and hides on narrow
   screens; the avatar with its dot remains. */
.who{display:flex;align-items:center;gap:.5rem;min-width:0}
.who .name{font-size:.8rem;font-weight:600;color:var(--ink);max-width:18ch;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:720px){.who .name{display:none}}
.avatar{width:30px;height:30px;border-radius:50%;background:var(--avatar-bg);color:var(--avatar-ink);display:flex;
  align-items:center;justify-content:center;font-size:.72rem;font-weight:700;flex:none;
  position:relative}
/* The avatar's corner dot CARRIES THE CONNECTION — green, amber slow,
   red gone, grey checking — ringed in the bar's background. Words and
   numbers live in the account menu; a lost connection still raises the
   red strip. */
.avatar .dot{position:absolute;right:-2px;bottom:-2px;width:10px;height:10px;
  border-radius:50%;background:var(--muted);border:2px solid var(--card)}
.avatar .dot.on{background:var(--ok)}
.avatar .dot.w{background:var(--warn)}
.avatar .dot.off{background:var(--st-danger)}
.avatar .dot.n{background:var(--muted)}
/* THE ACCOUNT MENU (3 Aug 2026) -- the who block became a button that
   opens it; the dropdown is the thememenu's shape, one shared look for
   every topbar menu. Kept deliberately short: entries join only when
   their modules exist (rule 22 -- no doors that open nothing). */
.whomenu{position:relative}
.whomenu > .who{background:none;border:0;padding:.05rem .25rem;border-radius:8px;cursor:pointer;font:inherit}
.whomenu > .who:hover{background:var(--blue-soft)}
/* 272px floor since the connection block moved in (22 Aug 2026): the
   speed row's measured floor — button beside a three-digit result —
   travelled here with it. */
/* NEVER TALLER THAN THE WINDOW (his go, 17 Oct 2026): the name card
   and the foot hold still, only the middle scrolls, so Sign out is
   always in view on a laptop. Held at its widest (300) so the card
   and the line under Sign out never wrap by the menu's own whim. */
.accmenu{position:absolute;right:0;top:calc(100% + .4rem);z-index:60;min-width:272px;max-width:300px;width:300px;
  background:var(--card);border:1px solid var(--line);border-radius:11px;
  box-shadow:0 12px 34px rgba(0,0,0,.18);padding:.3rem;
  display:flex;flex-direction:column;overflow:hidden;
  max-height:calc(100vh - var(--s1-topbar-h,2.55rem) - .9rem)}
.accmenu:focus{outline:none}
.acc-mid{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  background:linear-gradient(var(--card) 30%,transparent) top/100% 14px no-repeat local,
    linear-gradient(transparent,var(--card) 70%) bottom/100% 14px no-repeat local,
    radial-gradient(farthest-side at 50% 0,rgba(0,0,0,.14),transparent) top/100% 7px no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%,rgba(0,0,0,.14),transparent) bottom/100% 7px no-repeat scroll;
  background-color:var(--card)}
/* the connection: one folded line, the bars and Test speed inside */
.accmenu .acc-net{border-top:1px solid var(--line);margin:.25rem 0 0;padding:.2rem .5rem .3rem}
.accmenu .net-spd{border-top:0;padding-top:.1rem}
.accmenu .acc-nethd{width:100%;display:flex;align-items:center;gap:.5rem;background:none;border:0;cursor:pointer;
  font:inherit;font-size:.84rem;font-weight:600;color:var(--ink);padding:.45rem 0 .3rem;border-radius:7px;text-align:left}
.accmenu .acc-nethd.open{margin-bottom:.3rem}
.acc-nethd .acc-nethl{flex:1}
.acc-nethd .muted{font-weight:400}
.acc-nethd:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.acc-foot{flex:none;border-top:1px solid var(--line);margin-top:.25rem;padding-top:.25rem}
.acc-foot > button{width:100%;display:flex;align-items:center;gap:.55rem;background:none;border:0;
  padding:.42rem .5rem;border-radius:7px;cursor:pointer;font:inherit;font-size:.84rem;
  color:var(--ink);text-align:left}
.acc-foot > button:hover{background:var(--blue-soft)}
.acc-so2{display:flex;flex-direction:column;line-height:1.2}
.acc-so2 .muted{font-size:.74rem}
/* the name card: name, role in full, home branch, the User ID in its chip */
.acc-id{flex:none;display:flex;flex-wrap:wrap;align-items:flex-start;gap:.35rem .7rem;padding:.6rem .5rem .65rem;
  border-bottom:1px solid var(--line);margin-bottom:.25rem}
.acc-id > .acc-home,.acc-id > .acc-uid{flex-basis:100%}
.acc-id > .avatar{width:40px;height:40px;flex:none;font-size:.86rem;font-weight:650}
.acc-idt{min-width:0;display:flex;flex-direction:column;gap:.12rem}
.acc-name{font-weight:650;font-size:.86rem;overflow-wrap:anywhere}
.acc-role{font-size:.8rem;color:var(--ink);line-height:1.25}
.acc-home{display:flex;align-items:center;gap:.3rem;font-size:.78rem;line-height:1.25}
.acc-home svg{flex:none;width:12px;height:12px}
.acc-home b{font-weight:600;color:var(--ink)}
.acc-uid{display:flex;flex-wrap:wrap;align-items:center;gap:.2rem .3rem;font-size:.74rem;line-height:1.25}
.acc-uid > *{flex:none;white-space:nowrap}
.acc-uid svg{width:12px;height:12px}
/* THE PAGE GAP — the ONLY frame around a route. app.html wraps every
   route in one .content, so this sets the gap on every page: the same
   number on all four sides, in px so it does not move with the font —
   5px on a computer, 3px on a phone. A module never adds page-level
   padding. Cards keep their own inner padding. */
.content{padding:3px;width:100%} /* full-width: no max-width cap (2026-07-27) */
@media(min-width:700px){ .content{padding:5px} }

/* ================= HERO / STATS ================= */
.hero{background:linear-gradient(120deg,var(--side) 0%,var(--side-3) 100%);color:var(--side-ink);
  border-radius:16px;padding:1.5rem 1.3rem;margin-bottom:1.2rem;position:relative;overflow:hidden}
.hero::after{content:'';position:absolute;right:-70px;top:-70px;width:240px;height:240px;
  border-radius:50%;background:radial-gradient(circle,rgba(240,160,42,.24),transparent 68%)}
.hero .kicker{display:flex;align-items:center;gap:.5rem;font-size:.62rem;letter-spacing:.16em;
  color:var(--side-accent);font-weight:700;margin-bottom:.7rem}
.hero .kicker i{width:22px;height:2px;background:var(--side-accent);display:block}
.hero h1{font-size:1.55rem;font-weight:700}
.hero h1 span{color:var(--side-accent)}
.hero p{color:var(--side-nav);font-size:.86rem;max-width:56ch;margin-top:.5rem}
.hero .tagline{display:inline-block;margin-top:1rem;background:var(--side-hover);
  border:1px solid var(--side-line);border-radius:999px;padding:.35rem .8rem;font-size:.73rem}
.sectitle{display:flex;align-items:center;gap:.5rem;font-size:.63rem;letter-spacing:.15em;
  color:var(--muted);font-weight:700;margin:1.4rem 0 .7rem}
.sectitle i{width:18px;height:2px;background:var(--ok);display:block}
.sectitle .live{width:7px;height:7px;border-radius:50%;background:#25c168}
.stats{display:grid;grid-template-columns:repeat(2,1fr);gap:.65rem}
@media(min-width:640px){ .stats{grid-template-columns:repeat(3,1fr)} }
@media(min-width:960px){ .stats{grid-template-columns:repeat(6,1fr)} }
.stat{background:var(--card);border:1px solid var(--line);border-left:4px solid var(--blue);
  border-radius:11px;padding:.8rem .75rem}
.stat .n{font-size:1.5rem;font-weight:700;line-height:1;margin-top:.45rem}
.stat .l{font-size:.72rem;color:var(--muted);margin-top:.25rem}
.stat.b1{border-left-color:var(--blue)}   .stat.b2{border-left-color:var(--ok)}
.stat.b3{border-left-color:var(--amber)}  .stat.b4{border-left-color:var(--red)}
.stat.b5{border-left-color:var(--purple)} .stat.b6{border-left-color:var(--teal)}

/* ================= HOME: THE BRANCH STRIP AND THE SHORTCUTS =============
   NO TYPED LIST OF BRANCHES — both grids draw from the payload the shell
   holds. A branch tile is a BUTTON, not a card, because pressing it
   moves your books; keyboard and screen reader need to know. ========== */
.bstrip{display:grid;grid-template-columns:repeat(2,1fr);gap:.6rem}
@media(min-width:700px){ .bstrip{grid-template-columns:repeat(3,1fr)} }
@media(min-width:1150px){ .bstrip{grid-template-columns:repeat(6,1fr)} }
.bcard{background:var(--card);border:1px solid var(--line);border-left:4px solid var(--line);
  border-radius:11px;padding:.6rem .65rem;text-align:left;cursor:pointer;font:inherit;
  color:inherit;display:block;width:100%;transition:border-color .12s,box-shadow .12s}
.bcard:hover{border-color:var(--blue-line);box-shadow:var(--shadow)}
.bcard:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.bcard .bn{font-weight:650;font-size:.83rem;margin-top:.35rem;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bcard .bm{font-size:.7rem;color:var(--muted);margin-top:.2rem;
  display:flex;gap:.4rem;flex-wrap:wrap}
/* WHERE YOU ARE STANDING, unmistakably — the one tile that is not a
   destination. It is not disabled: pressing it is simply a no-op, and a
   greyed-out tile in the middle of a row reads as broken. */
.bcard.on{border-left-color:var(--ok);background:var(--ok-bg,var(--card));
  border-color:var(--ok)}
.bcard.off{opacity:.62;border-left-color:var(--muted)}
.bcard .here{font-size:.6rem;letter-spacing:.1em;font-weight:700;color:var(--ok)}

.quick{display:grid;grid-template-columns:repeat(2,1fr);gap:.55rem}
@media(min-width:560px){ .quick{grid-template-columns:repeat(4,1fr)} }
@media(min-width:1150px){ .quick{grid-template-columns:repeat(8,1fr)} }
.qtile{background:var(--card);border:1px solid var(--line);border-radius:11px;
  padding:.75rem .45rem;display:flex;flex-direction:column;align-items:center;gap:.4rem;
  text-decoration:none;color:inherit;transition:border-color .12s,box-shadow .12s}
.qtile:hover{border-color:var(--blue-line);box-shadow:var(--shadow)}
.qtile:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.qtile .qi{font-size:1.25rem;line-height:1}
.qtile .ql{font-size:.71rem;color:var(--muted);text-align:center;line-height:1.25}

/* ================= CARDS / FORMS ================= */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);
  padding:.65rem .75rem;margin-bottom:.55rem}
/* TWO CARDS THAT ARE ONE (his word, 18 Sep 2026, the invoice register:
   "remove the space"): the upper card ends flat with no gap beneath, the
   lower begins flat with no padding above, so the eye reads one card;
   the splitter, when drawn, rides the seam. */
.card.joins{margin-bottom:0;padding-bottom:.35rem;border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}
.card.joined{border-top:0;border-top-left-radius:0;border-top-right-radius:0;padding-top:.35rem}
/* a breath at the seam, both sides (his eye, 18 Sep 2026: "looks it
   stick to each other"); the foot line gives up its overhang there */
.card.joins .pgfoot{margin-bottom:0}
/* when the upper card shows nothing beneath its band (the stone view),
   the seam closes: no breath either side, so the lower card's strip
   sits 7 px under the band exactly as the document grid's lead does */
.card.joined.atop{padding-top:0;margin-top:-.35rem}
/* halved on his word, 21 Aug 2026 — the heading hugs its card's content */
.card-h{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:.22rem}
/* a title line that opens its card sits 5 px higher (his go, 18 Sep
   2026, "the page to also having some space") — every register and
   every document, one rule, the card's padding otherwise untouched */
.card > .card-h:first-child{margin-top:-.3rem}
.card-h .t{font-weight:650;font-size:.92rem}
/* A card whose only job is to hold a grid does not need a paragraph of air
   under its heading. */
.card > .muted:first-of-type{margin:.15rem 0 .45rem}
.card-h .sp{margin-left:auto}
/* A page's one sentence rides its title line and gives way first:
   trimmed with an ellipsis, its whole wording in the shell's note (.ov);
   a figure inside it keeps the page's ink. */
.card-h > .gives{flex:1 1 0;min-width:0;max-width:max-content;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;margin-left:.5rem}
.card-h > .gives b{color:var(--ink);font-weight:650}

/* A CARD HEADING THAT FOLDS ITS CARD AWAY. Owned here, never by a
   module. The chevron sits at the LEFT and the whole pair takes the
   click — the bar's right end rewrites itself and moves under the hand.
   ONE glyph rotated, as .navlabel and Collapse all use. The negative
   margin keeps the hover target off the heading's line. */
.card-h .fold{display:inline-flex;align-items:center;gap:.4rem;cursor:pointer;
  user-select:none;border-radius:5px;padding:.12rem .3rem;margin:-.12rem -.3rem;
  transition:background .13s}
.card-h .fold:hover{background:var(--panel)}
.card-h .fold .chev{flex:0 0 auto;opacity:.6;transition:transform .18s}
.card-h .fold.shut .chev{transform:rotate(-90deg)}

/* WHAT A FOLDED CARD STILL SAYS: one wrapping line, quiet label, ink
   value. `.miss` is the application's warning color for a thing not yet
   done. */
.densum{display:flex;flex-wrap:wrap;gap:.15rem 1.1rem;font-size:.8rem;
  color:var(--ink);align-items:baseline}
.densum i{font-style:normal;color:var(--muted);font-size:.92em}
.densum b{font-weight:600}
.densum .miss{color:var(--warn);font-weight:600}
.code{font-weight:700;font-size:.68rem;line-height:1;font-family:inherit;background:var(--code-bg);
  color:var(--code-ink);border:1px solid var(--blue-line);
  padding:.28rem .43rem;border-radius:5px;letter-spacing:.05em}
.grid{display:grid;grid-template-columns:1fr;gap:.65rem}
@media(min-width:620px){ .grid.two{grid-template-columns:1fr 1fr}
  .grid.three{grid-template-columns:repeat(3,1fr)} }
/* ONE BOX ACROSS THE WHOLE ROW, whatever the column count — so no screen
   writes a grid-column of its own (rule 27) and a wide control sits IN
   the same grid as its neighbours. */
.grid > .full{grid-column:1 / -1}

/* A CHIP THAT CANNOT BE UNTICKED, AND LOOKS LIKE IT (0128). Not
   `disabled`: it must still take a click, because the click is how it
   explains itself. Muted and cursor:default say "fixed" before the
   sentence has to. */
.chip.lock{opacity:.72;cursor:default;border-style:dashed}
.chip.lock:hover{border-color:var(--line)}

/* ============ THE THIS-BRANCH / ALL-BRANCHES SWITCH ============
   A two-button switch: the risk is not turning it on but forgetting it
   is on, and this reads as where you are standing. Rendered only when
   the right is held — a greyed-out hint at records you cannot see is
   worse than nothing. */
.segbtn{display:inline-flex;border:1px solid var(--line);border-radius:8px;overflow:hidden}
.segbtn button{border:0;background:var(--card);color:var(--muted);font:inherit;
  font-size:.76rem;padding:.34rem .7rem;cursor:pointer;white-space:nowrap}
.segbtn button + button{border-left:1px solid var(--line)}
.segbtn button:hover{color:var(--ink)}
.segbtn button.on{background:var(--blue);color:#fff;font-weight:650}
.segbtn button:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
/* THE CHIP THAT STOPS SOMEBODY FORGETTING. Deliberately loud: a customer
   list silently spanning six countries is how the wrong Meridian gets
   telephoned. */
.allchip{display:inline-flex;align-items:center;gap:.35rem;font-size:.7rem;font-weight:650;
  letter-spacing:.04em;background:var(--amber);color:#1a1204;
  border-radius:999px;padding:.22rem .6rem}

/* ============ THE PARTY DETAILS TAB, IN TWO COLUMNS ============
   Two thirds and one third: the left holds the three-up identity
   fields, the right two short blocks. Splits at 1150px and not before —
   narrower and the right column cannot hold a dropdown and a table.
   minmax(0,…) stops a wide table or long word pushing the other column
   off screen. */
.pdetail{display:grid;grid-template-columns:1fr;gap:1.1rem;align-items:start}
@media(min-width:1150px){ .pdetail{grid-template-columns:minmax(0,2fr) minmax(0,1fr);gap:1.4rem} }
/* A quiet rule between the columns on a wide screen only — it reads as
   two panels rather than one long run of fields that happens to wrap. */
@media(min-width:1150px){ .pdetail > .side{border-left:1px solid var(--line);padding-left:1.3rem} }

/* ============ THE PARTIES PAGE, ONE ROLE PER PARTY (29 Sep 2026) ============
   The role tabs carry their counts; the find box, status pills and
   category ride the grid's own row; the record wears a one-line strip,
   role cards, and an Overview of cards with bars drawn in place. */
.ptabs .ptn{font-weight:700;opacity:.8;margin-left:.15rem}
.gridtools .pfind{flex:0 1 20rem;min-width:11rem}
.gridtools .pcat{flex:0 0 10rem}
.linkbtn{border:0;background:transparent;color:var(--blue);text-decoration:underline;
  cursor:pointer;font:inherit;font-size:.82rem;padding:0 .2rem}
/* the record's tab row carries the facts at its right end: the row owns
   the line and the stickiness, the tabs keep their own size, the facts
   take what is left and never wrap (the screen folds them, stripFit) */
.ptabrow{display:flex;align-items:center;gap:1rem;border-bottom:1px solid var(--line);margin:-.2rem 0 .7rem}
.ptabrow .tabs{border-bottom:0;margin:0;flex:none}
.pfacts{margin-left:auto;display:flex;align-items:center;gap:1rem;white-space:nowrap;
  overflow:hidden;min-width:0;font-size:.8rem;padding-bottom:.1rem}
.pfacts .muted{font-size:.76rem}
.pfacts b{font-weight:600}

/* ============ EMPLOYEES: THE SALESPERSON STANDS OUT (0790) ============
   The chip wears the branch pill's measured pair (≥5.17:1 in every look);
   the card is the switch where the eye lands — blue while selling, amber
   while being switched off with customers still named, quiet otherwise. */
.sellchip{background:var(--blue);color:var(--blue-ink);font-weight:600}
.empthumb{width:24px;height:24px;border-radius:50%;object-fit:cover;vertical-align:middle;display:inline-block}
.empthumb.none{display:inline-flex;align-items:center;justify-content:center;background:var(--bg);
  color:var(--muted);font-weight:700;border:1px solid var(--line);letter-spacing:-.02em}
.sellcard{grid-column:span 2;display:flex;gap:.7rem;align-items:flex-start;align-self:end;
  border:1.5px solid var(--line);border-radius:10px;padding:.45rem .7rem;background:var(--card);color:var(--ink)}
.sellcard.on{border-color:var(--blue);background:color-mix(in srgb,var(--blue) 7%,var(--card))}
.sellcard.warn{border-color:var(--warn);background:var(--warn-soft)}
.sellcard .sellwords{flex:1;min-width:0;display:flex;flex-direction:column;gap:.25rem;align-items:flex-start}
.sellcard .sellwords b{font-size:.95rem}
.sellcard .sellwords .muted{font-size:.8rem}
.sellcard .sellline{font-size:.84rem}
.sellcard .sw{flex:none;position:relative;width:44px;height:24px;border-radius:12px;border:0;cursor:pointer;
  background:var(--faint);margin-top:1px;padding:0}
.sellcard .sw i{position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:var(--card);
  border:1px solid var(--line);box-sizing:border-box;transition:left .15s}
.sellcard .sw[aria-checked="true"]{background:var(--blue)}
.sellcard .sw[aria-checked="true"] i{left:23px;background:var(--blue-ink);border-color:var(--blue-ink)}
.sellcard .sw:disabled{cursor:not-allowed;opacity:.6}
.sellcard .sw:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
@media(max-width:700px){ .sellcard{grid-column:1 / -1} }
/* THE ASSISTS CARD (0953): the Salesperson card's dress under it, beside
   the leaving tick; one row per salesperson this person works for */
.sellcard.assistcard{grid-column:1 / -1;display:block;align-self:start;margin-top:.65rem}
@media(min-width:980px){ .sellcard.assistcard{grid-column:3 / 5} }
.sellcard.assistcard.none{display:flex;align-items:center;gap:.6rem}
.assistcard .ashead b{font-size:.95rem}
.assistcard .ashead .muted{font-size:.8rem}
.assistcard .asrow{display:grid;grid-template-columns:minmax(0,1fr) 9.4rem 9.4rem 26px;gap:.45rem;align-items:center;margin-top:.35rem}
.assistcard .ascols{font-size:.71rem;color:var(--muted);font-weight:600}
.assistcard .asx{width:26px;height:26px;padding:0;margin:0;line-height:1}
.assistcard .asadd{margin-top:.45rem}
@media(max-width:700px){ .assistcard .asrow{grid-template-columns:minmax(0,1fr) minmax(0,1fr) 26px}
  .assistcard .asrow select{grid-column:1 / -1} .assistcard .ascols{display:none} }
.proles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.4rem}
@media(max-width:900px){ .proles{grid-template-columns:repeat(2,minmax(0,1fr))} }
.prole{text-align:left;padding:.45rem .6rem;border-radius:8px;cursor:pointer;
  background:var(--card);color:var(--ink);border:1px solid var(--line);font:inherit}
.prole.on{border:2px solid var(--blue);padding:calc(.45rem - 1px) calc(.6rem - 1px)}
.prole:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.prole .pask{display:block;font-size:.76rem;margin-top:.1rem}
.pclash{font-weight:400;font-size:.76rem;color:var(--muted)}
.pclash.bad{color:var(--red)}
/* A POSSIBLE DUPLICATE IS AMBER, NEVER RED (0801, his word: red read as a
   refusal): the warning pair, the region standing even when empty so a
   screen reader hears the words arrive */
.pclash.w{color:var(--warn)}
.pdupe{margin:.3rem 0 0;padding:.2rem .5rem;border-radius:6px;font-size:.8rem;
  background:var(--warn-soft);color:var(--warn)}
.pdupe:empty{margin:0;padding:0;background:none}
/* HOME: YOUR SHARED LISTS (0802) — one row a list, the whole row the press */
.hshares{padding:.35rem .75rem .55rem}
.hsrow{display:flex;gap:.7rem;align-items:center;flex-wrap:wrap;width:100%;text-align:left;
  background:none;border:0;border-bottom:1px solid var(--line);padding:.45rem .2rem;
  font:inherit;color:var(--ink);cursor:pointer;min-height:32px}
/* A RECORD'S HISTORY (his go on the drawing, 30 Sep 2026) — the summary,
   the pills, Was struck and quiet, Now in bold ink, a change's later
   lines quieter than its first, and the As on line in the warning ink */
.rhsum{display:flex;gap:1.2rem;flex-wrap:wrap;font-size:.82rem;color:var(--muted);margin:0 0 .5rem}
.rhsum b{color:var(--ink)}
.rhbar{display:flex;gap:.45rem .9rem;align-items:center;flex-wrap:wrap;margin:0 0 .5rem}
.rhgrp{display:inline-flex;gap:.35rem;align-items:center;flex-wrap:wrap}
.rhcap{font-size:.78rem;color:var(--muted)}
.rhwas{color:var(--muted);text-decoration:line-through;text-decoration-color:var(--line)}
.rhnow{font-weight:600;color:var(--ink)}
.rhcont{color:var(--muted)}
.rhfade{opacity:.55}
.rhason{margin:0 0 .5rem;font-size:.82rem;color:var(--warn);font-weight:600}
.rhasonbox{outline:2px solid var(--warn);outline-offset:1px}
/* the clock's dot: changed in the last 7 days (his go, 30 Sep 2026) */
.rhdot{position:absolute;top:1px;right:1px;width:8px;height:8px;border-radius:50%;
  background:var(--warn);box-shadow:0 0 0 2px var(--card)}
/* THE CLOCK LEFT OF A NAME (his word, 1 Oct 2026, on Discounts): a slot
   exactly the clock's size (its 18px picture, .3rem padding a side, a 1px
   border a side), so a row with no clock keeps its name in line */
.rhslot{display:inline-block;min-width:calc(18px + .6rem + 2px);margin-right:.35rem;vertical-align:middle}
/* and the name beside it sits on the same middle — measured on the pane:
   clock and name centred within 1px, every row its old height */
.rhslot + input,.rhslot + b,.rhslot + .dsc-name{vertical-align:middle}
.recdoor{font-size:inherit}
/* A DRAG HANDLE ON A ROW WHOSE ORDER MEANS SOMETHING (his go, 2 Oct 2026):
   the grip is muted ink at the row's left, padded to the clock button's
   height beside it (measured on the pane, within 1px); the row it will
   land on wears a line along its top. No browser tooltip — the words are
   its name and the note under the table. Shared by every ordered list
   (S.reorder). */
.grip{display:inline-block;cursor:grab;color:var(--muted);font-size:1.1em;line-height:1;
  user-select:none;padding:.2rem .3rem;border-radius:4px;vertical-align:middle}
.grip:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
tr.ro-drag{opacity:.5}
tr.ro-over>td{box-shadow:inset 0 2px 0 var(--accent)}/* the date box keeps its own width on the pills' line, never a line of its own */
.rhbar input[type=date]{width:10.5rem;flex:none}
.rhlink{font:inherit;color:inherit;text-align:left;padding:0;
  text-decoration:underline dotted;text-decoration-color:var(--muted);text-underline-offset:3px}
.rhfield{font-weight:600;color:var(--ink)}
/* the number and the customer at the row's own size (his gos, 30 Sep 2026) */
.hsrow b,.hsrow .hsparty{font-size:.79rem}
.hsrow:hover{background:var(--bg)}
.hsrow:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.povg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.5rem}
@media(max-width:1100px){ .povg{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media(max-width:700px){ .povg{grid-template-columns:1fr} }
.povc{background:var(--bg);border:1px solid var(--line);border-radius:10px;padding:.55rem .75rem;min-width:0}
.povc.wide,.povg .wide{grid-column:span 2}
@media(max-width:700px){ .povc.wide,.povg .wide{grid-column:auto} }
/* the record's foot line is never a card: it takes a whole row below them */
.povg .pfoot{grid-column:1 / -1}
.pkv{display:flex;justify-content:space-between;gap:.6rem;margin:0;padding:.12rem 0;border-bottom:1px solid var(--line)}
.pkv > span:first-child{color:var(--muted)}
.pkv > b.neg{color:var(--red)}
.pbtns{display:flex;gap:.4rem;flex-wrap:wrap;align-items:center;margin-top:.45rem}
.patt{margin:.2rem 0 0 1rem;padding:0;font-size:.86rem}
.patt li.w{color:var(--ink);font-weight:600}
.povc .rowtable{width:100%;font-size:.82rem}
.povc .rowtable .n{text-align:right}
.pnote{font-size:.76rem;margin:.35rem 0 0}
/* an employee's last 30 days of sign-ins, oldest on the left (0799); the
   sentence above it carries the count, so the squares are never the only telling */
.edays{display:grid;grid-template-columns:repeat(30,minmax(0,1fr));gap:2px;margin-top:.3rem}
.edays i{display:block;height:10px;border-radius:2px;background:var(--line)}
.edays i.on{background:var(--blue)}
.tabs .tab .ptc{margin-left:.3rem;font-weight:600}
.tabs .tab .ptm{margin-left:.3rem}
/* four-up for dense editors (Employees, 2 Aug 2026) - two-up on
   middling widths so nothing squeezes. */
@media(min-width:620px){ .grid.four{grid-template-columns:1fr 1fr} }
@media(min-width:980px){ .grid.four{grid-template-columns:repeat(4,1fr)} }
/* halved on his word, 21 Aug 2026 — a label sits close to its own box */
label{display:block;font-size:.71rem;color:var(--muted);margin-bottom:.1rem;font-weight:600}
/* =====================================================================
   HOW TALL A BOX IS — ONE DECLARATION, THE WHOLE APPLICATION
   =====================================================================
   About 26px at the Normal step, and THE HEIGHT IS ALL PADDING: the
   .88rem text is what every label, hint and grid cell is tuned against.
   This is the only place a form box is sized; no module sizes its own,
   and the suite fails a build that does. The sign-in screen is the one
   named exception.
   ===================================================================== */
/* ONE HEIGHT FOR A BOX YOU TYPE IN AND A BOX YOU PICK FROM: the chip
   box's own minimum; a check holds the two rules to the same figure. */
input,select,textarea{width:100%;padding:.14rem .3rem;font:inherit;font-size:.88rem;
  min-height:1.9rem;max-width:100%}
/* A textarea's drag handle could stretch it OUT OF ITS CARD (the browser
   default is resize:both). Vertical growth is the useful axis; sideways
   only breaks the layout. Every textarea in the system. */
/* AND NO TEXTAREA IS EVER SHORTER THAN AN ORDINARY BOX. A growing box is
   measured by script, and a measurement taken off screen reads zero;
   this is the floor. The numbers are the line above's — one text line
   plus padding plus border — so it follows the font setting and cannot
   drift from the one place a box is sized. */
textarea{resize:vertical;min-height:calc(1.55em + .28rem + 2px)}
/* A FLOOR OF TWO LINES for a box built to hold a pasted list — the
   one-line floor with the text line doubled. */
textarea.twoline{min-height:calc(2*1.55em + .28rem + 2px)}
input,select,textarea{
  border:1px solid var(--line);border-radius:8px;background:var(--input-bg);color:var(--ink)}
/* =====================================================================
   QUIET WHEN YOU CLICK, CLEAR WHEN YOU TAB
   =====================================================================
   A calm border change on every focus; the ring ONLY while the keyboard
   drives. `.s1-kbd` is put on the page by shared/app.js on Tab or an
   arrow key and removed on the mouse. Not `:focus-visible`: browsers
   treat a text box as always visibly focused, so it fires on a click. */
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent)}
html.s1-kbd input:focus,
html.s1-kbd select:focus,
html.s1-kbd textarea:focus{outline:2px solid var(--accent);outline-offset:1px}
html.s1-kbd .branchpick .bpbtn:focus{outline:2px solid var(--accent);
  outline-offset:2px;border-radius:6px}
/* A LOCKED BOX LOOKS LOCKED, WHATEVER KIND OF BOX IT IS — textarea
   included, or a document past draft greys every box but the remarks. A
   control that cannot be used says so where it is. */
input:disabled,select:disabled,textarea:disabled{background:var(--panel);color:var(--muted)}
/* The base rule stretches EVERY input to full width with padding — right
   for text boxes, absurd for a tick or a radio. Sized here once;
   .check/.s1tick/.colpanel refine it later. */
input[type="checkbox"],input[type="radio"]{width:17px;height:17px;padding:0;min-height:0;
  flex:none;accent-color:var(--blue)}
.check{display:flex;align-items:center;gap:.5rem;font-size:.84rem;padding:.32rem 0}
.check input{width:17px;height:17px;flex:none}
.check label{margin:0;font-size:.84rem;color:var(--ink);font-weight:400}
/* THE SWITCH — a filter that reads ON or OFF at a glance. ONE shared
   control: a module writes the pattern, never a size or color. The
   on-track is the action color and its knob that color's ink. Sized in
   em so the font setting scales it. The label keeps its words in both
   states. */
.tgl{display:inline-flex;align-items:center;gap:.45rem;cursor:pointer;
  -webkit-user-select:none;user-select:none}
.tgl input{position:absolute;opacity:0;width:0;height:0}
.tgl .tr{flex:none;width:2.1em;height:1.15em;border-radius:999px;
  background:var(--line);position:relative;transition:background .15s}
.tgl .tr::after{content:'';position:absolute;top:.12em;left:.12em;
  width:.91em;height:.91em;border-radius:50%;background:var(--card);
  transition:left .15s}
.tgl input:checked + .tr{background:var(--amber)}
.tgl input:checked + .tr::after{left:calc(100% - 1.03em);background:var(--amber-ink)}
.tgl .tl{font-size:.84rem;color:var(--muted);white-space:nowrap}
.tgl input:checked ~ .tl{color:var(--ink);font-weight:600}
/* in a form cell the switch stands on the BOX LINE: a blank title line
   above, as every neighbour has, and the switch centred on the boxes'
   min-height. The factor makes the track 38 by 21 at the standard size —
   one factor, never a second copy of the geometry. */
.tgl.infield{min-height:1.9rem;font-size:1.13em}
/* keyboard focus rides the shell's s1-kbd marker, the application's one
   focus rule — the hidden box has no geometry, so the ring goes on the
   track it drives */
html.s1-kbd .tgl input:focus + .tr{outline:2px solid var(--accent);outline-offset:2px}
.btn{appearance:none;border:1px solid var(--btn-bg);background:var(--btn-bg);color:var(--btn-ink);
  padding:.52rem .85rem;border-radius:8px;font:inherit;font-size:.83rem;font-weight:600;cursor:pointer}
/* THE HOVER MUST KEEP THE TEXT READABLE: a brightness shift dims the
   button's OWN background and ink together, so contrast holds in every
   theme — never a borrowed color like the sidebar's hover shade.
   amber/ghost/danger keep their own :hover. */
.btn:hover{filter:brightness(0.92)}
/* AND EVERY BUTTON SHOWS WHERE THE KEYBOARD IS (what the reviews have
   found three times: a person tabbing had nothing to follow). The ring
   the kind switch and the home tiles already wear, so nothing new is
   invented; `:focus-visible` means it paints for the keyboard and never
   for the mouse, and an outline takes no room, so no layout moves.
   A chosen pill's own ring is a different thing and is untouched. */
.btn:focus-visible,.pill:focus-visible,.tbtn:focus-visible,
.modal-h .x:focus-visible,.s1grid .s1tick:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px}
.btn.amber{background:var(--amber);border-color:var(--amber);color:var(--amber-ink)}
/* THE BUTTON THAT MAKES A DOCUMENT IS THE ACTION COLOUR, ONE STEP
   STRONGER (his go, 21 Sep 2026, replacing the green of 20 Sep). Search
   and New both wore the plain action colour, so the title line said one
   thing twice; green told them apart but did not belong to any of the
   palettes. Three reasons it went: in three of the seven looks the green
   was never chosen at all and fell back to the light theme's emerald; in
   the gold look it was the SAME hex as the "confirmed" status chip; and
   since 21 Sep green also means a stone still sold on a document line —
   one colour doing three jobs. Now each look takes its own action colour
   and deepens it (a dark look brightens it instead, since its ink is
   dark), so the button belongs to the theme by construction and reads as
   the heavier of the two. Gold, whose action colour is the theme itself,
   deepens to bronze with white ink. Every pair is measured. */
.btn.make{background:var(--make);border-color:var(--make);color:var(--make-ink)}
/* Ghost and danger buttons sit ON a card, so their ink and border must come
   from the card's own scale, never from --side (the sidebar color, which is
   near-black in every theme and therefore invisible on a dark card). */
.btn.ghost{background:var(--card);color:var(--ghost-ink);border-color:var(--ghost-line)}
.btn.ghost:hover{background:var(--panel)}
.btn.danger{background:var(--card);color:var(--red);border-color:var(--danger-line)}
.btn.danger:hover{background:var(--red-soft)}
.btn.sm{padding:.34rem .6rem;font-size:.76rem}
/* A PICK THAT SITS ON A CARD'S TITLE LINE — it changes how rows are
   LOOKED at, not which are found, so it belongs beside the buttons. Its
   metrics ARE the small button's, so the line stays one height. */
.card-h select.hsel{padding:.34rem 1.4rem .34rem .6rem;font-size:.76rem;
  height:auto;width:auto;max-width:14rem;flex:none;
  border:1px solid var(--ghost-line);border-radius:var(--r,7px);
  background:var(--card);color:var(--ghost-ink)}
.btn:disabled{opacity:.45;cursor:not-allowed}
/* a button that would be refused wears the locked look but stays live,
   so the note saying why can be reached (rule 38) */
.btn.dim{opacity:.45}
.acts{display:flex;gap:.4rem;flex-wrap:wrap;margin-top:.75rem}
/* READABLE PILLS match the text they sit beside: titles and editors get
   .74rem; the grid override further down rises to the cell's own .8rem.
   Two rules, every screen — no module names a pill size (rule 26). */
.pill{display:inline-block;font-size:.74rem;padding:.16rem .5rem;border-radius:999px;font-weight:700}
.pill.on{background:var(--ok-soft);color:var(--ok)}
.pill.off{background:var(--red-soft);color:var(--red)}
.pill.w{background:var(--warn-soft);color:var(--warn)}
.pill.n{background:var(--panel);color:var(--muted)}
/* a pill carrying our own note on pointing says so with the cursor; a class,
   never a bound style — a bound style wipes the display:none x-show set */
.pill.tip{cursor:help}
/* a refused sign-in (0888): solid red, so it never reads as the soft red of Offline */
.pill.fail{background:var(--red);color:var(--red-ink)}
/* A PILL THAT IS AN ACT (Stone view, Document view — his dress, 18 Sep
   2026): EXACTLY the Line pills' clothes — a button wearing .pill.n,
   its own ring and all — plus a hand cursor. A first cut took the ring
   off and he asked why the dressing was not done. */
button.pill.act{cursor:pointer}
button.pill.act:hover{color:var(--ink)}
/* THE THREE-WAY SWITCH (his design C, 6 Sep 2026): joined parts, exactly
   one lit, the lit part wearing the on-pill's ground and ink — one
   decision, the pill's own. Cell-size type, like every pill. */
.seg{display:inline-flex;border:1px solid var(--line);border-radius:999px;overflow:hidden;vertical-align:middle}
.seg button{font:inherit;font-size:.74rem;font-weight:700;padding:.16rem .6rem;border:0;border-right:1px solid var(--line);
  background:var(--panel);color:var(--muted);cursor:pointer;line-height:1.3}
.seg button:last-child{border-right:0}
.seg button.on{background:var(--ok-soft);color:var(--ok)}
/* SEMANTIC STATUS PILLS. A screen writes what a record IS — st-approved,
   st-pending — never a color. The twelve tokens live in the theme
   blocks, measured per theme; a color changes in the themes alone. */
.pill.st-success{background:var(--st-success-soft);color:var(--st-success)}
.pill.st-warning{background:var(--st-warning-soft);color:var(--st-warning)}
.pill.st-danger{background:var(--st-danger-soft);color:var(--st-danger)}
.pill.st-info{background:var(--st-info-soft);color:var(--st-info)}
.pill.st-pending{background:var(--st-pending-soft);color:var(--st-pending)}
.pill.st-processing{background:var(--st-processing-soft);color:var(--st-processing)}
.pill.st-approved{background:var(--st-approved-soft);color:var(--st-approved)}
.pill.st-rejected{background:var(--st-rejected-soft);color:var(--st-rejected)}
.pill.st-cancelled{background:var(--st-cancelled-soft);color:var(--st-cancelled)}
.pill.st-draft{background:var(--st-draft-soft);color:var(--st-draft)}
.pill.st-completed{background:var(--st-completed-soft);color:var(--st-completed)}
.pill.st-inactive{background:var(--st-inactive-soft);color:var(--st-inactive)}
/* THE STONE'S OWN STATUSES. Sold wears its own token, not the danger one
   — alike today, free to part later. Written off keeps clear of Sold's
   red: a dead stone must never read as sold. */
.pill.st-hold{background:var(--st-hold-soft);color:var(--st-hold)}
.pill.st-memo{background:var(--st-memo-soft);color:var(--st-memo)}
.pill.st-sold{background:var(--st-sold-soft);color:var(--st-sold)}
.pill.st-cert{background:var(--st-cert-soft);color:var(--st-cert)}
.pill.st-wroff{background:var(--st-wroff-soft);color:var(--st-wroff)}
.muted{color:var(--muted);font-size:.79rem}
/* rule 35: a grid cell's quiet words ("follows lot", a dash) wear the cell's own size */
.ag-cell .muted{font-size:inherit}
/* The number preview keeps its terminal look in EVERY theme — a fixed
   dark ground, not the sidebar's color, because a light sidebar would
   have put pale green on white (measured, 2 Aug 2026). */
.preview{font-weight:700;font-size:1.02rem;line-height:1;font-family:inherit;background:#101c34;
  color:#6fe3a4;padding:.7rem .6rem;border-radius:9px;text-align:center;word-break:break-all}
/* A NEWER BUILD ON THE SERVER (31 July 2026). Bottom left, below the
   sign-out countdown in urgency and in z-order: z-index 60 floats over
   content and grids but under a window (.modal-bg is 80) — an update can
   wait; whatever the window is doing cannot. */
.updpop{position:fixed;left:.9rem;bottom:.9rem;z-index:60;display:flex;
  align-items:center;gap:.65rem;background:var(--card);color:var(--ink);
  border:1px solid var(--line);border-radius:12px;padding:.6rem .8rem;
  font-size:.82rem;box-shadow:0 10px 32px rgba(8,13,22,.35);
  max-width:min(420px,calc(100vw - 1.8rem))}
.updpop .x{border:0;background:transparent;color:var(--muted);cursor:pointer;
  font-size:1.05rem;line-height:1;padding:0 .1rem;font-family:inherit}
.updpop .x:hover{color:var(--ink)}

/* THE SIGN-OUT COUNTDOWN, PINNED TO THE WINDOW: top centre below the top
   bar wherever you are scrolled. z-index 95 — above a window (80), since
   the timeout does not care what is open, below a toast (100). It floats
   over the content so you can still save. */
.idlefix{position:fixed;top:3.1rem;left:50%;transform:translateX(-50%);z-index:95;
  width:min(560px,calc(100vw - 1.2rem))}
.idlefix .alert{margin:0;box-shadow:0 10px 32px rgba(8,13,22,.35)}
.alert{border-radius:10px;padding:.7rem .8rem;font-size:.82rem;margin-bottom:.7rem;
  display:flex;gap:.6rem;align-items:flex-start}
/* An alert is how a failed screen explains itself (rule 22), so its ink
   comes from the pill variables tuned per theme against the -soft grounds.
   The softer color-mix border is ignored by old browsers, which keep the
   full-strength one above it. */
.alert.w{background:var(--warn-soft);border:1px solid var(--warn);color:var(--warn)}
.alert.r{background:var(--red-soft);border:1px solid var(--red);color:var(--red)}
/* a screen that did not open: its two buttons and the folded refusal */
.failacts{display:flex;gap:.5rem;align-items:center;margin-top:.4rem}
.faildet{margin-top:.4rem;padding:.4rem .55rem;border:1px solid var(--line);border-radius:6px;
  background:var(--card);color:var(--muted);white-space:pre-wrap;overflow-wrap:anywhere}
.alert.i{background:var(--blue-soft);border:1px solid var(--blue);color:var(--blue)}
.alert.w{border-color:color-mix(in srgb,var(--warn) 38%,var(--card))}
.alert.r{border-color:color-mix(in srgb,var(--red)  38%,var(--card))}
.alert.i{border-color:var(--blue-line)}
.alert b{display:block;margin-bottom:.1rem}

/* ============ A BOX HOLDING SOMETHING NOBODY HAS SEARCHED ===========
   Where boxes wait for Search, these marks say which are out of step
   with the records below. THE MARK MOVES NOTHING — a border color, an
   inset bar, the label's ink; no padding or height. And nothing here
   repaints a ground: ink and ground are one decision. */
.unsrch > label,.unsrch label{color:var(--warn)}
.unsrch input,.unsrch select,.unsrch textarea,.unsrch .chipbox{
  border-color:var(--warn);box-shadow:inset 2px 0 0 var(--warn)}
.btn.unsrchb{border-color:var(--warn);color:var(--warn)}
.unsrchink{color:var(--warn);font-size:.78rem}
/* The words themselves are the overflow note's, shown on the marked box
   (his design, 5 Sep 2026); no band rule any more. */
.empty{text-align:center;padding:2.2rem 1rem;color:var(--muted);font-size:.85rem}
/* a screen still being built: one bold line, then what it will hold */
.empty .bbuilt-h{font-size:.95rem;color:var(--ink);font-weight:600;margin-bottom:.35rem}
.loading{text-align:center;padding:3.5rem 1rem;color:var(--muted)}
/* THE MESSAGE WEARS A GROUND BEFORE IT WEARS A KIND (his report, 11 Oct
   2026: a note of an unknown kind stood see-through over the Ask panel) —
   the note's own pair is the floor, so no kind is ever glass; and it
   stands above the panel, which floats at 880. */
.toast{position:fixed;left:50%;transform:translateX(-50%);bottom:1.1rem;max-width:92%;
  padding:.7rem .9rem;border-radius:9px;font-size:.84rem;z-index:890;
  box-shadow:0 8px 30px rgba(0,0,0,.2);font-weight:500;
  padding-right:2.1rem;cursor:pointer;user-select:text;background:var(--blue);color:var(--blue-ink)}
/* a press takes the message down; its × sits top right, where every
   window keeps it (his go, 18 Sep 2026), the right padding keeping the
   words clear of it; the words stay selectable so a drag copies them */
.toast .tx{display:block;min-width:0}
.toast .x{position:absolute;top:.35rem;right:.35rem;background:transparent;border:0;color:inherit;font:inherit;font-size:1.1rem;
  line-height:1;padding:0;cursor:pointer;opacity:.8;width:24px;height:24px}
.toast .x:hover{opacity:1}
.toast.ok{background:var(--ok);color:var(--ok-ink)}
.toast.err{background:var(--red);color:var(--red-ink)}
/* Neither good news nor bad — "your typing is still here". Takes --blue
   like the alerts, so it follows every theme (rule 27). */
.toast.i{background:var(--blue);color:var(--blue-ink)}
/* A WARNING TOAST WEARS THE WARNING ALERT'S CLOTHES — ground, ink and
   border one decision, every theme. It had no rule at all, so a
   warning floated transparent over the page (his report, 8 Sep 2026). */
.toast.warn{background:var(--warn-soft);color:var(--warn);border:1px solid var(--warn)}

/* THE ROW WHOSE CHILDREN ARE SHOWING: a light wash mixed from the
   theme's blue into the card color, its own stronger bottom line so the
   separator stays MORE visible, a 3px left accent bar as the sidebar
   uses, and no bold or text color change — the data is not different,
   only where you are. */
.s1grid .ag-row.s1-row-current{
  background:color-mix(in srgb, var(--blue) 18%, var(--card));
  border-bottom:1px solid color-mix(in srgb, var(--blue) 45%, var(--grid-row-line))}
/* The vertical bar as its own element, not an inset box-shadow, which
   sat under painted cells and vanished. A positioned child with a z-index
   sits above the cells; the row is already positioned by AG Grid, so its
   own `position` is untouched. */
.s1grid .ag-row.s1-row-current::before{
  content:'';position:absolute;left:0;top:0;bottom:0;width:4px;
  background:var(--blue);z-index:10;pointer-events:none}
.s1grid .ag-row.s1-row-current.ag-row-hover{
  background:color-mix(in srgb, var(--blue) 24%, var(--card)) !important}

/* AN ADDED ROW NOT YET SAVED (0664): a wash from the warning ink — the
   unfinished family, as the Changing chip — on the sales lines and the
   arrival's stone list alike; the module says which rows, never the color. */
.s1grid .ag-row.s1-row-added{background:color-mix(in srgb, var(--warn) 12%, var(--card))}
.s1grid .ag-row.s1-row-added.ag-row-hover{background:color-mix(in srgb, var(--warn) 18%, var(--card)) !important}
/* A ROW MARKED TO COME OFF (his go, 20 Sep 2026): the same wash from the
   danger ink, so a line going on and a line going off can never be read
   for one another. It is still on the document until Save changes. */
.s1grid .ag-row.s1-row-off{background:color-mix(in srgb, var(--red) 10%, var(--card))}
.s1grid .ag-row.s1-row-off.ag-row-hover{background:color-mix(in srgb, var(--red) 16%, var(--card)) !important}
/* A STONE THAT CAME BACK (0854): the row reads in the muted ink and its
   money is struck — the Line column still says Returned in words, so the
   state never rests on the grey alone. */
.s1grid .ag-row.s1-row-back .ag-cell{color:var(--muted)}
.s1grid .ag-row.s1-row-back .ag-cell[col-id="amount"],
.s1grid .ag-row.s1-row-back .ag-cell[col-id="special_amount"],
.s1grid .ag-row.s1-row-back .ag-cell[col-id="final_amount"]{text-decoration:line-through}
/* what came back, in the warning ink beside its minus sign (0854) */
.s1back, input.s1back:disabled{color:var(--red);-webkit-text-fill-color:var(--red)}
/* A DOCUMENT'S TOTAL (his go, 4 Oct 2026): no box, bold, at the boxes' own
   size, right-aligned under its label like the figures in the boxes, and
   never broken onto a second line — one slot holds a crore with paise */
.ro.s1tot{font-weight:700;text-align:right;white-space:nowrap;word-break:normal;padding-right:.35rem}
/* THE RETURNED BOX OPENS THE RETURN (0854): dressed as its read-only
   neighbours, its figure in the warning ink, dotted to say it has more;
   the returns' numbers in our own note on pointing or focus */
.s1backwrap{position:relative}
.s1backbox{width:100%;min-height:1.9rem;padding:.14rem .3rem;font:inherit;font-size:.88rem;text-align:right;
  border:1px solid var(--line);border-radius:8px;background:var(--panel);cursor:pointer}
.s1backbox .s1back{text-decoration:underline dotted;text-underline-offset:3px}
html.s1-kbd .s1backbox:focus{outline:2px solid var(--accent);outline-offset:1px}
.s1backnote{display:none;top:auto;bottom:100%;right:0;left:auto}
.s1backwrap:hover .s1backnote,.s1backwrap:focus-within .s1backnote{display:block}
/* the page's one floating note (S1TIP): fixed, over every grid and window */
.bnote.s1tip{position:fixed;z-index:1000}
/* A CELL WITH MORE TO SAY WEARS A CORNER MARK (his "go", 25 Oct 2026): a small
   amber triangle in the cell's top-right corner, costing no width; pointing,
   a tap or the keyboard opens the note its words carry. Grid cells stand
   absolutely, so the mark sits against the cell itself. */
.ag-cell .s1corner,.s1boxmark .s1corner{position:absolute;top:0;right:0;width:0;height:0;pointer-events:none;
  border-top:9px solid var(--warn);border-left:9px solid transparent}
/* the same mark on a box: inside its edge */
.s1boxmark{position:relative;display:block}
.s1boxmark .s1corner{top:1px;right:1px}
.s1tip .s1tipline{display:flex;gap:.5rem;align-items:center;margin-top:.3rem}
/* a pill or figure that opens a document is a button dressed as before */
.pill.s1pillbtn{border:0;font-family:inherit;font-size:inherit;cursor:pointer;text-decoration:underline dotted;text-underline-offset:3px}
.s1backcell{background:none;border:0;padding:0;font:inherit;cursor:pointer;text-decoration:underline dotted;text-underline-offset:3px}
html.s1-kbd .pill.s1pillbtn:focus,html.s1-kbd .s1backcell:focus{outline:2px solid var(--accent);outline-offset:1px}
/* a return's price, locked (0858): the whole cell answers pointing with our own note */
.s1retlock{display:block;cursor:help}
.s1backlink{display:block;background:none;border:0;padding:0;font:inherit;font-weight:700;color:var(--ink);cursor:pointer;text-align:left}
.s1backlink:hover{text-decoration:underline}
html.s1-kbd .s1backlink:focus{outline:2px solid var(--accent);outline-offset:1px}
/* THE REFUSED STONES ARE BACK IN THE BOX (his go, 19 Sep 2026): the box
   wears the red pair while their IDs sit in it, and the words beside it
   count them in the danger ink — nothing else on the row changes. */
input.refbox{background:var(--red-soft);border-color:var(--red)}
.refwords{color:var(--red);font-weight:600;cursor:default}

/* Our own tick box — a native input, centred, sized for a finger on the
   shop floor; accent-color keeps it on theme. The CELL is the click
   target, so it shows a pointer. */
.s1grid .s1tickcell{display:flex;align-items:center;justify-content:center;
  cursor:pointer}
.s1grid .s1tick{width:16px;height:16px;margin:0;cursor:pointer;
  accent-color:var(--blue);position:relative}
/* AND IT ANSWERS A 24 px PRESS WHILE STAYING 16 px TO THE EYE (his
   choice, 22 Sep 2026, drawn on his own register at three sizes: the
   box stays as it is and only the area that answers grows). The
   standard asks for 24 × 24; the box is 16 in a row 28 tall and a
   column 36 wide, so the larger target fits inside both and NOTHING
   MOVES — measured before it was promised. The reach is drawn as the
   box's own overlay, so a press on it is a press on the box. */
.s1grid .s1tick::before{content:"";position:absolute;left:50%;top:50%;
  width:24px;height:24px;transform:translate(-50%,-50%)}
/* The select-all box, centred in its header cell. */
.s1grid .s1tickhead .ag-header-cell-comp-wrapper{justify-content:center}

/* A BOOLEAN CELL STAYS CENTRED WHILE BEING EDITED: AG Grid's checkbox
   editor wrapper is left-aligned by default, so the tick would jump on
   click and back on blur. */
.s1grid .ag-cell-inline-editing .ag-cell-edit-wrapper,
.s1grid .ag-cell-inline-editing .ag-checkbox-edit{justify-content:center}

/* =====================================================================
   GRID — compact chrome.
   The toolbar lives INSIDE the grid box, directly above the column
   headers, so it costs one thin strip instead of a whole row plus a gap.
   The per-column filter row is hidden until asked for.
   ===================================================================== */
.gridbox{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--card);
  box-shadow:var(--shadow)}
/* AS SHORT AS IT CAN BE (his instruction, 18 Sep 2026): the toolbar's
   own padding halved and its box and buttons slimmed — the search box
   still meets 24 px, the buttons keep their text; one rule, every grid */
.gridtools{display:flex;align-items:center;gap:.3rem;padding:.16rem .4rem;
  background:var(--panel);border-bottom:1px solid var(--line)}
.gridtools .srch{position:relative;flex:1;max-width:290px}
.gridtools .srch input{padding:.2rem .5rem .2rem 1.75rem;font-size:.82rem;border-radius:7px;
  background:var(--input-bg) url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-4.2-4.2'/%3E%3C/svg%3E") no-repeat .5rem center}
/* A SCAN BOX (his go on the drawing, 13 Oct 2026): the search box's own
   anatomy without its glass, a fixed width beside the acts; a scan that
   finds nothing wears the red pair until the next one */
.gridtools .srch.scan{flex:0 0 13.75rem}
.gridtools .srch.scan input{padding-left:.5rem;background-image:none}
.gridtools .srch.scan.bad input{background:var(--red-soft);border-color:var(--red)}
/* the answer in the red pair is read in the pair's own red: the faint
   guidance grey stood at 4.03:1 on the soft red (review of 13 Oct 2026) */
.gridtools .srch.scan.bad input::placeholder{color:var(--red);opacity:1}
.gridtools select{width:auto;padding:.18rem .4rem;font-size:.78rem;border-radius:7px}
.gridtools .gap{margin-left:auto}
/* THE LEAD (0652): a module's own heading, fold and pills at the head
   of the one toolbar, wearing the toolbar's scale; nothing in it grows
   the standing height */
.gridtools .glead{display:inline-flex;align-items:center;gap:.4rem;flex:none;margin-right:.25rem}
.gridtools .glead .t{font-weight:650;font-size:.86rem;white-space:nowrap}
.gridtools .glead .fold{display:inline-flex;align-items:center;gap:.35rem;cursor:pointer;
  padding:.1rem .3rem;border-radius:6px}
.gridtools .glead .fold:hover{background:var(--card)}
.gridtools .glead .fold .chev{flex:0 0 auto;opacity:.6;transition:transform .18s}
.gridtools .glead .fold.shut .chev{transform:rotate(-90deg)}
.gridtools .glead .sep{width:1px;height:1.1rem;background:var(--line);margin:0 .15rem}
/* THE ONE PAGER FOOT (his ruling, 18 Sep 2026): beneath every paging
   grid — the arrivals list and the arrival's stones, the invoice list,
   its stones and its lines, the stock register, Stone Revision — at the
   toolbar's scale and as short as a line can be, so every page reads
   the same. A module lays its own words on it; the dress is here. */
/* THE FOOT SITS ON THE CARD'S EDGE (his instruction, 18 Sep 2026: "this
   empty space can be utilized"): the card's own bottom padding is eaten
   by the foot's negative margin, so the grid above takes those pixels
   — every paging grid, the same */
.pgfoot{display:flex;gap:.4rem;align-items:center;flex-wrap:wrap;margin:.15rem 0 -.45rem;font-size:.8rem;min-height:1.6rem}
.pgfoot .pgrange{font-weight:500;font-size:.8rem}
.pgfoot label{font-size:.76rem}
.pgfoot select{width:auto;padding:.14rem .3rem;font-size:.78rem;border-radius:6px}
.pgfoot .pgrp .btn{padding:.14rem .5rem;font-size:.78rem}
.pgfoot .pgrp .at{padding:.14rem .6rem;font-size:.78rem}
.pgfoot > .btn{padding:.14rem .5rem;font-size:.78rem}
/* AN ACT IN THE FOOT WEARS THE SMALL BUTTON WHOLE (his go, 20 Sep 2026):
   a .sm button a module lays on the foot keeps the small button's own
   padding and size, so it stands level with its neighbours in the strip
   beside it (Stone Revision's Edit prices was a step shorter). */
.pgfoot > .btn.sm{padding:.34rem .6rem;font-size:.76rem}
/* THE THREE NOTES RIDE THE PAGER LINE (his go on the drawing, 20 Sep
   2026, to save a row under the stones): one line high, named by their
   own placeholder, the whole sentence on hover; the pager keeps its
   right-hand place. A document with no stones yet still shows them. */
.pgfoot .pgnotes{display:flex;gap:.4rem;align-items:center;flex:1;min-width:0}
/* a screen's help sentence rides the line's empty left and gives way
   first, its whole wording in the shell's note (.ov) */
.pgfoot .pglead{flex:1 1 0;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:.8rem;margin-right:.5rem}
.pgfoot .pglead b{color:var(--ink);font-weight:650}
/* the pager half of a foot that carries notes: folds as one while the
   notes stay; its class owns the display, never the tag (the fold rule) */
.pgfoot .pgpager{display:contents}
/* one line on open, growing as typed into, a dragged height winning —
   exactly as the boxes behaved before they moved (his instruction, 20
   Sep 2026, on seeing a fixed line: "it should be growable like earlier") */
.pgfoot .pgnotes textarea,.pgfoot .pgnotes input{height:28px;min-height:28px;resize:vertical;padding:.2rem .45rem;
  font-size:.78rem;flex:1;min-width:6rem;max-width:16rem;overflow:auto;line-height:1.2}
/* NARROWER THAN A LAPTOP ONLY (his go, 26 Sep 2026, "it wont affect my
   current desktop views" — nothing here reaches 1200 px and up). Drawn
   on his invoice in a 1024 frame: the toolbar's lead shrank under the
   search box and hid the add box, and the three notes fell to one cut
   word each. Below 1200 the toolbar may take a second line, a lead
   button never breaks its word, and the notes take their own full line
   with the pager beneath. */
@media (max-width:1199px){
  .gridtools{flex-wrap:wrap;row-gap:.25rem}
  .gridtools .glead .btn{white-space:nowrap}
  .pgfoot .pgnotes{flex:1 1 100%}
  .pgfoot .pgnotes textarea,.pgfoot .pgnotes input{max-width:none}
}
/* THE SEARCH BAND'S FOLD on the title line (his go, 18 Sep 2026): the
   card's own fold anatomy, and the live filters as words when shut */
.card-h .fltfold{display:inline-flex;align-items:center;gap:.35rem;cursor:pointer;padding:.1rem .3rem;
  border-radius:6px}
.card-h .fltfold:hover{background:var(--card)}
.card-h .fltfold:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.card-h .fltfold .chev{flex:0 0 auto;opacity:.6;transition:transform .18s}
.card-h .fltfold.shut .chev{transform:rotate(-90deg)}
/* ONE ARROW SIZE FOR EVERY FOLD (his choice, 27 Sep 2026: 14 px at the
   normal scale) — a list, a document and a grid's lead alike; in rem,
   so it follows the font-size setting */
.fold .chev{font-size:.8rem}
/* THE WORDS GIVE WAY FIRST (his go, 18 Sep 2026: Print appeared and "+ New
   invoice" went to a second line): the folded band's words take the room
   the line has left and none it has not — shrinking to an ellipsis, and
   to nothing, before any button wraps */
.card-h .fltwords{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;flex:1 1 0;max-width:34vw}
/* THE SPLITTER between two stacked grids (his go, 18 Sep 2026): a bar
   you drag to share the window between them, remembered per person */
/* it TAKES THE CARD GAP rather than adding to it (his ask, 18 Sep 2026:
   "reduce the space between 2 grid"): the bar sits inside the register
   card's bottom margin, and the stones card follows it at once */
.vsplit{height:8px;margin:-.55rem 0 0;cursor:row-resize;display:flex;align-items:center;justify-content:center;
  border-radius:4px}
.vsplit + .card{margin-top:0}
/* between two joined cards the splitter rides the seam itself — an
   8 px bar under the foot line, the handle on it (18 Sep 2026) */
.card.joins + .vsplit{margin:0}
.vsplit:hover,.vsplit:focus-visible{background:var(--panel);outline:none}
/* the handle is seen before it is hovered (measured live, 18 Sep 2026:
   a 44 px hairline in the line colour all but vanished between the cards) */
.vsplit::before{content:'';width:72px;height:4px;border-radius:2px;background:var(--muted)}
.vsplit:hover::before,.vsplit:focus-visible::before{background:var(--accent)}
/* no room beyond the two floors: the bar wears the locked look and its
   own note says why (his go, 18 Sep 2026) — still reachable, so the
   note can be read */
.vsplit.dim{cursor:not-allowed}
.vsplit.dim::before{opacity:.35}
.vsplit.dim:hover::before,.vsplit.dim:focus-visible::before{background:var(--muted)}
/* a folded stone drawer keeps its strip and hides the grid beneath (0652) */
.stones-shut .gridbox > :not(.gridtools){display:none}
/* A SCREEN'S OWN ACTS, right of the search box. Nothing wraps and
   nothing grows the toolbar's standing height: the buttons wear the
   toolbar's own scale, as the tick strip's do on the foot line. */
.gridtools .gacts{display:flex;align-items:center;gap:.3rem;flex:none}
.gridtools .gacts .btn{padding:.24rem .6rem;font-size:.76rem;white-space:nowrap}
.tbtn{border:1px solid var(--line);background:var(--card);color:var(--muted);border-radius:7px;
  padding:.22rem .4rem;cursor:pointer;display:inline-flex;align-items:center;gap:.28rem;
  font:inherit;font-size:.74rem;font-weight:600;line-height:1}
.tbtn:hover{background:var(--blue-soft);border-color:var(--blue-line);color:var(--blue)}
.tbtn.on{background:var(--blue);border-color:var(--blue);color:var(--accent-ink)}
.tbtn .lbl{display:none}
/* words beside the icons from 1200 px up (was 820): a tablet held
   sideways wrapped "Fit width" onto two lines (the tablet check, 26 Sep
   2026); every button keeps its name for a screen reader */
@media(min-width:1200px){ .tbtn .lbl{display:inline} }
/* AND ON A TITLE LINE THAT HAS RUN OUT OF ROOM, at any width (his go on
   the drawing, 8 Oct 2026): the words step aside, the pictures stay —
   judged by the line itself (s1ToolsJudge), never by the window */
.gridtools.tight .tbtn .lbl{display:none}
/* THE TOTALS BAND: the pinned foot row wears the HEADER's dress with a
   firmer rule above, so it reads as furniture, not a stone. Every figure
   is bold by this ONE rule. One line; anything scroll-shaped is clipped. */
.ag-floating-bottom{background:var(--grid-head);
  border-top:2px solid var(--grid-col-line);position:relative}
/* the ROW inside the band paints itself too — without this its own
   white lies over the band's color and nothing shows (his report) */
.ag-floating-bottom .ag-row{background:var(--grid-head)}
.ag-floating-bottom .ag-cell{color:var(--grid-head-ink);font-weight:700}
/* SCROLLBARS hidden, SCROLLING kept (his report: the totals stopped
   lining under their columns) — the first cure hid the overflow
   itself, which is the very mechanism that slides the band in step
   with the grid. Only the bars disappear now. */
.ag-floating-bottom *{scrollbar-width:none}
.ag-floating-bottom *::-webkit-scrollbar{display:none}
/* the count label sits at the band's LEFT EDGE, under the tick
   column, and stays there at any horizontal scroll (his ask) */
.s1sumlabel{position:absolute;left:.45rem;top:50%;transform:translateY(-50%);
  z-index:2;font-weight:700;font-size:.78rem;color:var(--grid-head-ink);
  white-space:nowrap;pointer-events:none;
  /* the band's own ground, so a total scrolled under it is covered, never
     drawn through the words (his report, 25 Sep 2026: "6Q lines") */
  background:var(--grid-head);padding-right:.4rem}

/* TICKED OR ALL (his go, 4 Oct 2026): the corner's switch answers a press
   though the words around it do not; the band that adds only the ticked
   wears the accent line and a light wash, so it is never read as the whole */
.s1bandsw{display:inline-flex;margin-left:.5rem;border:1px solid var(--line);border-radius:999px;
  overflow:hidden;vertical-align:middle;pointer-events:auto}
.s1bandsw button{border:0;padding:0 .6rem;min-height:24px;font:inherit;font-weight:700;background:var(--card);
  color:var(--ink);cursor:pointer}
.s1bandsw button[aria-pressed="true"]{background:var(--accent);color:var(--accent-ink)}
html.s1-kbd .s1bandsw button:focus{outline:2px solid var(--accent);outline-offset:-2px}
.s1band-ticked .ag-floating-bottom{box-shadow:inset 0 2px 0 var(--accent)}
.s1band-ticked .ag-floating-bottom .ag-row,
.s1band-ticked .ag-floating-bottom .s1sumlabel{background:color-mix(in srgb, var(--accent) 12%, var(--grid-head))}

/* the foot line's joining acts (his report: the line grew) — every
   control the tick brings wears AT MOST the line's standing height,
   and NOTHING on the strip wraps: a pill folding "2 ticked" onto two
   lines was the second way the line grew (his screenshot) */
.s1tickacts .btn{padding:.24rem .6rem;font-size:.76rem}
.s1tickacts select{padding:.18rem .4rem;font-size:.76rem}
.s1tickacts .pill,.s1tickacts span{white-space:nowrap;flex:none}

/* THE TICKED ROW WEARS ITS MARK: the accent wash across every cell, so
   it shows at any horizontal scroll, closed by a 1.5 underline. Drawn
   without moving content; wins over the odd-row stripe. */
.ag-row.s1picked{background:var(--blue-soft);
  box-shadow:inset 0 -1.5px 0 var(--blue)}
.ag-row-odd.s1picked{background:var(--blue-soft)}
/* ROWS LIT BY SIA (S.lit): a wash of the action colour laid over the row's
   own ground — a status tint or a tick still shows beneath — and its words
   bold. The chip opens the grid's foot, packing its empty left. */
.s1grid .ag-row.s1lit{background-image:linear-gradient(color-mix(in srgb, var(--amber) 20%, transparent), color-mix(in srgb, var(--amber) 20%, transparent))}
.s1grid .ag-row.s1lit .ag-cell{font-weight:700}
.s1litchip{display:inline-flex;align-items:center;flex:none;border:1px solid color-mix(in srgb, var(--amber) 45%, var(--line));
  border-radius:999px;background:color-mix(in srgb, var(--amber) 5%, var(--card));white-space:nowrap}
.s1litchip button{border:0;background:transparent;color:var(--ink);font:inherit;font-size:.8rem;line-height:1.2;
  min-height:24px;padding:.14rem .5rem;border-radius:999px;cursor:pointer}
.s1litchip button:hover{text-decoration:underline}
.s1litchip button:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.s1litchip b{color:var(--amber);font-weight:700}
.s1litchip .sh{border-left:1px solid color-mix(in srgb, var(--amber) 30%, var(--line));border-radius:0}
.s1litchip .x{color:var(--muted);font-size:1rem;padding:.05rem .45rem}

/* THE COPY MENU (his ask, 23 Aug 2026): the free grid has no menu of
   its own, so every grid shares OURS — dressed as a card, themed. */
.s1copymenu{position:fixed;z-index:200;background:var(--card);
  border:1px solid var(--line);border-radius:9px;box-shadow:var(--shadow-lg);
  padding:.25rem;min-width:9rem}
.s1copymenu button{display:block;width:100%;text-align:left;border:0;
  background:none;color:var(--ink);font:inherit;font-size:.8rem;
  padding:.4rem .6rem;border-radius:6px;cursor:pointer;white-space:nowrap}
.s1copymenu button:hover{background:var(--blue-soft);color:var(--blue)}
/* the menu's heading, once (his go, 19 Sep 2026) — A CAPTION, NOT A ROW
   (his yes to the drawn design, 27 Sep 2026): small grey capitals with a
   clipboard mark, so it never reads as something to press */
.s1copymenu .h{display:flex;align-items:center;gap:.35rem;font-size:.68rem;font-weight:600;
  letter-spacing:.07em;text-transform:uppercase;color:var(--muted);padding:.4rem .6rem;
  white-space:nowrap;cursor:default;user-select:none;
  /* its own band, and a faint line between the choices (his ask, 27 Sep 2026) */
  background:var(--bg);border-bottom:1px solid var(--line)}
.s1copymenu:has(> .h){padding:0;overflow:hidden}
.s1copymenu:has(> .h) button{border-radius:0}
.s1copymenu button + button{border-top:1px solid color-mix(in srgb, var(--line) 60%, transparent)}
/* the choice's own letter, beside it, dressed as a key (27 Sep 2026) */
.s1copymenu button[data-key]::after{content:attr(data-key);float:right;margin-left:1.2rem;
  color:var(--muted);font-size:.72rem;font-weight:600;min-width:1.3em;text-align:center;
  border:1px solid var(--line);border-radius:4px;padding:0 .25em;line-height:1.4}

/* A TOOLS MENU UNDER A GRID (his go on the drawn menu, 26 Sep 2026): the
   copy menu's dress, opening UPWARD from the foot line and right-aligned
   to its button; a sub-list opens to the LEFT, away from the pager. An
   act the ticked rows cannot take stays listed, greyed, its reason on a
   second line in the muted ink. */
.s1menuwrap{position:relative;display:inline-flex}
.s1menu{position:absolute;z-index:95;background:var(--card);
  border:1px solid var(--line);border-radius:9px;box-shadow:var(--shadow-lg);
  padding:.25rem;min-width:15rem}
.s1menu.up{bottom:calc(100% + 4px);right:0}
.s1menu.left{right:100%;top:-.3rem;min-width:9rem;margin-right:2px}
/* a list opening on the menu's right, as wide as its longest word */
.s1menu.right{left:100%;top:-.3rem;min-width:0;width:max-content;max-width:16rem;margin-left:2px}
/* a department row: its name, then "moves N" or "all N here"; "N already here" beneath */
.s1menu-i.s1mdept{display:grid;grid-template-columns:1fr auto;column-gap:.8rem;align-items:center}
.s1mdept .s1mdc{font-size:.76rem;color:var(--muted)}
.s1mdept .s1menu-why{grid-column:1 / -1}
.s1menu-h{font-size:.8rem;font-weight:600;color:var(--ink);padding:.3rem .6rem .35rem;margin-bottom:.2rem;
  border-bottom:1px solid var(--line);white-space:nowrap;cursor:default;user-select:none}
.s1menu-i{display:block;width:100%;text-align:left;border:0;background:none;color:var(--ink);
  font:inherit;font-size:.85rem;padding:.4rem .6rem;border-radius:6px;cursor:pointer;white-space:nowrap}
.s1menu-i:hover,.s1menu-i:focus-visible{background:var(--blue-soft);color:var(--blue)}
.s1menu-i[aria-disabled="true"]{color:var(--muted);cursor:default}
.s1menu-i[aria-disabled="true"]:hover{background:none;color:var(--muted)}
.s1menu-why{display:block;font-size:.78rem;color:var(--muted);font-weight:400}
.s1menu-sub{position:relative}
.s1menu-more{display:flex;justify-content:space-between;gap:1rem}
.s1menu-more::after{content:"\25B8"}
.s1menu-more[aria-disabled="true"]::after{content:none}
/* A STONE NOT FREELY SELLABLE WEARS ITS STATUS ON ITS ROW (his choice of
   the drawn tint, 27 Sep 2026): a soft wash of the chip's own colour;
   Available is plain. A ticked row's own mark wins. */
.s1grid .ag-row.s1st-w:not(.s1picked){background-color:color-mix(in srgb, var(--warn-soft) 70%, var(--card))}
.s1grid .ag-row.s1st-st-memo:not(.s1picked){background-color:color-mix(in srgb, var(--st-memo-soft) 80%, var(--card))}
.s1grid .ag-row.s1st-st-hold:not(.s1picked){background-color:color-mix(in srgb, var(--st-hold-soft) 80%, var(--card))}
.s1grid .ag-row.s1st-st-sold:not(.s1picked){background-color:color-mix(in srgb, var(--st-sold-soft) 80%, var(--card))}
.s1grid .ag-row.s1st-st-cert:not(.s1picked){background-color:color-mix(in srgb, var(--st-cert-soft) 80%, var(--card))}
.s1grid .ag-row.s1st-st-wroff:not(.s1picked){background-color:color-mix(in srgb, var(--st-wroff-soft) 80%, var(--card))}
/* NO STRIPE (his word, 27 Sep 2026: "the coloured stripe i don't need
   now, it looks poor") — the wash alone says the status */

/* THE STOCK TOOLS' NEW DRESS (his yes to the drawn menu, 27 Sep 2026): the
   acts that can run first — a mark, the act in bold, a count — then, below
   a dashed line under a small caption, those that cannot, with a lock */
/* 17rem, and every line of words wraps inside it (his go, 27 Sep 2026) */
.s1menu.s1tools{display:flex;flex-direction:column;min-width:0;width:17rem}
.s1tools .s1ti > *{min-width:0}
.s1tools .s1ti .s1menu-why{white-space:normal;overflow-wrap:anywhere}
.s1menu.s1tools .s1menu-h{display:flex;align-items:baseline;gap:.2rem}
.s1tools .s1tmix{font-weight:400;color:var(--muted);font-size:.76rem;white-space:normal}
.s1tools .s1tcap{font-size:.68rem;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);
  padding:.25rem .6rem 0;cursor:default;user-select:none}
.s1tools .s1tcap.s1toff{border-top:1px dashed var(--line);margin-top:.25rem;padding-top:.45rem}
.s1tools .s1ti{display:grid;grid-template-columns:18px 1fr auto;column-gap:.55rem;align-items:center;white-space:normal}
.s1tools .s1ti.s1menu-more{grid-template-columns:18px 1fr auto auto}
.s1tools .s1ti .s1tico{display:flex;color:var(--blue)}
.s1tools .s1ti .s1tw{font-weight:600}
.s1tools .s1ti .s1menu-why{grid-column:2 / -1}
.s1tools .s1ti[aria-disabled="true"] .s1tico{color:var(--muted)}
.s1tools .s1ti[aria-disabled="true"] .s1tw{font-weight:500}

/* the register's door strip: view, video, photo, certificate. A door
   with nothing behind it stays visible and answers nothing — greying
   states a fact the data holds, never a guess about a far server. */
.s1doors{display:inline-flex;gap:.12rem;align-items:center}
.s1doors a.tbtn{text-decoration:none}
/* compact doors (his ask, 23 Aug 2026): smaller boxes, tighter row */
.s1doors .tbtn{padding:.14rem .26rem;position:relative}
/* AND EACH DOOR ANSWERS A 24 px PRESS WHILE KEEPING ITS COMPACT LOOK
   (his choice, 22 Sep 2026 — the same answer he gave for the tick box).
   The reviews measured them at 24 × 20, four short of the standard's
   24 × 24; the row is 28 tall, so the reach fits and the door itself is
   untouched. His compact doors of 23 August stand exactly as they are. */
.s1doors .tbtn::before{content:"";position:absolute;left:50%;top:50%;
  width:24px;height:24px;transform:translate(-50%,-50%)}
.ag-cell[col-id="media"]{padding-left:.25rem;padding-right:.25rem}
.tbtn.s1off{opacity:.38;pointer-events:none}
/* a certificate number that is also the lab page's door keeps the
   cell's own ink; the underline appears only under the hand */
a.s1cert{color:inherit;text-decoration:none}
a.s1cert:hover{text-decoration:underline}
/* A STATUS OR A NUMBER THAT OPENS ITS DOCUMENT (his go, 26 Sep 2026):
   the dress it already wore, plus a dotted underline and an arrow at the
   cell's own size (rule 35) — never a new colour or a smaller font. */
a.s1doclink{text-decoration:underline dotted;text-underline-offset:2px;cursor:pointer}
a.s1doclink:not(.pill){color:inherit}
a.s1doclink:hover{text-decoration-style:solid}
/* a screen the person cannot open is named in plain words (S.mayRoute) */
a.s1route:not([href]){color:inherit}
/* the arrow rides the plain numbers only; a status pill is marked by its
   underline alone (his word, 26 Sep 2026) — at his column widths the
   arrow was cut off the longer words */
a.s1doclink:not(.pill)::after{content:"\2197";margin-left:.15em}
/* the stone window's two panes (23 Aug 2026): viewer left, facts right
   in titled bands. Colors ride the theme's own scale; no geometry is
   named in the module. */
/* WHEN THE WINDOW MUST SCROLL, ONLY THE FACTS SIDE DOES: the viewer pane
   stays put and the bands column takes the scrollbar. Narrow windows
   stack and scroll as one. The class carries this, not block order —
   the general tall-window rule below sets a scrolling body. */
.tallcap .modal-b.svbody{display:flex;overflow:hidden}
.tallcap .modal-b.svbody > .stonev{flex:1;min-height:0}
.stonev{display:flex;gap:.8rem;flex-wrap:wrap}
.stonev .sv-l{flex:0 0 24rem;display:flex;flex-direction:column;gap:.45rem;align-self:flex-start}
/* the facts flow as TWO NEWSPAPER COLUMNS OF BANDS, not a grid — a grid
   turns every height difference into a hole. Each band is unbreakable.
   A column set never carries the height limit: held to a height it lays
   the rest out SIDEWAYS. The pane takes the limit and scrolls down. */
.stonev .sv-r{flex:1;min-width:20rem;
  max-height:100%;overflow-y:auto;overflow-x:hidden;padding-right:.2rem}
.stonev .sv-cols{columns:2;column-gap:.7rem}
.stonev .sv-cols > div{break-inside:avoid;margin-bottom:.55rem}
.stonev .sv-view{background:var(--card);border:1px solid var(--line);border-radius:10px;
  width:100%;aspect-ratio:1/1;overflow:hidden;display:flex;align-items:center;justify-content:center}
.stonev .sv-view iframe,.stonev .sv-view img{width:100%;height:100%;border:0;object-fit:contain}
/* The embedded viewer is shown at its own size, gutters and all — an
   enlargement cropped its content on his screen (tried and withdrawn,
   23 Aug 2026). Its inside is the lab page's own and stays untouched. */
.stonev .sv-tabs{display:flex;gap:.35rem}
.stonev .sv-tabs .btn{flex:1}
/* DETAILS AND HISTORY, TWO TABS OF THE STONE WINDOW (26 Sep 2026): the
   tabs sit on the title line, dressed as the viewer's own two; the
   history body is a column — the journey line, then the one grid. */
.modal-h .rectabs{display:inline-flex;gap:.35rem;margin-left:.8rem}
/* the History tab's clock (his go, 1 Oct 2026): beside the words, its dot
   on its corner; the tab keeps its height */
.rectab-h{display:inline-flex;align-items:center;gap:.3rem}
.rectab-ic{position:relative;display:inline-flex;line-height:0}
.rectab-ic .rhdot{top:-2px;right:-3px}
.tallcap .modal-b.sthist{display:flex;flex-direction:column;gap:.45rem}
.sthist .sthj{row-gap:.3rem}
.sthist .sthstop{display:inline-flex;gap:.35rem;align-items:center}
.sthist .sthgap{color:var(--muted);font-style:italic}
.sthist .glead .densum{margin-left:.4rem}
/* the price trail and the folded price changes (26 Sep 2026) */
.sthist .sthtrail{display:inline-flex;gap:.3rem;align-items:baseline;flex-wrap:wrap}
.sthodd{color:var(--st-danger);font-weight:700}
.sthind{display:inline-block;width:1.1rem}
.stonev .band-h{font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);margin:0 0 .15rem}
.stonev .band{border:1px solid var(--line);border-radius:8px;
  padding:.15rem .6rem;background:var(--card)}
/* A NAME AND ITS VALUE SIT TOGETHER: the value starts one gap after the
   longest name in its band and the spare width falls at the end. The
   rule lines still run the band's full width. */
.stonev .band .brows{display:grid;grid-template-columns:max-content 1fr;gap:0 .7rem}
.stonev .band .bk{color:var(--muted);padding:.28rem 0;font-size:.78rem;white-space:nowrap;
  border-top:1px solid var(--line)}
.stonev .band .bv{padding:.28rem 0;font-size:.8rem;overflow-wrap:anywhere;text-align:left;
  border-top:1px solid var(--line)}
.stonev .band .brows > :nth-child(-n+2){border-top:0}
@media(max-width:1100px){
  .tallcap .modal-b.svbody{display:block;overflow-y:auto}
  .stonev .sv-cols{columns:1}
  .stonev .sv-r{max-height:none;overflow:visible}
}
@media(max-width:700px){ .stonev .sv-l{flex:1 1 100%} }
/* The price rule's field table: ONE row per field and ONE choice on it —
   in the file, on the rule, or an add-on — so a field is never priced in
   two places. Only added fields sit here. The three tracks take their
   own width and the spare falls at the END. */
.pshape{display:grid;grid-template-columns:max-content max-content max-content minmax(0,1fr);
  gap:.25rem .8rem;align-items:center}
/* the grip: the only thing that starts a drag, so a row can still be
   read and its boxes used without one beginning by accident */
.pshape .pshape-grip{color:var(--muted);cursor:grab;line-height:0;padding:.15rem .1rem}
.pshape .pshape-grip:active{cursor:grabbing}
.pshape .dragging > div{opacity:.45}
.pshape .pshape-h{font-size:.74rem;letter-spacing:.05em;text-transform:uppercase;
  border-bottom:1px solid var(--line);padding-bottom:.2rem}
.pshape .pshape-how{display:flex;align-items:center;gap:.5rem}
.pshape .pshape-how .x{background:none;border:0;cursor:pointer;color:var(--muted);
  font-size:1.1rem;line-height:1;padding:0 .25rem;border-radius:6px}
.pshape .pshape-how .x:hover{background:var(--panel);color:var(--ink)}
/* AN ADD-ON LINE IS ONE LINE: a wrapping row moves an item down rather
   than shrink one. The row does not wrap; the two boxes give instead,
   which needs their content floor removed. Wrapping returns where the
   panes stack. */
.pshape .pshape-line{grid-column:1/-1;display:flex;gap:.4rem;flex-wrap:nowrap;
  align-items:center;margin:0 0 .1rem 1.2rem}
.pshape .pshape-line select{min-width:0}
.pshape .pshape-line > span{white-space:nowrap}
@media(max-width:1100px){ .pshape .pshape-line{flex-wrap:wrap} }
/* choose, then add - the picker sits under the list it fills */
.pshape-add{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-top:.5rem;
  font-size:.8rem}
/* the arithmetic worked out loud, so the order of the add-ons is
   something he can SEE rather than something he has to reason about */
.pladder{margin-top:.6rem;padding:.45rem .6rem;background:var(--panel);
  border-radius:8px;font-size:.8rem}
.pladder table{border-collapse:collapse;margin:.15rem 0}
.pladder td{padding:.05rem 0}
.pladder td:last-child{text-align:right;padding-left:1.2rem;
  font-variant-numeric:tabular-nums}
.pladder tr.last td{border-top:1px solid var(--line);padding-top:.2rem;font-weight:650}
/* the file the shape is about to ask for, named before it is downloaded */
.pcols{margin-top:.6rem;padding:.45rem .6rem;background:var(--panel);
  border-radius:8px;font-size:.8rem}
/* THE PRICE WINDOW FITS THE SCREEN (his go, 1 Oct 2026): wide, two
   columns, title and buttons fixed (tallcap); each column scrolls on
   its own when a long price needs it. One column again on a narrow screen. */
.modal.pwin{max-width:min(96vw,72rem)}
.pwin .modal-b{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr);
  padding:0;overflow:hidden}
.pwin .pcol{padding:.9rem 1rem;overflow-y:auto;min-height:0}
.pwin .pcol + .pcol{border-left:1px solid var(--line)}
@media(max-width:900px){
  .pwin .modal-b{display:block;overflow-y:auto}
  .pwin .pcol{overflow:visible}
  .pwin .pcol + .pcol{border-left:0;border-top:1px solid var(--line)} }
.psec{font-size:.78rem;font-weight:650;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);margin:0 0 .5rem}
.pcol > .psec:not(:first-child){margin-top:.9rem}
/* a label with its "i" beside it, on the label's own line */
.plab{display:flex;align-items:center;gap:.3rem;margin-bottom:.1rem}
.plab label,.plab .psec{margin:0}
/* a label line beside a plain label: the "i" holder takes the button's own
   height, not the page's line, so both boxes stand on one line */
.plab.pl-even > .pinfo{display:inline-flex}
.pinfo-b{appearance:none;width:1.05rem;height:1.05rem;border-radius:50%;padding:0;
  border:1px solid var(--line);background:var(--card);color:var(--muted);
  font:600 .66rem/1 inherit;cursor:help;display:inline-flex;align-items:center;justify-content:center;position:relative}
/* it answers a 24 px press while staying its size — the tick box's own overlay */
.pinfo-b::before{content:"";position:absolute;left:50%;top:50%;
  width:24px;height:24px;transform:translate(-50%,-50%)}
.pinfo-b:hover{color:var(--ink);border-color:var(--muted)}
.pinfo-b:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* In use as a switch on the title line — a real button with role switch */
.pswitch{appearance:none;background:none;border:0;cursor:pointer;font:inherit;font-size:.84rem;
  color:var(--ink);display:inline-flex;align-items:center;gap:.4rem;padding:.2rem .3rem;border-radius:6px}
.pswitch-t{width:30px;height:16px;border-radius:999px;background:var(--line);position:relative;flex:none;
  transition:background .12s}
.pswitch-t::after{content:'';position:absolute;left:2px;top:2px;width:12px;height:12px;border-radius:50%;
  background:var(--card);box-shadow:0 1px 2px rgba(0,0,0,.25);transition:left .12s}
.pswitch[aria-checked="true"] .pswitch-t{background:var(--accent)}
.pswitch[aria-checked="true"] .pswitch-t::after{left:16px}
.pswitch:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* one click adds a field: each unused field its own small dashed chip */
.chip.padd{font-size:.78rem;padding:.18rem .6rem;border-style:dashed}
/* the worked example and the file's columns side by side */
.ppreview{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:.6rem;margin-top:.6rem}
.ppreview .pladder,.ppreview .pcols{margin-top:0}
.colpanel{padding:.6rem .55rem;background:var(--panel);border-bottom:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:.15rem .9rem}
.colpanel label{display:inline-flex;align-items:center;gap:.32rem;font-size:.79rem;
  color:var(--ink);font-weight:400;margin:0}
.colpanel input{width:15px;height:15px}

/* =====================================================================
   THE COLUMN CHOOSER'S GRID. A wrap cannot align ticks, so: equal
   columns counted by measurement — auto-fill against a minimum in REM,
   following the window and the font-size setting. No column count is
   written anywhere. */
.colgrid{display:grid;gap:.15rem .9rem;
  grid-template-columns:repeat(auto-fill,minmax(11.5rem,1fr))}
/* minmax(0,…) above would let a long label push its column wider than
   its share and stagger the rest; the label is clipped instead, and the
   overflow note (S.ovn) reads it out on hover. */
.colgrid label{display:inline-flex;align-items:center;gap:.32rem;font-size:.79rem;
  color:var(--ink);font-weight:400;margin:0;min-width:0}
.colgrid label span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.colgrid input{width:15px;height:15px;flex:none}

/* The group heading is a control now, not a caption: its own tick takes
   the whole group on or off, and it says how much of the group is
   showing without anybody counting boxes. */
.colgrp{display:flex;align-items:center;gap:.4rem;margin-bottom:.25rem}
.colgrp label{display:inline-flex;align-items:center;gap:.4rem;cursor:pointer;
  font-weight:650;font-size:.76rem;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted);margin:0}
.colgrp input{width:14px;height:14px;flex:none}
.colgrp .n{font-weight:400;font-size:.74rem;letter-spacing:0;text-transform:none;
  color:var(--muted)}

/* THE ORDERED LIST ON COLUMN DEFAULTS — one row per column on ONE LINE:
   handle, name, where it sits, how wide, the way off. Only the handle
   looks draggable. */
.gdefrow{display:flex;align-items:center;gap:.4rem;padding:.18rem .35rem;
  border-bottom:1px solid var(--line)}
.gdefrow:last-child{border-bottom:0}
.gdefrow .grip{flex:none;cursor:grab;color:var(--muted);letter-spacing:-.22em;
  padding-right:.2rem;user-select:none}
.gdefrow .grip:active{cursor:grabbing}
.gdefrow .nm{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:.82rem}
.gdefrow .pos{flex:none;min-width:1.4rem;text-align:right;color:var(--muted);
  font-size:.78rem}
.gdefrow input{flex:none;width:4.2rem;height:1.55rem;padding:0 .3rem;font-size:.78rem}
/* WHERE IT WILL LAND, shown on the row being dragged over — a drag with
   no answer is a guess. */
.gdefrow.over{background:var(--amber-soft)}

/* THE PREVIEW STRIP — the header row at the widths actually typed. It
   scrolls sideways and does not push: its children are real pixels, and
   a flex row that wide would force the window wider than the screen.
   `min-width:0` is load-bearing — a flex child refuses to shrink below
   its content unless told it may. */
.gdefprev{display:flex;border:1px solid var(--line);border-radius:4px;
  overflow-x:auto;overflow-y:hidden;min-width:0;max-width:100%}
.gdefprev span{padding:.28rem .4rem;border-right:1px solid var(--line);
  font-size:.74rem;color:var(--muted);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.gdefprev span:last-child{border-right:0}
/* AND THE COLUMN IT SITS IN MAY SHRINK. Without this the preview's own
   scrolling is never reached: the grid track grows to fit it instead. */
.gdefcol{min-width:0;max-width:100%}

/* =====================================================================
   MODAL — used wherever a record is created or a decision confirmed.
   Rule: a screen shows the existing records first. Creating a new one
   happens in here, not in a form occupying the top of the page.
   ===================================================================== */
.modal-bg{
  position:fixed;inset:0;background:rgba(8,13,22,.55);z-index:80;
  display:flex;align-items:flex-start;justify-content:center;
  padding:4vh 1rem 2rem;overflow-y:auto;backdrop-filter:blur(2px);
}
.modal{
  background:var(--card);border:1px solid var(--line);border-radius:14px;
  width:100%;max-width:640px;box-shadow:0 24px 70px rgba(0,0,0,.45);
}
.modal.narrow{max-width:460px}
.modal-h{
  display:flex;align-items:center;gap:.6rem;padding:.9rem 1rem;
  border-bottom:1px solid var(--line);
  /* The header is the window's handle (the business, 28 July 2026): grab it
     anywhere that is not a button and drag. touch-action:none lets the
     same grab work with a finger on the shop floor; user-select stops the
     title being highlighted mid-drag. */
  cursor:move;user-select:none;touch-action:none;
}
.modal-h .t{font-weight:650;font-size:1rem}
.modal-h .x{
  margin-left:auto;background:none;border:0;cursor:pointer;color:var(--muted);
  font-size:1.3rem;line-height:1;padding:.1rem .35rem;border-radius:6px;
}
.modal-h .x:hover{background:var(--panel);color:var(--ink)}
.modal-b{padding:1rem}
.modal-f{
  display:flex;gap:.5rem;justify-content:flex-end;padding:.8rem 1rem;
  border-top:1px solid var(--line);background:var(--panel);
  border-radius:0 0 14px 14px;flex-wrap:wrap;
}
.modal-f .left{margin-right:auto}
/* THE LAYOUT LOCK: the switch beside Back to the default in the Columns
   window and at the end of the column strip — the house tick row's
   anatomy at the foot's type size; the Columns button's locked mark
   inherits the button's ink. */
.glock{display:inline-flex;align-items:center;gap:.35rem;font-size:.78rem;color:var(--muted);
  cursor:pointer;white-space:nowrap;user-select:none}
.glock input{width:15px;height:15px;margin:0;flex:none}
.glock svg{flex:none}
.tbtn .lockmark{display:inline-flex;margin-left:.1rem}

/* =====================================================================
   THE ASK — the system's own question window
   =====================================================================
   Above .modal-bg (80) because a question is asked ON TOP of its window,
   and above the toast (100) so a message cannot cover the buttons.
   Centred, not dropped from the top: two lines and two buttons. The
   destructive answer takes the danger outline; the safe one is solid
   and holds focus. */
.askbg{
  position:fixed;inset:0;background:rgba(8,13,22,.55);z-index:120;
  display:flex;align-items:center;justify-content:center;
  padding:1rem;backdrop-filter:blur(2px);
}
.ask{
  background:var(--card);border:1px solid var(--line);border-radius:14px;
  width:100%;max-width:460px;box-shadow:var(--shadow-lg);padding:1.1rem 1.15rem;
  position:relative;
}
/* the copy-the-number button rides the corner; the title leaves it room */
.ask .askcopy{position:absolute;top:.65rem;right:.65rem;display:inline-flex;align-items:center;gap:.35rem}
.ask:has(.askcopy) .ask-t{padding-right:6.5rem}
.ask-t{font-weight:650;font-size:1rem;color:var(--ink);margin-bottom:.4rem}
.ask-b{font-size:.86rem;color:var(--muted);line-height:1.45}
/* a question's own list (0804): the page's ink, one line each */
.ask-list{margin:.55rem 0 0;padding-left:1.15rem;font-size:.86rem;color:var(--ink);line-height:1.5}
.ask-list li{margin:.1rem 0}
/* A QUESTION WITH A LIST IS NEVER TALLER THAN THE SCREEN: the window
   stacks its parts, the list alone gives up height and scrolls in a
   framed box; the title and the answers stay in view */
.ask:has(.ask-list){max-height:calc(100vh - 2rem);display:flex;flex-direction:column;overflow:auto}
.ask:has(.ask-list) > *{flex:none}
.ask:has(.ask-list) > .ask-list{flex:0 1 auto;min-height:3rem;overflow:auto}
.ask:has(.ask-list) .ask-note{margin-top:0}
.ask-list.scrolls{border:1px solid var(--line);border-radius:8px;padding:.35rem .5rem .35rem 1.65rem}
.ask-list.scrolls:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.ask-lh{margin-top:.6rem;font-size:.86rem;font-weight:700;color:var(--ink)}
.ask-lh + .ask-list{margin-top:.35rem}
.ask-f{display:flex;gap:.5rem;justify-content:flex-end;margin-top:1.15rem;flex-wrap:wrap}
/* three answers stand on one line (his word, 3 Oct 2026): the window
   widens for them; only a phone too narrow for the line lets them wrap */
.ask.three{max-width:560px}
.ask.three .ask-f .btn{white-space:nowrap}
@media (min-width:600px){ .ask.three .ask-f{flex-wrap:nowrap} }
/* a question that asks for words: one labelled box under the body, the
   page's own label and box, full width (the special switch's reason) */
.ask-in{margin-top:.7rem}
.ask-in input{width:100%}
/* a question's sample table (the arrival's currency question, 1 Oct 2026):
   the body's size in the page's ink, numbers right, a quieter second line */
.ask.wide{max-width:640px}
.ask-tbl{width:100%;border-collapse:collapse;margin:.6rem 0;font-size:.86rem;color:var(--ink)}
.ask-tbl th,.ask-tbl td{padding:.25rem .4rem;text-align:left;vertical-align:top}
.ask-tbl th{font-weight:650}
.ask-tbl .n{text-align:right;font-variant-numeric:tabular-nums}
.ask-tbl thead tr{border-bottom:1px solid var(--line)}
.ask-tbl tfoot tr:first-child{border-top:1px solid var(--line)}
.ask-tbl tfoot td{font-weight:650}
.ask-tbl tbody td:first-child{font-weight:650}
.ask-tbl .sub{font-weight:400;color:var(--muted)}
.ask-tbl + .ask-b{margin-top:.1rem}
/* THE SALESPERSON'S NOTE TO THE APPROVER (his go, 25 Sep 2026: "not eye
   catching"): its own box in the warning family, first in the question
   and on the waiting document — the same dress in both places */
/* ONE LOOK EVERYWHERE (his words, 25 Sep 2026: "font size like other box
   only … the user note bold … everywhere same like"): the name as a label
   in the warning colour, the note bold in the warning ground and edge, at
   the size of the boxes around it */
.ask-note{margin:.1rem 0 .65rem}
.ask-note .k{color:var(--warn)}
.ask-note .v{background:var(--warn-soft);border:1px solid var(--warn);border-radius:8px;color:var(--ink);
  font-size:.88rem;font-weight:700;padding:.14rem .3rem;overflow-wrap:anywhere}
/* on the title row, where there is no room in the header: one line that
   shortens first (a band of its own disturbed the layout) */
.aprnote{background:var(--warn-soft);color:var(--ink);border-radius:6px;padding:0 .45rem;font-size:.78rem;line-height:1.5}
.aprnote .k{color:var(--warn)}
/* in the header's empty tail, where there is one: the header's own box */
.aprnotebox{min-width:0}
.aprnotebox label{color:var(--warn)}
.aprnotebox input:disabled{background:var(--warn-soft);border-color:var(--warn);color:var(--ink);font-weight:700;opacity:1}

/* ---- the approvers of a request (docs/0056): the chosen ride as chips
   inside a box dressed as every other box, the typing box last; the
   people who may approve are listed beneath as plain rows ---- */
.awbox{display:flex;flex-wrap:wrap;align-items:center;gap:.3rem;border:1px solid var(--input-line);
  border-radius:6px;padding:.2rem .3rem;background:var(--input-bg);min-height:2rem}
.awbox input{flex:1 1 8rem;border:none;background:transparent;min-width:6rem;padding:.15rem .2rem}
.awbox input:focus{outline:none}
.awbox:focus-within{outline:2px solid var(--blue);outline-offset:1px}
.awchip{display:inline-flex;align-items:center;gap:.2rem}
.awchip .x{border:none;background:transparent;color:inherit;cursor:pointer;min-width:24px;min-height:24px;padding:0}
.awlist{display:flex;flex-direction:column;margin:.3rem 0;max-height:9.5rem;overflow:auto}
.awopt{text-align:left;border:none;background:transparent;color:var(--ink);padding:.3rem .4rem;border-radius:4px;cursor:pointer;min-height:24px}
.awopt:hover,.awopt:focus-visible{background:var(--bg)}

/* ---- the same window with a list in it: which sheet, which one ----
   The rows are BUTTONS, so the keyboard reaches them by the browser's
   own rule and nothing here has to invent focus. The chosen one wears
   the amber every chosen thing wears. */
.pick-l{margin-top:.7rem;border:1px solid var(--line);border-radius:.45rem;
  overflow:hidden;max-height:15rem;overflow-y:auto}
.pick-r{display:flex;width:100%;align-items:center;gap:.6rem;text-align:left;
  background:none;border:0;border-bottom:1px solid var(--line);
  padding:.42rem .6rem;font:inherit;color:var(--ink);cursor:pointer}
.pick-r:last-child{border-bottom:0}
.pick-r:hover{background:var(--bg)}
.pick-r.on{background:var(--amber-soft);color:var(--amber)}
.pick-n{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pick-s{flex:none;font-size:.78rem;color:var(--muted)}
.pick-r.on .pick-s{color:var(--amber)}

/* ---- theme picker: an icon in the bar, names only once opened ---- */
.themepick{position:relative}
.themepick > button{
  background:var(--card);border:1px solid var(--line);border-radius:9px;
  padding:.3rem .5rem;cursor:pointer;display:flex;align-items:center;color:var(--muted);
}
.themepick > button:hover{background:var(--blue-soft);border-color:var(--blue-line);color:var(--blue)}
/* the bell wears the appearance button's dress; its number is the ink's own */
.bellpick{flex:none}
.bellpick > button{gap:.3rem;color:var(--ink)}
.bellnum{font-weight:700;font-size:.8rem;line-height:1}
/* THE BELL'S LIST (0865): the appearance menu's dress; a request is three
   short lines, so its row may wrap where an option may not */
.thememenu.belllist{min-width:0;width:min(26rem, calc(100vw - 1.5rem))}
.thememenu.belllist button.aprow{flex-direction:column;align-items:flex-start;gap:.12rem;white-space:normal}
.belllist .aprow .muted{font-size:.78rem}
/* A CHANGE WAITING FOR APPROVAL (0868): its line under the header, and the
   cells it moves in the unfinished amber */
.chgline{display:flex;gap:.6rem;align-items:center;flex-wrap:wrap;margin:.3rem 0 .1rem;font-size:.82rem}
.s1grid .ag-cell.s1cell_chg{background:var(--warn-soft);box-shadow:inset 0 0 0 1px var(--warn);font-weight:700}
/* the sender's row (0867): the row opens the invoice; Send again sits under it */
.belllist .aprsent{display:flex;flex-direction:column;align-items:flex-start}
.thememenu.belllist button.apagain{width:auto;margin:-.1rem 0 .3rem .5rem}
.belllist .apfoot{padding:.4rem .5rem .25rem;font-size:.76rem;color:var(--muted);
  border-top:1px solid var(--line);margin-top:.15rem}
/* REMINDERS IN THE BELL (0974): a due one carries Done and a snooze under
   its words, as Send again sits under a request; New reminder closes the group */
.belllist .remacts{display:flex;gap:.35rem;margin:-.1rem 0 .35rem .5rem}
/* a shipment's chip and its "new" move to the next line together (0995) */
.belllist .shipst{white-space:nowrap}
.thememenu.belllist .remacts button,.thememenu.belllist .remnew button{width:auto}
.belllist .remnew{padding:.15rem .5rem .4rem;border-bottom:1px solid var(--line);margin-bottom:.15rem}
.thememenu.belllist button.aprow.remplain{cursor:default}
/* WHY WAS IT LOST? (1048): the reasons pick and Later sit under the line,
   as a reminder's Done and snooze do; the pick keeps a box width of its own */
.belllist .lostask{display:flex;gap:.4rem;align-items:center;margin:-.1rem 0 .4rem .5rem}
.belllist .lostask select{width:13rem}
.thememenu.belllist .lostask button{width:auto}
/* THE REMINDER RINGS (0974, his drawing 2): bottom right, the card's own
   ground with the action colour's edge; above the SIA panel, below the message box */
.remring{position:fixed;right:1.1rem;bottom:1.1rem;width:min(440px, calc(100vw - 2.2rem));z-index:885;
  background:var(--card);color:var(--ink);border:1px solid var(--line);border-left:4px solid var(--blue);
  border-radius:9px;box-shadow:0 8px 30px rgba(0,0,0,.2);padding:.75rem .9rem .8rem;font-size:.84rem}
.remring .rh{display:flex;align-items:center;gap:.45rem;margin-bottom:.3rem;color:var(--blue)}
.remring .rh b{color:var(--ink)}
.remring .rn{margin-left:auto;font-size:.78rem;display:flex;align-items:center;gap:.3rem}
.remring .rw{font-weight:600;margin-bottom:.15rem;overflow-wrap:anywhere}
.remring .rs{font-size:.78rem}
.remring .remline{display:flex;align-items:center;gap:.5rem;margin-top:.1rem}
.remring .remline .rs{flex:1;min-width:0}
.remring .remline .ra{flex:none}
.remring .ra,.remring .rz{display:flex;align-items:center;gap:.4rem}
.remring .rz{margin-top:.5rem}
.remring .rz .muted{font-size:.78rem;margin-right:.15rem}
.remx{background:none;border:0;color:inherit;font:inherit;font-size:1rem;line-height:1;cursor:pointer;padding:0 .15rem;border-radius:4px}
.remx:hover{color:var(--ink)}
.remx:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
/* the window (his drawing 4) */
.remwin{display:flex;flex-direction:column;gap:.8rem}
.remwin .remwhen{margin-top:-.45rem}
.remwin .remquick{display:flex;gap:.35rem;flex-wrap:wrap;align-items:center}
.remwin .remquick .muted{margin-right:.15rem}
.remwin .remlink{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}
/* "Opens" names a group, not a box: a label's own dress without a label's promise */
.remwin .lbl{display:block;font-size:.71rem;color:var(--muted);margin-bottom:.1rem;font-weight:600}
.remwin .remlink .pill{display:inline-flex;align-items:center;gap:.35rem}
/* CONNECTION HEALTH (3 Aug 2026) -- the dot is a control like the
   theme picker; the popover is the thememenu shape (rule 26). The dot
   itself is a FILLED color (the pale pill would vanish at 10px). */
/* The connection state rides the avatar's corner dot and its content
   lives inside .accmenu (.acc-net). The menu's 272px floor is the speed
   row's measured width, keeping the result beside the Test speed button. */
.net-h{display:flex;align-items:center;gap:.5rem;margin-bottom:.3rem}
.net-why{font-size:.76rem;margin:.1rem 0 .5rem}
.spark{display:flex;align-items:flex-end;gap:2px;height:34px;margin-bottom:.45rem}
.spark .bar{flex:1 1 auto;min-height:2px;border-radius:2px 2px 0 0;background:var(--ok)}
.spark .bar.slow{background:var(--warn)}
.spark .bar.bad{background:var(--st-danger)}
/* Each fact stacks its value below its title — two 120px columns cannot
   hold a label and its figure on one line. Two columns stay so the menu
   does not grow taller. */
.net-rows{display:grid;grid-template-columns:1fr 1fr;gap:.45rem .8rem;margin-bottom:.5rem}
.net-rows > div{display:flex;flex-direction:column;align-items:flex-start;
  gap:.05rem;min-width:0;font-size:.78rem}
.net-rows > div > b{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.net-spd{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;
  border-top:1px solid var(--line);padding-top:.45rem}
/* Read by a screen reader, seen by nobody. The arrows are the whole label
   now that the words are gone, and an arrow announces as nothing at all. */
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.net-spd .spdres{display:inline-flex;align-items:center;gap:.3rem;font-size:.78rem;
  white-space:nowrap}
.net-spd .spdres b{color:var(--ink);font-weight:700;font-variant-numeric:tabular-nums}
.net-spd .spdres .dir{font-weight:700;line-height:1}
.net-spd .spdres .dir.dn{color:var(--spd-dn)}
.net-spd .spdres .dir.up{color:var(--spd-up)}
.net-spd .spdres .sep{color:var(--faint)}
.thememenu{
  position:absolute;right:0;top:calc(100% + .4rem);z-index:60;min-width:190px;
  background:var(--card);border:1px solid var(--line);border-radius:11px;
  box-shadow:0 12px 34px rgba(0,0,0,.18);padding:.3rem;
}
.thememenu button{
  width:100%;display:flex;align-items:center;gap:.55rem;background:none;border:0;
  padding:.42rem .5rem;border-radius:7px;cursor:pointer;font:inherit;font-size:.84rem;
  color:var(--ink);text-align:left;
  /* EVERY OPTION ON ONE LINE — a wrapped option reads as two choices. The
     menu is sized by its widest row, so this holds at every text size. */
  white-space:nowrap;
}
.thememenu button > span:nth-child(2){flex:1 1 auto}
.thememenu button:hover{background:var(--blue-soft)}
.thememenu button.on{background:var(--blue-soft);color:var(--blue);font-weight:650}
.thememenu .sw{width:18px;height:18px;border-radius:6px;flex:none;
  border:1px solid rgba(128,128,128,.35);box-shadow:inset -7px 0 0 rgba(0,0,0,.001)}
/* Each swatch shows the theme's page beside its SIGNATURE color — where
   page+sidebar would give two near-identical squares (Professional Light
   is white on white), the signature color stands in. */
.thememenu .sw[data-t="auto"],.acc-look .sw[data-t="auto"]{background:linear-gradient(135deg,#f8fafc 50%,#0f172a 50%)}
.thememenu .sw[data-t="prolight"],.acc-look .sw[data-t="prolight"]{background:linear-gradient(135deg,#f8fafc 50%,#2563eb 50%)}
.thememenu .sw[data-t="graphite"],.acc-look .sw[data-t="graphite"]{background:linear-gradient(135deg,#f3f4f6 50%,#374151 50%)}
.thememenu .sw[data-t="dark"],.acc-look .sw[data-t="dark"]{background:linear-gradient(135deg,#0f172a 50%,#3b82f6 50%)}
.thememenu .sw[data-t="gold"],.acc-look .sw[data-t="gold"]{background:linear-gradient(135deg,#111827 50%,#d4af37 50%)}
.thememenu .sw[data-t="diamond-blue"],.acc-look .sw[data-t="diamond-blue"]{background:linear-gradient(135deg,#f5f8fc 50%,#10243e 50%)}
.thememenu .sw[data-t="platinum"],.acc-look .sw[data-t="platinum"]{background:linear-gradient(135deg,#f7f7f5 50%,#2b3038 50%)}
.thememenu .sw[data-t="midnight-sapphire"],.acc-look .sw[data-t="midnight-sapphire"]{background:linear-gradient(135deg,#091321 50%,#55a6ff 50%)}
/* APPEARANCE INSIDE THE ACCOUNT MENU (his go, 11 Oct 2026): a row of round
   swatches, the current one ringed and named at the right; Font and size
   is a fold head that opens the two lists in place, not a second popup. */
.acc-look{border-top:1px solid var(--line);margin-top:.25rem;padding:.1rem .2rem .3rem}
/* the reminder sound on ONE line: the label, On · Off, then Play (0975;
   one line since his go, 17 Oct 2026) */
.acc-snd{display:flex;align-items:center;gap:.4rem;margin-left:auto}
.acc-look .lookh.acc-sndh{padding-bottom:.45rem}
.acc-look .lookh.acc-sndh > span:first-child{white-space:nowrap}
/* THE FOUR HEADS WEAR THE MENU'S OWN ROW LETTERING (his word on the
   drawing, 11 Oct 2026: the small capitals "not looking good"): the row
   size, sentence case, a little heavier than a row; the held value in the
   muted ink beside it. */
.acc-look .lookh{display:flex;align-items:center;justify-content:space-between;gap:.5rem;border-top:0;margin-top:0;padding:.45rem .3rem .3rem;
  font-size:.84rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--ink)}
.acc-look .lookh .apcur{font-weight:400;text-transform:none;letter-spacing:0;color:var(--muted);opacity:1}
.acc-look .sws{display:flex;gap:.4rem;padding:.1rem .3rem .35rem}
.acc-look .swb{border:0;background:none;padding:2px;border-radius:50%;cursor:pointer;display:grid;place-items:center}
.acc-look .swb .sw{display:block;width:20px;height:20px;border-radius:50%;border:1px solid rgba(128,128,128,.35)}
.acc-look .swb:hover .sw{box-shadow:0 0 0 2px var(--blue-soft)}
.acc-look .swb.on{outline:2px solid var(--blue);outline-offset:1px}
.acc-look .swb:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
.acc-look button.lookmore{width:100%;display:flex;align-items:center;justify-content:space-between;background:none;border:0;cursor:pointer;
  font:inherit;padding:.4rem .3rem .25rem;font-size:.84rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--ink);border-radius:7px}
.acc-look button.lookmore:hover{background:var(--blue-soft)}
.acc-look .thememenu.inline{position:static;min-width:0;max-width:none;max-height:none;box-shadow:none;border:0;padding:0 .1rem;overflow:visible}
.acc-look .thememenu.inline .apgroup{border-top:0;margin-top:0}
/* the menu has a fixed width here, so a fold head's held value wraps to a
   second line rather than being cut (rule 38); an option still never wraps */
.acc-look .thememenu.inline button.apgroup{white-space:normal;align-items:center;
  font-size:.84rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--ink)}
/* the label never wraps; the value beside it does */
.acc-look .thememenu.inline button.apgroup>span:first-child{white-space:nowrap;flex:none}
.acc-look .thememenu.inline .apcur{overflow:visible;text-overflow:clip;white-space:normal;line-height:1.3;color:var(--muted);opacity:1}
.thememenu .tick{margin-left:auto;color:var(--blue);font-weight:800}

/* ---- APPEARANCE: the typeface and size rows ----
   Color, typeface and size are one question, so they share one popover.
   Eighteen rows will not fit a short window, so the menu scrolls, capped
   against the viewport. Sized by its widest row so no label wraps — the
   measured font name differs by machine. */
.thememenu{min-width:max-content;max-width:calc(100vw - 1.5rem);
  max-height:calc(100vh - 5.5rem);overflow:auto}
.apgroup{
  padding:.45rem .5rem .2rem;font-size:.72rem;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;color:var(--muted);
}
.apgroup:not(:first-child){margin-top:.15rem;border-top:1px solid var(--line);padding-top:.5rem}
/* A GROUP HEAD THAT IS PRESSABLE (the foldable lists): same small
   lettering as a plain head — restated because the menu's own button
   rule outranks .apgroup — with the held value seated at the right. */
.thememenu button.apgroup{padding:.45rem .5rem .2rem;font-size:.72rem;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;color:var(--muted);border-radius:0}
.thememenu .apcur{text-align:right;font-weight:400;text-transform:none;
  letter-spacing:0;color:var(--ink);opacity:.8;overflow:hidden;text-overflow:ellipsis}
.thememenu .apchev{flex:none;font-weight:400}
/* THE SWATCH SHOWS THE THING ITSELF: a typeface row IN that typeface, a
   size row AT that size (rule 24). Size swatches are px so they do not
   change with the choice they preview. */
.thememenu .sw.ap{
  display:flex;align-items:center;justify-content:center;width:26px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);
  font-size:13px;line-height:1;box-shadow:none;
}
.thememenu .sw.ap[data-f="SYSTEM"]     {font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
.thememenu .sw.ap[data-f="INTER"]      {font-family:"Inter",sans-serif}
.thememenu .sw.ap[data-f="ROBOTO"]     {font-family:"Roboto",sans-serif}
.thememenu .sw.ap[data-f="SOURCE_SANS"]{font-family:"Source Sans 3",sans-serif}
.thememenu .sw.ap[data-z="COMPACT"]    {font-size:10px}
.thememenu .sw.ap[data-z="NORMAL"]     {font-size:12px}
.thememenu .sw.ap[data-z="COMFORTABLE"]{font-size:14px}
.thememenu .sw.ap[data-z="LARGE"]      {font-size:16px}
.thememenu .sw.ap[data-z="XLARGE"]     {font-size:18px}

/* ---- AG Grid, themed to match the application ----
   AG Grid's CSS variables for row and column borders do not reliably
   apply under quartz; both are explicit rules below. Never set `position`
   on .ag-row — AG Grid places rows absolutely with a transform. Hover
   effects must be paint-only. */
/* Two classes on the same element, deliberately. `.ag-theme-quartz` alone has
   the same specificity as `.s1grid`, so whichever stylesheet loaded last would
   win. This guarantees ours does, whatever the load order. */
.ag-theme-quartz.s1grid,
.s1grid{
  --ag-font-family:inherit;
  /* Compact by design. These four numbers set the density of every grid in
     the application — change them here, nowhere else. */
  --ag-font-size:.8rem;
  --ag-grid-size:3px;
  --ag-row-height:28px;
  --ag-header-height:30px;
  --ag-list-item-height:24px;
  --ag-cell-horizontal-padding:8px;

  --ag-background-color:var(--card);
  --ag-foreground-color:var(--ink);
  --ag-data-color:var(--ink);
  --ag-secondary-foreground-color:var(--muted);
  --ag-disabled-foreground-color:var(--faint);

  --ag-header-background-color:var(--grid-head);
  --ag-header-foreground-color:var(--grid-head-ink);
  --ag-odd-row-background-color:var(--grid-odd);
  --ag-row-hover-color:var(--grid-hover);
  --ag-selected-row-background-color:var(--blue-soft);

  --ag-border-color:var(--line);
  --ag-secondary-border-color:var(--grid-col-line);
  --ag-header-column-separator-display:block;
  --ag-header-column-separator-height:100%;
  --ag-header-column-separator-width:1px;
  --ag-header-column-separator-color:var(--grid-col-line);
  --ag-header-column-resize-handle-display:block;
  --ag-header-column-resize-handle-height:60%;
  --ag-header-column-resize-handle-width:2px;
  --ag-header-column-resize-handle-color:var(--blue-line);

  --ag-input-background-color:var(--input-bg);
  --ag-input-border-color:var(--input-line);
  --ag-input-focus-border-color:var(--blue);
  --ag-checkbox-checked-color:var(--blue);
  --ag-menu-background-color:var(--card);
  --ag-menu-foreground-color:var(--ink);
  --ag-control-panel-background-color:var(--panel);
  --ag-wrapper-border-radius:0;
  --ag-borders:none;
}

/* ================= THE LINES, stated explicitly ================= */

/* horizontal — between every row */
.s1grid .ag-row{
  border-bottom:1px solid var(--grid-row-line);
  transition:background-color .1s;
}
/* vertical — between every column, header included */
.s1grid .ag-cell{border-right:1px solid var(--grid-col-line)}
.s1grid .ag-cell:last-child{border-right:0}
.s1grid .ag-header-cell,
.s1grid .ag-header-group-cell{border-right:1px solid var(--grid-col-line)}
.s1grid .ag-header-cell:last-child{border-right:0}

/* ================= depth ================= */
/* Only the header and the outer box carry depth. Rows stay flat, because
   anything that lifts a row has to touch stacking, and that breaks it. */
.s1grid{box-shadow:inset 0 0 0 1px var(--grid-col-line)}
/* The header must read as a distinct band in EVERY theme. The top
   highlight is a variable because a white sheen ruins a dark header. */
.s1grid .ag-header{
  background:var(--grid-head);
  border-bottom:2px solid var(--line);
  box-shadow:0 2px 4px rgba(0,0,0,.14), inset 0 1px 0 var(--grid-head-hi);
}
/* Written out, not left to --ag-header-foreground-color. That variable was
   being overridden by the theme stylesheet and the text disappeared in the
   dark themes. */
.s1grid .ag-header-cell,
.s1grid .ag-header-group-cell,
.s1grid .ag-header-cell-text,
.s1grid .ag-header-cell-label{color:var(--grid-head-ink)}
.s1grid .ag-header-icon,
.s1grid .ag-header-cell-menu-button{color:var(--grid-head-ink);opacity:.75}
.s1grid .ag-header-cell-text{
  /* .70 of the base on his word (18 Aug 2026), up from .66 - the
     headings read faint below the .8rem cells despite being bold */
  font-size:.7rem;text-transform:uppercase;letter-spacing:.04em;font-weight:700;
}
.s1grid .ag-header-cell,
.s1grid .ag-header-group-cell{padding-left:8px;padding-right:8px}
.s1grid .ag-header-cell:hover{background:rgba(125,125,125,.10)}
.s1grid .ag-header-cell.ag-header-cell-sorted-asc,
.s1grid .ag-header-cell.ag-header-cell-sorted-desc{
  background:var(--blue-soft);color:var(--blue);
  box-shadow:inset 0 -2px 0 var(--blue);
}

/* hover and selection are paint-only — no position, no z-index, no margin */
.s1grid .ag-row-hover{background-color:var(--grid-hover)!important}
/* THE TICKED ROW UNDER THE HAND keeps its wash — the generic hover's
   important background would strip it — and the line firms from 1.5
   to 2, so hover reads on the line, not a color jump. Theme tokens
   throughout. */
.s1grid .ag-row.s1picked.ag-row-hover{
  background-color:var(--blue-soft)!important;
  box-shadow:inset 0 -2px 0 var(--blue)}
/* the grid ALSO paints hover as an overlay LAYER above the row — it
   was lying over the wash and the line whatever colors sat beneath
   (his second report). No overlay on a ticked row; the rule above is
   its one hover painter. */
.s1grid .ag-row.s1picked::before{content:none!important}
.s1grid .ag-row-selected{box-shadow:inset 3px 0 0 var(--blue)}

.s1grid .ag-cell{display:flex;align-items:center;line-height:1.2;color:var(--ink)}
.s1grid .ag-row{color:var(--ink)}
/* Buttons and pills inside cells must not force the row taller than the
   row height, or the compact setting is undone one cell at a time. */
.s1grid .ag-cell .btn{padding:.08rem .42rem;font-size:.68rem;line-height:1.25}
/* A pill in a cell reads AT the cell's font size. The slimmer vertical
   padding keeps the 28px row: .8rem × 1.3 plus 2 × .05rem ≈ 20px. */
/* A GRID CELL KEEPS ITS OWN HEIGHT: the shared box minimum would push a
   cell editor past the row it sits in. */
.s1grid input{min-height:0}
.s1grid .ag-cell .pill{font-size:.8rem;padding:.05rem .5rem;line-height:1.3}
/* RECORD-STATE chips read at TEXT weight in cells: Status / Sign-in /
   Login carry .state and lose the bold; every other cell chip keeps it.
   One rule, every module (rule 26); outside cells .state changes nothing. */
.s1grid .ag-cell .pill.state{font-weight:400}
/* A SPLIT CELL: content pushed to the two edges -- the Status chip
   left, the since-time right (the business, 3 Aug 2026, User Access; the
   .ag-cell-value wrapper is flex:1, so width:100% spans the cell).
   One rule, any future grid cell that pairs a chip with a figure. */
.s1grid .ag-cell .split{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;min-width:0}
/* THE WRAPPER MUST STRETCH: AG Grid wraps a string renderer's output in
   an anonymous <span> sized to content, so width:100% resolved against
   the content. The cell hands its width to any wrapper carrying a .split. */
.s1grid .ag-cell > span:has(> .split){flex:1 1 auto;min-width:0}
/* The multi-sort order badge ("Status 1") never shows (the business, same
   day): the two-column default sorts still WORK; only the 1/2 numeral
   beside the header arrow is hidden, in every grid at once. */
.s1grid .ag-sort-order{display:none}
/* IN A GRID CELL A CODE IS TEXT, NOT A CHIP: semi-bold (his go on the
   drawing, 29 Oct 2026: bold capitals read too dark), the cell's own size
   and ink. The amber chip form stays for windows and editors. One rule,
   every grid (rule 26). */
.s1grid .ag-cell .code{font-size:.8rem;background:transparent;color:inherit;border:0;
  padding:0;border-radius:0;letter-spacing:.03em;font-weight:600}
/* the FIRST COLUMN, never the first cell drawn: with columns drawn only
   while in view, a grid scrolled sideways put a later column first in the
   row and bolded it (Owed 308). The engine numbers every cell's column. */
.s1grid .ag-cell[aria-colindex="1"],.s1grid .ag-cell.s1c1{font-weight:500}
/* the running-number column — present, not prominent */
.s1grid .ag-cell.s1seq{
  justify-content:flex-end;color:var(--faint);font-weight:400;
  font-variant-numeric:tabular-nums;background:var(--grid-head);
}
.s1grid .ag-header-cell.s1seq .ag-header-cell-label{justify-content:flex-end}
/* THE NET COLUMNS' FAINT GROUND (his go, 5 Sep 2026): one translucent
   wash over heading and cells, so the odd-row stripe, the hover and
   the marked row still show through it; the ink is stated with it and
   stays the cell's own. The class is put on by the shell from the
   field name — no module names it. Nothing here changes size. */
.s1grid .ag-cell.s1net{background:var(--grid-net);color:var(--ink)}
.s1grid .ag-header-cell.s1net{background:var(--grid-net);color:var(--grid-head-ink)}
/* THE THREE NEW PRICE COLUMNS wear the pending colour the same way (his
   go, 5 Sep 2026): amber, one translucent token per theme, heading and
   cells, ink the cell's own, no geometry. Blue is what it sells for;
   amber is what you are changing it to. */
.s1grid .ag-cell.s1new{background:var(--grid-new);color:var(--ink)}
.s1grid .ag-header-cell.s1new{background:var(--grid-new);color:var(--grid-head-ink)}
/* QUIET WORDS ON EITHER WASH lean a fifth toward the ink: plain muted
   over a wash on a striped row read 4.35:1, under AA (28 Oct 2026). */
.s1grid .ag-cell.s1new .muted,.s1grid .ag-cell.s1net .muted{color:color-mix(in srgb,var(--muted) 80%,var(--ink))}
/* PRICE POSITION (1022): above the middle of similar stones amber, below
   it blue (his choice, 15 Oct 2026), from each look's measured status
   pair; no comparison possible is muted. All at the cell's own size. */
.s1pp-up{color:var(--st-warning);font-size:inherit}
.s1pp-dn{color:var(--st-info);font-size:inherit}
.s1pp-na{color:var(--muted);font-size:inherit}

.s1grid .ag-floating-filter{height:24px}
.s1grid .ag-floating-filter-input .ag-input-field-input{
  font-size:.72rem;height:19px;border-radius:4px;padding:0 .3rem;
}
/* HIS RULING, 15 Aug 2026: a step bigger. The strip carries the page-size
   choice as well as the arrows now, and at .72rem/30px it was the smallest
   thing on the screen and the one most often aimed at. */
.s1grid .ag-paging-panel{
  border-top:1px solid var(--line);background:var(--panel);
  color:var(--muted);font-size:.82rem;height:38px;
  box-shadow:inset 0 1px 0 var(--grid-head-hi);
}
.s1grid .ag-paging-panel .ag-paging-button{margin:0 3px}
/* The page-size box grows with the strip it sits in — a control that stayed
   at the old size inside a taller strip reads as a mistake. */
.s1grid .ag-paging-panel .ag-picker-field-wrapper,
.s1grid .ag-paging-panel .ag-wrapper{min-height:26px;font-size:.82rem}
.s1grid .ag-overlay-no-rows-center .s1empty,.s1grid .s1empty{
  color:var(--faint);font-size:.85rem;
}
/* the outer box carries the raised look */
.gridbox{box-shadow:0 1px 3px rgba(16,28,52,.10), 0 6px 16px rgba(16,28,52,.06)}
[data-theme="dark"] .gridbox,
[data-theme="gold"] .gridbox{box-shadow:0 2px 6px rgba(0,0,0,.5)}

/* =====================================================================
   ICON EMOJI SIZE — one number
   =====================================================================
   Later in the file, so it wins on equal specificity. Sets the EMOJI
   only — sidebar menu and card headers — from a single value. The
   sidebar chip is 30px and the card chips 28px; if the glyph sits proud,
   grow the chips.
   ===================================================================== */
:root{ --ic-emoji:24px }

nav a .ic{ font-size:var(--ic-emoji) }

/* =====================================================================
   NAV SECTIONS — added 27 July 2026 with the Parties module.
   The sidebar was one flat list of eight; the masters would have made it a
   wall. Sections roll up, and the state is remembered per browser.
   ===================================================================== */
.navgroup + .navgroup{margin-top:.15rem}
.navlabel{display:flex;align-items:center;justify-content:space-between;
  cursor:pointer;user-select:none;gap:.4rem;transition:color .15s}
.navlabel:hover{color:var(--side-label-hi)}
.navlabel .chev{flex:0 0 auto;opacity:.55;transition:transform .18s}
.navlabel.shut .chev{transform:rotate(-90deg)}
/* Collapsed sidebar: the heading is already hidden, so the chevron would be
   a stray glyph floating over the icons. */
aside.mini .navlabel .chev{display:none}

/* =====================================================================
   EDITABLE GRIDS
   Three states driven from the ROW so they survive a repaint:
     s1cell_dirty  changed, not yet saved
     s1cell_new    not in the database yet
     s1cell_bad    a required box left empty
   Colors from theme variables, never literals.
   ===================================================================== */
.s1grid .s1cell_dirty{background:var(--warn-soft);
  box-shadow:inset 2px 0 0 var(--warn)}
.s1grid .s1cell_new{background:var(--blue-soft)}
.s1grid .s1cell_bad{background:var(--red-soft);
  box-shadow:inset 0 0 0 1.5px var(--red)}
/* an unpriced stone's Deal/ct is a required box left empty, whatever
   band the column wears (his go, 18 Sep 2026) */
.s1grid .ag-cell.s1new.s1cell_bad{background:var(--red-soft)}
/* a line's Discount % above the special customer's limit (0837): the
   figure itself in red, so it does not read as a wash of another meaning */
.s1grid .ag-cell.s1cell_over{color:var(--red);font-weight:600}
/* a cell the row's Kind does not use (1065): the panel ground and muted
   ink, cells on or off, so "nothing goes here" reads before a press */
.s1grid .ag-cell.s1cell_locked{background:var(--panel);color:var(--muted);font-style:italic}
.s1grid .ag-cell-inline-editing{box-shadow:inset 0 0 0 2px var(--accent)}
.s1grid .swatch{display:inline-block;width:12px;height:12px;border-radius:3px;
  margin-right:.45rem;vertical-align:-1px;box-shadow:inset 0 0 0 1px rgba(0,0,0,.2)}

/* The unsaved-changes bar. Sticky, because on a 200-row grid the Save button
   must not be somewhere you have to scroll to find. */
.editbar{position:sticky;top:0;z-index:6;display:flex;align-items:center;
  gap:.6rem;flex-wrap:wrap;padding:.35rem .6rem;margin-bottom:.4rem;
  border-radius:8px;background:var(--warn-soft);color:var(--warn);
  border:1px solid var(--warn);font-size:.85rem;font-weight:600}
.editbar .sp{flex:1 1 auto}
.editbar.clean{background:var(--card);color:var(--muted);border-color:var(--line);
  font-weight:500}
/* A BAR THAT CARRIES ITS OWN HINT (his go on the drawing, 13 Oct 2026):
   the words take the room the buttons leave and wrap inside it, so the
   buttons never drop to a row of their own */
.editbar.says{flex-wrap:nowrap}
.editbar.says .say{flex:1 1 0;min-width:0;line-height:1.25}

/* The collapse-all caret. One glyph rotated, never two icons that could
   disagree about which state they mean. */
.gridtools .tbtn[data-gcollapse] svg{transition:transform .14s ease}
.gridtools .tbtn[data-gcollapse].shut svg{transform:rotate(-90deg)}

/* =====================================================================
   SEGMENTED TOGGLE
   ---------------------------------------------------------------------
   Two or three states of ONE setting in one control — two buttons side
   by side read as two things you can DO. The filled segment's ink is
   --accent-ink, which flips per theme.
   ===================================================================== */
.seg{display:inline-flex;align-items:center;gap:2px;padding:2px;
  background:var(--panel);border:1px solid var(--line);border-radius:999px}
.seg button{appearance:none;border:0;background:transparent;color:var(--muted);
  font:inherit;font-size:.78rem;font-weight:600;white-space:nowrap;
  padding:.3rem .75rem;border-radius:999px;cursor:pointer;
  transition:background .14s ease,color .14s ease}
.seg button:hover{color:var(--ink)}
.seg button.on{background:var(--accent);color:var(--accent-ink)}
.seg button.on:hover{color:var(--accent-ink)}
.seg button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.seg button:disabled{opacity:.45;cursor:not-allowed}
/* on a filter row it stands exactly as tall as the boxes beside it */
.seg.infield{box-sizing:border-box;min-height:1.9rem;align-items:stretch}
.seg.infield button{padding:0 .75rem}

/* =====================================================================
   THE RIGHTS GRID
   ---------------------------------------------------------------------
   A tick box means the row has this action, on or off; .s1cell_na means
   the row HAS NO SUCH ACTION — a dash, no box — so an empty box never
   means two things. The checkbox is hidden, not unrendered, so the cell
   stays an AG Grid boolean cell; pointer events go with it.
   ===================================================================== */
/* NO POSITION OF ITS OWN (his report, 25 Sep 2026: "Confirming an invoice"
   could not be ticked): AG Grid places every cell absolutely, and a
   relative one fell out of the row — the dashes and the one real box of a
   one-action row slid under the rows below. The absolute cell already
   anchors the dash. */
.s1grid .s1cell_na{pointer-events:none}
.s1grid .s1cell_na .ag-checkbox,
.s1grid .s1cell_na .ag-cell-wrapper,
.s1grid .s1cell_na input[type=checkbox]{visibility:hidden}
.s1grid .s1cell_na::after{content:'\2013';position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  color:var(--faint);font-weight:600}

/* The menu-group heading, drawn as a row because AG Grid Community has
   no row grouping. It has to read as a heading and not as a record, so:
   panel background, no separator above, and its own cells carry nothing. */
.s1grid .ag-row.s1-row-grp{background:var(--panel);font-weight:700}
.s1grid .ag-row.s1-row-grp .ag-cell{border-right-color:transparent}
.s1grid .s1cell_grp{background:var(--panel)}
.rgrp{display:inline-flex;align-items:center;gap:.4rem;cursor:pointer;
  user-select:none;letter-spacing:.02em}
.rgrp .cv{display:inline-block;width:.7rem;color:var(--muted);
  transition:transform .12s ease}
.rgrp .cv.shut{transform:rotate(-90deg)}
/* A right that nothing in the database reads yet. It must be grantable —
   you set a role up before the module lands — but it must not look as
   though it did something. */
.pill.soon{background:var(--panel);color:var(--muted);
  box-shadow:inset 0 0 0 1px var(--line)}

/* The master picker down the left of Reference Lists, height matched to
   the entry table: the RIGHT column sets the row height, the left cell
   stretches and the list absolute-fills it. A longer list scrolls
   INSIDE, search box sticky inside it; overscroll-behavior keeps it off
   the page. At ≤900px the layout stacks in normal flow. */
.mastercols{display:grid;grid-template-columns:230px minmax(0,1fr);gap:1rem}
@media (max-width:900px){.mastercols{grid-template-columns:1fr}}
/* no floor of its own: the entry card's grid fills the window, and a floor
   here would be read by the grid's fitter as room it may not take */
.masterside{position:relative;min-height:0}
.masterlist{position:absolute;inset:0;border:1px solid var(--line);
  border-radius:10px;background:var(--card);
  overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain}
@media (max-width:900px){
  .masterside{position:static;min-height:0}
  .masterlist{position:static;max-height:340px}}
.msearch{position:sticky;top:0;z-index:2;background:var(--card);
  padding:.45rem;border-bottom:1px solid var(--line)}
.msearch input{width:100%;font:inherit;font-size:.82rem;padding:.35rem .55rem;
  border:1px solid var(--line);border-radius:8px;background:var(--bg);
  color:var(--ink)}
.msearch input:focus{outline:none;border-color:var(--accent)}
.masterlist button{display:block;width:100%;text-align:left;border:0;
  background:transparent;color:var(--ink);padding:.5rem .75rem;font-size:.85rem;
  cursor:pointer;border-left:3px solid transparent;font-family:inherit}
.masterlist button:hover{background:var(--bg)}
.masterlist button.on{background:var(--bg);border-left-color:var(--accent);
  font-weight:650}
.masterlist button small{display:block;color:var(--muted);font-size:.72rem;
  font-weight:400;margin-top:.1rem;line-height:1.25}

/* =====================================================================
   TABS inside a window — added with the Parties module.
   A party is thirty fields across five sections; one long scroll makes
   people miss half of it.
   ===================================================================== */
.tabs{display:flex;gap:.15rem;flex-wrap:wrap;border-bottom:1px solid var(--line);
  margin:-.2rem 0 .7rem}
.tabs .tab{border:0;background:transparent;color:var(--muted);font-family:inherit;
  font-size:.85rem;padding:.42rem .7rem;cursor:pointer;border-bottom:2px solid transparent;
  margin-bottom:-1px;border-radius:6px 6px 0 0}
.tabs .tab:hover{color:var(--ink);background:var(--bg)}
.tabs .tab.on{color:var(--ink);font-weight:650;border-bottom-color:var(--accent)}

/* A compact table of editable rows — NOT AG Grid: six grid instances in
   a modal that opens all day cost more than two emails return. Named
   `rowtable`, not `mini`, which already means the collapsed sidebar. */
.rowtable{width:100%;border-collapse:collapse;font-size:.85rem}
.rowtable th{text-align:left;font-weight:600;color:var(--muted);font-size:.75rem;
  padding:.25rem .35rem;border-bottom:1px solid var(--line);white-space:nowrap}
.rowtable td{padding:.18rem .35rem;vertical-align:middle}
.rowtable input,.rowtable select{width:100%;margin:0}
/* ...but not the Primary radios/ticks, which that rule stretched to the
   full cell. Higher specificity, so position here is not load-bearing. */
.rowtable input[type="radio"],.rowtable input[type="checkbox"]{
  width:16px;height:16px;margin:0}
/* Child-table controls are COMPACT (2 Aug 2026, the parties density
   round): a select in a row of ten does not need a form field's full
   height. Shared, so Branches' and Companies' child tables tighten with
   the same line (rule 26). */
/* No size of its own: every box in the application is already short, so
   a local size here would make these the TALLEST on the page. */
.rowtable tr:hover td{background:var(--bg)}
@media (max-width:760px){
  .rowtable,.rowtable thead,.rowtable tbody,.rowtable tr,.rowtable td{display:block;width:100%}
  .rowtable thead{display:none}
  .rowtable tr{border:1px solid var(--line);border-radius:8px;padding:.4rem;margin-bottom:.4rem}
}

/* =====================================================================
   THE TIME-ZONE PICKER — a search box over an offset-ordered list. Every
   color is a variable; the option under the pointer and the one held
   both use the ordinary hover surface.
   ===================================================================== */
.tzwrap{position:relative}
.tzdrop{position:absolute;left:0;right:0;top:calc(100% + 2px);z-index:60;
  max-height:16rem;overflow:auto;background:var(--card);
  border:1px solid var(--line);border-radius:8px;
  box-shadow:0 8px 24px rgba(0,0,0,.18)}
.tzopt{padding:.32rem .6rem;font-size:.85rem;cursor:pointer;white-space:nowrap}
.tzopt:hover{background:var(--bg)}
.tzopt.on{font-weight:650}

/* =====================================================================
   FULL-SCREEN RECORD EDITOR — Parties. A party is ~60 fields across five
   tabs; a modal can never use the height. The editor replaces the list
   in place; the list is hidden, not destroyed, so Back returns to the
   same page, filters and layout (rule 25).
   ===================================================================== */
/* The editor bar sticks just BELOW the topbar (itself sticky at z-index
   30); at top:0 it would stick behind it. --s1-topbar-h is written by
   s1StickMeasure() in shared/app.js from the bar's real height, since
   below 901px the bar wraps to ~94px; the fallback is the one-line value. */
.editorbar{position:sticky;top:var(--s1-topbar-h,2.55rem);z-index:20;display:flex;align-items:center;
  gap:.5rem;flex-wrap:wrap;padding:.45rem .6rem;margin-bottom:.5rem}
.editorbar .t{font-weight:650;font-size:.95rem}
/* A sentence on the editor bar GIVES WAY FIRST (his ruling, 13 Sep 2026):
   a wrapping row wraps before it shrinks, so the sentence declares no
   basis of its own and grows only to its natural width — the tick and
   the pills beside it keep their places and it takes what is left,
   trimmed with an ellipsis; .ov lets the note show the whole wording. */
.editorbar .gives,.gridtools .glead .gives{flex:1 1 0;min-width:0;max-width:max-content;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
/* AND A GRID'S LEAD GIVES WAY BEFORE ITS SEARCH BOX DOES (his go, 24 Sep
   2026, on the stones strip at 1366): a lead may shrink only while it holds
   a .gives sentence, every box around that sentence lets it (.gives-row),
   and the search box keeps 12rem — so the sentence trims first. */
.gridtools .glead:has(.gives){flex:0 1 auto;min-width:0}
.gridtools .glead:has(.gives) ~ .srch{min-width:12rem}
.gridtools .glead .gives-row{min-width:0}
/* The actions sit here rather than in a footer, so Save is reachable from any
   tab without scrolling past sixty fields to find it. */
@media (max-width:700px){
  .editorbar{gap:.35rem}
  .editorbar .t{width:100%;order:-1}
}

/* Tabs stay put while the body scrolls — the business, 28 July: "when i scroll down
   the header tab should be fixed no scroll". Sits below the editor bar, so the
   two stack rather than overlap. */
/* 5.15rem was the one-line top bar plus this editor bar, added up by hand.
   Both are measured now (U6), so the strip stacks correctly whatever the
   width, the theme or the number of pins. */
.ptabrow.sticky,.tabs.sticky{position:sticky;
  top:calc(var(--s1-topbar-h,2.55rem) + var(--s1-editorbar-h,2.6rem));
  z-index:6;background:var(--card);
  margin:-.2rem -.75rem .7rem;padding:.25rem .75rem 0}

/* =====================================================================
   PICK CHIPS — roles, and the branches a party is visible to.
   Selected is FILLED, not outlined, and carries a tick so the state does
   not rest on color alone. The filled chip's ink is --accent-ink, which
   flips per theme.
   ===================================================================== */
.chip{appearance:none;font-family:inherit;font-size:.83rem;cursor:pointer;
  display:inline-flex;align-items:center;gap:.35rem;
  padding:.34rem .7rem;border-radius:999px;
  background:var(--card);color:var(--ghost-ink);
  border:1.5px solid var(--ghost-line);opacity:.75;
  transition:background .12s,color .12s,opacity .12s,box-shadow .12s}
.chip:hover{opacity:1;background:var(--panel)}
.chip .mk{font-weight:800;width:.75rem;display:inline-block;text-align:center}
.chip.on{background:var(--accent);color:var(--accent-ink);
  border-color:var(--accent);opacity:1;font-weight:650;
  box-shadow:0 1px 3px rgba(0,0,0,.18)}
.chip.on:hover{background:var(--accent);opacity:.92}
.chip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* The row of them, with a count so "none chosen" is obvious. */
.chiprow{display:flex;flex-wrap:wrap;gap:.4rem;margin:.15rem 0 .2rem}

/* =====================================================================
   THE RIGHTS SCREEN — one line of controls, two columns of grid, the
   sensitive-data grid at the right of the screens grid.
   ===================================================================== */

/* The chips and the buttons share a line. The chips take the space and
   may wrap within it; the buttons are flex:none and pinned right, so a
   sixth role — or a sixteenth — never pushes "Edit rights" off the
   screen. Same rule as the top bar: only one thing in a row may give. */
.rolebar{display:flex;align-items:flex-start;gap:.5rem;flex-wrap:nowrap;
  margin-top:.35rem}
.rolebar .chiprow{flex:1 1 auto;min-width:0;margin:0}
.rolebar .rolebtns{flex:0 0 auto;display:flex;gap:.4rem;flex-wrap:wrap;
  justify-content:flex-end}
/* On a phone the buttons go under the chips rather than squeezing them
   into one chip per line. */
@media(max-width:760px){
  .rolebar{flex-wrap:wrap}
  .rolebar .rolebtns{width:100%;justify-content:flex-start}
}

/* ONE ROOF PER SCREEN (his design, 28 Sep 2026): the roles down the left
   as a list that stays one column however many there are; the one grid
   beside it. The summary line reads the role's rights in words. */
/* THE LIST STANDS BESIDE THE GRID WITHOUT SETTING THE PAGE'S HEIGHT: the
   grid measures what sits below it against the frame, so a list in the
   flow taller than the grid's floor would leave the grid short by the
   list's own height (seen on the site, 28 Sep 2026). Out of the flow it
   sets nothing; past twenty roles it scrolls inside its own box. */
.rolesplit{position:relative;margin-top:.35rem}
.rolelist{position:absolute;left:0;top:0;width:200px;box-sizing:border-box;max-height:calc(100vh - 12rem);overflow-y:auto;overflow-x:hidden;
  border:1px solid var(--line);border-radius:10px;padding:.4rem;background:var(--card)}
.rolelist li button > span:first-child{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rolelist li button .n{flex:0 0 auto}
.rolemain{margin-left:212px}
.rolelist .srch{margin:0 0 .3rem}
.rolelist-acts{display:flex;gap:.4rem;margin:0 0 .4rem}
.rolelist-acts .btn{flex:1 1 0;min-width:0;padding-left:.3rem;padding-right:.3rem}
/* the editing words on the summary line: the unsaved count wears the
   unsaved colour, as the bar it replaced did */
.rolebtns .editwords{align-self:center;color:var(--muted);font-size:.83rem;white-space:nowrap}
.rolebtns .editwords.dirty{color:var(--warn);font-weight:700}
.rolelist ul{list-style:none;margin:0;padding:0;display:grid;gap:2px}
.rolelist li{min-width:0}
.rolelist li button{width:100%;box-sizing:border-box;display:flex;justify-content:space-between;align-items:center;gap:.4rem;
  border:0;background:transparent;color:var(--ink);font:inherit;font-size:.8rem;padding:.38rem .6rem;border-radius:7px;
  text-align:left;cursor:pointer}
.rolelist li button .n{color:var(--muted);font-size:.85em}
.rolelist li button:hover{background:var(--panel)}
.rolelist li button.on{background:var(--blue-soft);color:var(--blue);font-weight:700}
.rolelist li button.on .n{color:var(--blue)}
.rolelist li button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.rolesum{flex:1 1 auto;min-width:0;color:var(--muted);font-size:.83rem;line-height:1.5;padding-top:.3rem}
.rolesum b{color:var(--ink)}
/* ONE LINE AT EVERY WIDTH, FOR EVERY ROLE (his ask and go, 6 Oct 2026).
   It wrapped to two lines beside the edit buttons, three on a laptop and
   five while editing there, pushing the grid down each time. The line
   never wraps now: the page shows the whole sentence (.rs-w) or, where
   that is cut, the short one (.rs-c) — chosen by measuring, in
   roles.js — and what is still cut ends in "…" with the whole sentence
   in our own note (rule 38). "Why" is a door, so it is never cut. */
.rolesum{display:flex;align-items:baseline;gap:.3rem;white-space:nowrap}
.rolesum .rs-t{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}
.rolesum .rs-c,.rolesum.c .rs-w{display:none}
.rolesum.c .rs-c{display:inline}
.rolesum .rs-why{flex:none}
.rolesum .rs-why a:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
/* the fold and the Held by count are real buttons, so Enter and Space
   work them; they wear the cell's own ink and size */
/* a toolbar act that is a toggle: chosen is the ring plus the bold word */
.gacts .btn[aria-pressed="true"]{box-shadow:inset 0 0 0 2px var(--accent);font-weight:700}
button.rgrp,button.rheld{background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer}
button.rgrp:focus-visible,button.rheld:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.s1grid .ag-row.s1-row-roof .rgrp{font-weight:700}
/* a screen's name is bold, never "bolder" than its bold button (900);
   the role list beside it reads at the grid's own size, .8rem */
.s1grid .rgrp b{font-weight:700}
.s1grid .ag-row.s1-row-child{background:transparent}
.s1grid .ag-row.s1-row-note{background:var(--panel)}
.rchild{padding-left:1.6rem}
.rnote{padding-left:1.6rem;color:var(--muted);font-size:.92em}
.rmore{margin-left:.4rem;font-size:inherit}
/* ALL · READ ONLY · NONE ON THE SCREEN'S OWN ROW (his ask and go, 6 Oct
   2026). A row that carries them is one line that gives way in order
   when the column is narrow: the count goes first — whole, never half a
   word (it wraps out of a one-line box) — then the name ends in "…"; the
   three presses are never cut. The presses are the lines' own small
   button (.rl-mini), so nothing here names a size. */
.s1grid .ag-cell > span:has(> .rroof){flex:1 1 auto;min-width:0}
/* everything on the row stands on ONE baseline — name, count, the three
   presses — as the name and its count do on every other row; the count's
   left gap is the word space plus the margin it has there */
.rroof{display:flex;align-items:baseline;min-width:0;white-space:nowrap;
  /* the presses are taller than the words and would set the name a
     fraction of a pixel lower than its neighbours' — measured, and put back */
  position:relative;top:-.029em}
.rroof .rgrp{flex:0 1 auto;min-width:0}
.rroof .rgrp b{display:flex;align-items:baseline;min-width:0}
.rroof .rgrp .cv{flex:none}
.rroof .rn{min-width:0;overflow:hidden;text-overflow:ellipsis}
.rroof .rmore{flex:0 1000000 auto;min-width:0;display:inline-flex;flex-wrap:wrap;height:1.36em;line-height:1.36;overflow:hidden;
  margin-left:calc(.4rem + .28em)}
.rroof .rmore::before{content:"\200B";width:0}
/* a mark on the screen's name ("nobody holds it yet") keeps the word
   space it has on every other row, and is never squeezed */
.rroof > .pill{flex:none;margin-left:.28em}
.rroof .rset{flex:none;display:inline-flex;align-items:baseline;gap:5px;margin-left:.7rem}
.rroof .rset .rl-mini{margin-right:0}
/* THE COLUMN THAT TAKES THE ROOM LEFT (`fill`, app.js) cannot be dragged,
   and the engine hides a heading's handle when it cannot — which took
   the bar between this heading and the next away. The bar stays, as a
   mark only: nothing to grab, no drag cursor. */
.s1grid .ag-header-cell.s1fill .ag-header-cell-resize,
.s1grid .ag-header-cell.s1fill .ag-header-cell-resize.ag-hidden{display:block !important;pointer-events:none;cursor:default}
.rsec{letter-spacing:.06em;text-transform:uppercase;font-size:.8em;color:var(--muted)}
.rheld{cursor:pointer;text-decoration:underline dotted;text-underline-offset:3px}
.s1grid .ag-row.s1-row-grp .s1cell_na::after{content:none}
/* a cell that has no question to answer on this row: nothing drawn, nothing to press */
.s1grid .s1cell_blank{pointer-events:none}
.s1grid .s1cell_blank .ag-checkbox,
.s1grid .s1cell_blank .ag-cell-wrapper,
.s1grid .s1cell_blank input[type=checkbox]{visibility:hidden}

/* =====================================================================
   THE RIGHTS GRID'S LINES
   ---------------------------------------------------------------------
   A screen's other rights stand in lines under it, each one row drawn
   across the grid: a lead word, then three slots (two on a narrow grid,
   one on a phone). In every slot the tick, the words and the days box
   stand at the same three places, so a line reads down as columns. A
   tick and the days it governs share one outline; so do a right and the
   one that waits for it. Everything is the cell font (rule 35).
   ===================================================================== */
.s1grid .s1full{height:100%;container-type:inline-size}
/* an open screen and what stands under it read as one block */
.s1grid .ag-row.s1-row-open{background:var(--blue-soft);box-shadow:inset 3px 0 0 var(--blue)}
.s1grid .ag-row.s1-row-in{background:color-mix(in srgb,var(--blue-soft) 38%,var(--card));box-shadow:inset 3px 0 0 var(--blue-line)}
.rl{display:grid;grid-template-columns:118px minmax(0,1fr);align-items:start;box-sizing:border-box;
  min-height:27px;padding:1px 7px 1px 26px;font-size:var(--ag-font-size);line-height:1.25;color:var(--ink)}
.rl-lead{color:var(--muted);font-weight:600;line-height:25px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rl.deep .rl-lead{padding-left:26px}
.rl-slots{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));row-gap:1px}
.rl-it{display:grid;grid-template-columns:16px minmax(0,1fr) max-content;column-gap:7px;align-items:center;
  box-sizing:border-box;min-height:25px;padding:0 9px;border:1px solid transparent;border-radius:999px}
.rl-it.wide{grid-column:1 / -1}
.rl-it.one,.rl-pair{border:1px solid var(--ghost-line);border-radius:999px;background:var(--card)}
.rl-pair{grid-column:span 2;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));box-sizing:border-box}
.rl-pair .rl-it{min-height:23px;border-width:0;padding:0 9px}
/* the second of a pair starts where a thing in that slot alone would */
.rl-pair .rl-it + .rl-it{padding-left:10px}
/* changed and not yet saved: the same wash and edge a changed cell wears */
.rl-it.chg{background:var(--warn-soft);box-shadow:inset 2px 0 0 var(--warn)}
/* muted words on a line stay the cell's size */
.rl .muted,.rl-hs .muted,.rhid .muted{font-size:inherit}
.rl label.rl-lb{display:contents;cursor:pointer;font-size:inherit;font-weight:400;color:var(--ink);
  letter-spacing:0;text-transform:none;margin:0}
.rl-c1{display:flex;align-items:center;justify-content:center;line-height:1}
.rl-w{min-width:0;overflow-wrap:anywhere}
.rl-w .pill{margin-left:6px}
.rl-it.off .rl-w,.rl-it.slp .rl-w{color:var(--muted)}
.rl-tl{display:inline-grid;grid-auto-flow:column;align-items:center;column-gap:6px;justify-content:end;white-space:nowrap}
.rl-n{display:inline-block;width:54px;box-sizing:border-box;text-align:right;padding-right:7px}
.rl-un{display:inline-block;width:30px}
.rl input.rl-bx{width:54px;height:23px;min-height:0;box-sizing:border-box;text-align:right;padding:0 6px;margin:0;
  font:inherit;border:1px solid var(--input-line);border-radius:6px;background:var(--input-bg);color:var(--ink)}
.rl input.rl-bx::placeholder{color:var(--muted);font-weight:400}
/* days kept while their tick is off: there to read, not to type */
.rl input.rl-bx[readonly]{background:var(--panel);border-style:dashed;color:var(--muted)}
.rl-wn{color:var(--warn);font-weight:700}
.rl-jn{color:var(--muted);font-weight:700}
.rl mark,.rgrp mark,.rchild mark,.rhid mark{background:var(--warn-soft);color:inherit;padding:0 1px;border-radius:2px}
.rl-mini{font:inherit;font-weight:600;color:var(--ghost-ink);background:var(--card);border:1px solid var(--ghost-line);
  border-radius:6px;height:22px;line-height:20px;padding:0 8px;margin-right:6px;cursor:pointer}
.rl-mini:hover{background:var(--panel)}
.rl-it:focus-visible,.rl-mini:focus-visible,.rl input.rl-bx:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
/* the hidden columns' heading, and a group's own row */
.rl-hs{display:flex;align-items:center;gap:8px;box-sizing:border-box;min-height:27px;padding:0 7px;
  font-size:var(--ag-font-size);white-space:nowrap;overflow:hidden}
.rl-hs .muted{min-width:0;overflow:hidden;text-overflow:ellipsis;font-weight:400}
.rl-hs .linkbtn{flex:none}
.rhid{display:flex;align-items:center;gap:6px;flex:1 1 auto;min-width:0}
.rhid b{flex:none;font-weight:600}
.rhid-d{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}
.rhid .linkbtn{flex:none}
/* a second document on the same screen */
.rtab{display:inline-block;font-weight:700;color:var(--blue);border:1px solid var(--blue-line);background:var(--card);
  border-radius:5px;padding:0 5px;margin-right:6px;line-height:18px}
@container (max-width:1149px){
  .rl{grid-template-columns:92px minmax(0,1fr);padding-left:22px;padding-right:4px}
  .rl.deep .rl-lead{padding-left:14px}
  .rl-slots{grid-template-columns:repeat(2,minmax(0,1fr))}
  .rl-it{padding:0 7px;column-gap:6px}
  .rl-pair .rl-it{padding:0 7px}
  .rl-pair .rl-it + .rl-it{padding-left:8px}
  .rl-tl{column-gap:5px}
}
@container (max-width:640px){
  .rl{grid-template-columns:minmax(0,1fr);padding-left:10px}
  .rl.deep .rl-lead{padding-left:0}
  .rl-slots{grid-template-columns:minmax(0,1fr)}
  .rl-pair{grid-column:auto;grid-template-columns:minmax(0,1fr);border-radius:12px}
}
@media(max-width:800px){
  .rolelist{position:static;width:auto;max-height:none;margin-bottom:.5rem}
  .rolemain{margin-left:0}
}
/* The ? that carries what would otherwise sit on the screen as prose. */
.btn.ghost.sm.hlp{width:1.9rem;padding-left:0;padding-right:0;
  font-weight:800;text-align:center}

/* A conditional note, one line high, where a <p class="muted"> would
   have been three. */
.hint{margin:.4rem 0 0;font-size:.82rem;color:var(--muted);line-height:1.35}
.hint b{color:var(--ink)}

/* The two grids. 2fr / 1fr because the left one carries a name and four
   tick columns and the right one carries a name and one — measured, not
   guessed. Below 1100px they stack, sensitive underneath, so the phone
   layout is exactly what it was. */
/* ---- CURRENCY & FX: two columns ----
   3fr/2fr: a six-column register left, two label-and-value cards right.
   align-items:start so the short cards are not stretched to the
   register's height. Below 1100px one column, matching .rights2's
   breakpoint so the two screens stack together. */
.fx2{display:grid;grid-template-columns:1fr;gap:.75rem;align-items:start}
.fx2 > div{min-width:0;display:flex;flex-direction:column;gap:.75rem}
@media(min-width:1100px){ .fx2{grid-template-columns:3fr 2fr} }

/* ---- SYSTEM SETTINGS: two columns of cards (0133, 6 August 2026).
   Even halves, because both sides hold the same kind of thing — short
   cards of label-and-value. Same 1100px breakpoint as .fx2 and
   .rights2: three screens that stack at three different widths read as
   two of them being broken. */
.sys2{display:grid;grid-template-columns:1fr;gap:.75rem;align-items:start}
.sys2 > div{min-width:0;display:flex;flex-direction:column;gap:.75rem}
@media(min-width:1100px){ .sys2{grid-template-columns:1fr 1fr} }
/* A value that is shown and cannot be typed into. Not a disabled input:
   a greyed box invites a click and then refuses it, and these are facts
   rather than fields somebody has been locked out of. */
.ro{font-size:.88rem;padding:.3rem 0;word-break:break-all}

/* SYSTEM SETTINGS AS A SHEET (his go, 14 Oct 2026): a section list on the
   left, values in ink rather than greyed boxes, one line of help with the
   reason behind Why?, sections flowing down two columns in list order. */
.s1syspage{display:grid;grid-template-columns:200px minmax(0,1fr);gap:.75rem;align-items:start;margin-top:5px}
/* both held pieces stop under the top bar, never behind it */
.editbar.s1sysbar{top:var(--s1-topbar-h,2.55rem);z-index:21}
.s1sysnav{position:sticky;top:calc(var(--s1-topbar-h,2.55rem) + .4rem);background:var(--card);border:1px solid var(--line);border-radius:var(--r,10px);
  padding:.45rem .35rem;display:flex;flex-direction:column}
/* a group's name stands on its own band with the action-blue bar (his go on the drawing, 14 Oct 2026) */
.s1sysg{font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink);font-weight:700;
  background:var(--panel);border-left:3px solid var(--blue);border-radius:6px;padding:.32rem .5rem;margin:.6rem 0 .2rem}
.s1sysg:first-child{margin-top:0}
.s1sysnav a{padding:.3rem .5rem;margin-left:.35rem;border-radius:6px;color:var(--ink);text-decoration:none;font-size:.86rem}
/* the list sits in a <nav>, so the dark sidebar's hover ink must be overridden here */
.s1sysnav a:hover{background:var(--panel);color:var(--ink)}
.s1sysnav a.on{background:var(--blue-soft);color:var(--blue);font-weight:700}
.s1sysmain{min-width:0}
.s1systools{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-bottom:.5rem}
.s1systools input{flex:1 1 16rem;max-width:26rem}
.s1sysfindl{font-weight:700;font-size:.86rem}
.s1sysnone{color:var(--ink);font-size:.86rem}
.s1syscols{columns:2 26rem;column-gap:.75rem}
.s1syssec{break-inside:avoid;display:block;background:var(--card);border:1px solid var(--line);border-radius:var(--r,10px);
  margin:0 0 .75rem;overflow:hidden;scroll-margin-top:calc(var(--s1-topbar-h,2.55rem) + .5rem)}
/* a section the list jumps to lands below the top bar — and below the edit bar while one is open */
.s1syspage.s1sysediting .s1syssec{scroll-margin-top:calc(var(--s1-topbar-h,2.55rem) + 3.7rem)}
.s1sysh2{display:flex;align-items:center;gap:.45rem;flex-wrap:wrap;margin:0;padding:.55rem .85rem;font-size:.95rem;
  font-weight:700;line-height:1.25;border-bottom:1px solid var(--line)}
.s1sysh2 > span:first-child{margin-right:auto}
.s1sysh2 > h2{font-size:inherit;font-weight:inherit;line-height:inherit;margin:0 auto 0 0}
.s1sysrow{display:grid;grid-template-columns:minmax(0,1fr) minmax(8rem,38%);gap:.9rem;padding:.5rem .85rem;align-items:start}
.s1sysrow + .s1sysrow{border-top:1px solid var(--line)}
.s1sysname{display:block;font-weight:700;color:var(--ink);font-size:.88rem;margin:0}
.s1syshelp{color:var(--muted);font-size:.8rem;line-height:1.4;margin-top:.1rem}
.s1syshelp b{color:var(--ink)}
.s1sysv{min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:.25rem}
.s1sysv > div{width:100%}
.s1sysval{color:var(--ink);font-weight:700;font-size:.9rem;overflow-wrap:anywhere}
.s1sysmute{color:var(--muted);font-weight:400}
.s1syslock{display:block;color:var(--muted);font-size:.78rem;margin-top:.2rem}
.s1sysdot{display:inline-flex;align-items:center;gap:.3rem;color:var(--muted);font-size:.76rem}
.s1sysdot i{width:.45rem;height:.45rem;border-radius:50%;background:var(--blue);display:inline-block}
details.s1syswhy{display:inline;font-size:inherit}
details.s1syswhy > summary{display:inline;list-style:none;color:var(--blue);cursor:pointer;margin-left:.2rem}
details.s1syswhy > summary::-webkit-details-marker{display:none}
details.s1syswhy > summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
details.s1syswhy[open]{display:block}
details.s1syswhy > div{color:var(--ink);margin-top:.3rem;max-width:62ch;line-height:1.5}
.s1sysjobsay{color:var(--muted);font-size:.8rem;margin:.45rem .85rem}
.s1sysjfsay{color:var(--ink);font-size:.86rem;margin:.55rem 0 0}
.s1sysjobs{columns:2 24rem;column-gap:.75rem;padding:0 .85rem .7rem}
.s1sysjobs > div{break-inside:avoid;padding:.45rem 0 .1rem}
.s1sysjobs .s1sysg3{margin-top:0}
.s1sysjob details.s1syswhy{display:block;font-size:.8rem;margin-top:.1rem}
.s1sysg3{font-size:.72rem;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);font-weight:700;margin:.6rem 0 .3rem}
.s1sysjoblist{list-style:none;margin:0;padding:0;border:1px solid var(--line);border-radius:8px;overflow:hidden}
.s1sysjob{display:flex;gap:.9rem;align-items:flex-start;padding:.5rem .75rem;background:var(--card)}
.s1sysjob + .s1sysjob{border-top:1px solid var(--line)}
.s1sysjob > .s1sysk{flex:1;min-width:0}
.s1sysjobabout{color:var(--ink);font-size:.82rem;margin-top:.1rem}
.s1sysjobr{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:.35rem}
.s1sysjoberr{color:var(--red);font-size:.76rem;max-width:16rem;text-align:right}
.s1sysjobacts{display:flex;gap:.4rem}
.s1sysv .s1syswatchsel{width:5.5rem}
.s1sysv .s1syswatchnum{width:4.2rem}
/* a Watch number keeps its unit word on the same line; a row too wide for
   its column wraps between pairs, never between a box and its word */
.s1sysv .s1syspair{white-space:nowrap}.s1sysfacts{display:grid;grid-template-columns:repeat(auto-fit,minmax(17rem,1fr));gap:0 1.2rem;margin:0;padding:.5rem .85rem}
.s1sysfacts > div{display:flex;justify-content:space-between;gap:.75rem;padding:.3rem 0;border-bottom:1px dashed var(--line);font-size:.86rem}
.s1sysfacts dt{color:var(--muted)}
.s1sysfacts dd{margin:0;font-weight:700;color:var(--ink);overflow-wrap:anywhere;text-align:right}
.s1sysnet{display:flex;align-items:center;gap:.45rem;flex-wrap:wrap;padding:.1rem .85rem 0;font-size:.82rem}
.s1sysnet a{margin-left:auto}
@media(max-width:900px){
  .s1syspage{grid-template-columns:1fr}
  .s1sysnav{position:static;flex-direction:row;flex-wrap:nowrap;overflow-x:auto;gap:.2rem}
  .s1sysg{display:none}
  .s1sysnav a{flex:none}
  .s1sysrow{grid-template-columns:1fr;gap:.3rem}
}

.rights2{display:grid;grid-template-columns:1fr;gap:.7rem;margin-top:.55rem}
@media(min-width:1100px){ .rights2{grid-template-columns:2fr 1fr} }
/* A grid box inside a grid column must be allowed to be narrower than
   its content, or the column refuses to shrink and the row overflows. */
.rights2 > div{min-width:0}

/* The caption above each grid: the same words a .card-h carried, at a
   third of the height. Not inside the grid's own toolbar, because that
   strip belongs to the controls that ACT on the grid — Collapse all,
   search, filters — and a heading is not one of them. */
.gridcap{display:flex;align-items:center;gap:.45rem;margin:0 0 .3rem;
  font-size:.76rem;font-weight:700;letter-spacing:.03em;
  text-transform:uppercase;color:var(--muted);line-height:1.2}
.gridcap .pill{text-transform:none;letter-spacing:0}

/* =====================================================================
   FORM CONTROLS ARE 16px ON A PHONE
   =====================================================================
   iOS Safari zooms the whole page when a control under 16px takes focus.
   Only below 900px — desktop density is unchanged — and font-size only,
   so nothing else reflows.
   ===================================================================== */
@media (max-width:900px){
  input,select,textarea{font-size:16px}
  .branchpick .bpbtn{font-size:16px}
  .gridtools .srch input,.gridtools select{font-size:16px}
  .msearch input{font-size:16px}
  .rowtable input:not([type="radio"]):not([type="checkbox"]),
  .rowtable select{font-size:16px}
}

/* =====================================================================
   PRINT — blunt and theme-proof: black ink on white, chrome out, the
   content has the page. Not a document template — those come per
   document with Sales — but the floor that keeps Ctrl-P useful.
   ===================================================================== */
@media print{
  /* THEME-PROOF. Every color in this system is a variable, and three of
     the five themes are dark. Rather than override several hundred
     rules, the tokens that decide ink and paper are re-pointed for the
     printed page, so every component inherits sane values at once. */
  :root,
  html[data-theme]{
    --bg:#ffffff; --card:#ffffff; --ink:#000000; --muted:#333333;
    --faint:#444444; --line:#999999; --shadow:none;
    --side:#ffffff; --side-ink:#000000;
    --code-bg:#ffffff; --code-ink:#000000;
  }
  html,body{background:#ffffff!important;color:#000000!important;height:auto}
  *{box-shadow:none!important;text-shadow:none!important}

  /* CHROME OFF. None of this is part of the record: navigation, the
     branch picker, toolbars, transient messages and anything that only
     exists to be clicked. */
  aside,.topbar,.scrim,.toast,.updpop,.gridtools,.tabs,.editbar,
  .msearch,.pinbar,.branchpick,.modal-bg{display:none!important}
  /* Buttons print as ink-colored boxes that say nothing on paper. */
  .btn,button,.tbtn,.x{display:none!important}

  .shell{display:block}
  .main{display:block}
  .content{padding:0!important;width:auto}
  .card{border:1px solid #999999!important;border-radius:0;
        box-shadow:none!important;break-inside:avoid;page-break-inside:avoid}

  /* THE WHOLE GRID, NOT THE SCROLL VIEWPORT. AG Grid gives its wrapper a
     fixed pixel height and scrolls inside it; printed, that emits one
     screenful and silently drops the rest — which is worse than not
     printing, because the page looks complete. */
  [data-gridbox],.ag-root-wrapper,.ag-body-viewport,.ag-center-cols-viewport{
    height:auto!important;max-height:none!important;overflow:visible!important}
  .ag-header{position:static!important}

  /* A form is READ on paper: the boxes are noise, the values are not. */
  input,select,textarea{border:0!important;background:transparent!important;
    color:#000000!important;padding:0!important;-webkit-appearance:none;appearance:none}

  /* Rows and headings should not be orphaned across a page break. */
  tr,.rowtable tr{break-inside:avoid;page-break-inside:avoid}
  h1,h2,h3,.card-h{break-after:avoid;page-break-after:avoid}

  @page{margin:14mm}
}

/* ===== DENSE FORM: the whole stone window on ONE screen, small boxes,
   columns, vertical scroll only, starting after the main menu. Owned
   here so every transaction window inherits it (rule 26/27): a module
   adds class "densef" to its modal, nothing else. A grid flows DOWN;
   CSS multi-columns grow sideways. ===== */
/* THE WINDOW FOLLOWS THE MENU, IT DOES NOT GUESS AT IT: --rail-w is set
   by the shell from the same `mini` flag that draws the rail (app.js
   S.rail), so there is ONE fact about the menu's width. Below 940px the
   menu is a drawer and the window takes the whole width. */
:root{--rail-w:236px}
html.s1-rail{--rail-w:50px}
.densef{max-width:none;
  width:calc(100vw - var(--rail-w) - 10px);
  margin-left:calc(var(--rail-w) + 5px);margin-right:auto}
@media(max-width:939px){
  :root{--rail-w:0px}
  .densef{width:calc(100vw - 1.5rem);margin-left:auto;margin-right:auto}}

/* THE WHOLE WINDOW IS ON THE SCREEN, ALWAYS: never taller than the
   screen, laid out as a column so heading and button row keep their
   height, and the FIELDS scroll inside themselves. The cap subtracts
   exactly what .modal-bg reserves (4vh above, 2rem below). `min-height:0`
   on the scrolling part is the whole trick — a flex child refuses to
   shrink below its content without it. */
.densef{display:flex;flex-direction:column;
  max-height:calc(100vh - 4vh - 2rem)}
.densef .modal-h,.densef .modal-f{flex:none}
.densef .modal-b{flex:1 1 auto;min-height:0;overflow-y:auto}

/* THE SAME CAP WITHOUT THE FORM GRID — for windows that lay their body
   out themselves (the stone detail view): header and footer always on
   screen, the body scrolls. min-height:0 is the whole trick, as above. */
.tallcap{display:flex;flex-direction:column;
  max-height:calc(100vh - 4vh - 2rem)}
.tallcap .modal-h,.tallcap .modal-f{flex:none}
.tallcap .modal-b{flex:1 1 auto;min-height:0;overflow-y:auto}

/* ONE GRID, NOT TWO COLUMNS OF BLOCKS: every box sits on these tracks
   whatever heading it falls under. The count follows the width — no
   screen names a number. A heading is a full-width row. */
.densef .modal-b{display:grid;
  grid-template-columns:repeat(auto-fill,minmax(8.5rem,1fr));
  gap:.15rem .55rem;align-items:start;overflow-x:hidden}
.densef .modal-b > p{grid-column:1 / -1}
.densef .modal-b .sfhead{grid-column:1 / -1;
  color:var(--muted-ink,var(--muted));font-weight:600;letter-spacing:.05em;
  font-size:.72em;margin:.45rem 0 .05rem}
.densef .modal-b .sfhead:first-child{margin-top:0}

/* A NOTE THAT DOES NOT MOVE THE FORM. As a full-width paragraph
   between two headings, the ID answer would push every field below it
   on arrival and reflow the whole window. Out of the flow, it can say
   as much as a refusal needs to say and nothing shifts by a pixel. */
.densef .modal-b .sfnote{
  position:absolute;left:0;top:100%;z-index:6;
  min-width:100%;width:max-content;max-width:22rem;
  margin-top:2px;padding:.18rem .4rem;border-radius:5px;
  font-size:.72rem;line-height:1.35;
  background:var(--card);border:1px solid var(--line);
  box-shadow:0 4px 14px rgba(0,0,0,.12)}
.densef .modal-b .sfnote.bad{color:var(--red);border-color:var(--red)}
.densef .modal-b .sfnote.ok{color:var(--muted)}
.densef .modal-b label{font-size:.74em;margin:0 0 1px}
/* The boxes are no longer restated here: since 10 Aug 2026 this IS the
   size every box in the application has, so a second copy could only
   drift away from it. What stays is what is still particular to a dense
   window — the smaller label above the box. */
.densef .modal-b .check label{font-size:.85em}

/* A FULL-WIDTH PAIR: a text box that takes the width beside a dropdown
   sized by the browser to its own longest answer, so nothing is cut.
   One grid cell, so the form's tracks are untouched; labels keep their
   place above each box. The dropdown's width is measured, never typed. */
.densef .modal-b .sfpair{grid-column:1 / -1;display:flex;gap:.55rem;
  align-items:start}
.densef .modal-b .sfpair > div:first-child{flex:1 1 auto;min-width:0}
.densef .modal-b .sfpair > div + div{flex:none}
.densef .modal-b .sfpair > div + div select{width:auto}

/* THE SEARCH-AND-CHIP BOX — ONE DECLARATION, BOTH WINDOWS. Not scoped
   to `.densef`: the add-stone window and the stock register's stone
   window share it (rule 26). Nothing here may move to a style attribute
   — Alpine shows an element by DELETING `display` off its inline style.
   One cell wide, like every box around it; there is no `.chipwrap.full`. */
.chipwrap{position:relative}
.chipbox{
  display:flex;flex-wrap:wrap;align-items:center;gap:.2rem .3rem;
  padding:.2rem .3rem;min-height:1.9rem;cursor:text;
  border:1px solid var(--input-line);border-radius:6px;background:var(--input-bg)}
.chipwrap:focus-within .chipbox{border-color:var(--pick-line)}
.chipbox.off{background:var(--panel);cursor:default}
/* CHIPS STANDING OUTSIDE THE BOX (his ask, 25 Aug 2026 - the shape
   groups wear the register's dropdown with what is picked beside it).
   Same chip, same row rules; only the place differs, so nothing here
   states a chip size (rule 35 - the shared rules own that). */
.chipsout{display:flex;flex-wrap:wrap;gap:.2rem .3rem;margin:0 0 .25rem}
.chipsout:empty{display:none}
/* THE CHIP. Its short form is the value — that is the form that prints
   and the form his people write — with the full name beside it so nobody
   has to already know the shorthand. Muted, NOT smaller: nothing in this
   application renders below its own font size. */
.chipbox .chip{
  display:inline-flex;align-items:center;gap:.25rem;
  padding:.05rem .3rem;font-size:.85em;white-space:nowrap;
  border:1px solid var(--blue-line);border-radius:5px;background:var(--blue-soft)}
.chipbox .chip .cl{color:var(--muted)}
.chipbox .chip .x{
  border:0;background:none;padding:0 0 0 .1rem;margin:0;line-height:1;
  font-size:1.05em;color:var(--muted);cursor:pointer}
.chipbox .chip .x:hover{color:var(--red)}
/* A box whose order means something: a chip is picked up and dropped */
.chipbox .chip[draggable="true"]{cursor:grab}
.chipbox .chip.over{outline:2px solid var(--pick-line);outline-offset:1px}
/* The typing space takes whatever is left of the row and never forces
   the box wider than the column it sits in. */
/* THE TYPING SPACE IS NOT A FORM BOX — the OUTER chip box owns the one
   shared height. Without these lines the inner input inherits the box
   minimum and stacks it on the holder's padding, 9px too tall. */
.chipbox .chipq{
  flex:1 1 6rem;min-width:4rem;width:auto;min-height:0;
  border:0;outline:none;background:none;padding:0 .1rem;
  font:inherit;font-size:.88rem;color:var(--ink)}
/* THE ONE-ANSWER SHAPE: the closed box is a select — chosen answer or a
   muted invitation, chevron right — and the open panel holds the search
   on top with the WHOLE list scrolling under it; the panel is a column
   whose middle owns the overflow. All display decisions live here. */
.chipbox.sel1{cursor:pointer;flex-wrap:nowrap}
/* The chosen answer is PLAIN INK TEXT, as in every other drop box —
   his correction; the chip form stays on the several-answer box.
   Its size is the TYPING BOXES' OWN (.88rem, stated in rem): an em here
   reads off the surrounding text and prints a shade smaller than the
   typed word standing level beside it. */
.chipbox.sel1 .val{padding:.05rem .1rem;font-size:.88rem;color:var(--ink);
  /* the inherited line height stands taller than the box's own minimum,
     so without this cap the closed box outgrows the typing boxes beside
     it by a hair - measured in the browser, 18 Aug 2026 */
  line-height:1.3;
  min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.chipbox.sel1 .car{margin-left:auto;flex:none;width:.5em;height:.5em;
  margin-right:.15rem;margin-top:-.2em;
  border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);
  transform:rotate(45deg);transition:transform .12s}
.chipbox.sel1.on .car{transform:rotate(-135deg);margin-top:.2em}
.chipbox.sel1.off .car{opacity:.35}
.chipdrop.sel1{display:flex;flex-direction:column;overflow:hidden;
  /* wider than its box when the words need it — capped at a readable
     line, never past the screen; app.js sets the min to the box width */
  max-width:min(30rem,calc(100vw - 16px))}
.chipdrop.sel1 .row{max-width:100%}
.chipdrop.sel1 .row b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* THE CLEAR-EVERY-TICK BUTTON sits beside the search word, not on top of
   it, where a cross means "clear what I typed". The word keeps its full
   width when no ticks are on, because the button is not there. */
.chipdrop.sel1 .srch{flex:none;padding:.3rem;display:flex;align-items:center;gap:.3rem}
.chipdrop.sel1 .srch .chipclr{flex:none;white-space:nowrap}
.chipdrop.sel1 .srch .chipq{width:100%;box-sizing:border-box;
  font:inherit;font-size:.85em;color:var(--ink);
  border:1px solid var(--input-line);border-radius:6px;
  background:var(--input-bg);padding:.25rem .4rem;outline:none}
.chipdrop.sel1 .srch .chipq:focus{border-color:var(--pick-line)}
.chipdrop.sel1 .rows{flex:1 1 auto;min-height:0;overflow:auto}
.chipdrop .row.cur{font-weight:700}
.chipdrop .row.none{cursor:default;color:var(--muted);
  /* a box's own reason for an empty list is a sentence: it wraps whole (0789, rule 38) */
  white-space:normal}
/* THE ADD ROW AND THE ADD STRIP (18 Oct 2026, his go on the drawing): an
   empty list that can be filled in place offers one accent row, and the
   strip below it holds the screen's own boxes on the panel's own band.
   Shown only by a box that declares them; app.css owns every display. */
.chipdrop .row.add{color:var(--accent);font-weight:600}
/* a list still looking up its rows says so quietly — not dressed as an act */
.chipdrop .row.add.wait{color:var(--muted);font-weight:400;font-style:italic;cursor:default}
.chipdrop .chipadd{flex:none;padding:.3rem .5rem .45rem;border-top:1px solid var(--line);background:var(--panel)}
.chipdrop .chipadd .pair{display:flex;align-items:flex-end;gap:.35rem}
.chipdrop .chipadd .f{flex:1 1 0;min-width:0}
.chipdrop .chipadd .by{padding-bottom:.4rem;color:var(--muted)}
.chipdrop .chipadd label{display:block;font-size:.74em;color:var(--muted);margin:0 0 1px}
.chipdrop .chipadd input{width:100%;box-sizing:border-box;font:inherit;font-size:.88rem;
  padding:.25rem .4rem;border:1px solid var(--input-line);border-radius:6px;
  background:var(--input-bg);color:var(--ink);outline:none}
.chipdrop .chipadd input:focus{border-color:var(--pick-line)}
.chipdrop .chipadd .note{font-size:.75rem;color:var(--muted);margin-top:.3rem;white-space:normal}

/* THE LOT WINDOW AND THE PENCIL BESIDE A FOUND LOT (1075; his go on the
   drawing, 18 Oct 2026). The pencil sits inside the Lot box's right end,
   the box keeps its height and its row; the window is two columns — the
   name and grades, the packets by branch — one table, nothing stacked. */
.lotpen{position:absolute;right:4px;bottom:4px;width:25px;height:25px;border:0;border-radius:5px;
  background:var(--blue-soft);color:var(--accent);cursor:pointer;font:inherit;font-size:.88rem;line-height:25px;padding:0}
.lotpen:hover{background:var(--blue-line)}
.lotpen:disabled{opacity:.5;cursor:default}
input.haspen{padding-right:34px}
/* THE STONE WINDOW'S LOT NO (1087; his go on the drawing, 19 Oct 2026):
   a typing box that opens the house list once letters are typed, like the
   bulk Lot box — no dropdown mark (his go, 19 Oct 2026); its rows dress as
   every list's (the bar and the 28 px rows) */
.lotwrap{position:relative;min-width:0}
/* the drawing's width: the shared placer writes the box's own width
   inline, so the list's floor needs the weight; the foot wraps inside
   the rows' width and never widens the list over its neighbours */
.chipdrop.lotsug{min-width:15rem !important}
.chipdrop.lotsug > .muted{width:0;min-width:100%;box-sizing:border-box;white-space:normal}
.chipdrop.lotsug > .muted span{white-space:nowrap}
.chipdrop.lotsug .row.lotnew{flex:none;border-top:1px solid var(--line)}
.lotwin{display:grid;grid-template-columns:1.1fr 1fr;gap:.8rem 1.2rem}
@media(max-width:860px){ .lotwin{grid-template-columns:1fr} }
.lotwin label{display:block;font-size:.74em;color:var(--muted);margin:0 0 1px}
.lotwin input{width:100%;box-sizing:border-box}
/* Code and Nickname share one row (1092): the code box takes the wider share,
   its ↺ sits inside the box's right end as the arrival's lot pencil does */
.lotwin .lotcode{display:grid;grid-template-columns:1.5fr 1fr;gap:5px;align-items:end}
.lotwin .lotcode-c,.lotwin .lotcode-n{min-width:0}
.lotwin .lotcode-c{position:relative}
.lotgr{display:flex;flex-wrap:wrap;gap:.3rem;margin-top:.55rem}
.lotgr .chip{display:inline-flex;align-items:center;padding:.05rem .4rem;font-size:.85em;
  border:1px solid var(--blue-line);border-radius:5px;background:var(--blue-soft)}
/* LOT MASTER'S GRADE BOXES (1101): the line under them says the code, what
   changes (the warning ink) or the lot that already has the grades (red).
   Never the -ink tokens: those are text ON a filled colour (white on light) */
.lotwin .lotgrades{margin-top:.5rem}
/* the stone window's small headings (his go on the drawing, 21 Oct 2026) */
.lotwin .lot-h{font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
  font-weight:600;margin:0 0 .35rem;line-height:1.3}
.lotwin .lot-h span{text-transform:none;letter-spacing:0;font-weight:400}
.lotwin .lot-h2{margin-top:.75rem}
.lotwin .lot-h + .lotgrades{margin-top:0}
.lm-said{font-size:.78rem;margin:.15rem 0 .4rem;color:var(--muted);line-height:1.35}
.lm-said:empty{display:none}
/* BULK INVENTORY: a master packet reads grey in its lot; the packet window's
   facts stand as label over value, the notes one to a line; a tab's grid
   fills the window's body */
.s1grid .ag-row.bk-master .ag-cell{color:var(--muted)}
/* THE PACKET WINDOW IN THE STONE WINDOW'S SHAPE (his go, 21 Oct 2026): an
   empty picture says so under a faint bulk mark, with the lot's door; the
   weight and pieces sit as two quiet chips under the name */
.stonev .sv-view .bk-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.5rem;height:100%;padding:1rem;text-align:center;font-size:.8rem}
.stonev .sv-view .bk-empty .s1gem{opacity:.55}
.stonev .sv-view .bk-empty a{color:var(--blue);text-decoration:underline}
.bk-glance{display:flex;gap:.4rem;justify-content:center;flex-wrap:wrap;margin-top:.45rem}
.bk-facts{display:grid;grid-template-columns:repeat(auto-fill,minmax(14rem,1fr));gap:.4rem 1.2rem;margin:0}
.bk-facts > div{min-width:0}
.bk-facts dt{font-size:.74em;color:var(--muted);margin:0 0 1px}
.bk-facts dd{margin:0;font-weight:700;overflow-wrap:anywhere}
/* the packet window's doors (1125): the PDF button sits on the number's line; whose file it is, in plain ink */
.bk-facts .bk-pdf{vertical-align:middle;margin-left:.3rem}
.bk-facts .bk-whose{font-weight:400;font-size:.8em}
.bk-facts a.bk-door{color:var(--blue);text-decoration:underline}
.bk-notes{grid-template-columns:1fr}
.bk-notes dd{font-weight:400;white-space:pre-wrap}
.bk-tabgrid{display:flex;flex-direction:column;min-height:22rem}
.lm-said.chg{color:var(--warn);font-weight:600}
.lm-said.twin{color:var(--red);font-weight:600}
.lm-twinact{margin:0 0 .45rem}
/* SIEVE & SIZE'S SIZES COLUMN (1102): a word no lot can be made from reads a red 0 */
.pm-nosize{color:var(--red)}
/* + Add row's kind menu opens under the button, its right edge on the button's */
.s1menu.pm-addkind{top:calc(100% + 4px);right:0;min-width:11rem}
.lottab{width:100%;border-collapse:collapse;border:1px solid var(--line);border-radius:6px;overflow:hidden;font-size:.85em}
.lottab th,.lottab td{padding:.28rem .5rem;border-bottom:1px solid var(--line);text-align:left}
.lottab th{background:var(--panel);font-size:.86em;text-transform:uppercase;letter-spacing:.03em;color:var(--muted);font-weight:600}
.lottab .n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.lottab tfoot td{font-weight:700;border-bottom:0}
.lottab tbody tr:last-child td{border-bottom:0}
.lottab tfoot tr td{border-top:1px solid var(--line)}

/* THE SIEVE WINDOW (1080): a facts line in the record windows' small-caps
   labels, the read-only-until-Edit note, and the add strip under the grid.
   Every size is relative to the page font (rule 35: one number sets it). */
.swfacts{display:flex;flex-wrap:wrap;gap:.3rem 1.4rem;margin:0 0 .7rem;font-size:.9em}
.swfacts>div>span:first-child{display:block;font-size:.76em;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.swnote{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:.4rem .7rem;margin:0 0 .5rem;font-size:.88em}
.swadd{display:flex;align-items:flex-end;gap:.5rem;flex-wrap:wrap;padding:.5rem .6rem;background:var(--panel);border:1px solid var(--line);border-top:0;border-radius:0 0 8px 8px}
.swadd .f label{display:block;font-size:.74em;color:var(--muted);margin:0 0 1px}
.swadd .f input{width:6.5rem;text-align:right}
/* the size line's Shape list: as wide as its longest shape word, measured on the site (1096) */
#g_param_sizes .ag-select-list{min-width:15rem!important;max-width:none!important;width:auto!important}
.swadd .f select{min-width:11rem}

/* LOT MASTER (1079): the one search box in the card head, and the tick
   bar above the grid — the stone registers' pattern, the same chips. */
/* the Active tick inside the Lot window: the house check row, not the window's block labels */
.lotwin .check.lotact{display:flex;align-items:center;gap:.45rem;margin-top:.6rem}
.lotwin .check.lotact input{width:auto}
.lotwin .check.lotact label{display:inline;margin:0;font-size:inherit;color:var(--ink)}
/* the lot's two links under the branch table (1125): box and its door on one line */
.lotwin .lotlink{margin-top:.55rem}
.lotlink-r{display:flex;gap:.35rem;align-items:center}
.lotlink-r input{flex:1;min-width:0}
.lm-tick{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;padding:.35rem .6rem;margin:0 0 .4rem;background:var(--blue-bg,var(--panel));border:1px solid var(--blue-line,var(--line));border-radius:8px;font-size:.88em}

/* WHAT IS OFFERED. Fixed, because the window it opens in scrolls inside
   itself and clips what leaves it; placed by measurement in app.js. */
.chipdrop{
  display:block;position:fixed;left:0;top:0;z-index:95;
  max-height:20rem;overflow:auto;
  background:var(--card);border:1px solid var(--line);border-radius:7px;
  box-shadow:0 10px 28px rgba(0,0,0,.16)}
/* EVERY LIST'S ROW STANDS AT LEAST 28 PX AND ITS HIGHLIGHT CARRIES AN
   ACCENT BAR (his yes, 19 Oct 2026, from the Lot No drawing): the pick
   never rests on a shade alone; the bar's 3 px come out of the left
   padding, so the words stay level with the headings */
.chipdrop .row{
  display:flex;align-items:center;gap:.4rem;min-height:28px;box-sizing:border-box;
  padding:.22rem .5rem .22rem calc(.5rem - 3px);border-left:3px solid transparent;
  font-size:.85em;cursor:pointer;white-space:nowrap}
/* The label rides in a <b> for the ellipsis rules, not for weight: the
   list reads plain, and only the row's own weight — the current choice,
   a ticked row — shows through. */
.chipdrop .row b{font-weight:inherit}
/* a group's heading in a list: bold ink, a rule beneath, nothing to press */
.chipdrop .grp{padding:.3rem .5rem .15rem;font-size:.85em;font-weight:700;color:var(--ink);
  border-bottom:1px solid var(--line);cursor:default;white-space:nowrap}
.chipdrop .row .cl{color:var(--muted);overflow:hidden;text-overflow:ellipsis}
.chipdrop .row.hi{background:var(--grid-hover);border-left-color:var(--accent)}
/* The letters he typed, picked out of the word — his picture. An accent
   on the ink, never a smaller or a lighter word. */
.chipdrop .hi,.chipdrop .row .hi{font-style:normal}
.chipdrop .row i.hi{background:none;color:var(--accent);font-weight:700}
/* THE REFUSAL floats over what is below rather than pushing the form,
   and is wider than its one-column box, as `.sfnote` is: at least as
   wide as the box, as wide as its words need, never wider than a
   comfortable sentence. */
.chipmsg{
  display:block;position:absolute;left:0;top:100%;z-index:6;
  min-width:100%;width:max-content;max-width:22rem;
  margin-top:1px;padding:.12rem .4rem;border-radius:5px;
  background:var(--red-soft);border:1px solid var(--danger-line);
  box-shadow:0 4px 14px rgba(0,0,0,.12);
  font-size:.78rem;color:var(--red)}
/* THE OFFER RIDES INSIDE THE FLOATING NOTE (0232) — a button in the
   flow would push every box below it, which is exactly what the float
   exists to prevent. It inherits the note's type size, and its display
   lives HERE: an element Alpine shows may never declare display inline
   (the 13 Aug arrivals-strip lesson). */
.chipmsg .chipmk{
  display:inline-block;margin-left:.35rem;padding:0 .35rem;
  border:1px solid var(--danger-line);border-radius:4px;
  background:var(--card);color:var(--ink);font:inherit;cursor:pointer}
.chipmsg .chipmk:hover{border-color:var(--accent);color:var(--accent)}
/* THE UNFOLDED STRIP IS A GRID, AND THAT RULE LIVES HERE — NEVER IN THE
   MODULE: Alpine shows an element by deleting `display` off its inline
   style, so an inline grid dies the moment the strip is shown. */
/* THE DOCUMENT ROW WEARS THE STOCK BAND'S SLOT (his ruling, 6 Sep 2026:
   "follow the box size everywhere") — the same 6.6rem track as
   .fgrid.fine.slots, so a box on an inward, an invoice or any document
   screen to come is the width of a box on the stock register. Set once
   here; no module names a width; a two-slot box says `span 2`. */
.densec { display: grid; grid-template-columns: repeat(auto-fill, minmax(6.6rem, 1fr));
  gap: .05rem .5rem; align-items: start; }
.densec label { font-size: .74em; margin: 0 0 1px; }
/* THE ARRIVAL'S PACKET WINDOW, ITS MONEY ROW (his go on the drawing, 21 Oct
   2026): "Purch. Price/ct (USD) *" and "Purch. Amount (USD)" read on one
   line; Box (a short number) gives the room — 18 points of a 123-point
   box, 12 to the price and 6 to the amount; every other box stays where it
   was. Only while the row holds exactly eight boxes (8 × 6.6rem + 7 gaps
   up to the width a ninth would need); otherwise the shared track rules
   as before. */
.pkmoney-wrap { container-type: inline-size; }
@container (min-width: 56.3rem) and (max-width: 63.89rem) {
  .densec.pkmoney { grid-template-columns: 1fr 1fr 1fr 1.0973fr 1.0486fr .8541fr 1fr 1fr; }
}

/* ---- A NOTE THAT FLOATS -------------------------------------------
   The exchange rate under the Ex rate box is out of the flow, over what
   is below it, so a long triangulated rate moves nothing. Shown on hover
   and focus, and always in the tooltip. */
/* THE WAIT LINE: a 2px fixed line at the browser's own top edge (top:0,
   not under the top bar — it does not read --s1-topbar-h), drawn over
   the bar at z-index 120. It costs no layout (rule 25). `on` creeps to
   92% and stops, since nothing knows the real progress; `done` completes
   fast; `fail` finishes red and holds (rule 22). */
#s1bar{
  position:fixed;left:0;top:0;height:2px;width:0;
  background:var(--accent);z-index:120;opacity:0;pointer-events:none;
  transition:opacity .15s;
}
#s1bar.on  {opacity:1;animation:s1grow 8s cubic-bezier(.15,.85,.3,1) forwards}
#s1bar.done{opacity:1;width:100%;transition:width .18s ease-out,opacity .25s .18s}
#s1bar.fail{opacity:1;width:100%;background:var(--red);
            transition:width .18s ease-out,opacity .3s 1s}
@keyframes s1grow{0%{width:0}40%{width:55%}75%{width:80%}100%{width:92%}}

/* And the sentence for a wait long enough that a line alone says too
   little. Centred under the bar, never over the work. */
#s1slow{
  position:fixed;left:50%;transform:translateX(-50%);
  top:calc(var(--s1-topbar-h,44px) + 10px);z-index:120;
  padding:.3rem .7rem;border-radius:7px;
  background:var(--card);border:1px solid var(--line);
  box-shadow:0 6px 20px rgba(0,0,0,.14);
  font-size:.8rem;color:var(--ink);pointer-events:none;
}

/* NO STEPPER ARROWS ON ANY NUMBER BOX. A `step` fine enough for ten
   decimals also decides how far one click moves the value, so a stray
   click writes a rate of one ten-billionth. Said once for the whole
   application, not opted into. The `step` attributes stay: without
   arrows they only govern how many decimals may be typed. */
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

/* THE CURRENCY LENS in the top bar (0177). Sized like the pin and
   theme controls beside it — flex:none, because the bar is fitted by
   measurement and only the breadcrumb is allowed to give. */
.moneypick{position:relative;flex:none}
/* A PAIR OF GLASSES, NOT A PLACE (his go, design A, 19 Sep 2026): the
   light box with a dashed line and an eye says "how you are reading";
   the solid pill beside it says "where you are". Same height as before. */
.moneypick>button{
  display:flex;align-items:center;gap:.35rem;
  padding:.28rem .5rem;border:1px dashed var(--pick-line);border-radius:9px;
  background:var(--pick-bg);color:var(--ink);cursor:pointer;
  font:inherit;line-height:1;white-space:nowrap;
}
.moneypick>button:hover{border-color:var(--accent)}
/* The code IS the control's face, so it carries the weight an icon would
   have. "As billed" is longer than a three-letter code and must not make
   the bar reflow, so the face is given a floor and never wraps. */
.moneypick .mpv{font-weight:600;white-space:nowrap;min-width:2.2rem;text-align:center}
/* the quiet word naming the view — Group or Branch — beside the code
   (his pick, 22 Aug 2026); As billed needs no word */
.moneypick .mpw{font-size:.76rem;color:var(--muted);white-space:nowrap}
.moneypick .mpe{color:var(--muted);flex:none}
.moneymenu{
  position:absolute;right:0;top:calc(100% + 4px);z-index:60;
  min-width:15rem;padding:.2rem;
  background:var(--card);border:1px solid var(--line);border-radius:8px;
  box-shadow:0 8px 24px rgba(0,0,0,.16);
}
.moneymenu .mm{
  display:block;width:100%;text-align:left;
  padding:.28rem .45rem;border:0;border-radius:6px;
  background:none;color:var(--ink);cursor:pointer;font:inherit;
}
.moneymenu .mm:hover{background:var(--hover)}
.moneymenu .mm.on{background:var(--hover);font-weight:600}
.moneymenu .mm b{display:block;font-weight:600}
.moneymenu .mm i{display:block;font-style:normal;font-size:.78rem;color:var(--muted)}

.fxbox{position:relative}
/* THE LABEL LINE NEVER WRAPS (6 Sep 2026): at the band's slot "Ex rate ·
   USD/INR 94.5116" no longer fits, and a wrapped label pushed the box
   below its neighbours. One line, cut with …; the full words read in
   our note (S.ovn) through the label's `ov` class (rule 38). */
.fxbox label{display:block;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The resolved rate, ON the label line: always visible, and it adds no
   height because the label was already there. Ellipsised rather than
   wrapped, so a long number can never push the row either. */
.fxval{font-weight:600;color:var(--ink);white-space:nowrap}
/* IT FLOATS OVER THE PAGE, NOT INSIDE IT — position:fixed, never
   absolute: an absolute box still counts towards page width and a
   no-wrap note near the right edge produces a horizontal scrollbar. The
   placing is ours (S.note in app.js), the same mechanism the overflow
   note uses, clamped to the screen; the wording wraps. z-index 90 —
   above a window (80), below the countdown (95) and toast (100). */
.fxnote{
  position:fixed;left:0;top:0;z-index:90;
  max-width:min(28rem,90vw);
  padding:.1rem .35rem;border-radius:5px;
  background:var(--card);border:1px solid var(--line);
  box-shadow:0 4px 14px rgba(0,0,0,.12);
  font-size:.72rem;color:var(--muted);
  white-space:normal;overflow-wrap:anywhere;
  opacity:0;pointer-events:none;transition:opacity .12s;
}
/* SHOWN BY A CLASS, NOT BY :hover. A fixed note has to be PUT somewhere
   before it is shown, and CSS cannot measure; hovering now asks app.js
   to place it and then turns it on. The two moments it speaks are
   unchanged — the mouse over the box, or the box holding the cursor. */
.fxnote.on{opacity:1}

/* =====================================================================
   THE OVERFLOW NOTE — a box that cannot show all of its value says so,
   in OUR words, under the box, at once (rule 38). Same skin as .fxnote;
   fixed, on the body, so no panel or modal clips it; wraps rather than
   running off screen. z-index 90: above a window (80), below the
   countdown (95) and toast (100).
   ===================================================================== */
.ovnote{
  position:fixed;z-index:90;left:0;top:0;
  max-width:min(46rem,90vw);
  padding:.18rem .4rem;border-radius:5px;
  background:var(--card);border:1px solid var(--line);
  box-shadow:0 4px 14px rgba(0,0,0,.12);
  font-size:.78rem;color:var(--ink);
  white-space:pre-wrap;overflow-wrap:anywhere;
  opacity:0;pointer-events:none;transition:opacity .1s;
}
.ovnote.on{opacity:1}

/* A FROM-TO PAIR: ONE LABEL, TWO EQUAL BOXES, NOTHING BETWEEN THEM. Both
   may shrink below their content, or the pair pushes its column wider
   than the grid allows. */
.pair2{display:grid;grid-template-columns:1fr 1fr;gap:.3rem}
.pair2 > *{min-width:0}

/* THE "BOXES SHOW" PICKER on a card header — a label and a narrow box on
   one line. It sits inside the element that folds, never on it: Alpine
   strips an inline display when it shows an element. */
.showpick{display:flex;align-items:center;gap:.4rem}
.showpick label{font-size:.78rem;margin:0}
.showpick select{width:9rem}

/* THE SUMMARY BOX — several answers, one fixed height. What is chosen
   is said in words and a count; the list carries the ticks. It wears the
   select shape because that is what it now behaves like. */
.chipbox.sum .val{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.chipbox.sum.has .val{color:var(--ink)}
.chipdrop .row .tick{display:inline-block;width:1em;flex:none;color:var(--accent)}
.chipdrop .row.on{font-weight:500}

/* THE PAGER AS ONE JOINED GROUP (his picture, 18 Aug 2026): the ends and
   the neighbours in a single outline, with the page you are on standing
   in the middle of it. The number is a position, not a control — it
   carries no hover and no pointer, so nothing about it invites a click
   it cannot answer. */
.pgrp{display:inline-flex;align-items:stretch;border:1px solid var(--line);
      border-radius:var(--r);overflow:hidden}
.pgrp > *{border:0;border-radius:0;margin:0}
.pgrp > * + *{border-left:1px solid var(--line)}
/* THE INK COMES WITH THE BACKGROUND, ALWAYS: the base button is FILLED
   with light ink, so a transparent background alone leaves white on
   white. Ghost ink belongs with a ghost background. */
.pgrp .btn{background:var(--card);color:var(--ghost-ink);
           padding:.3rem .7rem;font-size:.82rem;font-weight:500}
.pgrp .btn:hover:not(:disabled){background:var(--panel)}
.pgrp .at{display:flex;align-items:center;padding:.3rem .85rem;
          background:var(--accent);color:#fff;font-weight:500;font-size:.82rem;
          cursor:default;user-select:none}
/* ON A NARROW SCREEN THE PAGER KEEPS ITS ARROWS AND DROPS ITS WORDS
   (6 Sep 2026): a laptop at 1366 wide wrapped the foot line onto two
   rows, and the pager was the widest thing on it. The titles still say
   First/Prev/Next/Last; only the printed word goes. One rule for every
   pager in the application. */
@media (max-width:1500px){.pgrp .btn .w{display:none}}

/* A STATUS PILL THAT IS ALSO A FILTER wears the grid's own pill — a
   status must read as one thing wherever it appears. OFF is the same
   pill faded, never a different color. */
/* THE FADE IS GONE (his go, 21 Sep 2026). An unchosen pill used to print
   at four-fifths strength, which composites BOTH its ink and its ground
   against the card: the same chips that measure 4.7-8.0:1 at full
   strength fell to 3.2-3.8:1 in four of the seven looks, under the
   readable floor. He had already reported it once ("when it is not
   selected cant read") and the fade was lifted from .45 to .8 by eye,
   never measured. Chosen is said by the ring and the bold word, which
   is the louder signal anyway; the pointer is answered by a light ring
   in the same language, one weight below the chosen one. */
.pill.stf{border:0;font:inherit;font-size:.74rem;font-weight:400;
          padding:.16rem .5rem;border-radius:999px;cursor:pointer;
          transition:box-shadow .1s}
.pill.stf:hover{box-shadow:0 0 0 1px currentColor}
/* CHOSEN IS SAID THE SAME WAY WHEREVER A PILL IS ALSO A FILTER (21 Sep
   2026): the ring is its own colour and the word turns bold. Written
   once for every filter pill, so the Line filter under a document's
   stones and the status pills on a register cannot drift apart. */
.pill.on1{opacity:1;box-shadow:0 0 0 2px currentColor;font-weight:700}
/* Available anchors the row (his instruction, 18 Aug 2026): one step
   larger and bold whether or not it is chosen. The rest arrive regular
   and turn bold when selected. Title line only - grid cells keep one
   size. */
.pill.stf.on{font-size:.85rem;font-weight:700}
/* The All button sits in the pill row, so it takes the pill's own
   height and shape (his instruction, 18 Aug 2026). */
.btn.stall{font-size:.74rem;padding:.16rem .6rem;border-radius:999px;line-height:1.3}

/* THE FILTER GRID — twelve columns; a single control takes 2, a from-to
   pair 3, so rows fill to the edge. Six columns on a narrow screen, two
   on a phone, where a pair takes the whole width. */
/* THE FILTER GRID PACKS — density is the standing rule. The track count
   follows the width (no screen and no media query names one), a single
   box is one track, a pair two, and dense flow backfills any hole a
   two-track box leaves at a row's end. Tracks stretch, so every row
   runs edge to edge. */
.fgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(8.5rem,1fr));
       gap:.25rem .45rem;align-items:start;grid-auto-flow:dense}
/* START, NOT END (his ask, 20 Aug 2026): a hand-stretched find box
   makes its row tall, and end-alignment hung every box on that row at
   the bottom of the blank. On an ordinary row the two read identically
   — the row is exactly as tall as its boxes — so only the stretched
   case moves. */
.fgrid > *{min-width:0}
/* NARROWED BOXES ON THE ROW THAT ASKS FOR THEM: the TRACK narrows and
   every box not narrowing widens its span, so only the named boxes move
   and the row stays one grid. One number, a minimum in rem, following
   the font setting. The More filters band keeps the plain .fgrid. */
/* QUARTER TRACKS, so three-quarter and full boxes are whole numbers of
   them: a narrowed box takes THREE, an ordinary one FOUR. 1.9rem, not a
   quarter of 8.5rem — MEASURED: a four-track box also swallows three
   gaps, and a plain quarter made every full box 16px wider. */
.fgrid.fine{grid-template-columns:repeat(auto-fill,minmax(1.9rem,1fr))}
/* ONE TRACK, ONE BOX, for the SEARCH ROW alone: quarter tracks leave an
   orphan slot no box can fill. A track the width of a box means every
   slot holds a whole box and every line but the last fills at every
   window width, nothing measuring, no box ever resized. 6.6rem is the
   narrowed box's existing width. The More filters band keeps quarter
   tracks — its money and date ranges are two tracks. */
.fgrid.fine.slots{grid-template-columns:repeat(auto-fill,minmax(6.6rem,1fr))}
/* BOXES OF ONE WIDTH TOGETHER, AND NOTHING PULLED OUT OF ORDER
   (docs/0047): dense packing back-fills a hole with a LATER box and
   spends the reading order set on the Parameters menu. Off here; only
   the More filters band carries this. The row above keeps dense for the
   one very wide paste box. */
.fgrid.blocks{grid-auto-flow:row}
/* A LABEL OVER A NARROW BOX DOES NOT WRAP — where it does not fit, the
   catalogue's SHORT wording is used. This rule is the floor: one line,
   and the overflow note (S.ovn) reads out anything still past the box. */
.fgrid.fine label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  display:block;max-width:100%}
/* THE SWITCH IS A LABEL TOO, and the rule above turned it into a block
   on the Inward band the day the band wore `fine` (6 Sep 2026): the
   track collapsed to nothing and drew over its words. A switch keeps
   its own row shape. */
.fgrid.fine label.tgl{display:inline-flex;overflow:visible;text-overflow:clip}

/* THE FIND BOX'S SCOPE TAG seats in the paste box's corner. The text
   owns the full width on every line, so the TAG gives way: a caret in
   the box fades it to a ghost; it returns solid on leaving or pointing.
   Compact (.76rem) because it sits in a corner, not on a line of words.
   Narrowed, it wears the scope capsule's coat — background and ink one
   decision. */
/* ONE FIND BOX EVERYWHERE (his ruling, 6 Sep 2026): FOUR slots wide on
   every register — Stock, Stone Revision, Inward, the transaction
   screens — two lines tall, stretching to its row; the width is said
   here once and no module names it. */
.findwrap{position:relative;display:flex;grid-column:span 4;min-width:0;align-self:stretch}
.findwrap textarea{flex:1 1 auto;min-width:0}
.findscope{position:absolute;right:.3rem;bottom:.35rem;width:auto;
  font-size:.76rem;padding:.06rem .3rem;background:var(--panel);
  transition:opacity .12s}
.findwrap textarea:focus ~ .findscope{opacity:.22}
.findscope:hover{opacity:1}
.findscope.on{border-color:var(--amber);background:var(--amber);color:var(--amber-ink)}

/* THE HEADER'S BUTTON GROUP CARRIES ITS OWN PUSH: a card header wraps,
   and a bare spacer only pushes on its own line. The auto margin on the
   group hugs the right edge of whatever line it lands on. */
.card-h .hdrbtns{margin-left:auto;display:flex;align-items:center;gap:.4rem;flex:none}

/* ============ ROLES HISTORY — what changed, in words ============
   Every word in the window is the cell font; only the day heading and
   the kind chip are the heading size, as a grid's own headings are. */
.modal.rhw{width:min(880px,94vw);max-width:none;max-height:88vh;display:flex;flex-direction:column}
.rhw .modal-h,.rhw .modal-f,.rhw .rh-tools{flex:none}
.rh-sub{color:var(--muted);font-size:.8rem}
.rh-tools{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;padding:.55rem 1rem;border-bottom:1px solid var(--line);background:var(--panel)}
.rh-tools select{width:auto;flex:none;min-width:0;margin:0;font-size:.8rem}
.rh-tools .rh-find{width:auto;flex:1 1 200px;margin:0;font-size:.8rem}
.rh-kinds{display:inline-flex;gap:.3rem;flex-wrap:wrap}
.rh-kchip{font:inherit;font-size:.8rem;border:1px solid var(--line);background:var(--card);color:var(--ink);border-radius:999px;padding:.18rem .65rem;cursor:pointer}
.rh-kchip b{margin-left:.2rem}
.rh-kchip.on{background:var(--blue);border-color:var(--blue);color:var(--blue-ink)}
.rh-b{flex:1 1 auto;min-height:0;overflow:auto;padding:.2rem 1rem 1rem;font-size:.8rem}
.rhw .modal-f{font-size:.8rem}
.rh-day{position:sticky;top:0;background:var(--card);padding:.6rem 0 .3rem;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);border-bottom:1px solid var(--line);z-index:1}
.rh-ev{display:grid;grid-template-columns:3.2rem 2rem 1fr auto;gap:.1rem .6rem;padding:.6rem 0;border-bottom:1px dashed var(--line);align-items:start}
.rh-tm{color:var(--muted);font-variant-numeric:tabular-nums;padding-top:.3rem;font-size:.8rem}
.rh-av{width:1.9rem;height:1.9rem;border-radius:50%;display:grid;place-items:center;font-size:.72rem;font-weight:700;background:var(--avatar-bg);color:var(--avatar-ink)}
.rh-av.sys{background:var(--code-bg);color:var(--muted);font-size:.8rem}
.rh-hl{line-height:1.45;padding-top:.2rem;font-size:.8rem}
.rh-rl{display:inline-block;background:var(--amber-soft);color:var(--ink);border-left:3px solid var(--amber);border-radius:5px;padding:0 .4rem;font-weight:700;margin:0 .1rem}
.rh-kind{font-size:.74rem;border-radius:999px;padding:.1rem .5rem;font-weight:700;white-space:nowrap;margin-top:.25rem}
.rh-kind.k-r{background:var(--ok-soft);color:var(--ok)}
.rh-kind.k-p{background:var(--blue-soft);color:var(--blue)}
.rh-kind.k-n{background:var(--amber-soft);color:var(--ink);border:1px solid var(--amber)}
.rh-kind.k-x{background:var(--red-soft);color:var(--red)}
.rh-body{grid-column:3 / 5;display:grid;gap:.35rem}
.rh-body:empty{display:none}
.rh-chips{display:flex;flex-wrap:wrap;gap:.3rem;align-items:center}
.rh-add,.rh-rem,.rh-br{border-radius:7px;padding:.12rem .5rem;font-size:.8rem;display:inline-flex;gap:.35rem;align-items:baseline;color:var(--ink)}
.rh-add{background:var(--ok-soft);border:1px solid color-mix(in srgb,var(--ok) 35%,transparent)}
.rh-add::before{content:'+';color:var(--ok);font-weight:800}
.rh-rem{background:var(--red-soft);border:1px solid color-mix(in srgb,var(--red) 35%,transparent);text-decoration:line-through}
.rh-rem::before{content:'\2212';color:var(--red);font-weight:800;display:inline-block;text-decoration:none}
.rh-add i,.rh-rem i{font-style:normal;color:var(--muted);font-size:.8rem}
.rh-br{background:var(--panel);border:1px solid var(--line)}
.rh-grp{border:1px solid var(--line);border-radius:10px;overflow:hidden}
.rh-row{display:grid;grid-template-columns:11rem 1fr;gap:.6rem;padding:.35rem .6rem;border-top:1px solid var(--line)}
.rh-row:first-child{border-top:0}
.rh-scr{font-weight:700}
.rh-row .rh-chips{gap:.25rem}
.rh-more{justify-self:start;font-size:.8rem}
.rh-note{color:var(--muted);font-size:.8rem;line-height:1.5}
@media(max-width:700px){ .rh-ev{grid-template-columns:2.6rem 1fr auto} .rh-av{display:none} .rh-row{grid-template-columns:1fr} }

/* ============ ROLES — HOW TO READ THIS SCREEN ============
   One screen of the grid drawn small and numbered, every mark in one
   key, four cards, the save warning. All of it the cell font, wide
   enough that the whole is in view without scrolling. */
.modal.hrw{width:min(1260px,96vw);max-width:none;max-height:94vh;display:flex;flex-direction:column}
.hrw .modal-h,.hrw .modal-f{flex:none}
.hr-b{flex:1 1 auto;min-height:0;overflow:auto;display:grid;grid-template-columns:1.5fr 1fr;gap:.6rem;line-height:1.38;font-size:.8rem}
.hr-sec{font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);margin:0 0 .45rem}
.hr-demo{border:1px solid var(--line);border-radius:10px;overflow:hidden;font-size:.8rem}
.hr-demo .hd,.hr-demo .rw{display:grid;grid-template-columns:2.6fr repeat(7,.62fr) .8fr;align-items:center}
.hr-demo .hd{background:var(--grid-head);color:var(--grid-head-ink);font-weight:700;font-size:.7rem;text-transform:uppercase;letter-spacing:.04em}
.hr-demo .hd>span,.hr-demo .rw>span{padding:.35rem .4rem;text-align:center;white-space:nowrap}
.hr-demo .hd>span:first-child,.hr-demo .rw>span:first-child{text-align:left}
.hr-demo .rw{border-top:1px solid var(--grid-row-line)}
/* a line of the grid, and the row of a second document */
.hr-demo .rw.ln{display:block;background:color-mix(in srgb,var(--blue-soft) 38%,var(--card))}
.hr-demo .rw.ln>span{display:block;padding:.2rem .4rem .2rem 1.4rem;white-space:normal}
.hr-demo .rw.sub>span:first-child{padding-left:1.4rem;font-weight:600}
.hr-demo .ld{display:inline-block;width:6.2em;color:var(--muted);font-weight:600}
.hr-demo .pl{display:inline-block;border:1px solid var(--ghost-line);border-radius:999px;padding:0 .6rem;background:var(--card);margin-right:.5rem}
.hr-demo .mo{color:var(--muted);font-weight:400}
.hr-demo .tb{display:inline-block;font-weight:700;color:var(--blue);border:1px solid var(--blue-line);border-radius:5px;padding:0 5px;margin-right:6px;line-height:18px}
.hr-demo u{color:var(--blue);text-decoration:underline dotted}
.hrw .ok{color:var(--ok);font-weight:800} .hrw .ok.faded{opacity:.45} .hrw .dot,.hrw .dash{color:var(--faint)}
.hrw .wn{color:var(--warn);font-weight:700} .hrw .mu{color:var(--muted)}
.hrw .nb{display:inline-grid;place-items:center;width:1.15rem;height:1.15rem;border-radius:50%;background:var(--blue);color:var(--blue-ink);font-size:.7rem;font-weight:800;font-style:normal;vertical-align:middle;margin-left:.25rem}
.hr-steps{margin:.4rem 0 0;padding:0;list-style:none;display:grid;gap:0;font-size:.8rem;line-height:1.38}
.hr-steps li{display:grid;grid-template-columns:1.5rem 1fr;gap:.4rem;align-items:start}
.hr-steps .nb{margin:.2rem 0 0;width:1.25rem;height:1.25rem}
.hr-legend{border:1px solid var(--line);border-radius:10px;overflow:hidden}
.hr-legend .lg{display:grid;grid-template-columns:11.5em 1fr;gap:.6rem;padding:.22rem .6rem;border-top:1px solid var(--line);align-items:center;font-size:.8rem}
.hr-legend .sym{min-width:1.6rem;text-align:left;font-size:.8rem}
.hr-legend .sym .pill{white-space:nowrap}
.hr-legend .lg:first-child{border-top:0}
.hr-cards{grid-column:1 / -1;display:grid;grid-template-columns:repeat(4,1fr);gap:.6rem}
.hr-card{border:1px solid var(--line);border-radius:10px;padding:.45rem .6rem;background:var(--panel)}
.hr-card h3.t{font-size:.8rem;margin:0 0 .2rem}
.hr-card .ic{margin-right:.3rem}
.hr-card p{margin:0;font-size:.8rem;line-height:1.35}
.hr-save{grid-column:1 / -1;display:grid;grid-template-columns:2rem 1fr;gap:.6rem;align-items:center;border:1px solid var(--warn);background:var(--warn-soft);border-radius:10px;padding:.4rem .6rem;font-size:.8rem}
.hr-save .ic{font-size:.8rem;text-align:center}
@media(max-width:1100px){ .hr-cards{grid-template-columns:repeat(2,1fr)} }
@media(max-width:760px){ .hr-b{grid-template-columns:1fr} .hr-cards{grid-template-columns:1fr} }

/* =====================================================================
   THE PRICE MATRIX, IN THE PAGE — not a window; 33 carat bands need the
   width. The scroller owns the overflow so the PAGE never scrolls
   sideways; head and word columns stay put while the bands move. No
   pixel height declared. */
/* the acts ride the title line; margin-left:auto holds them, Close
   last, at the right edge on this line or the next when it wraps */
.pmx-acts{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-left:auto}
.pmx-set{display:contents}
.pmx-state,.pmx-cmp{white-space:nowrap}
/* shape groups fold to one line each; only the open one shows its
   shapes, so the window stays short however many groups exist */
.grp-row{border:1px solid var(--line);border-radius:6px;margin-bottom:.45rem}
.grp-line{display:flex;gap:.5rem;align-items:center;padding:.45rem .6rem;cursor:pointer}
.grp-line:hover{background:var(--bg)}
.grp-line .sp{margin-left:auto}
.grp-line .grp-ch{color:var(--muted);width:.95rem;text-align:center;display:inline-flex}
.grp-line .grp-ch svg{transform:rotate(-90deg);transition:transform .12s}
.grp-line .grp-ch.on svg{transform:none}
.grp-line .grp-pen{color:var(--muted);display:inline-flex}
.grp-open{padding:.1rem .6rem .6rem 1.95rem}
.grp-read{display:flex;flex-wrap:wrap;gap:.35rem;padding:.15rem 0 .2rem}
/* the matrix shape picker: the shared chip box dressed into the card
   header - no label line, sized beside the version select */
.pmx-shapes{min-width:13rem;display:inline-block}
.pmx-show{display:flex;align-items:center;gap:.35rem}
/* while every shape is ticked, the open list says what a click means
   and each row under the mouse offers "only" - the one-click road back
   from the whole table to one shape */
.pmx-shapes.allon .chipdrop::before{content:'Everything is showing — click a shape to see it alone';
  display:block;color:var(--muted);
  padding:.15rem .4rem .3rem;border-bottom:1px solid var(--line);margin-bottom:.25rem}
.pmx-shapes.allon .chipdrop .row{position:relative}
.pmx-shapes.allon .chipdrop .row:hover::after{content:'only';
  position:absolute;right:.5rem;color:var(--muted)}
.pmx-shapes .chipwrap>label{display:none}
.pmx-state{padding:.12rem .5rem;border-radius:.35rem;border:1px solid var(--line)}
.pmx-state.live{background:var(--ok-soft);border-color:var(--ok);color:var(--ok)}
.pmx-state.draft{background:var(--warn-soft);border-color:var(--warn);color:var(--warn)}
.pmx-state.ended{background:var(--bg);color:var(--muted)}

.pmx-scroll{overflow:auto;max-height:calc(100vh - 15rem);border:1px solid var(--line);
  border-radius:.4rem;background:var(--card)}
/* DRESSED IN THE REGISTERS' OWN CLOTHES (his go, 28 Aug): the matrix
   is a different machine — a spreadsheet, not a record list — but it
   wears the same tokens as every grid, so a theme moves both at once.
   The .8rem is the registers' own cell size, the one floor rule 35
   names. */
.pmx{border-collapse:separate;border-spacing:0;min-width:100%;font-size:.8rem}
/* STATED WIDTHS, HIS RULING 27 Aug. While the table sizes itself to
   its contents no column can be narrower than its widest value, so a
   column dragged inwards sprang back. Every column carries a width
   once they have been measured, and anything too long is clipped
   rather than widening its own column. */
.pmx.fixed{table-layout:fixed}
.pmx.fixed th,.pmx.fixed td{overflow:hidden;text-overflow:ellipsis}
/* LINES BOTH WAYS. A matrix of bare numbers with no column line reads as
   one field of digits; his ask, 27 Aug. Same hairline as the row lines,
   so nothing gains weight. */
.pmx th,.pmx td{padding:4px 6px;border-bottom:1px solid var(--grid-row-line);
  border-right:1px solid var(--grid-col-line);white-space:nowrap;position:relative}
.pmx tr > *:last-child{border-right:0}
.pmx thead th{position:sticky;top:0;z-index:2;background:var(--grid-head);
  color:var(--grid-head-ink);font-weight:600;border-bottom:1px solid var(--grid-row-line)}
.pmx thead th.mxheld{background:var(--grid-head)}
/* A HEADING IS READ WHOLE: it wraps onto a second line before it is cut,
   at the column's own width, and stands on the line above the numbers. */
.pmx thead th{white-space:normal;line-height:1.2;vertical-align:bottom}
.pmx.fixed thead th{text-overflow:clip}
.pmx th.w,.pmx td.w{text-align:left}
/* A NUMBER DECLARES ITS ALIGNMENT IN EVERY MODE — reading and editing
   alike, so a column does not jump when Edit is pressed. */
.pmx th.n,.pmx td.n{text-align:right}
/* the registers' stripe — parity computed from the DATA index, because
   the windowed rows' place in the page shifts as the window moves */
.pmx tbody tr.odd td{background:var(--grid-odd)}
.pmx tr.odd td.mxheld{background:var(--grid-odd)}
.pmx tbody tr:hover td{background:var(--grid-hover)}
/* THE SPACER ROWS of the windowed matrix hold height and nothing else —
   no padding, no line, no hover, or the stand-in betrays itself. */
.pmx tr.pmx-sp>td{padding:0;border:0;background:none}
.pmx tbody tr.pmx-sp:hover td{background:none}

/* EDITING. The armed look is the cell's own, not a border that would
   change the column's width the moment Edit is pressed. */
.pmx td.ed{cursor:cell}
.pmx td.ed:hover{outline:1px solid var(--amber);outline-offset:-1px}
/* THE CURRENT CELL wears the grid's focus outline in every mode (his
   ask, 5 Sep 2026); the cell holding the open box shows ONE line — the
   box's own — never its outline or its hover under it as well. */
.pmx td.cur{outline:2px solid var(--blue);outline-offset:-2px}
.pmx td:has(>.pmx-in),.pmx td.ed:has(>.pmx-in):hover{outline:none}
html.s1-kbd .pmx-in:focus{outline:none}
.pmx td.moved{background:var(--warn-soft);color:var(--warn)}
.pmx tbody tr:hover td.moved{background:var(--warn-soft)}
/* THE SELECTED ROW'S BAND — blue on purpose: amber in this table means
   "changed, unsaved" and a colour that means something is not reused.
   A changed cell keeps its amber inside the band; a binned row's red
   wins over it (those rules stand later in this sheet). */
.pmx tr.sel td{background:var(--blue-soft)}
.pmx tbody tr.sel:hover td{background:var(--blue-soft)}
.pmx tr.sel td.mxheld{background:var(--blue-soft)}
.pmx tbody tr.sel:hover td.mxheld{background:var(--blue-soft)}
.pmx tr.sel td.moved,.pmx tbody tr.sel:hover td.moved{background:var(--warn-soft)}
.pmx tr.sel{box-shadow:inset 3px 0 0 var(--blue)}
.pmx-in{width:100%;min-width:4rem;padding:.02rem .2rem;text-align:right;
  border:1px solid var(--amber);border-radius:.2rem;background:var(--card);
  color:var(--ink);font:inherit}
/* THE OPEN PRICE BOX FITS ITS ROW, so the rows below never jump when a
   price opens; in a narrow column it takes the column's own width. */
.pmx .pmx-in{min-height:0;height:1.6em;line-height:1.4em;padding:0 .2rem}
.pmx.fixed .pmx-in{min-width:0}
.pmx td:has(>.pmx-in){padding-top:0;padding-bottom:0}
/* NOTHING IN A CELL RENDERS SMALLER THAN THE CELL (rule 35): the arrow
   is the only mark allowed to be quieter, and it is quieter by COLOUR,
   not by size. */
.pmx-arrow{color:var(--muted)}
.pmx-arrow.up{color:var(--ok)}
.pmx-arrow.dn{color:var(--red)}
/* THE CHANGE SLOT (his report, 29 Oct 2026): one width across the table,
   its figures even, so every price ends on one edge and every change
   starts on one */
.pmx td.n .pmx-arrow{display:inline-block;min-width:var(--pmx-aw,0);margin-left:.3em;
  text-align:left;font-variant-numeric:tabular-nums}
/* A BULK VERSION (1139): a size priced apart is a column of its own, shaded
   blue and named by its heading; the dot marks a line that prices a lot the
   branch holds. A changed cell's own shade still wins. */
.pmx thead th.apart{background:var(--blue-soft);color:var(--ink);box-shadow:inset 0 -2px 0 var(--blue)}
.pmx tbody tr td.apart:not(.moved){background:var(--blue-soft)}
.pmx-held{display:inline-block;width:.5em;height:.5em;border-radius:50%;
  background:var(--ok);margin-right:.35rem;vertical-align:middle}
/* in a price cell the dot sits in the corner, so the price keeps its room */
.pmx td.n .pmx-held{position:absolute;left:3px;top:3px;margin:0;width:6px;height:6px}
.pmx-apart-word{color:var(--blue)}
/* THE FRAMED CELL'S COLUMN: its heading underlined in ink — blue is
   already the size priced apart and the chosen row */
.pmx thead th.curcol{box-shadow:inset 0 -3px 0 var(--ink);color:var(--ink)}
/* the table takes the keyboard; the framed cell is its focus mark */
.pmx-scroll:focus{outline:none}
/* A SIZE'S BIN shows under the pointer, on the keyboard, or when marked —
   never standing over a heading's words otherwise; it takes no width */
.pmx thead .pmx-bx{position:absolute;left:3px;top:3px;padding:0 1px;opacity:0;
  background:inherit;border-radius:2px;z-index:4}
.pmx thead th:hover .pmx-bx,
.pmx thead .pmx-bx:focus-visible,.pmx thead .pmx-bx.on{opacity:1}
/* LOCKED WHILE EDITING: the date and shape boxes wear the locked look
   and a lock where their arrow stood */
.pmx-lockwrap{position:relative;display:inline-flex}
select.pmx-locked{appearance:none;-webkit-appearance:none;padding-right:1.8rem;cursor:not-allowed}
.pmx-shapes.pmx-locked{position:relative}
.pmx-shapes.pmx-locked .chipbox{color:var(--muted);cursor:not-allowed}
.pmx-shapes.pmx-locked .car{visibility:hidden}
.pmx-lockwrap.on::after,.pmx-shapes.pmx-locked::after{content:'';position:absolute;
  right:.6rem;top:50%;width:13px;height:13px;margin-top:-6.5px;pointer-events:none;
  background:var(--muted);
  -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='11' width='16' height='10' rx='2'/><path d='M8 11V7a4 4 0 0 1 8 0v4'/></svg>") center/contain no-repeat;
  mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='11' width='16' height='10' rx='2'/><path d='M8 11V7a4 4 0 0 1 8 0v4'/></svg>") center/contain no-repeat}
/* THE KEY LINE under the table: the framed cell, the keys, the marks */
/* ONE LINE, WHATEVER CELL IS FRAMED: the cell box and the key keep their
   room, and the hint between them gives way, its whole words in our note */
.pmx-foot{display:flex;align-items:center;flex-wrap:nowrap;gap:.35rem 1rem;margin-top:.45rem}
.pmx-foot>span:first-child{flex:none}
.pmx-hint{flex:1 1 0;min-width:0;max-width:max-content;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.pmx-here{display:inline-block;color:var(--ink);font-weight:700;white-space:nowrap;
  padding:.1rem .5rem;border:1px solid var(--line);border-radius:.35rem;background:var(--card)}
.pmx-herev{color:var(--blue)}
.pmx-keys{display:flex;flex-wrap:nowrap;gap:.25rem .9rem;margin-left:auto;flex:0 1 auto;min-width:0;justify-content:flex-end}
.pmx-keys .k.gives{display:block;flex:0 1 auto;min-width:3rem;overflow:hidden;text-overflow:ellipsis}
.pmx-keys .k{display:inline-flex;align-items:center;gap:.3rem;white-space:nowrap}
.pmx-keys b{color:var(--ink)}
.pmx-apart-sw{display:inline-block;width:.9rem;height:.75rem;border-radius:2px;
  background:var(--blue-soft);box-shadow:inset 0 -2px 0 var(--blue)}

/* THE WORD COLUMNS STAY PUT WHILE THE BANDS MOVE. Each pinned cell's
   `left` is MEASURED by the screen — a guessed offset staggers every
   column after the first. Here is only what cannot be measured: that
   they stick, are opaque, and where the seam is. */
/* THE EDGE HE DRAGS to set a column's width. It sits inside the header
   cell's own padding, so it takes no width of its own and cannot move
   the column it is measuring. Double-click puts the width back. */
.pmx-grip{position:absolute;top:0;right:0;width:9px;height:100%;z-index:3;
  cursor:col-resize;user-select:none}
.pmx-grip:hover{background:var(--amber)}

/* HELD STILL WHILE THE BANDS SCROLL. The class is the matrix's OWN —
   "pin" is the shell's navigation button, and a shared name turns every
   held cell into a little button. */
.pmx td.mxheld,.pmx th.mxheld{position:sticky;z-index:1;background:var(--card);
  display:table-cell}
.pmx thead th.mxheld{z-index:4}
.pmx .mxheld-last{border-right:2px solid var(--line)}
.pmx tbody tr:hover td.mxheld{background:var(--grid-hover)}

/* THE BIN LIVES INSIDE THE PINNED PART, so a line can be marked however
   far right the bands have been scrolled. */
.pmx th.bin,.pmx td.bin{width:1.7rem;text-align:center;padding-left:.25rem;
  padding-right:.25rem;color:var(--muted)}
.pmx td.bin{cursor:pointer}
.pmx td.bin:hover{color:var(--red)}
.pmx td.bin svg{vertical-align:-2px}
.pmx-bx{background:none;border:0;padding:0 0 0 .35rem;margin:0;color:var(--muted);
  cursor:pointer;font:inherit;vertical-align:-2px}
.pmx-bx:hover{color:var(--red)}
.pmx-bx.on{color:var(--red)}

/* MARKED, NOT GONE. Nothing leaves until Save, so a line on its way out
   still reads — struck through, in the refusal colour, with its bin
   turned into the way back. */
.pmx tr.gone td{color:var(--muted);text-decoration:line-through}
.pmx tr.gone td.mxheld{background:var(--red-soft)}
.pmx tbody tr.gone:hover td.mxheld{background:var(--red-soft)}
.pmx tr.gone td.bin{color:var(--red);text-decoration:none}
/* AND A ROW THAT HAS ARRIVED BUT NOT LANDED wears the same amber as a
   changed cell — one meaning, one colour. */
.pmx tr.fresh td.mxheld{background:var(--warn-soft);color:var(--warn)}
.pmx tbody tr.fresh:hover td.mxheld{background:var(--warn-soft)}

/* THE UPLOAD WINDOW'S MARKED CALENDAR. The browser's picker cannot be
   painted, so the window carries its own: version days wear the
   register's meanings (live / draft / ended-struck), the picked day is
   solid ink so no status colour is borrowed for selection. */
.pcal{border:1px solid var(--line);border-radius:.5rem;padding:.6rem;margin-top:.5rem}
.pcal-h{display:flex;align-items:center;gap:.4rem;margin-bottom:.35rem}
.pcal-g{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center;font-size:.8rem}
.pcal-d{padding:.28rem 0;border-radius:.4rem;cursor:pointer;border:1px solid transparent}
.pcal-d:hover{background:var(--bg)}
.pcal-d.out{color:var(--faint)}
.pcal-d.today{border-color:var(--line)}
.pcal-d.live{background:var(--ok-soft);color:var(--ok);font-weight:600}
.pcal-d.draft{background:var(--warn-soft);color:var(--warn);font-weight:600}
.pcal-d.ended{background:var(--bg);color:var(--muted);text-decoration:line-through}
.pcal-d.sel{background:var(--ink);color:var(--card);font-weight:600}
.pcal-l{display:flex;gap:.8rem;margin-top:.45rem;font-size:.74rem;color:var(--muted);flex-wrap:wrap}
.pcal-l i{display:inline-block;width:.6rem;height:.6rem;border-radius:3px;vertical-align:-1px;margin-right:.25rem}

/* DISCOUNTS: the term-limit group stands apart from the special (his
   drawing, 3 Oct 2026) — a light shade behind it, a line before it, and
   each group heading's one-line meaning under its name */
.dsc-lim{background:var(--bg)}
/* one size per job (his go on the drawing, 28 Oct 2026): a group heading's
   meaning reads at the headings' own size; a category's name at the boxes' */
.dsc-sub{display:block;font-weight:400}
.dsc-name{font-size:.88rem;font-weight:700}
/* the two cards side by side where both fit at their content's width,
   else one under the other; the special's two tables stack in its card */
.dscpair{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,46rem),1fr));column-gap:.35rem;align-items:start}
.dsc-tbl{border-collapse:collapse}
.dsc-tbl + .dsc-tbl{margin-top:.7rem}
.dsc-cap{caption-side:top;text-align:left;padding:.2rem .4rem;font-weight:700}
.dsc-cap .dsc-sub{display:inline}
/* THE PRICES DOWN THE LEFT, THEIR TERMS BESIDE (1149): Roles' list, in the
   flow here so the Save below it never meets it; one column when narrow */
.dscsplit{display:grid;grid-template-columns:200px minmax(0,1fr);gap:12px;align-items:start;margin-top:.35rem}
.dscsplit .rolelist{position:static;width:auto;max-height:calc(100vh - 14rem)}
.dscsplit .rolelist ul ul{display:grid;gap:2px}
/* a group heading sits on a light neutral band so it never reads as a price
   (his go on the drawing, 28 Oct 2026); grey, not blue — blue marks the open price */
.dsc-grp{font-size:.8rem;font-weight:700;color:var(--ink);background:color-mix(in srgb,var(--muted) 12%,var(--card));
  border-radius:6px;padding:.3rem .6rem;margin:.45rem 0 .15rem}
.dscsplit .rolelist > ul > li:first-child .dsc-grp{margin-top:.1rem}
/* A TITLE IS A FLAT STRIP, THE CHOSEN PRICE A PILL (his go on the drawing,
   28 Oct 2026): the title runs the list's full width, square, a line above
   and below; the chosen price keeps Roles' pill and wears the price grids'
   selected-row bar, so the two never look alike */
.dscsplit .dsc-grp{margin:.5rem -.4rem .2rem;border-radius:0;padding:.28rem 1rem;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.dscsplit .rolelist li button.on{box-shadow:inset 3px 0 0 var(--blue)}
.rolelist li button .n.wn{color:var(--warn);font-weight:700}
.dscmain{min-width:0}
/* the summary wraps rather than hide behind its buttons (28 Oct 2026) */
.dscmain .rolebar{flex-wrap:wrap}
.dsc-follow{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;padding:.45rem .6rem;font-size:.83rem;
  background:var(--panel);border-radius:7px;margin-top:.3rem}
@media(max-width:800px){.dscsplit{grid-template-columns:minmax(0,1fr)}}

/* PRICES — WHAT MOVED (0849; his drawing, approved 3 Oct 2026). The
   groups on the left, the picked group's sheet on the right at the
   grid's own height; every word at the page's size, none larger. */
.pwm .modal-b.pwm-b{display:flex;flex-direction:column;gap:.55rem}
.pwm-top{display:flex;flex-direction:column;gap:.5rem}
.pwm-head{background:var(--ok-soft);border-left:3px solid var(--ok);border-radius:.35rem;
  padding:.5rem .75rem;color:var(--ink)}
/* every price fell: the band is never green for a fall (his go, 29 Oct 2026) */
.pwm-head.alldn{background:var(--red-soft);border-left-color:var(--red)}
.pwm-pills,.pwm-ctl{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
/* the totals, the choices and their labels read at the box size, the
   size of the sheet beside them (his go on the drawing, 29 Oct 2026) */
.pwm-pills .pill,.pwm-ctl .pill{font-size:.88rem}
.pwm-ctl > .muted{font-size:.88rem}
.pwm-gap{margin-left:.9rem}
.pwm-mt{display:inline-flex;align-items:center;gap:.25rem;padding-top:0;padding-bottom:0}
.pwm-mtb{border:0;background:none;font:inherit;color:inherit;cursor:pointer;padding:.16rem 0}
.pwm-mt input{width:3.6rem;padding:.05rem .3rem;font:inherit;text-align:right;
  border:1px solid var(--line);border-radius:.3rem;background:var(--card);color:var(--ink)}
.pwm-none{margin:0}
.pwm-body{display:flex;gap:.8rem;align-items:stretch;min-height:0}
.pwm-left{flex:0 0 46%;min-width:0}
.pwm-side{flex:1;min-width:0;position:relative;border:1px solid var(--line);border-radius:.5rem}
/* the side is a column: the title line stays, only the sheet scrolls
   (both ways), and the old -> new reading is pinned beneath it, always
   in view. The sheet scroller has no top padding, so no row shows
   through above its held heading. */
.pwm-side > div{position:absolute;inset:0;display:flex;flex-direction:column;padding:0 .75rem}
.pwm-side > p{position:static;padding:.6rem .75rem 0;margin:0}
.pwm-sh{flex:none;display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap;margin-bottom:.45rem;padding-top:.6rem}
.pwm-sheet{flex:1 1 auto;min-height:0;overflow:auto}
.pwm-sh .sp{margin-left:auto}
.pwm-key{color:var(--muted);white-space:nowrap;font-size:.88rem}
.pwm-key i{display:inline-block;width:3.2rem;height:.5rem;border-radius:999px;vertical-align:1px;margin:0 .3rem;
  background:linear-gradient(90deg,color-mix(in srgb,var(--red) 34%,var(--card)),var(--card),
  color-mix(in srgb,var(--ok) 34%,var(--card)))}
/* the held headings cover the 2px spacing round them, so no row shows
   through; the list needs no spacing at all */
.pwm-heat{border-collapse:separate;border-spacing:2px;width:100%}
.pwm-list{border-collapse:collapse;width:100%}
.pwm-heat thead th{font-weight:700;font-size:.88rem;padding:.2rem .15rem;text-align:center;white-space:nowrap;
  position:sticky;top:0;z-index:2;background:var(--card);box-shadow:0 0 0 2px var(--card)}
.pwm-heat tbody th{font-weight:700;font-size:.88rem;padding:.2rem .15rem;text-align:left;white-space:nowrap;
  position:sticky;left:0;z-index:1;background:var(--card);box-shadow:0 0 0 2px var(--card)}
.pwm-heat thead th:first-child{left:0;z-index:3}
.pwm-heat td{text-align:center;padding:.3rem .12rem;border-radius:.25rem;font-weight:600;font-size:.88rem;
  color:var(--ink);white-space:nowrap;cursor:default;background:var(--panel)}
.pwm-heat td.same{font-weight:400;color:var(--muted)}
.pwm-heat td.fade{background:var(--card);color:var(--muted);font-weight:400;box-shadow:inset 0 0 0 1px var(--line)}
.pwm-heat td.nil{background:none}
/* a price that moved unlike its group, framed in ink on its group's sheet */
.pwm-heat td.odd{outline:2px solid var(--ink);outline-offset:-3px}
.pwm-heat td:focus-visible{outline:2px solid var(--amber);outline-offset:1px}
.pwm-list th{text-align:left;font-weight:700;padding:.2rem .4rem;position:sticky;top:0;z-index:1;
  background:var(--card);box-shadow:0 1px 0 var(--line)}
.pwm-list td{padding:.2rem .4rem;border-bottom:1px solid var(--line)}
.pwm-list .r{text-align:right}
.pwm-note{flex:none;margin:0 -.75rem;padding:.45rem .75rem .55rem;color:var(--ink);font-size:.88rem;
  border-top:1px solid var(--line);background:var(--card)}
.pwm-bar{position:relative;display:block;width:100%;min-width:4.5rem;height:.5rem;
  background:var(--panel);border-radius:999px}
.ag-cell span:has(> .pwm-bar){flex:1 1 auto;display:flex;align-items:center}
.pwm-bar::after{content:'';position:absolute;left:50%;top:-2px;bottom:-2px;width:1px;background:var(--muted)}
.pwm-bar i{position:absolute;top:0;bottom:0}
.pwm-bar i.up{left:50%;background:var(--ok);border-radius:0 999px 999px 0}
.pwm-bar i.dn{right:50%;background:var(--red);border-radius:999px 0 0 999px}
@media (max-width:760px){
  .pwm-body{flex-direction:column}
  .pwm-left{flex:none}
  .pwm-side > div{position:static}
}

/* =====================================================================
   YEARS & NUMBERING (0878, his go on the drawing, 5 Oct 2026): the year
   strip, oldest first, one card a year; the chosen card wears the
   action ring. The earlier-years box opens under its own button and
   closes only by Cancel or Escape (rule 29).
   ===================================================================== */
.fy-runs{font-size:.82rem}
.fy-cap{font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:700;margin:.1rem 0 .35rem}
.fy-row{display:flex;gap:.45rem;align-items:stretch}
.fy-earlier{position:relative;flex:none;display:flex}
.fy-strip{display:flex;gap:.45rem;align-items:stretch;overflow-x:auto;padding:.15rem .1rem .35rem;min-width:0;flex:1 1 auto}
.fy-card{flex:none;min-width:8.6rem;display:flex;flex-direction:column;align-items:flex-start;text-align:left;
  border:1px solid var(--line);background:var(--card);border-radius:10px;padding:.45rem .65rem;
  cursor:pointer;font:inherit;color:var(--ink)}
.fy-card:hover{border-color:var(--blue-line);background:var(--blue-soft)}
.fy-card[aria-pressed="true"]{border:2px solid var(--blue);padding:calc(.45rem - 1px) calc(.65rem - 1px)}
.fy-card .fy-l{font-weight:700;font-size:1.02rem}
.fy-card .fy-d,.fy-card .fy-f{font-size:.74rem;color:var(--muted)}
.fy-card .fy-d{margin-top:.1rem}
.fy-card .fy-f{margin-top:.25rem;display:flex;gap:.35rem;align-items:center}
.fy-card.fy-add{border-style:dashed;color:var(--blue);font-weight:700;align-items:center;justify-content:center;min-width:7.2rem}
.fy-card:disabled{cursor:default}
.fy-pop{position:absolute;z-index:40;top:100%;left:0;margin-top:.35rem;width:23rem;max-width:90vw;
  background:var(--card);border:1px solid var(--line);border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,.14);padding:.75rem}
.fy-pop-t{font-weight:700;margin-bottom:.45rem}
.fy-pop label{display:block;font-size:.8rem;margin-bottom:.2rem}
.fy-pop-n{margin:.5rem 0 .6rem;font-size:.8rem}
.fy-pop-acts{display:flex;justify-content:flex-end;gap:.45rem}
.fy-head{gap:.45rem}
.fy-note{font-size:.82rem;flex:1 1 0;min-width:0;max-width:max-content;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fy-acts{display:flex;gap:.45rem;align-items:center}
.fy-why{font-size:.78rem}
.btn.fy-dz:not(:disabled){color:var(--red);border-color:var(--red)}
/* a document not used in this branch reads dim and takes no tick */
.ag-row.fy-off .ag-cell{color:var(--muted)}
.ag-row.fy-off .s1tick{visibility:hidden}

/* =====================================================================
   HOME, FIRST ROUND (0881, 5 Oct 2026) — a slim greeting line in the
   menu's own dark, then two columns of cards. Every colour a variable.
   ===================================================================== */
.hb-top{background:linear-gradient(120deg,var(--side) 0%,var(--side-3) 100%);color:var(--side-ink);
  border-radius:12px;padding:.6rem 1rem;margin-bottom:.6rem;display:flex;align-items:baseline;
  gap:.4rem 1rem;flex-wrap:wrap;
  /* it stays at the top while the cards scroll (his ask, 5 Oct) — under
     the top bar like the editor bar, with a ring of page ground so no card
     shows round its corners */
  position:sticky;top:var(--s1-topbar-h,2.55rem);z-index:20;box-shadow:0 0 0 .4rem var(--bg)}
.hb-top h1{font-size:1.15rem;font-weight:700;margin:0}
.hb-topm{color:var(--side-nav);font-size:.8rem}
.hb-grid{display:grid;grid-template-columns:1fr;gap:.7rem;align-items:start}
@media(min-width:980px){ .hb-grid{grid-template-columns:1fr 1fr} }
.hb-col{display:flex;flex-direction:column;gap:.7rem;min-width:0}
.hb-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:.75rem .9rem;box-shadow:var(--shadow);min-width:0}
.hb-h{display:flex;align-items:baseline;gap:.5rem;margin-bottom:.45rem;flex-wrap:wrap}
.hb-h h2{font-size:.9rem;font-weight:700;margin:0;color:var(--ink)}
.hb-h .sp,.hsrow .sp{flex:1}
.hb-sub{font-size:.76rem;color:var(--muted)}
a.hb-sub{color:var(--blue)}
.hb-big-row{display:flex;align-items:baseline;gap:.7rem;flex-wrap:wrap}
.hb-big{font-size:1.6rem;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}
.hb-chg{font-size:.8rem;font-weight:700}
.hb-chg.up{color:var(--ok)} .hb-chg.down{color:var(--red)} .hb-chg.n{color:var(--muted);font-weight:400}
.hb-bars{display:block;width:100%;height:56px;margin-top:.45rem}
.hb-bars rect.now{fill:var(--blue)} .hb-bars rect.was{fill:var(--blue-line)}
.hb-axis{display:flex;justify-content:space-between;gap:.5rem;font-size:.72rem;color:var(--muted);margin-top:.15rem}
.hb-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem;margin-top:.6rem;
  border-top:1px solid var(--line);padding-top:.55rem}
.hb-kpis div{display:flex;flex-direction:column;gap:.1rem}
.hb-kpis b{font-size:.95rem;font-variant-numeric:tabular-nums}
.hb-kpis span{font-size:.74rem;color:var(--muted)}
.hb-stand{font-size:.8rem;margin:.55rem 0 0;padding:.45rem .6rem;background:var(--panel);border-radius:8px}
.hb-stack{display:flex;height:14px;border-radius:7px;overflow:hidden;background:var(--panel)}
.hb-stack span{display:block;height:100%}
.hb-leg{display:flex;flex-wrap:wrap;gap:.3rem .9rem;margin-top:.45rem;font-size:.78rem}
.hb-leg i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:.3rem;vertical-align:-1px}
.hb-age{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:.5rem;align-items:end;height:96px;margin-top:.35rem}
.hb-age div{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;gap:.15rem}
.hb-age span{display:block;width:70%;max-width:46px;min-height:2px;border-radius:4px 4px 0 0;max-height:52px}
.hb-age b{font-size:.78rem;font-variant-numeric:tabular-nums}
.hb-age em{font-style:normal;font-size:.72rem;color:var(--muted);white-space:nowrap}
/* 1022: the money each bar holds, one line under its words; the row grows
   by that line so the bars keep their height */
.hb-age.val{height:114px}
.hb-age i{font-style:normal;font-size:.72rem;font-weight:600;color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums}
.hb-hr{display:grid;grid-template-columns:minmax(6rem,13rem) 1fr auto;gap:.2rem .6rem;align-items:center;
  font-size:.8rem;padding:.2rem 0}
.hb-hl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hb-hl.me{font-weight:700}
.hb-ht{height:10px;background:var(--panel);border-radius:5px;overflow:hidden}
.hb-ht span{display:block;height:100%;background:var(--blue-line);border-radius:5px}
.hb-ht span.me{background:var(--blue)} .hb-ht span.ok{background:var(--ok)}
.hb-hv{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.hb-hx{grid-column:1 / -1;font-size:.72rem;color:var(--muted);margin-top:-.15rem}
.hb-heatw{overflow-x:auto}   /* a narrow phone scrolls the table, never the page */
.dsc-wide{overflow-x:auto;max-width:100%;padding:2px;margin:-2px}   /* the same for the special categories; the 2px keep the focus ring whole */
.hb-heat{width:100%;min-width:30rem;border-collapse:separate;border-spacing:3px;font-size:.78rem;table-layout:fixed}
.hb-heat th[scope=row],.hb-heat thead th:first-child{width:5.5rem}
.hb-bars rect.cut{fill:var(--card)}
/* each bar's day and amount under the pointer (10 Oct 2026) */
.hb-barbox{position:relative}
.hb-tip{position:absolute;bottom:100%;transform:translateX(-50%);background:var(--ink);color:var(--card);font-size:.74rem;font-weight:600;
  padding:.18rem .45rem;border-radius:6px;white-space:nowrap;pointer-events:none;z-index:5;font-variant-numeric:tabular-nums}
.hb-sold{color:var(--muted)} .hb-sold b{color:var(--ink)}

/* ---- HOME, ARRANGED AND THE SECOND ROUND (0882–0884, 5 Oct 2026) ---- */
.hb-top{align-items:center}
.hb-topsp{flex:1}
/* The line's ground is the menu's own (--side), light in one look and dark
   in the rest, so every edge, ground and ring on it is drawn from the
   line's own ink (--side-ink) — never a fixed white, which vanishes on
   the light ground. */
.hb-tbtn,.hb-tsel{font:inherit;font-size:.8rem;border-radius:7px;padding:.28rem .7rem;cursor:pointer;
  border:1px solid color-mix(in srgb,var(--side-ink) 50%,transparent);
  background:color-mix(in srgb,var(--side-ink) 10%,transparent);color:var(--side-ink)}
.hb-tsel option{color:var(--ink);background:var(--card)}
/* the role picker is as wide as its words, so the line does not wrap (his look, 6 Oct) */
.hb-top .hb-tsel{width:auto;max-width:22rem}
.hb-tbtn:hover{background:color-mix(in srgb,var(--side-ink) 18%,transparent)}
.hb-tbtn:focus-visible,.hb-tsel:focus-visible{outline:2px solid var(--side-ink);outline-offset:2px}
.hb-tbtn.ok{background:var(--blue);border-color:var(--blue);color:var(--blue-ink)}
.hb-tbtn:disabled{opacity:.6;cursor:default}
.hb-arrbar{display:flex;gap:.45rem;align-items:center;flex-wrap:wrap}
/* This branch | All my branches, on the greeting line: the chosen one is
   the line's ink filled, its word in the line's ground — the pair turned
   over, so it reads in every look */
.hb-scope{display:inline-flex;border:1px solid color-mix(in srgb,var(--side-ink) 50%,transparent);border-radius:7px;overflow:hidden}
.hb-scope button{font:inherit;font-size:.78rem;border:0;background:transparent;color:var(--side-ink);padding:.28rem .7rem;cursor:pointer}
.hb-scope button[aria-pressed="true"]{background:var(--side-ink);color:var(--side);font-weight:700}
.hb-scope button:focus-visible{outline:2px solid var(--side-ink);outline-offset:-3px}
.hb-scope button[aria-pressed="true"]:focus-visible{outline-color:var(--side)}
.hb-scope button:disabled{cursor:default}
.hb-tray{background:var(--card);border:1px dashed var(--blue);border-radius:var(--r);padding:.55rem .8rem;margin:0 0 .7rem}
.hb-trayt{margin:0 0 .35rem;font-size:.8rem;color:var(--muted)}
.hb-trayl{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center;font-size:.8rem;margin-top:.25rem}
.hb-trayl > b{margin-right:.2rem}
.hb-chipw{display:inline-flex;align-items:center}
.hb-chip{font:inherit;font-size:.78rem;border:1px solid var(--blue-line);background:var(--blue-soft);color:var(--blue);
  border-radius:999px;padding:.18rem .7rem;font-weight:600;cursor:pointer}
.hb-chipw .hb-chip{border-radius:999px 0 0 999px}
.hb-chipx{font:inherit;font-size:.8rem;border:1px solid var(--blue-line);border-left:0;background:var(--card);color:var(--muted);
  border-radius:0 999px 999px 0;padding:.18rem .5rem;cursor:pointer}
.hb-chip.off{background:var(--panel);border-color:var(--line);color:var(--muted);font-weight:500}
.hb-chip:focus-visible,.hb-chipx:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.hb-arr .hb-card{outline:2px dashed var(--blue-line);outline-offset:2px}
.hb-tools{display:flex;gap:.3rem;align-items:center;margin:-.2rem 0 .5rem;padding-bottom:.4rem;border-bottom:1px dashed var(--line)}
.hb-tools button{font:inherit;font-size:.74rem;border:1px solid var(--line);background:var(--card);color:var(--ink);
  border-radius:6px;padding:.12rem .5rem;cursor:pointer;min-width:1.9rem}
.hb-tools button:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.hb-tools .sp{flex:1}
.hb-tools .x{color:var(--red);border-color:var(--danger-line)}
.hb-grip{cursor:grab;color:var(--muted);font-size:1.05rem;padding:0 .2rem;user-select:none}
.hb-fx{font-size:.76rem;color:var(--muted);margin:.15rem 0 0}
.hb-ring{display:flex;gap:.8rem;align-items:center;margin:.35rem 0}
.hb-ringt{font-weight:600;font-size:.82rem}
.hb-rbg{fill:none;stroke:var(--panel);stroke-width:8}
.hb-rfg{fill:none;stroke:var(--blue);stroke-width:8;stroke-linecap:round}
.hb-rfg.ok{stroke:var(--ok)}
.hb-rtx{font-size:.875rem;font-weight:700;fill:var(--ink)}
.hb-seg{display:inline-flex;border:1px solid var(--line);border-radius:7px;overflow:hidden}
.hb-seg button{font:inherit;font-size:.74rem;border:0;background:var(--card);color:var(--muted);padding:.2rem .6rem;cursor:pointer}
.hb-seg button[aria-pressed="true"]{background:var(--blue-soft);color:var(--blue);font-weight:700}
.hb-seg button:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
.hb-heat td.cv.low,.hb-key.cv.low{background:var(--red-soft);color:var(--red);font-weight:700}
.hb-heat td.cv.slow,.hb-key.cv.slow{background:var(--warn-soft);color:var(--warn)}
.hb-key{border-radius:4px;padding:0 .3rem}
.hb-ht span.rt{background:var(--warn)}
/* price against list (0887): plain cells, his own row in bold */
.hb-pr td{background:transparent;border-bottom:1px solid var(--line);border-radius:0}
.hb-pr tr.me th,.hb-pr tr.me td{font-weight:700}

/* ---- SALES TARGETS (0883) ---- */
.tg-year,.tg-acts,.tg-fill{display:inline-flex;align-items:center;gap:.4rem;flex-wrap:wrap}
.tg-year label,.tg-fill label{margin:0;font-size:.8rem;color:var(--muted)}
/* the label sits beside its box on the title line, as the neighbours do (rule 42) */
.card-h .tg-year,.card-h .tg-fill{flex-wrap:nowrap}
.card-h .tg-year > label,.card-h .tg-fill > label{display:inline;white-space:nowrap}
.card-h .tg-year select{width:auto;min-width:6rem}
.tg-fill input{width:4.5rem}
.ag-row.tg-branch .ag-cell{font-weight:700}
/* ---- OCCASIONS (0980): the kind chips, Year and Branch beside their boxes
   on the title line (rule 42), the branch ticks in the window ---- */
.card-h .oc-kinds{display:inline-flex;gap:.3rem;flex-wrap:wrap;margin-left:.4rem}
.card-h .oc-sel{display:inline-flex;align-items:center;gap:.35rem;margin:0;font-size:.8rem;color:var(--muted);white-space:nowrap}
.card-h .oc-sel select{width:auto;min-width:7rem}
.oc-brs{border:1px solid var(--line);border-radius:10px;padding:.4rem .7rem .5rem;margin-top:.6rem;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(12rem,1fr));column-gap:1rem}
.oc-brs > div:first-of-type:has(#ocAll){grid-column:1 / -1}
.oc-brs legend{font-size:.8rem;color:var(--muted);padding:0 .3rem}
.ag-row.oc-removed .ag-cell{color:var(--muted)}
/* Employees: "Keep private" rides the Date of birth label's own line */
/* the row is the label's own height — the tick floats at its right, so the
   box below sits level with Full name and Gender (rule 42) */
.em-lblrow{position:relative}
.em-lblchk{position:absolute;right:0;top:0;bottom:0;display:inline-flex;align-items:center;gap:.25rem;font-size:.78rem;color:var(--muted);white-space:nowrap}
.em-lblchk input{width:auto;margin:0}
.em-lblchk label{margin:0;font-size:inherit;color:inherit;font-weight:400}
/* ---- ROLES: a role's Home cards — one list, a card a line; the window
   never grows past the screen, the list scrolls inside it ---- */
.modal.hcw{width:min(1000px,94vw);max-width:none;max-height:88vh;display:flex;flex-direction:column}
.hcw .modal-h,.hcw .modal-f{flex:none}
.hcw .modal-b{flex:1 1 auto;min-height:0;overflow:auto}
.hcw .modal-b>p.muted{font-size:.8rem;margin:0 0 .5rem}
.hc-list{border:1px solid var(--line);border-radius:8px;overflow:hidden}
.hc-row{display:grid;grid-template-columns:215px minmax(0,1fr) max-content;gap:12px;align-items:baseline;box-sizing:border-box;
  min-height:28px;padding:3px 8px;border-top:1px solid var(--grid-row-line);font-size:.8rem}
.hc-row:first-of-type{border-top:0}
.hc-row:nth-of-type(even){background:var(--grid-odd)}
.hc-row b{font-weight:700}
.hc-row .hc-d{color:var(--muted);line-height:1.35}
.hc-row .pill{white-space:nowrap;justify-self:end}
/* SET IN PLACE (0960): only the chosen state is coloured — Shown green,
   Offered amber, Off red — the rest plain words; an Off card's name
   steps back. Every switch is one width so the column lines up. */
.hctop{display:flex;align-items:center;gap:.6rem;margin-bottom:.35rem}
.hcw .modal-b .hctop>p.muted{flex:1;margin:0;font-size:.8rem}
.hctop label{font-size:.8rem;color:var(--muted);white-space:nowrap;margin:0}
.hcsum{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;margin:.1rem 0 .5rem}
.hcsum .k{display:inline-flex;align-items:center;padding:.2rem .6rem;border-radius:999px;font-size:.8rem;font-weight:700}
.hcsum .k.s{background:var(--ok-soft);color:var(--ok)}
.hcsum .k.o{background:var(--warn-soft);color:var(--warn)}
.hcsum .k.f{background:var(--red-soft);color:var(--red)}
.hcsw{display:inline-flex;justify-self:end;align-self:center;border:1px solid var(--line);border-radius:8px;padding:2px;gap:2px;background:var(--card)}
.hcsw button{border:0;background:transparent;border-radius:6px;padding:.28rem 0;text-align:center;font:inherit;color:var(--muted);cursor:pointer;min-height:28px}
.hcsw button[data-s=SHOWN]{width:4.9rem}
.hcsw button[data-s=OFFERED]{width:4.6rem}
.hcsw button[data-s=NONE]{width:3.2rem}
.hcsw button:hover:not([disabled]):not(.on){background:var(--grid-hover)}
.hcsw button:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.hcsw button.on{font-weight:700}
.hcsw button.on[data-s=SHOWN]{background:var(--ok-soft);color:var(--ok)}
.hcsw button.on[data-s=OFFERED]{background:var(--warn-soft);color:var(--warn)}
.hcsw button.on[data-s=NONE]{background:var(--red-soft);color:var(--red)}
.hcsw button[disabled]{opacity:.45;cursor:not-allowed}
.hc-row.isoff b{color:var(--muted);font-weight:400}
.hc-row .hcwarn{display:block;color:var(--warn);font-size:1em;margin-top:.15rem}
@media(max-width:700px){ .hc-row{grid-template-columns:minmax(0,1fr) max-content} .hc-row .hc-d{grid-column:1 / -1;grid-row:2} }
.hb-heat th{font-weight:600;color:var(--muted);text-align:center;font-size:.74rem}
.hb-heat th[scope=row]{text-align:left;color:var(--ink)}
.hb-heat td{text-align:center;padding:.3rem .2rem;border-radius:5px;background:var(--panel);font-variant-numeric:tabular-nums}
.hb-todo{display:flex;flex-direction:column}
.hb-todo a{display:flex;align-items:center;gap:.6rem;padding:.4rem .3rem;border-bottom:1px solid var(--line);
  text-decoration:none;color:var(--ink);font-size:.82rem;border-radius:6px}
.hb-todo a:last-of-type{border-bottom:0}
.hb-todo a:hover{background:var(--bg)}
.hb-todo a:not([href]){cursor:default}
.hb-todo a:not([href]):hover{background:none}
.hb-todo a:focus-visible,.hb-br:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.hb-todo .go{margin-left:auto;color:var(--muted);font-size:1rem}
/* a reminder row: the line and, when not yet due, Change · Remove at its end (0975) */
.hb-todo .hb-remrow{display:flex;align-items:center;gap:.35rem;border-bottom:1px solid var(--line)}
.hb-todo .hb-remrow:last-of-type{border-bottom:0}
.hb-todo .hb-remrow > a{flex:1;min-width:0;border-bottom:0}
.hb-remacts{display:flex;gap:.3rem;flex:none}
.hb-n{min-width:2.4rem;text-align:center;font-weight:700;border-radius:999px;padding:.12rem .45rem;font-variant-numeric:tabular-nums}
.hb-n.a{background:var(--warn-soft);color:var(--warn)} .hb-n.r{background:var(--red-soft);color:var(--red)}
.hb-n.b{background:var(--blue-soft);color:var(--blue)}
/* a card's own act in its heading line (Reminders' New reminder): the link's dress, a button's road */
.hb-h .hb-new{background:none;border:0;padding:0;font:inherit;font-size:.82rem;font-weight:600;color:var(--blue);cursor:pointer}
.hb-h .hb-new:hover{text-decoration:underline}
.hb-h .hb-new:focus-visible{outline:2px solid var(--blue);outline-offset:2px;border-radius:3px}
/* a pinned SIA answer (0998): the pin before its name, ↻ after its time, a foot of two links */
.hb-pinmk{vertical-align:-2px;margin-right:.35rem;color:var(--muted)}
.hb-h .hb-pinr{background:none;border:0;padding:0 .2rem;font:inherit;font-size:.9rem;color:var(--muted);cursor:pointer;line-height:1;position:relative}
/* the press reaches 24 px around ↻ and the foot's links; nothing moves (his 22 Sep choice: the reach grows, never the control) */
.hb-h .hb-pinr::before,.hb-pinf a::before{content:'';position:absolute;left:50%;top:50%;width:max(100%, 24px);height:max(100%, 24px);transform:translate(-50%,-50%)}
.hb-pinf a{position:relative}
.hb-h .hb-pinr:hover{color:var(--ink)}
.hb-h .hb-pinr:disabled{opacity:.45;cursor:default}
.hb-h .hb-pinr:focus-visible,.hb-pinf a:focus-visible{outline:2px solid var(--blue);outline-offset:2px;border-radius:3px}
.hb-pinf{display:flex;align-items:baseline;gap:1rem;margin:.5rem 0 0}
/* a pinned card's figure is the Target card's size, not Sales this month's headline (his go, 13 Oct 2026) */
.hb-big.hb-pinbig{font-size:1rem}
/* a pinned card's row: the number takes its own width, the words beside it the rest */
.hb-hr.hb-pinrow{grid-template-columns:auto minmax(0,1fr) auto}
.hb-pinf .sp{flex:1}
.hb-pinf a{cursor:pointer;text-decoration:underline}
.hb-pinf .hb-pinl{color:var(--blue)}
.hb-pinf .hb-pina{color:var(--ink)}
.hb-feed{display:flex;flex-direction:column}
.hb-feed > div{display:flex;align-items:center;gap:.6rem;padding:.32rem 0;border-bottom:1px solid var(--line);font-size:.8rem;flex-wrap:wrap}
.hb-feed > div:last-child{border-bottom:0}
.hb-feed .w{min-width:4.6rem;color:var(--muted);font-variant-numeric:tabular-nums}
.hb-feed > div > span:nth-child(2){flex:1;min-width:10rem}
.hb-fun{display:grid;grid-template-columns:repeat(4,1fr);gap:.4rem}
.hb-fun div{background:var(--panel);border-radius:8px;padding:.45rem .5rem;font-size:.74rem;color:var(--muted);display:flex;flex-direction:column}
.hb-fun b{font-size:1.05rem;color:var(--ink)}
.hb-br{display:grid;grid-template-columns:auto 1fr auto minmax(5.5rem,auto);gap:.6rem;align-items:center;width:100%;
  text-align:left;background:transparent;border:0;border-bottom:1px solid var(--line);padding:.38rem .25rem;
  font:inherit;font-size:.8rem;color:var(--ink);cursor:pointer;border-radius:6px}
.hb-br:hover{background:var(--bg)}
.hb-br.on{cursor:default;background:var(--blue-soft)}
.hb-br.off{color:var(--muted)}
.hb-br .here{color:var(--blue);font-size:.7rem;letter-spacing:.04em}
.hb-quick{grid-template-columns:repeat(2,1fr)}
@media(min-width:560px){ .hb-quick{grid-template-columns:repeat(4,1fr)} }

/* ---- ASK SHASHVAT (0963, his go on the drawing, 11 Oct 2026) ----
   The top-bar button lit while open; the panel floats on the right over
   whatever screen is open, so nothing beneath moves or resizes. Every
   colour is the theme's own. */
.askpick > button.on{background:var(--blue-soft);border-color:var(--blue);color:var(--blue);box-shadow:inset 0 0 0 1px var(--blue)}
/* THE SPARKLE (his go, 11 Oct 2026): under the mouse the star tilts and
   glows, and two small stars twinkle in turn at its corners for as long as
   the mouse rests; the same twinkle plays once (.twinkle) when an answer
   lands while the panel is closed. Still for anyone who asks for less
   motion. */
.askpick > button{position:relative;overflow:visible;gap:.3rem;padding-right:.6rem}
/* the button says its name, as drawn on his screen (11 Oct 2026) */
.askpick .askword{font-weight:700;font-size:.85rem;white-space:nowrap}
.askpick > button svg{transition:transform .25s}
.askpick > button:hover svg,.askpick > button.twinkle svg{color:var(--blue);filter:drop-shadow(0 0 4px rgba(22,107,195,.55));transform:rotate(-12deg) scale(1.08)}
.askpick > button::before,.askpick > button::after{content:"";position:absolute;border-radius:50%;background:var(--blue);opacity:0;pointer-events:none;
  clip-path:polygon(50% 0,62% 38%,100% 50%,62% 62%,50% 100%,38% 62%,0 50%,38% 38%)}
.askpick > button::before{left:4px;top:3px;width:9px;height:9px}
.askpick > button::after{right:3px;bottom:4px;width:7px;height:7px}
.askpick > button:hover::before,.askpick > button.twinkle::before{animation:s1tw 1.1s ease-in-out infinite}
.askpick > button:hover::after,.askpick > button.twinkle::after{animation:s1tw 1.1s ease-in-out .35s infinite}
.askpick > button.twinkle::before,.askpick > button.twinkle::after{animation-iteration-count:2}
@keyframes s1tw{0%,100%{opacity:0;transform:scale(.4) rotate(0)}50%{opacity:1;transform:scale(1) rotate(45deg)}}
@media (prefers-reduced-motion: reduce){
  .askpick > button svg{transition:none}
  .askpick > button:hover svg,.askpick > button.twinkle svg{transform:none}
  .askpick > button:hover::before,.askpick > button:hover::after,.askpick > button.twinkle::before,.askpick > button.twinkle::after{animation:none;opacity:.8}
}
.modal.s1pinw{max-width:460px}
.s1pinmk{display:inline-flex}
/* THE PANEL STANDS OVER THE PAGE AND UNDER EVERYTHING ELSE (his go, 13 Oct
   2026): above the page's own sticky bars (20), below the top bar and its
   menus (30), the notes, every window (80), every question (120) and the
   messages — so nothing opens hidden under it */
.s1ask{position:fixed;top:47px;right:5px;bottom:5px;width:min(440px, calc(100vw - 10px));z-index:25;
  transition:transform .2s ease, opacity .2s ease;
  background:var(--card);color:var(--ink);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 10px 30px rgba(11,22,35,.18);display:flex;flex-direction:column;font-size:.88rem;overflow:hidden}
/* while a window is open the panel steps aside, its chat kept, and comes back when the window closes */
.s1ask.aside{transform:translateX(calc(100% + 12px));opacity:0;pointer-events:none;visibility:hidden;
  transition:transform .2s ease, opacity .2s ease, visibility 0s linear .2s}
@media (prefers-reduced-motion: reduce){.s1ask{transition:none}}
/* THE TITLE BAND AND TABS WEAR THE SIDEBAR'S OWN COLOURS (his go on the
   drawing, 11 Oct 2026), so the panel reads as part of the application in
   every theme; the drag edge and the wide press grow it — a dragged width
   is kept per person. */
.s1ask.wide{width:min(66vw, calc(100vw - 10px))}
.s1ask .s1drag{position:absolute;left:0;top:0;bottom:0;width:8px;cursor:col-resize;z-index:3;touch-action:none}
.s1ask .s1drag::after{content:"";position:absolute;left:2px;top:50%;width:3px;height:44px;margin-top:-22px;border-radius:3px;background:var(--line)}
.s1ask .s1drag:hover::after,.s1ask .s1drag:focus-visible::after{background:var(--blue)}
.s1ask .s1drag:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}
/* the top edge sets the height; its bar wears the band's own ink */
.s1ask .s1vdrag{position:absolute;left:8px;right:0;top:0;height:7px;cursor:row-resize;z-index:3;touch-action:none}
.s1ask .s1vdrag::after{content:"";position:absolute;top:2px;left:50%;width:44px;height:3px;margin-left:-22px;border-radius:3px;background:var(--side-ink);opacity:.6}
.s1ask .s1vdrag:hover::after{opacity:.9}
.s1ask .s1vdrag:focus-visible{outline:2px solid var(--side-ink);outline-offset:-2px}
/* Clear chat sits with the box's own tools (his suggestion, 11 Oct 2026) */
.s1ask .inp .tools .clr{height:30px;flex:none;border:0;border-radius:8px;background:transparent;color:var(--muted);font:inherit;font-size:.82rem;font-weight:600;
  padding:0 .5rem;display:inline-flex;align-items:center;gap:.3rem;cursor:pointer}
.s1ask .inp .tools .clr span{display:grid}
.s1ask .inp .tools .clr:hover:not(:disabled){background:var(--blue-soft);color:var(--blue)}
.s1ask .inp .tools .clr:disabled{opacity:.5;cursor:default}
.s1ask .inp .tools .clr:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.s1ask .ah{display:flex;align-items:center;gap:.5rem;padding:.4rem .5rem .1rem .75rem;background:var(--side);color:var(--side-ink)}
.s1ask .tile{width:28px;height:28px;flex:none;border-radius:8px;display:grid;place-items:center;background:var(--side-hover);color:var(--side-accent)}
.s1ask .ttl{display:flex;flex-direction:column;min-width:0}
.s1ask .ttl b{font-size:.95rem}
.s1ask .ah .mut{color:var(--side-dim)}
.s1ask .mut{color:var(--muted)} .s1ask .sm{font-size:.8rem}
.s1ask .ib{width:30px;height:30px;flex:none;border-radius:8px;border:0;background:transparent;color:var(--muted);
  display:grid;place-items:center;cursor:pointer;position:relative}
.s1ask .ah .ib{color:var(--side-ink);opacity:.85} .s1ask .ah .ib:hover{background:var(--side-hover);color:var(--side-ink);opacity:1}
.s1ask .ah .ib[aria-pressed="true"]{background:var(--side-hover);color:var(--side-accent);opacity:1}
.s1ask .ah .ib:focus-visible{outline-color:var(--side-ink)}
.s1ask .s1tabs{display:flex;gap:.3rem;padding:.15rem .75rem .45rem;background:var(--side)}
.s1ask .s1tabs [role="tab"]{border:0;border-radius:999px;padding:.2rem .7rem;font:inherit;font-size:.82rem;color:var(--side-ink);opacity:.85;background:var(--side-hover);cursor:pointer}
.s1ask .s1tabs [role="tab"]:hover{opacity:1}
.s1ask .s1tabs [role="tab"][aria-selected="true"]{background:var(--card);color:var(--ink);font-weight:600;opacity:1}
.s1ask .s1tabs [role="tab"]:focus-visible{outline:2px solid var(--side-ink);outline-offset:2px}
/* one slim line: screen · branch, then what is ticked; the ask box gets the
   room (his ask, 11 Oct 2026). Both halves wrap rather than cut (rule 38). */
.s1ask .s1ctx{display:flex;align-items:center;gap:.5rem;padding:.35rem .75rem;border-bottom:1px solid var(--line);background:var(--bg)}
.s1ask .s1ctx .ico{width:22px;height:22px;flex:none;border-radius:6px;background:var(--blue-soft);color:var(--blue);display:grid;place-items:center}
.s1ask .s1ctx .ico svg{width:13px;height:13px}
.s1ask .s1ctx .cw{min-width:0;display:flex;flex-wrap:wrap;column-gap:.5rem;align-items:baseline}
.s1ask .s1ctx b{font-size:.84rem}
/* the words stay ONE line (his B, 11 Oct 2026): a long search is cut and
   says itself whole on hover through the shell's note (.ov) */
.s1ask .s1ctx .sm{font-size:.76rem;display:block;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.s1ask .s1ctx .live{margin-left:auto;flex:none;font-size:.74rem;font-weight:600;color:var(--ok);background:var(--ok-soft);border-radius:999px;padding:.2rem .55rem}
.s1ask .s1ctx .live::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--ok);margin-right:.35rem;vertical-align:middle}
.s1ask .hi{font-size:1.05rem;line-height:1.3}
/* the four tiles share one height — the tallest title's — so the block is
   even whether or not a title wraps (his go, 11 Oct 2026) */
.s1ask .tiles{display:grid;grid-template-columns:1fr 1fr;grid-auto-rows:1fr;gap:.55rem}
.s1ask .sug.tile4{flex-direction:column;align-items:flex-start;gap:.25rem;padding:.6rem .65rem;border-radius:12px}
.s1ask .sug.tile4 .si{margin-bottom:.1rem}
.s1ask .sug.tile4 .t{font-weight:600;font-size:.88rem;line-height:1.25;text-align:left} .s1ask .sug.tile4 .d{font-size:.76rem;line-height:1.3;text-align:left}
.s1ask .sug.tile4:disabled{opacity:.55;cursor:default}
.s1ask .later{display:flex;gap:.6rem;align-items:flex-start;padding:.7rem .75rem;border:1px solid var(--line);border-radius:12px;background:var(--bg)}
.s1ask .later .ico{width:28px;height:28px;flex:none;border-radius:8px;background:var(--blue-soft);color:var(--blue);display:grid;place-items:center}
.s1ask .inp .tools{display:flex;gap:.15rem;flex:1}
.s1ask .inp .tools .ib:hover{background:var(--blue-soft);color:var(--blue)}
/* the house's own focus ring on the panel's buttons and links, as the other
   windows draw it (accessibility review, 11 Oct 2026); the text box keeps
   the keyboard-only rule every box shares (html.s1-kbd), never :focus-visible */
.s1ask button:focus-visible,.s1ask a:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.s1ask .ib:hover{background:var(--bg);color:var(--ink)}
.s1ask .ib[aria-pressed="true"]{color:var(--blue);background:var(--blue-soft)}
.s1ask .ib:focus-visible,.s1ask .sug:focus-visible,.s1ask .chip:focus-visible,.s1ask .how:focus-visible,
.s1ask .pbtn:focus-visible,.s1ask .go:focus-visible,.s1ask td a:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.s1ask .ab{flex:1;overflow:auto;padding:.85rem;display:flex;flex-direction:column;gap:.75rem}
.s1ask .grp{font-size:.74rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);margin-top:.2rem}
.s1ask .sug{display:flex;align-items:center;gap:.6rem;width:100%;text-align:left;padding:.55rem .6rem;border:1px solid var(--line);
  border-radius:10px;background:var(--card);color:var(--ink);font:inherit;cursor:pointer}
.s1ask .sug:hover{border-color:var(--blue);background:var(--blue-soft)}
.s1ask .sug .si{color:var(--blue);display:grid;flex:none} .s1ask .sug .sc{margin-left:auto;color:var(--muted);display:grid;flex:none}
.s1ask .sug.rec{border:0;padding:.35rem .25rem;background:transparent} .s1ask .sug.rec .si{color:var(--muted)}
.s1ask .sug.rec:hover{background:var(--bg)}
/* the person's own words wear the light blue, ink on it (his B, 11 Oct 2026) */
.s1ask .q{align-self:flex-end;max-width:85%;background:var(--blue-soft);color:var(--ink);border:1px solid color-mix(in srgb,var(--blue) 35%,transparent);padding:.5rem .75rem;border-radius:14px 14px 4px 14px;white-space:pre-wrap;overflow-wrap:anywhere}
.s1ask .ans{border:1px solid var(--line);border-radius:12px;overflow:hidden}
.s1ask .band{padding:.6rem .75rem;background:var(--blue-soft);border-bottom:1px solid var(--line)}
.s1ask .band b{font-size:.95rem}
.s1ask .abody{padding:.6rem .75rem;display:flex;flex-direction:column;gap:.5rem}
/* a wide answer (seven columns with the floor) scrolls sideways inside its
   card rather than cutting its last heading (design review, 11 Oct 2026) */
.s1ask .tbl{overflow-x:auto;max-width:100%}
.s1ask table{border-collapse:collapse;width:100%;font-size:.84rem}
.s1ask th{text-align:left;color:var(--muted);font-weight:600;border-bottom:1px solid var(--line);padding:.25rem .35rem;white-space:nowrap}
.s1ask td{padding:.3rem .35rem;border-bottom:1px solid var(--line)}
.s1ask .r{text-align:right;font-variant-numeric:tabular-nums}
/* the By branch table's total row (16 Oct 2026) */
.s1ask tr.tot td{font-weight:700;border-bottom:0}
/* an answer's rows in a narrow panel: two lines each, nothing cut, nothing
   scrolling sideways (his go on the drawing, 11 Oct 2026) */
.s1ask .arows{display:flex;flex-direction:column;border-top:1px solid var(--line)}
.s1ask .arow{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.1rem .6rem;padding:.45rem .1rem;border-bottom:1px solid var(--line)}
.s1ask .arow .l1{display:flex;align-items:center;flex-wrap:wrap;gap:.2rem .45rem;min-width:0}
.s1ask .arow .l1 a,.s1ask .arow .l1 b{font-weight:700;white-space:nowrap}
/* a name that opens its list wears the action colour and a chevron; a name
   that opens nothing stays plain ink (his go on the drawing, 12 Oct 2026) */
.s1ask .arow .l1 a{color:var(--blue);text-decoration:underline;text-decoration-color:currentColor;text-underline-offset:3px;cursor:pointer}
.s1ask .arow .l1 a::after{content:'\203A' / '';display:inline-block;margin-left:.25rem;text-decoration:none}
.s1ask .arow .l1 a:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.s1ask .arow .amt{text-align:right;font-weight:650;font-variant-numeric:tabular-nums;white-space:nowrap}
.s1ask .arow .l2{grid-column:1 / -1;color:var(--muted);font-size:.8rem}
.s1ask td a{color:var(--blue);font-weight:700;white-space:nowrap;text-decoration:underline;text-decoration-color:currentColor;text-underline-offset:3px;cursor:pointer}
.s1ask td a::after{content:'\203A' / '';display:inline-block;margin-left:.25rem;text-decoration:none}
.s1ask .how{display:flex;align-items:flex-start;gap:.35rem;border:0;background:transparent;color:var(--muted);font:inherit;
  font-size:.8rem;padding:0;cursor:pointer;text-align:left}
.s1ask .how svg{flex:none;margin-top:.15rem;transition:transform .12s}
.s1ask .how[aria-expanded="true"] svg{transform:rotate(90deg)}
.s1ask .acts{display:flex;align-items:center;gap:.25rem;border-top:1px solid var(--line);padding:.4rem .5rem .4rem .75rem}
/* a reminder SIA prepared (0974): three short lines, then Set and Change */
.s1ask .remprop{line-height:1.55}
.s1ask .remprop b{color:var(--ink)}
/* PREPARE (his go on the drawings, 11 Oct 2026): the card reads who, the
   figure, the problems, then one button — order makes the hierarchy, never
   a bigger letter; a problem is a sign and words in the warning dress */
.s1ask .prepwrap{display:flex;flex-direction:column;gap:.6rem}
.s1ask .prepk{display:flex;align-items:center;gap:.45rem;flex-wrap:wrap}
.s1ask .prepwho{display:flex;align-items:center;justify-content:space-between;gap:.45rem;margin-top:.15rem}
.s1ask .prepwho .chip{flex:none;white-space:nowrap}
.s1ask .prepwholist{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.45rem}
.s1ask .prepwholist .chip{border-radius:10px;text-align:left}
.s1ask .sug.tile4[aria-pressed="true"]{border-color:var(--blue);box-shadow:inset 0 0 0 1px var(--blue)}
.s1ask .prepfind{display:flex;gap:.35rem;width:100%}
.s1ask .prepfind input{flex:1;min-width:0}
.s1ask .prepfig{font-weight:700;font-variant-numeric:tabular-nums}
.s1ask .prepprob{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.15rem .45rem;padding:.4rem .5rem;border-radius:8px;
  background:var(--warn-soft);color:var(--ink);border:1px solid var(--warn)}
.s1ask .prepprob .wi{color:var(--warn);font-weight:700}
.s1ask .prepprob .fx{grid-column:2;display:flex;gap:.35rem;flex-wrap:wrap;margin-top:.15rem}
.s1ask .prepfold{display:flex;align-items:center;gap:.35rem;color:var(--ink);font:inherit;font-size:.85rem;background:none;border:0;padding:0;cursor:pointer;align-self:flex-start}
.s1ask .prepfold[aria-expanded="true"] svg{transform:rotate(90deg)}
.s1ask .prepmk{background:var(--make);color:var(--make-ink);border:1px solid var(--make);border-radius:8px;padding:.4rem .8rem;font:inherit;font-weight:700;cursor:pointer}
.s1ask .prepmk:disabled{opacity:.55;cursor:default}
.s1ask .preplnk{background:none;border:0;color:var(--ink);text-decoration:underline;text-decoration-color:var(--muted);text-underline-offset:3px;font:inherit;font-size:.85rem;padding:.2rem .3rem;cursor:pointer}
.s1ask .preplnk.sm{font-size:.8rem;padding:0}
.s1ask .prepmk:focus-visible,.s1ask .preplnk:focus-visible,.s1ask .prepfold:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.s1ask .prepmsg{display:flex;flex-direction:column;gap:.35rem;border-top:1px solid var(--line);padding:.5rem .75rem}
.s1ask .prepmsg textarea{width:100%;resize:vertical}
.s1ask .prepmsgacts{display:flex;gap:.35rem;flex-wrap:wrap}
.s1tabs .prepbadge{display:inline-grid;place-items:center;min-width:1.1rem;height:1.1rem;margin-left:.3rem;padding:0 .25rem;border-radius:999px;
  background:var(--blue);color:var(--blue-ink);font-size:.72rem;font-weight:700;line-height:1}
.s1ask .preptray{display:flex;flex-direction:column;border-top:1px solid var(--line)}
.s1ask .preptray .arow .pill{align-self:start}
.s1ask .prepbundle{display:flex;flex-direction:column;border-top:1px solid var(--line)}
.s1ask .prepart{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:.1rem .55rem;align-items:start;padding:.5rem .1rem;border-bottom:1px solid var(--line)}
.s1ask .prepart:last-child{border-bottom:0}
.s1ask .prepart input[type="checkbox"]{margin-top:.2rem;width:16px;height:16px;accent-color:var(--blue)}
.s1ask .prepart label{font-size:inherit;font-weight:400;color:var(--ink);text-transform:none;letter-spacing:0;margin:0}
.s1ask .prepart label b{font-weight:700}
.s1ask .prepart .amt{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.s1ask .prepart .l2{grid-column:2 / -1;color:var(--muted);font-size:.8rem}
.s1ask .prepart .prepmsgtext{grid-column:2 / -1;font-size:.85rem;color:var(--ink);background:var(--bg);border:1px solid var(--line);border-radius:8px;padding:.35rem .5rem;white-space:pre-wrap}
/* SIA's day (0979): Home's own number chips and words, a row per line */
.s1ask .sday{display:flex;flex-direction:column;gap:.1rem}
.s1ask .sday .grp{margin-top:.55rem}
.s1ask .sdayrow{display:flex;align-items:center;gap:.5rem;width:100%;text-align:left;padding:.35rem .25rem;color:var(--ink)}
.s1ask .sdayrow .sdayw{flex:1;min-width:0}
.s1ask .sdayrow .sdaygo{margin-left:auto;color:var(--muted);flex:none}
.s1ask .sdayq{padding:.3rem .25rem;color:var(--ink)}
.s1ask .sdaymore{margin:.05rem 0 0 .3rem}
.s1ask .sdaygood{padding:.45rem .6rem;border-radius:8px;background:var(--ok-soft);color:var(--ink)}
.s1ask .sdaymk{flex:none;width:1.5rem;text-align:center;font-size:1.05rem;line-height:1.3}
/* WATCH (1029): a line — its count, its words, its money — and three presses */
.s1ask .wtchsub{margin:.15rem 0 .35rem}
.s1ask .wtchl{border-top:1px solid var(--line);padding:.55rem .25rem .6rem}
.s1ask .wtchtop{display:flex;align-items:flex-start;gap:.5rem}
.s1ask .wtchtop .hb-n{flex:none}
.s1ask .wtchtop .sdayw{flex:1;min-width:0}
.s1ask .wtchsubl{display:block;color:var(--muted);font-size:.82rem;margin-top:.1rem}
.s1ask .wtchamt{flex:none;font-weight:700;font-variant-numeric:tabular-nums;text-align:right}
.s1ask .wtchacts{display:flex;flex-wrap:wrap;gap:.4rem;margin:.4rem 0 0 2.9rem}
.s1ask .wtchlater{position:relative}
.s1ask .wtchmenu{position:absolute;top:100%;right:0;margin-top:.25rem;background:var(--card);border:1px solid var(--line);border-radius:10px;
  box-shadow:var(--shadow);padding:.25rem;z-index:3;min-width:11rem}
.s1ask .wtchmenu button{display:block;width:100%;text-align:left;background:none;border:0;font:inherit;font-size:.85rem;color:var(--ink);
  padding:.4rem .6rem;border-radius:7px;cursor:pointer}
.s1ask .wtchmenu button:hover{background:var(--blue-soft)}
.s1ask .wtchmenu button:focus-visible{outline:2px solid var(--blue);outline-offset:-2px;background:var(--blue-soft)}
.s1ask .wtchmenu button:disabled{opacity:.55;cursor:default}
.s1ask .wtchfoot{color:var(--muted);font-size:.8rem;margin-top:.5rem}
.s1ask .remset{display:flex;gap:.35rem;align-items:center}
.s1ask .pbtn{background:var(--blue);color:var(--blue-ink);border:0;border-radius:8px;padding:.4rem .8rem;font:inherit;font-weight:600;cursor:pointer}
.s1ask .fu{display:flex;flex-wrap:wrap;gap:.4rem}
.s1ask .chip{border:1px solid var(--line);border-radius:999px;padding:.25rem .7rem;background:var(--card);color:var(--ink);font:inherit;font-size:.82rem;cursor:pointer}
.s1ask .chip:hover{border-color:var(--blue);background:var(--blue-soft)}
.s1ask .err{border:1px solid var(--line);border-radius:12px;padding:.6rem .75rem;background:var(--bg)}
/* the panel cannot ask (no access, budget used, questions used up): the
   warning alert's own clothes, his word 11 Oct 2026 */
.s1ask .err.stop{background:var(--warn-soft);color:var(--warn);border-color:var(--warn)}
.s1ask .wait{display:flex;align-items:center;gap:.5rem;color:var(--muted)}
.s1ask .dots{display:inline-flex;gap:3px} .s1ask .dots i{width:5px;height:5px;border-radius:50%;background:var(--blue);opacity:.35;animation:s1askdot 1s infinite}
.s1ask .dots i:nth-child(2){animation-delay:.15s} .s1ask .dots i:nth-child(3){animation-delay:.3s}
@keyframes s1askdot{50%{opacity:1}}
@media (prefers-reduced-motion: reduce){ .s1ask .dots i{animation:none;opacity:.8} .s1ask .how svg{transition:none} }
.s1ask .af{padding:.6rem .75rem;border-top:1px solid var(--line)}
.s1ask .inp{display:flex;flex-wrap:wrap;align-items:flex-end;gap:.35rem .5rem;border:1.5px solid var(--line);border-radius:12px;padding:.5rem .35rem .35rem .75rem;background:var(--card)}
.s1ask .inp:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft)}
.s1ask .inp textarea{flex:1 0 100%;border:0 !important;outline:0;resize:none;min-height:24px;max-height:96px;padding:.2rem 0 !important;
  background:transparent;color:var(--ink);font:inherit;box-shadow:none !important;overflow-y:auto}
/* the box around the question carries the focus ring, keyboard or mouse;
   the question itself never draws a second one inside it */
html.s1-kbd .s1ask .inp textarea:focus{outline:none}
.s1ask .go{width:32px;height:32px;flex:none;border-radius:9px;border:0;background:var(--blue);color:var(--blue-ink);display:grid;place-items:center;cursor:pointer}
.s1ask .go:disabled{opacity:.45;cursor:default}
.s1ask .hint{display:flex;justify-content:space-between;gap:.5rem;margin-top:.4rem;font-size:.76rem;color:var(--muted)}
.s1ask kbd{font:inherit;border:1px solid var(--line);border-bottom-width:2px;border-radius:4px;padding:0 .25rem}
/* a role's Ask Shashvat window (Roles & Permissions): whether it may ask,
   then its people and what each gets */
.awstate{display:flex;gap:.5rem;align-items:flex-start;padding:.5rem .7rem;border:1px solid var(--line);border-radius:8px}
.awstate.yes{background:var(--ok-soft)} .awstate.yes b{color:var(--ok)}
.awstate.no{background:var(--panel)} .awstate.no b{color:var(--muted)}
.awpeople td{border-bottom:1px solid var(--line);padding:.3rem .35rem}
.awpeople .r{text-align:right;font-variant-numeric:tabular-nums}
/* the role's SIA window holds its suggested questions too (0997): wider,
   and like the Home cards window it never grows past the screen */
.modal.aww{width:min(760px,96vw);max-width:none;max-height:88vh;display:flex;flex-direction:column}
.aww .modal-h,.aww .modal-f{flex:none}
.aww .modal-b{flex:1 1 auto;min-height:0;overflow:auto}
.awtilehead{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:.35rem}
.awtilehead label{margin:0}
.awtiles{width:100%}
.awtiles td{vertical-align:top;border-bottom:1px solid var(--line);padding:.35rem .35rem}
.awtiles th.n,.awtiles td.n{width:1.6rem}
.awtiles td.n{padding-top:.6rem}
.awtiles th.tw{width:46%}
.awtiles input,.awtiles textarea{width:100%}
.awtiles input.tt{font-weight:700}
.awtiles input.ts{margin-top:.25rem}
.awtiles textarea{resize:none}
.awtwarn{color:var(--warn);margin-top:.15rem}
.awtilefoot{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;flex-wrap:wrap}
.awtilefoot .muted{flex:1 1 14rem;font-size:.78rem}
