/* Tokens from docs/design/staff-directory/README.md. The colour semantics do
     safety work — see "Colour Semantics" there before changing any of these. */
  :root {
    /* the two typefaces, named once (Haoming, 2026-10-08): Inter — the open face nearest
       Apple's San Francisco, which is not licensed for the web — for everything read;
       IBM Plex Mono kept for the labels, numbers and chips */
    --sans:"Inter", system-ui, -apple-system, sans-serif;
    --mono:"IBM Plex Mono", ui-monospace, monospace;
    --ink:#1c2026; --ink-2:#3b4350; --muted:#737a85; --absent:#9aa1ac;
    --border-absent:#c3c8cf; --divider:rgba(23,26,31,.09); --divider-light:rgba(23,26,31,.07);
    --surface:#fff; --subtle:#fafbfc; --sunken:#f2f3f5; --band:#f6f7f8; --chip:#eceef1;
    --page:#e6e8ec;   /* the ground behind every content page — a step darker than --sunken so the cards pop (Haoming, 2026-09-24) */
    --interactive:#14657a; --positive:#3fa66a;
    /* the Dashboard's chart (2026-10-27, the dataviz method, validated): the locum series' one
       accent, and the light step of the full-time gray (3.4:1 on the surface; the overtime step is --ink-2) */
    --viz-locum:#0f86a6; --viz-dim:#848b96;
    --nurse-day:#e35c93; --nurse-night:#e0a02a; --nc-blue:#4a7dd6;
    --hca-day:#2fa3bd; --hca-night:#3fa66a;
    /* directory card strips mean GENDER (2026-08-28). Blue and pink per
       Haoming, pushed DEEPER than nc-blue (#4a7dd6) and nurse-day pink
       (#e35c93) to keep the families tellable apart — and the card carries
       an M/F letter too, so colour is never the only signal. */
    --male:#1d4ed8; --female:#c9256d;
    /* the paint chart (2026-09-15): every colour outside :root refers to a
       name here, by MEANING — danger needs a person, warn is look-not-blocked,
       positive is fine, go is the advance teal. -soft is the card wash,
       -line its border, -ink the text on it, -strong the pressed shade.
       The four fill-* are Sister's Excel fills, the data, named once. */
    --white:#fff; --ground:#e9ebee;
    --ink-rgb:23,26,31; --white-rgb:255,255,255; --interactive-rgb:20,101,122;
    --interactive-strong:#0d4655;
    --danger:#b1512b; --danger-strong:#96421f; --danger-soft:#fdf6f2; --danger-line:#ecd3c6;
    --danger-ink:#6e1a15; --danger-tint:#f4a49f; --danger-tint-strong:#f09088;
    --warn:#d9a21b; --warn-soft:#fdf6e7; --warn-line:#efdcb0; --warn-ink:#6b5424;
    --mark:#fbe7a3;   /* the search-match highlighter — a step darker than warn-soft (Haoming, 2026-09-30) */
    --positive-soft:#eef6f1; --positive-line:#cfe3d6; --positive-ink:#1e6b3a;
    --go:#3d7f85; --go-strong:#2f6b71; --go-soft:#e9f3f3; --go-ink:#1f4d52;
    --choice-soft:#e4eefb; --choice-line:#bfd3f0; --choice-ink:#1e3f7a;   /* a chosen option in a segmented pair — pale blue (Haoming, 2026-10-08) */
    --today:#e5484d;   /* today's number on the person page's strip, a filled circle — Apple Calendar's red for today (Haoming, 2026-10-08) */
    --unfilled:#e4a6a7;   /* a critical field still empty on the person page's Details, filled so it shows at a glance (Haoming, 2026-10-27: his 228,166,167) */
    --holiday-soft:#dbe9f7; --holiday-ink:#1d4ed8;   /* a public holiday's date header (Haoming, 2026-09-30: a light blue cell, not a red number) */
    --fill-nurse-day:#ff99ff; --fill-nurse-night:#ffd966; --fill-hca-day:#66ffff; --fill-hca-night:#99ff99;
  }
  * { box-sizing:border-box; }
  body {
    margin:0; background:var(--ground); color:var(--ink);
    font:13px/1.45 var(--sans);
    padding:0;
  }
  /* the shell is the whole window and never scrolls itself — no trackpad
     bounce on the frame (Haoming, 2026-09-24); scrolling lives in the
     panes below */
  html, body { height:100%; overflow:hidden; overscroll-behavior:none; }
  .mono { font-family:var(--mono); }

  /* the app shell (CRM reference, 2026-08-20): sidebar + main, full height.
     Edge to edge since 2026-09-01 (Haoming) — no frame, no margin, the
     whole desktop screen is workspace. */
  /* Fixed frame, inner scroll (Haoming, 2026-08-20): the shell fills the
     window; the sidebar and breadcrumb stay put; only the content pane
     scrolls, in its own box. */
  .app { display:flex; background:var(--surface); overflow:hidden;
         height:100vh; }
  .side { flex:none; width:216px; background:var(--subtle);
          border-right:1px solid var(--divider); padding:16px 12px;
          display:flex; flex-direction:column; gap:14px; overflow-y:auto; }
  .side-brand { font-weight:600; font-size:14px; padding:0 8px;
               color:inherit; text-decoration:none; }  /* brand goes home */
.side-brand:hover { color:var(--interactive); }
  .side-brand .slash { color:var(--border-absent); }
  .side-nav { display:flex; flex-direction:column; gap:1px; }
  .sn { display:flex; align-items:center; gap:6px; padding:6px 8px; border-radius:6px;
        font-weight:600; font-size:12.5px; color:var(--muted); text-decoration:none; }
  .sn:hover { background:var(--sunken); color:var(--ink); }
  .sn.active { background:var(--ink); color:var(--white); }
  .sn .tab-badge { margin-left:auto; }
  .side-top { display:flex; align-items:center; justify-content:space-between;
              padding-right:2px; }
  .side-collapse, .side-expand { border:1px solid var(--divider); background:var(--surface);
        color:var(--muted); border-radius:6px; width:24px; height:24px; cursor:pointer;
        font:600 13px var(--sans); line-height:1; }
  .side-collapse:hover, .side-expand:hover { color:var(--interactive);
        border-color:var(--interactive); }
  .side-expand { display:none; }
  .app.side-hidden .side { display:none; }
  .app.side-hidden .side-expand { display:inline-flex; align-items:center;
        justify-content:center; }
  .sn-div { border:0; border-top:1px solid var(--divider); margin:8px 0; }
  /* accordion groups (sidebar reference, 2026-08-20) */
  .sn-sec summary { list-style:none; cursor:pointer; display:flex; align-items:center;
        padding:7px 8px; border-radius:6px; font-weight:600; font-size:13px;
        color:var(--ink); user-select:none; }
  .sn-sec summary::-webkit-details-marker { display:none; }
  .sn-sec summary::after { content:"›"; margin-left:auto; color:var(--absent);
        transition:transform .12s ease; }
  .sn-sec[open] summary::after { transform:rotate(90deg); }
  .sn-sec summary:hover { background:var(--sunken); }
  .sn-sec .sn { padding-left:22px; font-weight:500; }
  .main { flex:1; min-width:0; display:flex; flex-direction:column;
          overflow:hidden; }
  .page-scroll { flex:1; overflow-y:auto; display:flex; flex-direction:column; }
  .page-scroll > .results, .page-scroll > .person-body { flex:1 0 auto; }
  .topbar { display:flex; align-items:center; gap:10px; padding:11px 20px;
            border-bottom:1px solid var(--divider); }
  .topbar .crumb { font-size:12.5px; color:var(--muted); }
  .topbar .crumb a { color:var(--muted); text-decoration:none; }
  .topbar .crumb a:hover { color:var(--interactive); }
  .crumb-sep { color:var(--border-absent); margin:0 4px; }
  /* summary band */
  .band { display:flex; flex-wrap:wrap; gap:8px; align-items:center;
          padding:11px 20px; background:var(--band); border-bottom:1px solid var(--divider-light); }
  .lead { font:600 11px var(--mono); letter-spacing:.06em;
          text-transform:uppercase; color:var(--muted); margin-right:4px; }
  .pill { background:var(--white); border:1px solid rgba(var(--ink-rgb),.12); border-radius:20px;
          padding:5px 10px; font-size:11.5px; color:var(--ink-2); text-decoration:none; }
  .pill b { font-weight:600; color:var(--ink); }
  .pill.toggle { color:var(--interactive); }

  /* results */
  .results { background:var(--page); padding:16px 20px 22px; }
  .grid { display:grid; grid-template-columns:repeat(4, 1fr); gap:12px; }
  @media (max-width:1100px) { .grid { grid-template-columns:repeat(2, 1fr); } }
  /* Motion (Haoming, 2026-09-17), every timing named once: the cascade is
     the welcome on a real page load, on the cards on screen only; a search
     or filter answer is patched in by the script in directory.html (moves,
     fades — its timings sit there); a slow answer dims the grid after 300ms
     (htmx-request), a fast one shows nothing. Soft and short, never bouncy. */
  .grid { --card-in:260ms; --cascade-step:50ms; --dim-after:300ms; --ease:cubic-bezier(.2,0,0,1);
          position:relative;                          /* a leaving card fades where it stood */
          transition:opacity 120ms ease; }
  .grid.first .card { opacity:0; }                 /* until the script has counted the cards on screen */
  .grid.first.ready .card { opacity:1; }
  .grid.first.ready .card.in { animation:card-in var(--card-in) var(--ease) backwards;
                               animation-delay:calc(var(--i, 0) * var(--cascade-step)); }
  @keyframes card-in { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:none; } }
  .grid.htmx-request { opacity:.55; transition-delay:var(--dim-after); }
  @media (prefers-reduced-motion: reduce) {
    .grid.first .card, .grid.first.ready .card.in { opacity:1; animation:none; }
    .grid.htmx-request { transition:none; }
  }

  /* top command bar (mock 1b, 2026-08-28) — no panel: the dropdown buttons
     carry their own state and the grid gets the rail's width back. Inside
     the fixed frame the bar stays put; only the cards scroll. */
  .page-scroll > #directory-view { flex:1 1 0; min-height:0;
          display:flex; flex-direction:column; }
  #directory-view > .results { flex:1 1 0; min-height:0; overflow-y:auto; }
  .cmdbar { background:var(--surface); border-bottom:1px solid var(--divider);
            padding:12px 18px 10px; }
  .cmd-top { display:flex; align-items:center; gap:12px; }
  .cmd-top .lead { white-space:nowrap; }
  /* the search sits flush beside the count and runs long, like the mock —
     the spotlight glyph lives inside the field. Doubled selectors outrank
     the base .search rules (margin-left:auto, width:250px) further down. */
  .cmd-search.cmd-search { flex:1 1 auto; position:relative; margin-left:0; }
  .cmd-search-ico { position:absolute; left:11px; top:50%; transform:translateY(-50%);
                    color:var(--muted); display:inline-flex; pointer-events:none; }
  .cmd-search.cmd-search input { width:100%; padding-left:32px; }
  .cmd-filters { display:flex; align-items:center; gap:8px; flex-wrap:wrap;
                 margin-top:10px; }
  .cmd-gap { flex:0 0 10px; }
  .cmd-clear { margin-left:auto; font-size:12px; color:var(--muted); text-decoration:none;
               padding:6px 4px; }
  .cmd-clear:hover { color:var(--interactive); text-decoration:underline; }
  details.dd { position:relative; }
  details.dd > summary { list-style:none; cursor:pointer; user-select:none;
          display:inline-flex; align-items:center; gap:6px;
          border:1px solid rgba(var(--ink-rgb),.16); border-radius:20px;
          background:var(--surface); padding:6px 12px;
          font:600 11.5px var(--sans); color:var(--ink); }
  details.dd > summary::-webkit-details-marker { display:none; }
  details.dd > summary:hover { border-color:var(--interactive); }
  .dd-state { font-weight:500; color:var(--muted); }
  .dd-caret { color:var(--muted); font-size:9px; }
  /* set = dark fill: the button label IS the filter state */
  details.dd > summary.set { background:var(--ink); border-color:var(--ink);
          color:var(--white); }
  details.dd > summary.set .dd-state,
  details.dd > summary.set .dd-caret { color:rgba(var(--white-rgb),.75); }
  .dd-pop { position:absolute; top:calc(100% + 6px); left:0; z-index:40;
            min-width:232px; max-width:calc(100vw - 24px);
            background:var(--surface); border:1px solid var(--divider);
            border-radius:10px; padding:6px; box-shadow:0 10px 28px rgba(var(--ink-rgb),.16); }
  /* the right-most menus open leftward so no popover can leave the screen */
  .cmd-filters details.dd:nth-last-of-type(-n+2) .dd-pop { left:auto; right:0; }
  .dd-head { display:flex; justify-content:space-between; align-items:baseline;
             padding:4px 8px 6px; font:600 10px var(--mono);
             letter-spacing:.08em; text-transform:uppercase; color:var(--absent); }
  .dd-head a { color:var(--interactive); text-decoration:none; text-transform:none;
               letter-spacing:0; font:500 11px var(--sans); }
  .dd-row { display:flex; align-items:center; border-radius:6px; }
  .dd-row:hover { background:var(--sunken); }
  .dd-main { flex:1; min-width:0; display:flex; align-items:center; gap:8px;
             padding:6px 8px; text-decoration:none; color:var(--ink); font-size:12.5px; }
  .dd-text { flex:1; min-width:0; }
  .dd-count { color:var(--absent); font:500 11px var(--mono); }
  /* hover OR keyboard focus reveals "only" — replaces the whole selection
     with that value. opacity (not visibility) keeps it in the tab order. */
  .dd-only { opacity:0; padding:6px 10px; font-size:11px; font-style:italic;
             color:var(--interactive); text-decoration:none; }
  .dd-row:hover .dd-only, .dd-row:focus-within .dd-only,
  .dd-only:focus { opacity:1; }
  /* EN stays visually distinct even in a menu row — may not give medicine */
  .dd-text.en { flex:none; border:1.5px solid var(--ink); border-radius:4px;
                padding:0 5px; }
  .dd-text.dashed { flex:none; border:1.5px dashed var(--muted); border-radius:4px;
                    padding:0 5px; }
  .dd-note { margin:2px 8px 4px; font-size:11px; color:var(--muted); }
  .cb { flex:none; width:13px; height:13px; border:1.5px solid var(--border-absent); border-radius:3px;
        background:var(--white); display:inline-flex; align-items:center; justify-content:center; }
  .cb.on { background:var(--ink); border-color:var(--ink); }
  .cb.on::after { content:"✓"; color:var(--white); font-size:9px; line-height:1; }
  .rail-count { color:var(--absent); font:500 11px var(--mono); }
  .filter-chips { display:flex; flex-wrap:wrap; gap:5px; }
  .fchip { text-decoration:none; color:var(--ink); background:var(--white);
           border:1px solid rgba(var(--ink-rgb),.12); border-radius:5px; padding:4px 8px;
           font:600 10.5px var(--mono); }
  .fchip:hover { border-color:var(--interactive); }
  .fchip.dashed { border:1.5px dashed var(--muted); }
  .fchip.on { background:var(--ink); color:var(--white); border-color:var(--ink); }
  .fchip.on::before { content:"✓ "; }
  .fchip.on .rail-count { color:rgba(var(--white-rgb),.7); }
  .rm-chip { text-decoration:none; color:var(--ink); background:var(--white);
             font:inherit; cursor:pointer; margin:1px 2px;
             border:1px solid rgba(var(--ink-rgb),.12); border-radius:20px;
             padding:5px 10px; font-size:12px; }
  .rm-chip .rm-x { color:var(--absent); margin-left:2px; }
  /* interactive teal, not terracotta — the attention colour stays rationed
     for expiry/danger (S3 #7, UI review) */
  .rm-chip:hover { border-color:var(--interactive); }
  .rm-chip:hover .rm-x { color:var(--interactive); }
  @media (max-width:900px) {
    .cmd-top { flex-wrap:wrap; }
  }

  /* compact 1a ledger card */
  .card { background:var(--surface); border:1px solid var(--divider); border-radius:9px;
          overflow:hidden; box-shadow:0 1px 2px rgba(var(--ink-rgb),.05);
          transition:transform .13s ease, box-shadow .13s ease; }
  /* Non-active (agency bank): a faint diagonal hatch over the whole card, so
     active vs bench reads at a glance. Informational, never punitive — the
     stripes stay at ~3% ink and everything beneath remains legible. */
  .card.inactive { position:relative; }
  .card.inactive::after { content:""; position:absolute; inset:0; pointer-events:none;
          background:repeating-linear-gradient(135deg,
                     transparent 0 9px, rgba(var(--ink-rgb),.045) 9px 12px); }
  .card.inactive .card-body { opacity:.85; }
  .strip { height:8px; }
  /* gender not recorded — the house absence treatment (grey + dotted), so
     the unknown state survives greyscale instead of reading as "no strip" */
  .strip.na { background:var(--subtle); border-bottom:1px dotted var(--border-absent); }
  .card-body { padding:12px 13px; }
  .head { display:flex; gap:10px; align-items:flex-start; }
  .tile { flex:none; width:40px; text-align:center; padding:6px 0; border-radius:6px;
          font:600 11.5px var(--mono); background:var(--ink); color:var(--white); }
  .tile.hollow { background:var(--white); color:var(--ink); border:2px solid var(--ink); padding:4px 0; }
  .tile.hca { background:var(--ink-2); }
  .who { min-width:0; }
  .name { font-weight:600; font-size:14px; letter-spacing:-.01em; line-height:1.25;
          overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .meta { font:500 11px var(--mono); color:var(--muted); margin-top:2px;
          overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .locum-chip { display:inline-block; border:1.5px dashed var(--muted); border-radius:4px;
                font:600 9.5px var(--mono); letter-spacing:.06em;
                padding:1px 4px; margin-left:5px; vertical-align:1px; color:var(--muted); }
  /* Status chip for Non-Active staff — the hatch's text twin (S2 #5). Solid
     grey border vs the locum chip's dashed one: status, not employment. */
  .status-chip { display:inline-block; border:1px solid var(--divider); border-radius:4px;
                 font:600 9.5px var(--mono); letter-spacing:.06em;
                 padding:1px 4px; color:var(--muted); background:var(--band); }
  .status-chip.new { color:var(--positive); border-color:var(--positive-line); background:var(--positive-soft); }

  .badges { display:flex; flex-wrap:wrap; gap:5px; margin-top:10px; }
  .badge { font:600 9.5px var(--mono); letter-spacing:.04em;
           padding:3px 6px; border-radius:4px; background:var(--ink); color:var(--white); }
  .absent-note { color:var(--absent); border-bottom:1px dotted var(--border-absent);
                 font-size:11.5px; }

  .facts { margin-top:10px; padding-top:9px; border-top:1px solid var(--divider);
           font-size:11.5px; color:var(--ink-2); }
  .facts .label { color:var(--muted); }
  .oos { font-style:italic; color:var(--muted); }      /* out of scope ≠ missing */


.tab-badge { font:600 10px var(--mono); background:var(--chip);
             color:var(--ink-2); border-radius:3px; padding:1px 5px; margin-left:3px; }

/* gaps — piles */
.gaps-tone { color:var(--muted); font-size:11.5px; }
.piles { display:grid; grid-template-columns:repeat(auto-fill, minmax(230px, 1fr));
         gap:10px; margin-bottom:16px; }
.pile { display:block; background:var(--surface); border:1px solid var(--divider);
        border-radius:9px; padding:12px 14px; text-decoration:none; color:var(--ink);
        box-shadow:0 1px 2px rgba(var(--ink-rgb),.05); }
.pile:hover { border-color:var(--interactive); }
.pile.selected { border:1.5px solid var(--ink); }
.pile.attention { border-color:var(--danger-line); background:var(--danger-soft); }
.pile.attention .pile-count { color:var(--danger); }
.pile-count { display:block; font:600 22px var(--mono); letter-spacing:-.02em; }
.pile-label { display:block; font-weight:600; font-size:12.5px; margin-top:2px; }
.pile-hint { display:block; color:var(--muted); font-size:11px; margin-top:3px; line-height:1.4; }
.all-clear { color:var(--positive); font-weight:600; }

/* gaps — coverage sheet */
.sheet { background:var(--surface); border:1px solid var(--divider); border-radius:9px;
         padding:4px 14px 10px; overflow-x:auto; }
.sheet table { width:100%; border-collapse:collapse; font-size:12px; }
.sheet th { text-align:left; font:600 10.5px var(--mono);
            letter-spacing:.05em; text-transform:uppercase; color:var(--muted);
            border-bottom:2px solid var(--ink); padding:9px 10px 6px; }
.sheet td { padding:8px 10px; border-bottom:1px solid var(--divider-light); }
.person-col { min-width:220px; }
.person-name { font-weight:600; font-size:12.5px; }
.mini-tile { display:inline-block; min-width:30px; text-align:center; padding:2px 4px;
             border-radius:4px; font:600 9.5px var(--mono);
             background:var(--ink); color:var(--white); margin-right:7px; }
.mini-tile.hollow { background:var(--white); color:var(--ink); border:1.5px solid var(--ink); }
.mini-tile.hca { background:var(--ink-2); }
.ok { color:var(--positive); font-weight:600; }
.dash { color:var(--border-absent); }
.expired-chip { font:600 10px var(--mono); background:var(--danger-soft);
                color:var(--danger); border-radius:4px; padding:2px 6px; }
.sheet-legend { color:var(--muted); font-size:11px; margin:10px 0 2px; }

/* search */
.search { margin-left:auto; }
.search input {
  width:250px; background:var(--subtle); border:1px solid rgba(var(--ink-rgb),.14);
  border-radius:7px; padding:7px 11px; font:inherit; font-size:12px; color:var(--ink);
}
.search input::placeholder { color:var(--absent); }
.search input:focus { outline:none; border-color:var(--interactive);
                      box-shadow:0 0 0 3px rgba(var(--interactive-rgb),.10); }

/* gaps — find-in-list */
.sheet-search { display:flex; align-items:center; gap:8px; margin-bottom:10px; }
.sheet-search input {
  width:300px; background:var(--surface); border:1px solid rgba(var(--ink-rgb),.14);
  border-radius:7px; padding:7px 11px; font:inherit; font-size:12px; color:var(--ink);
}
.sheet-search input::placeholder { color:var(--absent); }
.sheet-search input:focus { outline:none; border-color:var(--interactive);
                            box-shadow:0 0 0 3px rgba(var(--interactive-rgb),.10); }

/* person detail */
.person-header { padding:20px 24px 18px; color:var(--white); }
.person-header .crumb { font:500 10.5px var(--mono); letter-spacing:.08em;
         color:rgba(var(--white-rgb),.9); }
.person-header .crumb a { color:inherit; text-decoration:none; }
.person-header .crumb a:hover { text-decoration:underline; }
.person-title { margin:4px 0 0; font:600 30px/1.1 var(--sans);
                letter-spacing:-.02em; text-shadow:0 1px 3px rgba(var(--ink-rgb),.2); }
.chips { display:flex; flex-wrap:wrap; gap:10px; margin-top:12px; }
.chip { font:600 11px var(--mono); border-radius:5px; padding:4px 9px; }
.chip.dark { background:rgba(var(--ink-rgb),.82); color:var(--white); }
.chip.light { background:rgba(var(--white-rgb),.9); color:var(--ink); }
/* the Requests tab (2026-09-22): a month filter and the kind of each request */
.chip.on { background:var(--ink); color:var(--white); }
.chip.code-R { background:var(--ground); color:var(--ink); }
.chip.code-AL { background:var(--positive-soft); color:var(--positive-ink); }
.chip.code-CT { background:var(--warn-soft); color:var(--warn-ink); }

.person-body { display:grid; grid-template-columns:1fr 1fr 1fr; align-items:start; }
.person-body .col { padding:20px 22px; border-right:1px solid var(--divider); }
.person-body .col:last-child { border-right:0; }
@media (max-width:1000px) { .person-body { grid-template-columns:1fr; }
  .person-body .col { border-right:0; border-bottom:1px solid var(--divider); } }

/* The person page (redesigned 2026-10-08 from Haoming's mocks): three
   hanging folders in a drawer. The open folder is in front, its tab joined
   to its body (the panel); the others sit behind it, each a step higher,
   so their tabs and a sliver of their top edge show above the front one —
   the edge is a line the tab draws along the top, clipped at the drawer's
   right. Pull a tab and that folder comes forward while the rest drop
   back (a short slide: motion that preserves place). Ink for the open
   folder, the chip grey for the ones behind, never a hue — gaps are
   neutral — and no library. */
.person-page { padding:12px 20px 24px; background:var(--page); }   /* the drawer sits a touch closer under the header (Haoming, 2026-10-08) */
.ptabs { display:flex; align-items:flex-end; position:relative; padding:34px 0 0 6px; }
/* nothing clips the drawer: a landing folder overshoots a little on the spring,
   and a clipped tab would part from its body for that beat (Haoming's catch) */
/* no z-index on the drawer itself: tabs, edges and the panel share one
   stacking order, back to front — edge 2, tab 2, edge 1, tab 1, the panel
   (the open folder's body), the open tab */
.ptab { position:relative; display:inline-flex; align-items:center; gap:8px; padding:9px 18px 11px;
        margin-right:-10px; border-radius:11px 11px 0 0; background:var(--chip); color:var(--ink-2);
        font-weight:600; font-size:13px; text-decoration:none; border:1px solid var(--border-absent); border-bottom:0;
        --lift:0px; transform:translateY(var(--lift)); transition:transform var(--tab-move), background var(--tab-move);
        --tab-move:200ms cubic-bezier(.4,0,.2,1); }
/* the folders' top edges belong to the drawer, one per depth (never to a
   tab: a tab in flight carries nothing, and lands on the panel's own edge);
   rounded ends, stopping short of the drawer's corner */
.fedge { position:absolute; left:14px; bottom:-4px; border:3px solid var(--divider); border-left:0; border-bottom:0;
         border-radius:0 12px 0 0; background:var(--page); }   /* a top edge that turns down at the right; the
         body is filled with the drawer's ground, so the folder behind it is hidden where this one stands */
.fedge[data-depth="1"] { right:14px; height:13px; border-color:var(--border-absent); z-index:2; }
.fedge[data-depth="2"] { right:22px; height:20px; border-color:var(--divider); z-index:0; }
.ptab .n { font:600 10.5px var(--mono); letter-spacing:.06em; color:var(--muted); }
.ptab[data-depth="1"] { --lift:-7px; z-index:3; background:var(--chip); }
.ptab[data-depth="2"] { --lift:-14px; z-index:1; background:var(--sunken); }
.ptab.on { --lift:0px; z-index:5; background:var(--ink); color:var(--white); border-color:var(--ink); padding-top:11px; }
.ptab.on .n { color:rgba(var(--white-rgb),.65); }
.ptab .tab-badge { margin-left:4px; }
.ptab.on .tab-badge { background:rgba(var(--white-rgb),.18); color:var(--white); }
.ptab:hover:not(.on) { color:var(--ink); }
/* Pulling a folder (Haoming, 2026-10-08): the chosen folder — its tab AND
   its body, the panel, joined throughout (his catch: a tab in the air with
   nothing under it) — lifts clear of the stack from where it sat (--from,
   set by the script on both), hangs a beat, and drops into the front slot
   on the soft spring; the old front tab sinks back on the plain transition. */
.ptab.lift, .ppanel.slot { animation:folder-lift var(--lift-time) var(--lift-ease) both; --lift-time:460ms;
             --lift-ease:cubic-bezier(.34,1.3,.64,1); --lift-high:-26px; }
@keyframes folder-lift {
  0%   { transform:translateY(var(--from, 0px)); }
  40%  { transform:translateY(var(--lift-high)); }
  100% { transform:translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .ptab { transition:none; } .ptab.lift, .ppanel.slot { animation:none; } }
.ppanel { position:relative; z-index:4; background:var(--surface); border:1px solid var(--border-absent); border-top:3px solid var(--ink);
          border-radius:0 12px 12px 12px; padding:18px 20px; box-shadow:0 2px 8px rgba(var(--ink-rgb),.06); }
.stat-row { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:12px; margin-bottom:14px; }
.stat { background:var(--sunken); border-radius:10px; padding:14px 16px; display:flex; flex-direction:column; gap:3px; }
.stat-k { color:var(--muted); font-size:12px; }
.stat-v { font-size:26px; font-weight:700; line-height:1.15; color:var(--ink); }
.stat-s { color:var(--muted); font-size:11.5px; }
.ov-grid { display:grid; grid-template-columns:minmax(0, 2fr) minmax(260px, 1fr); gap:14px; align-items:start; }
.pcards { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:14px; align-items:start; }
.pcard { background:var(--sunken); border-radius:10px; padding:14px 16px; }
.ov-main .pcard + .pcard, .ov-side .pcard + .pcard { margin-top:14px; }
.pcard h3 { margin:0 0 10px; font-size:13.5px; font-weight:700; color:var(--ink); }
.pcard-head { display:flex; justify-content:space-between; align-items:baseline; gap:10px; }
.pcard .sub-head { margin:14px 0 4px; font:600 11px var(--mono); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.pcard .field { background:var(--surface); }
/* the month strip as the mock draws it (2026-10-08): the weekday letter, a
   pill a day in the Excel fills — an OIC day ringed in ink, today dashed —
   and the number below, bold on a working day; an HCA's strip reads the HCA
   fills through the same names. (.strip is the card's gender bar.) */
.dstrip { display:flex; flex-wrap:wrap; gap:4px; --am:var(--fill-nurse-day); --pm:var(--fill-nurse-night); }
.dstrip.hca, .legend.hca, .code.hca { --am:var(--fill-hca-day); --pm:var(--fill-hca-night); }
.dcol { display:flex; flex-direction:column; align-items:center; gap:4px; width:22px; }
/* today is the number in a filled red circle, white digit — Apple Calendar's
   own mark (Haoming, 2026-10-08; the mock's dashed pill confused people, and a
   dashed pill is a rest day here) */
.dcol .dn { width:18px; height:18px; display:grid; place-items:center; border-radius:50%; }
.dcol.now .dn, .dcol.now.work .dn { background:var(--today); color:var(--white); }   /* white on red, whatever the day */
.dcol .wd { font:600 10px var(--mono); font-style:normal; color:var(--muted); }
.dcol .dn { font:600 11px var(--mono); color:var(--muted); }
.dcol.work .dn { color:var(--ink); }
.dp { width:20px; height:40px; border-radius:7px; background:var(--chip); display:flex; align-items:center; justify-content:center; }
.dp i { font:600 7.5px var(--mono); font-style:normal; color:var(--ink-2); max-width:18px; overflow:hidden; }
.dp.am { background:var(--am); }
.dp.pm { background:var(--pm); }
.dp.both { background:linear-gradient(to bottom, var(--am) 50%, var(--pm) 50%); }
.dp.absent { background:linear-gradient(to bottom, var(--am) 50%, var(--pm) 50%); opacity:.45; }
.dp.clinic { background:var(--go-soft); }
.dp.leave { background:var(--positive-soft); }
.dp.r { background:var(--surface); border:1.5px dashed var(--border-absent); }
.dp.gone { background:repeating-linear-gradient(135deg, var(--chip) 0 4px, var(--surface) 4px 8px); }
.dp.oic { box-shadow:inset 0 0 0 2px var(--ink); }
.coming-head { margin:16px 0 0; padding-bottom:8px; border-bottom:1px solid var(--divider); font-size:12.5px; font-weight:700; color:var(--ink); }
.legend { font-size:11px; color:var(--muted); display:inline-flex; align-items:center; gap:6px;
          --am:var(--fill-nurse-day); --pm:var(--fill-nurse-night); }
.legend .lg { display:inline-block; width:10px; height:10px; border-radius:3px; margin-left:6px; }
.legend .lg.am { background:var(--am); } .legend .lg.pm { background:var(--pm); }
.legend .lg.oic { background:var(--surface); box-shadow:inset 0 0 0 2px var(--ink); }
.coming .row { display:flex; align-items:center; gap:14px; padding:7px 0; border-bottom:1px solid var(--divider); font-size:12.5px; }
.coming .row:last-child { border-bottom:0; }
.coming .when { font-weight:600; min-width:7.5em; }
.coming .code { font:600 10.5px var(--mono); border-radius:5px; padding:3px 8px; color:var(--ink);
                --am:var(--fill-nurse-day); --pm:var(--fill-nurse-night); background:var(--chip); }
.coming .code.am { background:var(--am); } .coming .code.pm { background:var(--pm); }
.coming .code.24h { background:linear-gradient(to bottom, var(--am) 50%, var(--pm) 50%); }
.coming .code.clinic { background:var(--go-soft); color:var(--go-ink); }
.coming .note { color:var(--muted); }
.facts-grid { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:10px 16px; }
.fact { display:flex; flex-direction:column; gap:2px; font-size:12.5px; }
.fact .k { color:var(--muted); } .fact .v { font-weight:600; color:var(--ink); }
.attn .arow { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; padding:9px 0; border-bottom:1px solid var(--divider); }
.attn .arow:last-child { border-bottom:0; }
/* a gap to fix wears the light red wash (Haoming, 2026-10-08, from the mock);
   the two fact rows — leaving, not rostered — stay plain: red means fix */
.attn .arow.gap { background:var(--danger-soft); border:1px solid var(--danger-line); border-radius:9px;
                  padding:10px 12px; margin-bottom:8px; }
.attn .arow.gap .alabel { color:var(--danger-ink); }
.attn .arow.gap .btn { background:var(--danger-ink); border-color:var(--danger-ink); color:var(--white); }
.attn .alabel { display:block; font-weight:600; font-size:12.5px; }
.attn .ahint { display:block; color:var(--muted); font-size:11px; line-height:1.4; margin-top:2px; }
.attn .btn { flex:none; }
.f-value.oos { font-weight:400; color:var(--muted); }
/* History: month headings, a row per line — when, what, who */
.hseg { width:min(100%, 22rem); }
.hseg label { padding:5px 8px; font-size:12px; }
.hist { margin-top:4px; }
.hist [hidden] { display:none !important; }   /* the rows' grid would otherwise beat hidden */
.hmonth { margin:12px 0 2px; font:600 10.5px var(--mono); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.hrow { display:grid; grid-template-columns:5em minmax(0, 1fr) auto; gap:12px; padding:8px 0; border-bottom:1px solid var(--divider); font-size:12.5px; align-items:baseline; }
.hrow:last-of-type { border-bottom:0; }
.hwhen { color:var(--muted); font:500 11px var(--mono); }
.htext { color:var(--ink); }
.hwho { color:var(--muted); font-size:11.5px; white-space:nowrap; }
.hwho.them { color:var(--ink-2); font-weight:600; }
@media (max-width:1000px) {
  .stat-row, .ov-grid, .pcards, .facts-grid { grid-template-columns:1fr; }
}

.col-head { font:600 11px var(--mono); letter-spacing:.06em;
            text-transform:uppercase; color:var(--muted); margin:0 0 10px; }
.col-hint { color:var(--muted); font-size:11.5px; line-height:1.5; }
.field { display:flex; justify-content:space-between; gap:12px; padding:9px 10px;
         border-radius:6px; background:var(--subtle); margin-bottom:2px; }
.field.unfilled { background:var(--unfilled); }   /* one of the person's own Gaps piles, until it is filled */
.field.unfilled .f-label, .field.unfilled .absent-note { color:var(--white); }   /* white on the fill (Haoming, 2026-10-27) */
.f-label { color:var(--muted); font-size:12.5px; }
.f-value { font-weight:600; font-size:12.5px; text-align:right; }
.dot { display:inline-block; width:7px; height:7px; border-radius:50%;
       background:var(--border-absent); margin-right:2px; }
.dot.on { background:var(--positive); }

.cap-grid { display:grid; grid-template-columns:1fr 1fr; gap:6px; }
.cap-pill { padding:9px 11px; border-radius:7px; font-weight:600; font-size:11.5px;
            display:flex; justify-content:space-between; }
.cap-pill.held { background:var(--ink); color:var(--white); }
.cap-pill .tick { opacity:.55; }
/* clickable variant — every vocabulary tag, hollow until held */
button.cap-pill { font-family:inherit; text-align:left; cursor:pointer;
                  background:var(--white); border:1px solid var(--divider); color:var(--muted); }
button.cap-pill:hover { border-color:var(--interactive); color:var(--ink); }
button.cap-pill.held { background:var(--ink); color:var(--white); border-color:var(--ink); }


.todo { display:block; border:1px solid var(--divider); border-radius:9px;
        padding:11px 13px; margin-bottom:8px; text-decoration:none; color:var(--ink);
        background:var(--surface); }
.todo:hover { border-color:var(--interactive); }
.todo.attention { background:var(--danger-soft); border-color:var(--danger-line); }
.todo-label { display:block; font-weight:600; font-size:12.5px; }
.todo-hint { display:block; color:var(--muted); font-size:11px; margin-top:2px; line-height:1.4; }

/* clickable cards / rows */
a.card-link { text-decoration:none; color:inherit; display:block; min-width:0; }
/* A grid cell will not shrink below its content unless min-width says so —
   without this, one long name pushes the whole row past the screen edge. */
.grid > * { min-width:0; }
.person-col a { color:inherit; text-decoration:none; }
.person-col a:hover .person-name { color:var(--interactive); }
/* The lift belongs to cards you can OPEN (directory/archive links) — a plain
   info card or a dashboard placeholder must not advertise interactivity
   (S2 #5, UI review 2026-08-20: teal is for things you can act on). */
a.card-link .card:hover { border-color:var(--interactive); transform:translateY(-3px);
              box-shadow:0 6px 16px rgba(var(--ink-rgb),.10); }
@media (prefers-reduced-motion: reduce) {
  .card, a.card-link .card:hover { transition:none; transform:none; }
}

/* import flow */
.upload-box { background:var(--surface); border:1px dashed var(--border-absent);
              border-radius:9px; padding:18px; }
.upload-box input[type=file] { font-size:12.5px; margin-right:10px; }
.btn { background:var(--interactive); color:var(--white); border:0; border-radius:7px;
       padding:8px 14px; font:600 12.5px var(--sans); cursor:pointer; }
.btn:hover { background:var(--interactive-strong); }
.btn:disabled { background:var(--chip); color:var(--muted); cursor:default; }
.warn-box { background:var(--danger-soft); border:1px solid var(--danger-line); border-radius:9px;
            padding:12px 14px; font-size:12.5px; margin-bottom:14px; }
.warn-box ul { margin:6px 0 6px 18px; padding:0; }
.warn-box a { color:var(--interactive); }
.attention-pill { border-color:var(--danger-line); background:var(--danger-soft); color:var(--danger); }
.confirm-row { display:flex; align-items:center; gap:10px; margin-top:18px; }

/* edit-in-place */
.f-value.editable { cursor:pointer; border-bottom:1px dashed transparent; }
.f-value.editable:hover { color:var(--interactive); border-bottom-color:var(--interactive); }
.field.editing { background:var(--white); border:1.5px solid var(--interactive);
                 box-shadow:0 0 0 3px rgba(var(--interactive-rgb),.10); }
.field.editing form { display:flex; align-items:center; gap:6px; }
.field.editing input, .field.editing select {
  font:600 12.5px var(--sans); border:1px solid var(--divider);
  border-radius:4px; padding:3px 6px; background:var(--white); color:var(--ink); }
/* a refused value stays ringed red until it is retyped (2026-10-14; the sign-in field's "no") */
.field.editing input.refused, .add-form input.refused { border-color:var(--danger); box-shadow:0 0 0 3px var(--danger-soft); }
.btn-small { padding:4px 9px; font-size:11px; }
.cancel-link { color:var(--muted); font-size:11px; cursor:pointer; }
.cancel-link:hover { color:var(--interactive); }
/* page-drawn type-ahead (R days person field) — per the reference design:
   a search field with a magnifier, a tall names-only card beneath, roomy
   rows, full-width hover band, thin visible scrollbar. */
.suggest-wrap { position:relative; display:block; }
/* doubled-up selector so the left padding for the magnifier outranks the
   generic .add-form input padding — they tied once and the icon sat on the
   text (Haoming, 2026-08-14) */
.suggest-wrap input, .add-form .suggest-wrap input, .offer-add .suggest-wrap input[type=text] {
  width:100%; box-sizing:border-box; padding:7px 9px 7px 34px;
  border-radius:9px; }   /* the inbox door's box joined the list (2026-09-21): same tie, same fix */
.suggest-wrap::before { content:""; position:absolute; left:11px; top:11px;
    width:15px; height:15px; pointer-events:none; opacity:.45;
    background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23171a1f" stroke-width="2.4" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.2" y2="16.2"/></svg>') no-repeat center / contain; }
.suggest-list { position:absolute; top:calc(100% + 6px); left:0; right:0; z-index:20;
                background:var(--surface); border:1px solid var(--divider);
                border-radius:12px; box-shadow:0 12px 36px rgba(var(--ink-rgb),.16);
                max-height:21rem; overflow-y:auto; }
.suggest-item { display:block; width:100%; text-align:left; padding:12px 18px;
                border:0; background:transparent; cursor:pointer;
                font:500 14px var(--sans); color:var(--ink); }
.suggest-item:hover, .suggest-item:focus-visible { background:var(--sunken); outline:none; }
.suggest-list::-webkit-scrollbar { width:6px; }
.suggest-list::-webkit-scrollbar-thumb { background:var(--border-absent); border-radius:3px; }
.suggest-list::-webkit-scrollbar-track { background:transparent; }

/* search-match highlight — soft, keeps the ink colour */
mark { background:var(--mark); color:inherit; border-radius:2px; padding:0 1px; }
.import-error { color:var(--danger); background:var(--danger-soft); border:1px solid var(--danger-line);
                border-radius:6px; padding:8px 12px; }

/* archive */
.archived-card { background:var(--sunken); box-shadow:none; }
.archived-card .card-body { opacity:.72; }
.strip.hatched { background:repeating-linear-gradient(135deg,var(--border-absent) 0 5px,var(--border-absent) 5px 10px); }
.tile.archived-tile { background:var(--absent); }
.archived-banner { background:var(--sunken); border-bottom:1px solid var(--divider);
                   padding:9px 24px; font-size:12px; color:var(--ink-2); }
.person-header { display:flex; justify-content:space-between; align-items:flex-start; gap:16px; }
/* Archive is a rare, deliberate act — a quiet control in the far corner, not a
   feature of the page. */
.header-actions { flex:none; margin-left:auto; align-self:flex-start;
                  display:flex; flex-direction:column; align-items:flex-end; }
.btn-white { background:rgba(var(--white-rgb),.14); color:rgba(var(--white-rgb),.85);
             border:1px solid rgba(var(--white-rgb),.4); font-size:10.5px;
             font-weight:500; padding:3px 8px; border-radius:5px; }
.btn-white:hover { background:rgba(var(--white-rgb),.92); color:var(--ink); }
.none { color:var(--muted); }

/* centred confirmation modal */
.modal { border:1px solid var(--divider); border-radius:10px; padding:20px 22px;
         max-width:26rem; box-shadow:0 8px 40px rgba(var(--ink-rgb),.25); }
.modal::backdrop { background:rgba(var(--ink-rgb),.45); }
.modal h3 { margin:0 0 8px; font-size:15px; }
.modal p { margin:0 0 12px; font-size:12.5px; color:var(--ink-2); line-height:1.5; }
.modal label { font-size:12.5px; color:var(--ink-2); display:block; margin-bottom:14px; }
.modal input[type=text] { border:1px solid var(--divider); border-radius:4px;
                          padding:4px 7px; font:inherit; margin-left:6px; }
.modal-actions { display:flex; justify-content:flex-end; gap:8px; }
.btn-quiet { background:var(--chip); color:var(--ink-2); }
.btn-quiet:hover { background:var(--border-absent); }

/* Destructive confirm. The design reserves saturated red for patient-safety in
   the roster product, so this is its terracotta — the strongest "act with care"
   colour the system allows. */
.btn-danger { background:var(--danger); }
.btn-danger:hover { background:var(--danger-strong); }

/* add user — sits after the search, far right, per the 1d app bar */
.add-user { text-decoration:none; flex:none; }
.add-form { background:var(--surface); border:1px solid var(--divider); border-radius:9px;
            padding:18px 20px; max-width:30rem; display:flex; flex-direction:column; gap:14px;
            margin:12px auto 0; box-shadow:0 1px 3px rgba(var(--ink-rgb),.07); }
.add-form label { font-size:12.5px; color:var(--ink-2); display:flex;
                  flex-direction:column; gap:5px; font-weight:600; }
.add-form input, .add-form select { border:1px solid var(--divider); border-radius:6px;
                  padding:7px 9px; font:inherit; font-size:13px; color:var(--ink); }
.add-form small { color:var(--muted); font-weight:400; }
/* the late-finish form's sum, before she saves (2026-11-11): a line of its own under the fields, holding its height */
.add-form .ct-check-line { margin:0; min-height:17px; font-size:12px; color:var(--ink-2); }
.add-form .ct-check.no { color:var(--danger); }
.add-form .warn-box { margin-bottom:0; }

/* Add a user, redesigned (2026-10-08): two numbered sections in one form,
   rows revealed by the answer that needs them, the Directory card beside
   it as it will look. Grade and employer are choices drawn as tiles and a
   segmented pair — never free text that a misspelling turns into a locum. */
.add-page { display:flex; gap:18px; align-items:flex-start; max-width:66rem; margin:12px auto 0; }
.add-page .add-form { flex:1 1 0; min-width:0; max-width:none; margin:0; padding:0; gap:0; }
.add-sec { padding:18px 20px; display:flex; flex-direction:column; gap:14px; }
.add-sec + .add-sec { border-top:1px solid var(--divider); }
.add-page .confirm-row { padding:16px 20px; margin-top:0; border-top:1px solid var(--divider); }
.add-page .twin-box { margin:0 20px; }
.sec-head { display:flex; align-items:center; gap:10px; }
.sec-head h3 { margin:0; font-size:14px; font-weight:600; color:var(--ink); }
.sec-n { flex:none; width:22px; height:22px; border-radius:50%; background:var(--ink); color:var(--white);
         font:600 11px var(--mono); display:grid; place-items:center; }
.sec-note { margin-left:auto; color:var(--muted); font-size:11.5px; }
.opt { margin-left:auto; font:600 10.5px var(--mono); letter-spacing:.06em;
       text-transform:uppercase; background:var(--sunken); color:var(--muted); border-radius:4px; padding:3px 7px; }
.add-form .add-field { display:flex; flex-direction:column; gap:5px; }   /* .field is the person page's row */
.add-form .field-label { font-size:12.5px; color:var(--ink-2); font-weight:600; }
.add-form .field-label small { font-weight:400; margin-left:6px; }
.add-form .row2 { flex-direction:row; gap:10px; }
.add-form .row2 > label { flex:1 1 0; }
.add-form [hidden] { display:none !important; }
.tiles { display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:8px; }
.tile-opt { position:relative; border:1px solid var(--divider); border-radius:8px; padding:9px 11px;
            cursor:pointer; display:flex; flex-direction:column; gap:2px; font-weight:400; background:var(--surface); }
.tile-opt input { position:absolute; inset:0; opacity:0; margin:0; cursor:pointer; }
.tile-opt b { font-size:13px; color:var(--ink); }
.tile-opt span { font-size:11.5px; color:var(--muted); }
.tile-opt:has(input:checked) { border-color:var(--ink); box-shadow:inset 0 0 0 1px var(--ink); }
.tile-opt:has(input:focus-visible), .seg label:has(input:focus-visible) { outline:2px solid var(--interactive); outline-offset:2px; }
.seg { display:flex; background:var(--sunken); border-radius:8px; padding:3px; }
.seg label { flex:1 1 0; text-align:center; padding:7px 10px; border-radius:6px; cursor:pointer; position:relative;
             font-weight:400; font-size:13px; color:var(--ink-2); }
.seg label b { font-weight:600; color:var(--ink); }
.seg label input { position:absolute; inset:0; opacity:0; margin:0; cursor:pointer; }
.seg label:has(input:checked) { background:var(--surface); box-shadow:0 1px 2px rgba(var(--ink-rgb),.12); }
/* the chosen one reads at a glance (Haoming, 2026-10-08): a pale wash — blue for a
   rank, green for the employer — with its ink on the words, never the bare white */
.seg.seg-rank label:has(input:checked) { background:var(--choice-soft); color:var(--choice-ink);
             box-shadow:inset 0 0 0 1px var(--choice-line); }
.seg.seg-rank label:has(input:checked) b { color:var(--choice-ink); }
.seg.seg-emp label:has(input:checked), .seg.hseg label:has(input:checked) {
             background:var(--positive-soft); color:var(--positive-ink);
             box-shadow:inset 0 0 0 1px var(--positive-line); }   /* History's All · Their actions · Record too (Haoming, 2026-10-08) */
.seg.seg-emp label:has(input:checked) b, .seg.hseg label:has(input:checked) b { color:var(--positive-ink); }
.add-hint { margin-left:auto; color:var(--muted); font-size:12px; }
.add-form .btn[disabled] { opacity:.45; cursor:default; }
.add-rail { flex:none; width:300px; display:flex; flex-direction:column; gap:10px; position:sticky; top:12px; }
.rail-kicker { font:600 10.5px var(--mono); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.rail-kicker + .rail-kicker, .gap-list + .rail-kicker { margin-top:8px; }
.add-rail .card.preview { pointer-events:none; }
.add-rail .card.preview .name.empty { color:var(--muted); }
.gap-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:6px;
            font-size:12.5px; color:var(--ink-2); }
.gap-list li::before { content:""; display:inline-block; width:11px; height:11px; border:1.5px dashed var(--border-absent);
                       border-radius:50%; margin-right:8px; vertical-align:-1px; }
@media (max-width:900px) {
  .add-page { flex-direction:column; }
  .add-rail { width:auto; position:static; }
  .tiles { grid-template-columns:repeat(2, minmax(0, 1fr)); }
}

/* roster month calendar */
/* The scroll container. overflow:auto is what makes every sticky rule below
   real — without it the table spills the box and nothing pins (S1, UI review
   2026-08-13). The viewport budget below serves the MONTH pages only:
   topbar (~40) + band (~44) + results padding/margins (~30) ≈ 115px of
   chrome above the grid (recounted for the edge-to-edge shell, 2026-09-01).
   The PLANNING page ignores this cap entirely — its flex chain tells
   .cal-scroll its exact height, no guessing (scroll-nesting review). */
.cal-scroll { max-height:calc(100vh - 115px); overflow:auto; background:var(--surface);
              border:1px solid var(--divider); border-radius:9px; }
/* The transparent right border is breathing room after the last day column —
   padding on a horizontal scroller is unreliable at the scroll end, a border
   on the table itself always travels with it (Haoming, 2026-08-24). */
.cal { border-collapse:separate; border-spacing:0; font-size:11px;
       border-right:14px solid transparent;
       /* fill whatever width the pane offers (2026-09-01: collapsing the
          sidebar must widen the day columns, never leave a blank gutter),
          and spread it EVENLY — fixed layout gives the name column its set
          width and splits the rest equally across the days. Below the
          min-width the horizontal scroll takes over as before. */
       width:100%; min-width:1100px; table-layout:fixed; }
.cal .who { width:230px; overflow:hidden; text-overflow:ellipsis; }
/* Name and grade tag are independent (2026-09-02): the name truncates with
   an ellipsis, the tag keeps its seat at the cell's end — "Tommy Tan Ju… NS".
   Hovering makes the name SCROLL IN PLACE (back and forth) inside its own
   box to reveal the tail — nothing expands, the tag never moves. The
   distance and speed come from --shift/--dur, measured per row by the
   grid script. */
.cal tbody td.who .who-in { display:flex; align-items:center; gap:4px;
        height:100%; }
.cal tbody td.who .who-name { flex:1 1 auto; min-width:0; overflow:hidden;
        text-overflow:ellipsis; white-space:nowrap; }
.cal tbody td.who .who-in .g { flex:none; margin-left:0; }
.cal tbody td.who:hover .who-name { text-overflow:clip; }
.cal tbody td.who:hover .who-name > * { display:inline-block;
        animation:who-scroll var(--dur, 2s) ease-in-out .2s infinite alternate; }
@keyframes who-scroll { from { transform:translateX(0); }
                        to { transform:translateX(var(--shift, 0px)); } }
.cal th, .cal td { padding:0; text-align:center; white-space:nowrap; }
.cal thead th { position:sticky; top:0; z-index:4; background:var(--surface);
                font:600 10px var(--mono); color:var(--muted); }
/* Three header rows, pinned at cumulative offsets so none paints over another. */
.cal thead tr.dow th { top:15px; height:15px; }
.cal thead tr.dom th { top:30px; border-bottom:1px solid var(--divider); }
/* Without a sets row the same offsets would leave a 15px see-through gap at
   the top of the scroller — two rows pin tight instead (2026-08-25). */
.cal.no-sets thead tr.dow th { top:0; }
.cal.no-sets thead tr.dom th { top:15px; }
.cal .who { position:sticky; left:0; z-index:2; background:var(--surface); text-align:left;
            padding:2px 9px; overflow:hidden;  /* width set by the fixed-layout 230px rule */
            text-overflow:ellipsis; border-right:1px solid var(--divider);
            font-size:11.5px; font-weight:600; }
.cal thead .who, .cal tfoot .who { z-index:5; }
.cal .who a { color:inherit; text-decoration:none; }
.cal .who a:hover { color:var(--interactive); }
.cal .who .g { color:var(--muted); font-size:9.5px; font-weight:400; margin-left:4px; }
.cal .wknd { background:var(--band); }
.cal td.c { width:1.8rem; height:1.4rem; border-bottom:1px solid var(--divider-light);
            border-right:1px solid var(--divider-light); }
.cal td.c span { display:block; height:100%; line-height:1.4rem; font-size:8.5px;
                 color:var(--ink); }
/* Grow-on-hover for tappable cells (2026-08-25; the dock wave was tried and
   reverted). A BLANK tappable cell grows a ghost pill — before, empty cells
   had nothing to grow and hovering them showed nothing (Haoming's catch). */
.cal td.c span { transition:transform .08s ease; }
.cal td[data-mk]:hover span { transform:scale(1.45); position:relative;
    z-index:3; border-radius:4px; box-shadow:0 3px 10px rgba(var(--ink-rgb),.22); }
/* layer 3 (Haoming, 2026-09-17): over its neighbours and the name column
   (2), UNDER the pinned header and footer (4) — a grown pill on a row
   half-scrolled under the footer never paints over the strength row, and
   the set outline stays at 1 so a scrolled-under cell never paints over a
   name */
.cal td[data-mk]:hover .blank { background:var(--surface);
    outline:1.5px dashed var(--border-absent); outline-offset:-2px; }
.cal td.c .on { font-weight:700; }
/* MC / HL painted over a cell (2026-09-14): the colour is the plan, the
   italic wording is what happened */
.cal td.c .absent { font-style:italic; letter-spacing:.02em; }
/* an MC day wears a dotted edge (Haoming, 2026-09-22): the sick day reads
   apart from a rostered or a leave cell at a glance, on white or over a shift */
.cal td.c .mc { outline:1.5px dotted var(--ink-2); outline-offset:-2px; border-radius:4px; }
/* PRECEPT is the widest code on the sheet — one point down, with side air so
   the letters never touch the pill edge (Haoming, 2026-08-21). */
.cal td.c .on.code-sm { font-size:8.5px; padding:0 3px; letter-spacing:-.01em; }
.cal td.c .on.swap { box-shadow:inset 0 0 0 1.5px var(--danger); }
/* the 24-hour cell carries no E — the heavy ring is what says "both
   shifts" (Haoming, 2026-09-03) */
.cal td.c .on.unresolved { box-shadow:inset 0 0 0 2.5px var(--warn-ink); }
.cal td.c .away { color:var(--ink-2); outline:1px dashed var(--muted); outline-offset:-2px;
                  font-weight:600; }
/* The away hours are the only text in the cell, so they can be big and bold.
   The line-height is tight to keep the hours visually centred in the cell. */
.cal td.c .away.hours { font-size:7px; line-height:11px; letter-spacing:-.02em;
                        padding:2px 3px; }
/* Identical ranges on consecutive days merge into one dashed span, hours
   written once — the ribbon treatment, in the away clothes. The td's own
   rb-cont class already blanks the column divider inside the run. */
.cal td.c .away.aw-start, .cal td.c .away.aw-mid, .cal td.c .away.aw-end {
  outline:none; border-top:1px dashed var(--muted); border-bottom:1px dashed var(--muted); }
.cal td.c .away.aw-start { border-left:1px dashed var(--muted); border-radius:5px 0 0 5px; }
.cal td.c .away.aw-end { border-right:1px dashed var(--muted); border-radius:0 5px 5px 0; }
.cal td.c .off { color:var(--muted); }
/* 30% thinner role separators (Haoming, 2026-08-25) */
.cal tr.band td { background:var(--band); text-align:left; padding:0 9px;
                  line-height:12px; height:12px;
                  font:700 9.5px var(--mono); letter-spacing:.09em;
                  text-transform:uppercase; color:var(--muted); position:sticky; left:0; }
/* The strength footer pins to the bottom of the scrollport — the "is this
   day short?" answer stays visible while the 85 staff rows scroll. Six rows,
   stacked at cumulative bottom offsets (1.35rem each). */
/* Row height must EQUAL the pinning step below, or the rows overlap while
   pinned and spread at the scroll bottom — the stretch/compress jump
   (Haoming, 2026-08-21). So: separator as a shadow (no layout height) and no
   vertical padding on the label cells. WHOLE pixels everywhere — the old
   1.35rem step (21.6px) rounded differently per frame on fast scroll,
   flashing hairline seams of roster between the rows; translateZ pins the
   rows on the compositor so fast wheel scrolling cannot leave them behind. */
.cal tfoot th, .cal tfoot td { position:sticky; z-index:4; background:var(--surface);
                               box-shadow:0 -1px 0 var(--divider);
                               height:22px; line-height:22px; vertical-align:middle;
                               transform:translateZ(0); }
.cal tfoot .who { padding:0 9px; line-height:22px; }
/* The small target label baseline-aligns against the bigger label text and
   inflated the line box to 23px — 1px over the pinning step, which re-opened
   the scroll jump on some zooms (Haoming, 2026-08-24). Kept out of the line
   box entirely. */
.cal tfoot .who .g { line-height:1; vertical-align:middle; }
.cal tfoot tr:nth-last-child(1) th, .cal tfoot tr:nth-last-child(1) td { bottom:0; }
.cal tfoot tr:nth-last-child(2) th, .cal tfoot tr:nth-last-child(2) td { bottom:22px; }
.cal tfoot tr:nth-last-child(3) th, .cal tfoot tr:nth-last-child(3) td { bottom:44px; }
.cal tfoot tr:nth-last-child(4) th, .cal tfoot tr:nth-last-child(4) td { bottom:66px; }
.cal tfoot tr:nth-last-child(5) th, .cal tfoot tr:nth-last-child(5) td { bottom:88px; }
.cal tfoot tr:nth-last-child(6) th, .cal tfoot tr:nth-last-child(6) td { bottom:110px; }
/* the font shorthand resets line-height to "normal" — restate it, or
   baseline alignment inflates the row past the 22px pinning step */
.cal tfoot td.n { font:600 10px var(--mono); line-height:22px; }
/* Gaps are not errors: shortfall reads neutral, and only the deep tier may
   use the sanctioned terracotta (S2, UI review 2026-08-13). */
.cal tfoot td.n.short { color:var(--danger); background:var(--danger-soft); }
.cal tfoot td.n.thin { color:var(--muted); background:var(--sunken); }
.cal tfoot td.n.fine { color:var(--ink-2); }
/* A generated grid reads in two reds and black (Haoming, 2026-09-17): short
   of target is the loud one — white on the strong red — over the cap the
   quiet one, red on the pale ground; met is plain black. Sister's imported
   sheets keep the neutral tiers above: a short day there is a fact. */
.cal.gen tfoot td.n.short { color:var(--white); background:var(--danger-strong); font-weight:700; }
.cal.gen tfoot td.n.over { color:var(--danger); background:var(--danger-soft); font-weight:700; }
.cal.gen tfoot td.n.fine { color:var(--ink); }
/* critical generation notes (2026-09-01): worklist styling, capped scroll;
   the bookkeeping folds behind a disclosure */
.gen-crit { display:flex; flex-direction:column; gap:6px;
            max-height:230px; overflow-y:auto; }
.gen-crit .gen-note { padding:7px 10px; align-items:center; }
.gen-more > summary { list-style:none; cursor:pointer; margin-top:8px;
        font:600 11px var(--sans); color:var(--interactive); }
.gen-more > summary::-webkit-details-marker { display:none; }
.gen-more > summary::before { content:"▸ "; }
.gen-more[open] > summary::before { content:"▾ "; }
/* locked stages say so (2A note 1) */
.step.locked { opacity:.55; }
.step-lock { margin-left:auto; font:500 9.5px var(--mono);
             letter-spacing:.06em; text-transform:uppercase; color:var(--absent); }
/* a PENDING extra request (marketplace, 2026-09-01): the darker request
   shade needs light bold text; approval hands the cell back to the normal
   colours with the E label kept */
.cal .on.eoff { color:var(--white); font-weight:700; }
/* a PARKED request (2026-09-14): pending on a line already at target — the
   same cell, faded, with a dashed edge; swept unless approved */
.cal .on.eoff.parked { opacity:.55; outline:1.5px dashed rgba(var(--ink-rgb),.6);
                       outline-offset:-2px; }
.cal td[data-mk]:hover .on.eoff.parked { opacity:.85; }
/* thin bar under the date: a segment marks a MISSING stamp — OIC in the
   nurse colours by default; scrolled into the HCA band the table gains
   .hca-view and the bar swaps to SOC in the HCA colours (2026-08-31,
   draft grids only). .quiet keeps the row height when nothing is missing. */
.oicbar { display:flex; gap:1px; height:3px; margin-top:1px; cursor:pointer;
          transition:transform .12s ease, filter .12s ease; }
/* pop on hover (Haoming, 2026-08-31): the bar thickens and brightens so the
   hover target is unmistakable — transform only, the header never reflows */
.oicbar:hover, .oicbar.is-open { transform:scaleY(2.2); filter:brightness(.92) saturate(1.4);
                box-shadow:0 1px 3px rgba(var(--ink-rgb),.25); }
.oicbar i { flex:1; border-radius:1px; }
.oicbar .am { background:var(--fill-nurse-day); }
.oicbar .pm { background:var(--fill-nurse-night); }
.oicbar .am.h { background:var(--fill-hca-day); }
.oicbar .pm.h { background:var(--fill-hca-night); }
.oicbar.quiet { visibility:hidden; }
.cal .oicbar.hb { display:none; }
.cal.hca-view .oicbar.hb { display:flex; }
.cal.hca-view .oicbar.nb { display:none; }
.cal tfoot td.n.zero { color:var(--border-absent); }
/* ribbons (design 2.1a): consecutive same-shift days read as one bar. The td
   border goes transparent wherever the run continues; radii cap the ends. */
.cal td.c.rb-cont { border-right-color:transparent; }
.cal td.c .on.rb-start { border-radius:5px 0 0 5px; }
.cal td.c .on.rb-end { border-radius:0 5px 5px 0; }
.cal td.c .on.rb-solo { border-radius:5px; }
/* the short-day spotlight: everything else steps back */
.cal td.c.dimd { opacity:.22; }
/* screen title + filter chips in the band */
.screen-title { font:600 19px var(--sans); letter-spacing:-.01em; }
.chip-row { display:inline-flex; gap:5px; flex-wrap:wrap; }
.pill.on { background:var(--ink); color:var(--white); border-color:var(--ink); }
/* by-employer view: highlighter marks on the NAMES, one colour per employer
   (Haoming, 2026-08-17 — visible grouping, legend behind a ⓘ). Saturated
   enough to read as groups, ink stays legible on all eight. */
.nm-hl { display:inline-block; padding:0 5px; border-radius:4px; }

/* a set handover gets a heavier rule than an ordinary week boundary */
.cal th.set-label.boundary { border-left:3px solid var(--absent); }
/* Cells the decode could not read — never allowed to look like a day off. */
.cal td.c .unk { background:var(--danger-soft); outline:1.5px dashed var(--danger); outline-offset:-2px;
                 color:var(--danger); font-weight:700; }
.cal td.c .on.unkcode { box-shadow:inset 0 0 0 1.5px var(--danger); }
/* Not yet employed here — a different truth from "day off". */
.cal td.c .notyet { background:repeating-linear-gradient(135deg,var(--sunken) 0 4px,var(--chip) 4px 8px); }
/* the flagged / needs-a-human lists */
.issues { list-style:none; margin:0; padding:0; font-size:12px; }
.issues li { padding:2px 0 2px 10px; border-left:2px solid var(--divider); margin-bottom:3px; }
.issues li.check { border-left-color:var(--danger); }
.issues li.hard { border-left-color:var(--danger); }
.issues li.soft { border-left-color:var(--border-absent); }
.issues .cell-refs { color:var(--muted); font-size:10.5px; }

/* 4-3-4 set labels above the calendar, as in the sheet's row 2 */
.cal tr.sets th { font:600 9px var(--mono); letter-spacing:.08em;
                  color:var(--muted); border-bottom:1px solid var(--divider-light);
                  height:15px; }
.cal th.set-label { border-left:2px solid var(--divider); background:var(--band); }

/* colour legend popover */
.legend-pop { position:relative; display:inline-block; }
.legend-pop summary { list-style:none; cursor:pointer; width:20px; height:20px;
  display:inline-flex; align-items:center; justify-content:center; border-radius:50%;
  color:var(--interactive); font-size:13px; border:1px solid rgba(var(--ink-rgb),.14);
  background:var(--surface); }
.legend-pop summary::-webkit-details-marker { display:none; }
.legend-pop summary:hover { border-color:var(--interactive); }
.legend-pop[open] summary { background:var(--interactive); color:var(--white); }
.legend-panel { position:absolute; right:0; top:26px; z-index:20; width:19rem;
  background:var(--surface); border:1px solid var(--divider); border-radius:9px;
  padding:12px 14px; box-shadow:0 6px 24px rgba(var(--ink-rgb),.18); }
/* a legend at the foot of a rail opens upward and to the right of its ⓘ,
   so nothing hangs off the bottom edge (the inbox's drafted-month strip,
   2026-11-09) */
.legend-pop.up .legend-panel { top:auto; bottom:26px; left:0; right:auto; }
.mstrip-wrap .legend-pop { vertical-align:middle; margin:0 4px 0 6px; }
/* the ⓘ sits on the kicker line, so its panel gives back the kicker's
   mono, caps and tracking */
.mstrip-wrap .legend-panel { font:400 12px var(--sans); letter-spacing:0; text-transform:none;
  text-align:left; color:var(--ink); }
.mstrip-wrap .legend-panel h3 { font:600 12.5px var(--sans); }
.lg-swatch.lg-blank { background:var(--white); border-style:dashed; }
.legend-panel h3 { margin:0 0 8px; font-size:12.5px; }
.legend-panel p { margin:0 0 5px; font-size:12px; color:var(--ink-2);
  display:flex; align-items:center; gap:7px; }
.lg-swatch { flex:none; width:22px; height:8px; border-radius:2px;
  border:1px solid rgba(var(--ink-rgb),.15); }
.lg-note { margin-top:8px !important; color:var(--muted) !important;
  display:block !important; line-height:1.45; }
/* the legend's groups and lettered swatches (copy reworked 2026-09-18) */
.lg-group { margin:9px 0 3px !important; font:600 9.5px var(--mono) !important;
  letter-spacing:.08em; text-transform:uppercase; color:var(--muted) !important; }
.legend-panel p:first-of-type.lg-group { margin-top:0 !important; }
.lg-letter { height:14px; color:var(--ink); font:700 9px sans-serif; text-align:center; line-height:14px; }
.legend-panel .mono { flex:none; min-width:22px; font-size:10.5px; color:var(--ink); }
.lg-sub { margin:-3px 0 5px 29px !important; color:var(--muted) !important; }   /* a bracketed aside under its line */

/* the band's lone ⓘ, far right */
.band-right { margin-left:auto; display:flex; align-items:center; gap:8px; }
.band-right .search { margin-left:0; }

/* dashboard frame (CRM reference; placeholder slots until contents decided) */
.dashboard { padding:20px 24px; display:flex; flex-direction:column; gap:16px; }
.dash-head h1 { margin:0; font:600 19px var(--sans);
                letter-spacing:-.01em; }  /* the house screen-title size */
.dash-sub { margin:4px 0 0; color:var(--muted); font-size:13px; }
/* the glance (Haoming's mock, 2026-10-27): Needs action — a table, the item bold, why in a
   line, when with a small line under it (red only when overdue or short), the buttons at the
   end, filled for the urgent — four tiles, then the month's cover beside the feed */
.dash-title { margin:0; font:600 14px var(--sans); letter-spacing:-.01em; }
.dash-title .count { display:inline-block; min-width:18px; margin-left:4px; padding:1px 6px; border:1px solid var(--divider);
                     border-radius:5px; font:500 11px var(--mono); color:var(--ink-2); text-align:center; vertical-align:2px; }
.dash-label { font:600 10.5px var(--mono); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.needs { padding:14px 16px 6px; }
.needs-head { display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:6px; }
.needs-note { font-size:12px; color:var(--muted); }
.needs-table td { padding-top:11px; padding-bottom:11px; vertical-align:middle; }
.need-item { font-weight:600; white-space:nowrap; }
.need-why { color:var(--ink-2); }
.need-when { white-space:nowrap; }
.need-when small { display:block; font-size:11.5px; color:var(--muted); }
.need-when.red { color:var(--danger); font-weight:600; }
.need-when.red small { color:var(--muted); font-weight:400; }
.need-act { text-align:right; white-space:nowrap; }
.need-act form { display:inline; }
.need-act .btn + .btn, .need-act form + .btn, .need-act form + form { margin-left:6px; }
/* every button on the Dashboard wears the phone's Requests pair (Haoming, 2026-10-27: the admin's
   small button read mean beside the mock): Approve's filled block and Decline's ringed twin, scaled
   to a table row, in the admin's own teal — the urgent acts filled, every way on ringed */
.dashboard .btn { display:inline-flex; align-items:center; vertical-align:middle; height:32px; padding:0 14px; border:0;
                  border-radius:10px; font:700 13px var(--sans); text-decoration:none; }
.dashboard .btn-outline { background:none; color:var(--ink); box-shadow:inset 0 0 0 1.5px var(--border-absent); }
.dashboard .btn-outline:hover { background:var(--subtle); }
.dash-tiles { display:grid; grid-template-columns:repeat(4, 1fr); gap:14px; }
.dash-tile { display:flex; flex-direction:column; gap:4px; padding:16px 18px; color:inherit; text-decoration:none; }
.dash-tile-n { font:600 28px/1.1 var(--sans); letter-spacing:-.02em; }
.dash-tile-n small { font-size:15px; font-weight:500; letter-spacing:0; color:var(--ink-2); }
.dash-tile-n.red { color:var(--danger); }
.dash-tile-sub { font-size:12.5px; color:var(--ink-2); }
.untold-line { margin:6px 0 0; font-size:12.5px; color:var(--ink-2); }
.untold-line form { display:inline; }
.untold-line .linkish { padding:0; border:0; background:none; color:inherit; font:inherit; cursor:pointer; text-decoration:underline; }
/* the chart beside the feed: a figure with its legend in the caption, thin marks on hairline
   furniture, the footer line under a rule, a table twin folded under; the readout floats over the page */
.dash-main { display:grid; grid-template-columns:2fr 1fr; gap:14px; }
.dash-main > .ph { align-self:start; }
.viz { margin:0; padding:14px 16px; display:flex; flex-direction:column; gap:8px; }
.viz figcaption { display:flex; align-items:baseline; justify-content:space-between; gap:10px; }
.viz-svg { width:100%; height:auto; display:block; overflow:visible; }
.viz-weekend { fill:var(--band); }
.viz-grid { stroke:var(--divider-light); stroke-width:1; }
.viz-target { stroke:var(--ink-2); stroke-width:1; }
.viz-axis { stroke:var(--border-absent); stroke-width:1; }
.viz-tick { font:500 10px var(--sans); fill:var(--muted); font-variant-numeric:tabular-nums; }
.viz-tick-target { font-weight:600; fill:var(--ink-2); }
.viz-tick-dim { fill:var(--absent); }
.viz-tick-today { font-weight:700; fill:var(--interactive); }
.viz-label { font:600 10.5px var(--sans); fill:var(--ink-2); }
.viz-ft { fill:var(--viz-dim); }
.viz-extra { fill:var(--ink-2); }
.viz-locum { fill:var(--viz-locum); }
.viz-gap { fill:var(--danger); }
.viz-today { stroke:var(--interactive); stroke-width:1.5; }
.viz-today-label { font:600 9.5px var(--sans); fill:var(--interactive); letter-spacing:.06em; text-transform:uppercase; }
.viz-hit { fill:transparent; }
.viz-mark { cursor:default; outline:none; }
.viz-mark:hover :is(.viz-ft, .viz-extra, .viz-locum, .viz-gap), .viz-mark:focus :is(.viz-ft, .viz-extra, .viz-locum, .viz-gap) { opacity:.75; }
.viz-legend { display:flex; gap:12px; font-size:11.5px; color:var(--ink-2); }
.viz-legend span { display:inline-flex; align-items:center; gap:6px; }
.viz-legend .sw { width:10px; height:10px; border-radius:2px; display:inline-block; }
.viz-legend .sw.ft { background:var(--viz-dim); }
.viz-legend .sw.extra { background:var(--ink-2); }
.viz-legend .sw.locum { background:var(--viz-locum); }
.viz-legend .sw.gap { background:var(--danger); }
.viz-legend .sw.today { width:2px; height:11px; border-radius:0; background:var(--interactive); }
.viz-foot { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:2px; padding-top:10px;
            border-top:1px solid var(--divider-light); font-size:12px; color:var(--muted); }
.viz-table > summary { font-size:11.5px; color:var(--muted); cursor:pointer; }
.viz-tip { position:absolute; z-index:5; padding:6px 9px; border-radius:6px; background:var(--ink); color:var(--surface); font-size:11.5px; line-height:1.35; display:flex; flex-direction:column; pointer-events:none; white-space:nowrap; }
.viz-tip b { font-size:13px; }
.viz-tip[hidden] { display:none; }
.dashboard { position:relative; }
.dash-list { padding:14px 16px; display:flex; flex-direction:column; gap:8px; }
.dash-table { width:100%; border-collapse:collapse; font-size:12.5px; }
.dash-table th { text-align:left; font:600 10.5px var(--mono); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); padding:4px 8px 6px 0; border-bottom:1px solid var(--divider); }
.dash-table td { padding:7px 8px 7px 0; border-bottom:1px solid var(--divider-light); vertical-align:top; }
.dash-table tr:last-child td { border-bottom:0; }
.dash-table .num, .dash-table th.num { text-align:right; font-variant-numeric:tabular-nums; }
.dash-table td.when { white-space:nowrap; color:var(--ink-2); }
.dash-table td.red { color:var(--danger); font-weight:600; }
@media (max-width:1100px) { .dash-main { grid-template-columns:1fr; } .dash-tiles { grid-template-columns:repeat(2, 1fr); } }
.card.ph { border:1.5px dashed var(--border-absent); box-shadow:none;
           background:var(--subtle); padding:18px; display:flex;
           flex-direction:column; gap:6px; align-items:flex-start; }
.card.ph .ph-label { font:600 10.5px var(--mono);
           letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.ph-tall { min-height:260px; }

/* month-planning workspace (design adopted 2026-08-24): stepper + stage rail.
   The band is gone (2026-08-31) — the month name rides the stepper row. */
.plan-head { display:flex; align-items:stretch; gap:10px; margin-bottom:16px; }
.plan-head details.plan-month-dd { position:relative; display:inline-flex;
              align-items:center; }
.plan-month { flex:none; display:inline-flex; align-items:center; gap:5px;
              font:600 13px var(--mono); letter-spacing:.03em;
              color:var(--ink); padding:0 4px; white-space:nowrap;
              list-style:none; cursor:pointer; user-select:none; }
summary.plan-month::-webkit-details-marker { display:none; }
.plan-month:hover { color:var(--interactive); }
/* the month menu's skip toggle stays visible — it IS the point of the row */
.dd-skip { opacity:1; }
.plan-head .plan-steps { flex:1; margin-bottom:0; }
.plan-steps { display:grid; grid-template-columns:repeat(6, 1fr); gap:1px;
              background:var(--divider); border:1px solid var(--divider);
              border-radius:9px; overflow:hidden; margin-bottom:16px; }
.step { background:var(--surface); padding:10px 14px; display:flex;
        align-items:center; gap:8px; font-size:12.5px; font-weight:600;
        color:var(--muted); }
.step-dot { width:18px; height:18px; border-radius:50%; border:1.5px solid var(--border-absent);
        display:inline-flex; align-items:center; justify-content:center;
        font:600 10px var(--mono); flex:none; }
.step.done .step-dot { background:var(--ink); border-color:var(--ink); color:var(--white); }
.step.now { color:var(--ink); box-shadow:inset 0 -3px 0 var(--ink); }
.step.now .step-dot { background:var(--ink); border-color:var(--ink); color:var(--white); }
/* Only the MIDDLE scrolls (Haoming, 2026-09-01): the planning page pins
   the stepper and the right rail; the centre column gets its own scrollbar
   when it needs one. The rail is a WHITE full-height panel (per the 2A
   reference) — its cards flatten into sections — and the next-stage
   button is standardised to the bottom-right, pinned to the rail's floor. */
.page-scroll > .results.plan-page { flex:1 1 0; min-height:0;
        display:flex; flex-direction:column; overflow:hidden; }
/* a page whose panels scroll inside it (Planning) gives the outer pane
   nothing to scroll — so the outer pane does not (Haoming, 2026-09-24): no
   bounce, no stray page scrollbar; the cards and lists inside keep their
   own. Every other page keeps its outer scroll. */
.page-scroll:has(> .results.plan-page) { overflow:hidden; overscroll-behavior:contain; }
.results.plan-page .plan-split { flex:1 1 0; min-height:0;
        align-items:stretch; }
.plan-split { display:flex; gap:16px; align-items:flex-start; }
/* ONE vertical scroller per stage (scroll-nesting review, 2026-09-01):
   the column does NOT scroll — the flex chain hands .cal-scroll its exact
   height, so the grid is the single scroller and its sticky thead/tfoot
   keep working. Stage 1 joined the calendar-centred stages on 2026-09-09
   when the verdict dashboard went. */
.results.plan-page .plan-cal-wrap { max-height:100%; }
.results.plan-page .plan-cal-wrap { overflow:visible;
        display:flex; flex-direction:column; min-height:0; }
.results.plan-page .plan-cal-wrap .cal-wrap { flex:1 1 0;
        min-height:0; display:flex; flex-direction:column; }
.results.plan-page .plan-cal-wrap .cal-scroll { flex:1 1 0;
        min-height:0; max-height:none; }
.results.plan-page .plan-rail { max-height:100%; background:var(--surface);
        border:1px solid var(--divider); border-radius:10px;
        padding:14px 16px; overflow:hidden; }
.results.plan-page .plan-rail .card { border:none; border-radius:0;
        background:transparent; padding:0 0 6px; }
.results.plan-page .plan-rail .card { flex:none; }
.results.plan-page .plan-rail .amx-fold .offer-log { max-height:140px; overflow-y:auto; }
.plan-cal-wrap { flex:1; min-width:0; }
.plan-cal { min-height:320px; }
/* Inside the workspace the stepper + band sit above the grid, so the scroller
   budgets for more chrome than the plain month page (same fold rule). */
.plan-rail { flex:none; width:320px; display:flex; flex-direction:column; gap:12px; }
.plan-stage { padding:14px 16px; }
.plan-stage-kicker { font:600 10.5px var(--mono); letter-spacing:.08em;
        text-transform:uppercase; color:var(--muted); }
.plan-stage-title { margin:6px 0 10px; font-size:15px; }
.plan-checklist { list-style:none; margin:0; padding:0; display:flex;
        flex-direction:column; gap:8px; font-size:12.5px; }
.plan-checklist a { color:var(--interactive); }
.plan-note { font-size:12px; color:var(--ink-2); margin:10px 0 0; }
.plan-links { font-size:12.5px; line-height:1.9; margin:8px 0 0; }
.plan-links a { color:var(--interactive); }
.plan-ph { border:1.5px dashed var(--border-absent); border-radius:8px;
        padding:12px; background:var(--subtle); }
@media (max-width:1100px) { .plan-split { flex-direction:column; }
        .plan-rail { width:auto; }
        /* stacked layout: back to one normal page scroll */
        .page-scroll > .results.plan-page { display:block; overflow:visible; }
        .results.plan-page .plan-cal-wrap,
        .results.plan-page .plan-cal-wrap,
        .results.plan-page .plan-rail { max-height:none; overflow:visible;
                display:block; }
        .results.plan-page .plan-cal-wrap .cal-scroll {
                max-height:calc(100vh - 115px); } }
/* At the Inputs stage nothing is generated yet, so an all-zero footer is not
   a shortage — mute the terracotta until a draft exists (2026-08-24). */
.plan-inputs .cal tfoot td.n.short { color:var(--muted); background:var(--surface); }

/* stage 3: the offer queue (2026-08-24) */
.offer-list { display:flex; flex-direction:column; gap:8px; margin:10px 0; }
/* Two-line row (2026-08-25): the rail is too narrow for name + date +
   buttons abreast — the name owns the first line in full, date/status and
   the buttons share the second. Nothing truncates, nothing collides. */
.offer-row { display:flex; flex-wrap:wrap; align-items:center; gap:4px 8px;
             padding:8px 10px; border:1px solid var(--divider);
             border-radius:8px; background:var(--surface); font-size:12.5px; }
.offer-who { font-weight:600; flex:1 1 100%; overflow-wrap:break-word; }
.offer-when { color:var(--ink-2); font-size:11px; }
.offer-actions { display:flex; gap:6px; margin-left:auto; }
.offer-actions form { margin:0; }
.offer-add { display:flex; flex-direction:column; gap:7px; margin-top:14px;
             padding-top:12px; border-top:1px solid var(--divider); }
.offer-add input[type=text], .offer-add select {
             border:1px solid var(--divider); border-radius:6px; padding:6px 9px;
             font:inherit; font-size:12.5px; }
.offer-add-row { display:flex; gap:7px; align-items:center; }
.offer-ok { font-size:12px; color:var(--positive); }
/* The Logs card holds its height: ~4 rows visible, newest on top, the rest
   scrolling inside — a fifth row peeks to say there is more (2026-08-25).
   Row ≈ 41px (padding + border + text); 4×41 + gaps + a ~18px peek. */
.offer-log { max-height:198px; overflow-y:auto; }
/* peek (2026-08-25): done stepper stages are read-only links; the peeked one
   is marked, and the banner says looking is not moving. */
a.step { text-decoration:none; cursor:pointer; }
a.step:hover .step-name { color:var(--interactive); }
.step.peek { box-shadow:inset 0 0 0 1.5px var(--interactive); }

/* adopt-and-amend piece 2 (2026-08-25): the tap strip and the journal */
.amend-strip { position:absolute; z-index:40; background:var(--surface);
    border:1px solid var(--divider); border-radius:9px; padding:9px 11px;
    box-shadow:0 8px 22px rgba(var(--ink-rgb),.14); max-width:290px; }
.amend-head { font:600 11px var(--mono); letter-spacing:.04em;
    color:var(--muted); margin-bottom:7px; text-transform:uppercase; }
.amend-chips { display:flex; gap:6px; flex-wrap:wrap; }
.amend-note { font-size:12px; color:var(--muted); font-style:italic; }
.amx-reverted .offer-who, .amx-reverted .offer-when {
    text-decoration:line-through; color:var(--absent); }
td[data-mk] { cursor:pointer; }
/* the wireframe's NEED treatment on the strength footer */
.cal tfoot .need { font:600 8.5px var(--mono);
    letter-spacing:.07em; color:var(--muted); background:var(--chip);
    border-radius:4px; padding:1px 4px; margin-left:4px; }
.amend-ph { display:flex; gap:6px; align-items:center; }
.amend-ph input { border:1px solid var(--divider); border-radius:6px;
    padding:4px 8px; font:inherit; font-size:12px; width:150px; }

/* fullscreen calendar (2026-08-25): bigger cells for smaller eyes. zoom
   scales the WHOLE layout coherently — sticky offsets included — where
   transform:scale would break the pinned header and footer. */
.cal-wrap { position:relative; }
/* lives INSIDE the pinned sets row (reference placement, 2026-08-25) — same
   spot in and out of fullscreen, inverted on exit so the control never moves */
.cal-expand { border:1px solid var(--divider); background:var(--surface);
    cursor:pointer; border-radius:8px; padding:0 7px; margin-left:8px;
    font:600 9px var(--sans); color:var(--interactive);
    line-height:13px; height:13px; vertical-align:middle; }
/* icon-only, right end of the 4-3-4 sets cell (Haoming, 2026-08-25) */
.cal-expand-icon { float:right; height:13px; line-height:11px; padding:0 4px;
    font-size:10px; border-radius:5px; margin:0; }
/* fallback for grids without a sets row: floats in the gap above the card */
.cal-expand-float { position:absolute; top:-16px; left:0; z-index:10;
    border-radius:8px; padding:0 6px; font-size:10px; line-height:12px;
    height:14px; margin:0; }
.cal-wrap.cal-full .cal-expand { background:var(--ink); color:var(--white);
    border-color:var(--ink); }
.cal-expand:hover { border-color:var(--interactive); }
.cal-wrap.cal-full { position:fixed; inset:0; z-index:80; background:var(--surface);
    padding:44px 14px 14px; display:flex; flex-direction:column; }
.cal-wrap.cal-full .cal-scroll { max-height:none; flex:1 1 0; min-height:0; }
.cal-wrap.cal-full .cal { zoom:1.45; }
.cal-wrap.cal-full .cal-expand-float { position:fixed; top:10px; left:14px;
    z-index:81; height:auto; padding:4px 10px; font-size:11px; line-height:1.4;
    border-radius:12px; }
/* the tap strip must float above the fullscreen layer */
.amend-strip { z-index:90; }
/* the swap arrows (2026-09-14): shift options <-> the codes menu, from
   stage 2 on — bottom-right, out of the chips' way */
.amend-strip.has-flip { padding-right:32px; }
.amend-flip { position:absolute; right:7px; bottom:7px; width:20px; height:20px;
              padding:0; border-radius:6px; border:1px solid var(--divider);
              background:var(--surface); color:var(--ink-2); font-size:12px;
              line-height:18px; text-align:center; cursor:pointer; }
.amend-flip:hover { border-color:var(--ink); color:var(--ink); }
/* the ⇅ switch's motion (2026-09-15): the header stays put, the body's
   height eases between the two panels, the outgoing row lifts out of the
   flow and fades along the direction of travel while the incoming row
   fades in from the other side a beat later; the codes chips arrive in a
   short cascade, the arrows make a half turn each tap. Every timing is a
   custom property here — tweak them in this block, nowhere else. */
.amend-strip { --sw-h:220ms; --sw-ease:cubic-bezier(.2,0,0,1);   /* height + arrows */
               --sw-out:140ms; --sw-in:180ms; --sw-delay:40ms;   /* fade out / fade in / in-delay */
               --sw-y:8px;                                        /* the slide distance */
               --sw-step:10ms; --sw-cap:120ms; }                  /* codes cascade: per chip, cap */
.amend-body { position:relative; }
.amend-body.sw-anim { overflow:hidden; transition:height var(--sw-h) var(--sw-ease); }
.amend-body.sw-up   { --sw-dir:1; }    /* assign → codes: content travels upward */
.amend-body.sw-down { --sw-dir:-1; }   /* codes → assign: content travels downward */
.amend-chips.sw-old { position:absolute; left:0; right:0; top:0; pointer-events:none;
    transition:opacity var(--sw-out) ease-out, transform var(--sw-out) ease-out; }
.amend-chips.sw-old.sw-go { opacity:0; transform:translateY(calc(var(--sw-y) * var(--sw-dir) * -1)); }
.amend-chips.sw-new { opacity:0; transform:translateY(calc(var(--sw-y) * var(--sw-dir)));
    transition:opacity var(--sw-in) ease-out var(--sw-delay), transform var(--sw-in) ease-out var(--sw-delay); }
.amend-chips.sw-new.sw-go { opacity:1; transform:none; }
/* the cascade: the codes row itself lands at once, each child follows
   --i steps behind, the run capped */
.amend-chips.sw-new.sw-stagger { opacity:1; transform:none; transition:none; }
.amend-chips.sw-stagger > * { transition:opacity var(--sw-in) ease-out, transform var(--sw-in) ease-out;
    transition-delay:calc(var(--sw-delay) + min(var(--i, 0) * var(--sw-step), var(--sw-cap))); }
.amend-chips.sw-new.sw-stagger:not(.sw-go) > * { opacity:0;
    transform:translateY(calc(var(--sw-y) * var(--sw-dir))); }
.amend-flip { transition:transform var(--sw-h) var(--sw-ease); }
@media (prefers-reduced-motion: reduce) {
  /* a plain crossfade: no travel, no cascade, the height and arrows snap */
  .amend-strip { --sw-y:0px; --sw-step:0ms; --sw-cap:0ms; --sw-delay:0ms; }
  .amend-body.sw-anim, .amend-flip { transition:none; }
}

/* the wireframe's blocked chips: visible, hollow, rule one tap away */
/* a blocked option (Haoming, 2026-09-18: "same size, greyed out, not the
   dotted"): the chip's own shape, greyed, no border to grow it; the tap
   still says why. Hover stays grey — nothing here invites the click. */
.chip-hollow, .chip-hollow:hover { background:var(--chip) !important; color:var(--absent) !important;
    border:0 !important; }
.amend-reason { margin-top:7px; font-size:11.5px; color:var(--ink-2);
    font-style:italic; border-top:1px solid var(--divider); padding-top:6px; }

/* the strip's CRT entrance and exit (Haoming, 2026-08-26): opens like a
   screen warming on — a thin bright line stretching to full height with a
   whisker of overshoot — and closes like an old TV: squash to a glowing
   line, then wink out sideways. */
@keyframes strip-on {
  0%   { transform:scaleY(.04) scaleX(.75); opacity:.55; filter:brightness(1.6); }
  60%  { transform:scaleY(1.05) scaleX(1);  opacity:1;   filter:brightness(1.05); }
  100% { transform:none; filter:none; }
}
@keyframes strip-off {
  0%   { transform:none; opacity:1; }
  45%  { transform:scaleY(.04) scaleX(1); opacity:1; filter:brightness(2.2); }
  100% { transform:scaleY(.02) scaleX(.02); opacity:0; filter:brightness(3); }
}
.amend-strip { transform-origin:center center;
    transition:left .5s cubic-bezier(.3,.9,.25,1), top .5s cubic-bezier(.3,.9,.25,1); }
/* the liquid hop (Haoming, 2026-08-26): an open strip FLOWS to the next
   cell — glide on left/top with a soft squash mid-flight — while the CRT
   on/off stays for true opens and true closes. */
@keyframes strip-flow {
  0%   { transform:none; }
  45%  { transform:scaleX(1.07) scaleY(.9); }
  100% { transform:none; }
}
.amend-strip.strip-flow { animation:strip-flow .5s cubic-bezier(.3,.9,.25,1); }
.amend-strip.strip-on  { animation:strip-on  .5s cubic-bezier(.2,.9,.3,1.2); }
.amend-strip.strip-off { animation:strip-off .22s cubic-bezier(.7,0,.9,.4) forwards; }
@media (prefers-reduced-motion: reduce) {
  .amend-strip.strip-on, .amend-strip.strip-off,
  .amend-strip.strip-flow { animation:none; }
  .amend-strip { transition:none; }
}

/* the send gate, mock 4A (2026-09-02): decision in the heading, two numbers,
   one row per short day grouped by set, chips in the roster's own colours */
.modal.gate-box { max-width:50rem; width:min(50rem, calc(100vw - 48px)); padding:0; }
.gate-kicker { font:600 10px var(--mono); letter-spacing:.1em;
               text-transform:uppercase; color:var(--muted); padding:20px 24px 0; }
/* doubled selectors outrank the modal's generic h3/p margins (the flush-left
   bug, 2026-09-02) */
.modal.gate-box .gate-title-row { display:flex; align-items:center; gap:10px; margin:4px 24px 6px; }
.modal.gate-box .gate-title-row .gate-title { margin:0; }
.modal.gate-box .gate-title-row .legend-panel p { display:block; line-height:1.5; }   /* prose, not swatch rows */
.modal.gate-box .gate-title { margin:4px 24px 6px; font:700 22px var(--sans);
              letter-spacing:-.01em; }
.modal.gate-box .gate-sub { margin:0 24px 14px; font-size:12.5px; line-height:1.55;
              color:var(--ink-2); }
/* the one-way band (Haoming, 2026-10-27): the irreversible thing first, the only red on the
   box; under it the rail's pre-flight verdict, so the decision is made with it in view */
.modal.gate-box .gate-warn { margin:0 24px 10px; padding:10px 12px; border-radius:9px; background:var(--danger-soft);
                             border:1px solid var(--danger-line); color:var(--danger-ink); font-size:12.5px; line-height:1.5; }
.modal.gate-box .gate-pf { margin:0 24px 12px; font:500 12px var(--sans); color:var(--ink-2); }
.modal.gate-box .gate-pf .warn { color:var(--danger); font-weight:600; }
.gate-stats { display:grid; grid-template-columns:repeat(2, 1fr); gap:10px;
              padding:14px 24px; background:var(--sunken); }
.gate-stat { background:var(--surface); border:1px solid var(--divider); border-radius:9px;
             padding:12px 14px; }
.gate-stat b { display:block; font:700 20px var(--sans); }
.gate-stat span { display:block; font:600 12px var(--sans); }
.gate-stat small { display:block; margin-top:3px; font-size:11px; color:var(--muted); }
.gate-list-head { padding:14px 24px 4px; font:600 12px var(--sans); }   /* Inter, sentence case — not a kicker (Haoming, 2026-10-28) */
.gate-list-head span { margin-left:8px; font:500 11px var(--sans);
                       letter-spacing:0; text-transform:none; color:var(--muted); }
/* a scrollable region is keyboard-focusable, and showModal lands focus on
   it — no ring (the blue-border bug, 2026-09-02) */
.gate-list { max-height:300px; overflow-y:auto; padding:0 24px; outline:none;
             scrollbar-width:none; }   /* no bar (2026-10-28): the fade below is the cue, as in the inbox */
.gate-list::-webkit-scrollbar { display:none; }
.gate-list::after { content:""; display:block; position:sticky; bottom:0; height:44px; margin-top:-44px;
                    pointer-events:none; opacity:0; transition:opacity 160ms ease;
                    background:linear-gradient(to bottom, rgba(var(--white-rgb),0), var(--surface)); }
.gate-list.more::after { opacity:1; }
.modal.gate-box:focus { outline:none; }
.gate-grp { display:flex; align-items:center; gap:10px; margin:10px 0 4px;
            font:600 10px var(--mono); letter-spacing:.08em;
            text-transform:uppercase; color:var(--muted); }
.gate-grp i { flex:1; border-top:1px solid var(--divider); }
.gate-row { display:flex; align-items:center; gap:10px; padding:5px 8px;
            border-radius:6px; }
.gate-row.wknd { background:var(--warn-soft); }
.gate-day { flex:none; width:44px; font:600 11px var(--mono); }
.gate-chips { flex:1; display:flex; flex-wrap:wrap; gap:6px; }
.gate-slots { flex:none; font:500 11px var(--mono); color:var(--muted); }
.gchip { display:inline-flex; align-items:center; gap:5px; padding:2px 8px;
         border:1px solid var(--divider); border-radius:6px; background:var(--surface);
         font:500 11.5px var(--sans); }
.gchip::before { content:""; width:8px; height:8px; border-radius:2px; }
.gchip.nd::before { background:var(--fill-nurse-day); }   /* nurse AM */
.gchip.nn::before { background:var(--fill-nurse-night); }   /* nurse PM */
.gchip.hd::before { background:var(--fill-hca-day); }   /* HCA AM */
.gchip.hn::before { background:var(--fill-hca-night); }   /* HCA PM */
.gchip.oic { background:var(--danger-soft); border-color:var(--danger-line); color:var(--danger); }
.gchip.oic::before { background:var(--danger); }
/* the locum box's warnings (never-sent FT ask, the auto-reject sweep):
   one tinted band between the list and the footer */
.gate-warn { margin:12px 24px 0; padding:10px 14px; border-radius:8px;
             background:var(--danger-soft); border:1px solid var(--danger-line); }
.modal.gate-box .gate-warn p { margin:0; font-size:12px; line-height:1.5; color:var(--danger-ink); }
.modal.gate-box .gate-warn p + p { margin-top:6px; }
.gate-foot { display:flex; align-items:center; gap:8px; padding:14px 24px 20px;
             margin-top:10px; border-top:1px solid var(--divider); }
.modal.gate-box .gate-foot p { flex:1; margin:0; font-size:11.5px; line-height:1.5;
              color:var(--muted); }
.gate-foot form { margin:0; }
.gate-foot.right { justify-content:flex-end; }   /* no hint: the two buttons sit bottom-right, side by side */
.modal.gate-box:focus { outline:none; }          /* the box holds the opening focus quietly */
/* the reference's three buttons: bordered white Back, salmon Proceed with a
   red border, solid teal Release — one height, one radius */
.gbtn { display:inline-flex; align-items:center; padding:10px 18px; border-radius:8px;
        border:1px solid transparent; font:600 13.5px var(--sans);
        cursor:pointer; text-decoration:none; white-space:nowrap; line-height:1.2; }
.gbtn-back { background:var(--white); border-color:var(--border-absent); color:var(--ink); }
.gbtn-back:hover { border-color:var(--ink); }
.gbtn-hold { background:var(--danger-tint); border-color:var(--danger); color:var(--danger-ink); }
.gbtn-hold:hover { background:var(--danger-tint-strong); }
.gbtn-go { background:var(--go); color:var(--white); }
.gbtn-go:hover { background:var(--go-strong); }

/* ---- Stage 3 as an inbox (mock 5a, 2026-09-02) ------------------------
   The window banner: one teal line under the stepper — state, deadline,
   reply tally; Inbox/Calendar and the state's one verb on the right. */
.win-banner { display:flex; align-items:center; gap:10px; padding:10px 16px;
              border-radius:9px; margin-bottom:12px; font-size:12.5px;
              background:var(--go-soft); color:var(--go-ink); }
.win-banner.win-shut { background:var(--subtle); color:var(--ink-2); }
.win-banner.win-closed { background:var(--warn-soft); color:var(--warn-ink); }
.win-dot { width:8px; height:8px; border-radius:50%; background:var(--go); flex:none; }
.win-shut .win-dot { background:transparent; border:1.5px solid var(--muted); }
.win-closed .win-dot { background:var(--warn); }
.win-banner b { font-weight:700; }
.win-text { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.win-right { display:flex; align-items:center; gap:8px; flex:none; }
.win-right form { margin:0; }
.seg { display:inline-flex; background:var(--white); border:1px solid var(--divider);
       border-radius:8px; padding:2px; }
.seg a { padding:5px 12px; border-radius:6px; font:600 12px var(--sans);
         color:var(--ink-2); text-decoration:none; }
.seg a.on { background:var(--ink); color:var(--white); }
.wbtn { background:var(--white); border:1px solid var(--divider); border-radius:8px;
        padding:6px 12px; font:600 12px var(--sans);
        color:var(--ink); cursor:pointer; }
.wbtn:hover { border-color:var(--ink); }
.wbtn-go { background:var(--go); border-color:var(--go); color:var(--white); }
.wbtn-go:hover { background:var(--go-strong); }

/* two panels, each its own scroller — side by side, never nested */
.results.plan-page /* the in-place wrapper (2026-09-22) takes no part in layout: the split
   stays a direct child of the page block for its height chain */
#inbox { display:contents; }
/* the inbox entrance (Haoming, 2026-09-22), real loads only (`first`): the
   cards on screen cascade in — 160ms each, a 4px rise, the script's step
   between them — and the panel fades in a beat later; a swapped-in inbox
   carries no class and plays nothing */
#inbox.first .icard { opacity:0; }
#inbox.first.ready .icard { opacity:1; }
#inbox.first.ready .icard.in { animation:icard-in 160ms cubic-bezier(.2,0,0,1) backwards;
                               animation-delay:calc(var(--i, 0) * var(--step, 20ms)); }
@keyframes icard-in { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }
#inbox.first .inbox-panel { animation:panel-in 220ms cubic-bezier(.2,0,0,1) 120ms both; }
@keyframes panel-in { from { opacity:0; } }
@media (prefers-reduced-motion: reduce) {
  #inbox.first .icard, #inbox.first.ready .icard.in { opacity:1; animation:none; }
  #inbox.first .inbox-panel { animation:none; }
}
.inbox-split { flex:1 1 0; min-height:0; }
.inbox-split { display:flex; border:1px solid var(--divider); border-radius:10px;
               background:var(--surface); overflow:hidden; }
.inbox-list { flex:0 0 46%; min-width:0; border-right:1px solid var(--divider);
              display:flex; flex-direction:column; min-height:0; }
.inbox-head { display:flex; align-items:flex-end; justify-content:space-between;
              gap:12px; padding:18px 20px 12px; }
.inbox-title { margin:0; font-size:19px; letter-spacing:-.01em; line-height:1.2; }
.inbox-sub { margin:6px 0 0; font-size:12px; color:var(--ink-2); line-height:1.5; }
.itabs { display:flex; gap:6px; flex:none; }
.itabs a { padding:6px 11px; border:1px solid var(--divider); border-radius:8px;
           font:600 12px var(--sans); color:var(--ink-2);
           text-decoration:none; white-space:nowrap; }
.itabs a span { color:var(--muted); font-weight:500; margin-left:4px; }
.itabs a.on { background:var(--ink); border-color:var(--ink); color:var(--white); }
.itabs a.on span { color:rgba(var(--white-rgb),.7); }
.inbox-tools { display:flex; align-items:center; gap:10px; padding:0 20px 10px;
               border-bottom:1px solid var(--divider); }
.inbox-cards { flex:1 1 0; min-height:0; overflow-y:auto; padding:14px 20px;
               display:flex; flex-direction:column; gap:10px; }
.inbox-more { padding:8px 20px 12px; font-size:11.5px; color:var(--muted);
              border-top:1px solid var(--divider); }
.icard { display:block; border:1.5px solid var(--divider); border-radius:10px;
         padding:12px 14px; text-decoration:none; color:inherit; background:var(--white); }
.icard:hover { border-color:var(--ink-2); }
.icard.sel { border-color:var(--go); box-shadow:0 0 0 1px var(--go) inset; }
.icard-head { display:flex; align-items:center; gap:8px; }
.gtag { background:var(--ink); color:var(--white); border-radius:5px; padding:2px 6px;
        font:600 10px var(--mono); flex:none; }
.icard-name { font-weight:700; font-size:13.5px; flex:1; min-width:0;
              overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.itag { font:600 9.5px var(--mono); letter-spacing:.08em;
        text-transform:uppercase; color:var(--muted); background:var(--subtle);
        border-radius:4px; padding:3px 7px; flex:none; }
.itag.place { color:var(--warn-ink); background:var(--warn-soft); }
.itag.on { color:var(--go-ink); background:var(--go-soft); }
.dchips { display:flex; flex-wrap:wrap; gap:6px; margin:10px 0 8px; }
.dchip { display:inline-flex; align-items:center; gap:5px; padding:3px 8px;
         border-radius:6px; border:1px solid var(--divider); background:var(--subtle);
         font:500 11.5px var(--mono); color:var(--ink-2); }
.dchip b { font-weight:700; color:var(--ink); }
.dchip i { font-style:normal; color:var(--muted); }
/* a date on a shortfall (2026-09-18): the pending cell's dark shade of its
   half, set inline from the same map the grid uses; white lettering */
.dchip.gap { border-color:transparent; color:var(--white); }
.dchip.gap b, .dchip.gap i { color:var(--white); }
.icard-foot { font-size:11.5px; color:var(--ink-2); }

.inbox-panel { flex:1 1 0; min-width:0; display:flex; flex-direction:column; min-height:0; }
.panel-body { flex:1 1 0; min-height:0; overflow-y:auto; }
/* the dates panel and the cards list show no bar (Haoming, 2026-09-22): a
   fade along the bottom edge is the cue that rows continue below, gone at
   the end; the inbox script toggles `more` on scroll, resize and every
   swap. The heads above each — the name, the title and tabs — never move. */
.panel-body, .inbox-cards { scrollbar-width:none; }
.panel-body::-webkit-scrollbar, .inbox-cards::-webkit-scrollbar { display:none; }
.panel-body::after, .inbox-cards::after { content:""; display:block; position:sticky; bottom:0;
    height:44px; margin-top:-44px; pointer-events:none; opacity:0; transition:opacity 160ms ease;
    flex:none;   /* the cards list is a flex column: a shrinkable fade collapsed to nothing */
    background:linear-gradient(to bottom, rgba(var(--white-rgb),0), var(--surface)); }
.inbox-cards::after { height:58px; margin-top:calc(-58px - 10px); bottom:-14px; }
    /* past the column's own gap, and past its 14px bottom padding — a sticky
       element inside a padded scroller stops at the padding edge otherwise,
       leaving the fade hanging above the base (Haoming's catch, 2026-09-22) */
.panel-body.more::after, .inbox-cards.more::after { opacity:1; }
.panel-head { padding:18px 22px 12px; border-bottom:1px solid var(--divider);
              /* pinned (Haoming, 2026-09-22): only the dates scroll beneath */
              position:sticky; top:0; z-index:2; background:var(--surface); }
.panel-name { margin:0; font-size:17px; letter-spacing:-.01em; }
.panel-all { display:flex; gap:8px; margin-top:10px; }   /* Approve all · Reject all (2026-09-24) */
.panel-grade { font:500 11px var(--mono); color:var(--muted); margin-left:6px; }
.panel-sub { margin:6px 0 0; font-size:12.5px; color:var(--ink-2); }
.panel-kicker { padding:14px 22px 6px; font:600 10.5px var(--mono);
                letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.orows { display:flex; flex-direction:column; gap:8px; padding:0 22px 14px; }
.orow { display:flex; align-items:center; gap:10px; padding:8px 10px;
        border:1px solid var(--divider); border-radius:8px; background:var(--white); }
.orow.st-declined, .orow.st-withdrawn { background:var(--subtle); color:var(--muted); }
.oday { background:var(--ink); color:var(--white); border-radius:6px; padding:4px 9px;
        font:600 11px var(--mono); flex:none; }
.oconseq { flex:1; min-width:0; font-size:12.5px; color:var(--ink-2); }
.oacts { display:flex; gap:6px; flex:none; }
.oacts form { margin:0; }
.gbtn-sm { padding:6px 12px; font-size:12px; }
.gbtn-no { background:var(--white); border-color:var(--danger); color:var(--danger); }
.gbtn-no:hover { background:var(--danger-soft); }
.uncov { display:flex; align-items:center; gap:14px; margin:0 22px 14px;
         padding:12px 16px; border-radius:8px; background:var(--danger-soft);
         border:1px solid var(--danger-line); font-size:12.5px; color:var(--danger-ink); }
.uncov b { font-size:22px; font-weight:700; color:var(--danger); }
.plan-rail .uncov { margin:10px 0 0; }
.panel-foot { display:flex; align-items:center; gap:10px; padding:12px 22px;
              border-top:1px solid var(--divider); }
.panel-foot form { margin:0; }
.panel-tally { flex:1; min-width:0; font-size:12px; color:var(--ink-2); line-height:1.5; }
.panel-tally b { display:block; color:var(--ink); }
.gbtn-stack { flex-direction:column; align-items:flex-start; gap:1px; padding:8px 18px; }
.gbtn-stack small { font-weight:500; font-size:10.5px; opacity:.85; }
@media (max-width:1100px) { .inbox-split { flex-direction:column; }
        .inbox-list { flex:none; border-right:0; border-bottom:1px solid var(--divider); } }

/* slice 2 (2026-09-02): the undo pill, the month strip, the slot prompt */
.did-pill { display:flex; align-items:center; gap:12px; margin:14px 22px 0;
            padding:9px 14px; border-radius:8px; background:var(--ink); color:var(--white);
            font-size:12.5px; }
.did-pill span { flex:1; min-width:0; }
.did-pill form { margin:0; }
.did-pill button { background:transparent; border:1px solid rgba(var(--white-rgb),.5);
                   color:var(--white); border-radius:6px; padding:4px 12px; cursor:pointer;
                   font:600 12px var(--sans); }
.did-pill button:hover { background:rgba(var(--white-rgb),.12); }
.panel-kicker-sub { margin-left:8px; text-transform:none; letter-spacing:0;
                    font:500 11px var(--sans); }
/* pinned below the scrolling rows: the cells share the width evenly and
   never scroll (Haoming, 2026-09-02) */
.mstrip-wrap { flex:none; border-top:1px solid var(--divider); }
.mspans { display:flex; gap:2px; padding:0 22px; margin-bottom:2px; }
.mspan { flex:1 1 0; min-width:0; overflow:hidden; white-space:nowrap; text-align:center;
         font:500 9px var(--mono); color:var(--muted);
         background:var(--band); border-left:2px solid var(--divider); border-radius:3px; padding:2px 0; }
.mspan.boundary { border-left:3px solid var(--absent); }
.mstrip { display:flex; gap:2px; padding:0 22px; }
.mcell { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; gap:2px; }
.mdow, .mnum { font:500 9px var(--mono); color:var(--muted); }
.mcell.wknd .mnum { color:var(--ink-2); font-weight:700; }
.mbox { width:100%; height:24px; border-radius:4px; display:flex; align-items:center;
        justify-content:center; font:600 9px var(--mono);
        background:var(--subtle); color:var(--ink); }
.mbox.rest { background:var(--white); border:1px dashed var(--border-absent); color:var(--muted); }
.mbox.pend { color:var(--white); }
.mbox.x24 { box-shadow:inset 0 0 0 2.5px var(--warn-ink); }
.mstrip-note { margin:8px 22px 14px; font-size:11.5px; color:var(--ink-2); }
.modal.gate-box.slot-box { max-width:34rem; }
/* the one-question confirm boxes (Approve all / Reject all, 2026-09-24): an
   alert, not a gate — narrow, even inset all round, no divider before the
   buttons */
.modal.gate-box.confirm { max-width:26rem; padding:28px 28px 24px; }
.modal.gate-box.confirm .gate-title { margin:0 0 8px; font-size:20px; }
.modal.gate-box.confirm .gate-sub { margin:0; }
.modal.gate-box.confirm .gate-foot { margin-top:24px; padding:0; border-top:0; }
/* the one line a Reject may carry for the person (Requests tab, 2026-10-15) */
.modal.gate-box.confirm .gate-why { display:block; width:100%; box-sizing:border-box; margin:8px 0 0;
                                    padding:9px 11px; border:1px solid var(--divider); border-radius:8px;
                                    font:inherit; font-size:13px; color:var(--ink); background:var(--white); }
.modal.gate-box.confirm .gate-why:focus { outline:none; border-color:var(--ink); }
.slot-list { max-height:220px; }
.slot-list .gate-chips { font-weight:600; font-size:12.5px; }

/* slice 3 (2026-09-02): stage 3 calendar view — rows with an offer carry a
   teal edge and float up their band; the rail holds the selected offer */
.cal tbody tr.has-offer td.who { box-shadow:inset 3px 0 0 var(--go); }
.rail-pill { margin:0 0 12px; }
.sel-name { margin:6px 0 4px; font-weight:700; font-size:14px; }
.sel-line { margin:0; display:flex; align-items:center; gap:8px; }
.sel-acts { display:flex; gap:8px; margin-top:10px; }
.sel-acts form { margin:0; }
.ap-row { flex-wrap:nowrap; align-items:center; gap:8px; }
.ap-row form { margin:0; margin-left:auto; }
.ap-who { display:flex; flex-direction:column; min-width:0; font-size:12px; line-height:1.3; }
.ap-who .mono { font-size:11px; color:var(--ink-2); }

/* the rail footer matches the inbox footer (2026-09-03): back and next
   side by side, right-aligned, one button style */
/* the rail is 320px: the two buttons share ONE row (Haoming, 2026-09-15 —
   the content above needs the height), trimmed rather than wrapped */
.oicbar:focus-visible { outline:2px solid var(--interactive); outline-offset:2px; }

/* stage 4 slice 2 (2026-09-03): the straight-24 pair */
.pair-note { font-size:11.5px; color:var(--go-ink); background:var(--go-soft); border-radius:6px 6px 0 0;
             padding:5px 10px; margin-bottom:-8px; }
.orow.paired { border-left:3px solid var(--go); }

/* Locum dates page (2026-09-03): one chip per claim, its status in the look */
.lchip { display:inline-block; margin:0 4px 4px 0; padding:2px 8px; border-radius:6px;
         border:1px solid var(--divider); background:var(--subtle);
         font:500 11.5px var(--mono); color:var(--ink-2); }
.lchip.st-approved { font-weight:700; color:var(--ink); border-color:var(--go); }
.lchip.st-declined, .lchip.st-withdrawn { text-decoration:line-through; color:var(--muted); }
/* a waiting date decided where it is listed (2026-11-11): the date, why it waits, Approve and Reject */
.ldecide { display:flex; align-items:center; gap:8px; margin:4px 0 0; font-size:12px; }
.ldecide form { margin:0; }
.ldecide-why { color:var(--danger-ink); }
/* the early door card in the stage-1 rail */

/* the tapped pending cell while its request sits in the rail (2026-09-04) */
.cal td.c.sel-cell .on { box-shadow:inset 0 0 0 2.5px var(--go); }

/* Desktop only (2026-09-04; the card instead of the blur, 2026-10-14): under
   the width the grid needs the shell is off screen and the wall is a plain
   card in the sign-in page's clothes — nothing greyed, nothing reachable by
   tab behind it. 1000 px admits an iPad in landscape (1024) and walls one
   upright (768); a narrowed desktop window meets the same card. The sign-in
   page shows its own narrow block on the same breakpoint (.door-narrow), so
   no session starts on a phone. */
.desktop-only, .door-narrow { display:none; }
@media (max-width:999px) {
  .app { display:none; }
  .desktop-only { display:grid; place-items:center; min-height:100vh; padding:16px;
                  background:var(--page); font-family:var(--sans); color:var(--ink); }
  .signin-page .door-wide { display:none; }
  .door-narrow { display:block; }
}
.wall-who { color:var(--muted); }
.wall-out { margin:12px 0 0; text-align:center; }
.wall-link { all:unset; cursor:pointer; font:500 12.5px var(--sans); color:var(--muted); }
.wall-link:hover { color:var(--interactive); }
@media print { .desktop-only { display:none !important; } .app { display:flex !important; } }

/* the fatigue reading on a pending row (2026-09-07) */
.fat { color:var(--danger); font-weight:700; }

/* stage 1's blank-cell strip (2026-09-11): the Day/Night toggle for duty codes */
.amend-seg { display:inline-flex; border:1px solid var(--divider); border-radius:7px;
             padding:2px; margin:0 4px; background:var(--white); }
.amend-seg button { border:0; background:transparent; padding:3px 9px; border-radius:5px;
                    font:600 11px var(--sans); color:var(--ink-2); cursor:pointer; }
.amend-seg button.on { background:var(--ink); color:var(--white); }

/* stage 1's legend button under the grid (2026-09-11) */
.inputs-foot { margin-top:8px; }
.legend-pop.wide summary { width:auto; padding:0 10px; font:600 11.5px var(--sans); }
/* the stage-1 legend sits at the FOOT of a column that does not scroll, so
   its panel opens UPWARD — nothing in the centre may run off the screen
   (Haoming, 2026-09-11) */
.legend-pop.wide .legend-panel { left:0; right:auto; top:auto; bottom:calc(100% + 6px);
                                 max-height:min(70vh, 32rem); overflow-y:auto; }
.lg-group { font:600 10.5px var(--mono); letter-spacing:.06em; text-transform:uppercase;
            color:var(--muted); margin-top:8px; }
.lg-code { display:inline-block; min-width:34px; font-weight:700; }

/* PH in lieu: the source date under the code (2026-09-11) */
.cal td.c .off.two { line-height:10px; }
.cal td.c .off.two small { display:block; font:500 7px var(--mono);
                           letter-spacing:-.02em; color:var(--muted); }

/* the date picker (2026-09-11), after Haoming's reference: header with
   arrows, weekday row, days grid, the chosen day filled */
.datepick-pop { z-index:300; width:264px; background:var(--white); border:1px solid var(--divider);
                border-radius:12px; padding:12px; box-shadow:0 10px 32px rgba(var(--ink-rgb),.18);
                font:500 13px var(--sans); }
.dp-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:8px; }
.dp-head b { font-size:14px; }
.dp-head button { width:28px; height:28px; border:1px solid var(--divider); border-radius:7px;
                  background:var(--white); cursor:pointer; font-size:15px; color:var(--ink-2); }
.dp-head button:hover { border-color:var(--ink); color:var(--ink); }
.dp-grid { display:grid; grid-template-columns:repeat(7, 1fr); gap:2px; }
.dp-dow { text-align:center; font-size:11px; color:var(--muted); padding:4px 0; }
.dp-day { height:32px; border:0; border-radius:8px; background:transparent; cursor:pointer;
          font:500 13px var(--sans); color:var(--ink); }
.dp-day:hover { background:var(--subtle); }
.dp-day.out { color:var(--muted); }
.dp-day.today { background:var(--subtle); position:relative; }
.dp-day.today::after { content:""; position:absolute; left:50%; bottom:3px; width:6px; height:2px;
                       margin-left:-3px; border-radius:1px; background:var(--muted); }
.dp-day.on { background:var(--interactive); color:var(--white); font-weight:600; }

/* the open and close (Haoming, 2026-09-11): the calendar slides down out
   from behind the strip, and straight back up behind it, swallowed at the
   strip's bottom edge through a short soft edge — the panel keeps its
   size; only what crosses the line goes. The window is padded so the
   panel's drop shadow moves with it */
.dp-mask { position:fixed; z-index:300; overflow:hidden; pointer-events:none;
           -webkit-mask-image:linear-gradient(to bottom, transparent 0, #000 6px);
           mask-image:linear-gradient(to bottom, transparent 0, #000 6px); }
.dp-mask .datepick-pop { pointer-events:auto; }
.datepick-pop.dp-sliding { transition:transform .3s cubic-bezier(.5,0,.8,.6); }
.datepick-pop.dp-in { transition-timing-function:cubic-bezier(.2,.8,.3,1); }   /* the drop eases to a stop */
@media (prefers-reduced-motion: reduce) {
  .datepick-pop.dp-sliding { transition:none; }
}

/* Logic (temp) — the rulebook page (2026-09-14) */
.logic { max-width:66rem; }
.logic .card { padding:14px 16px; margin-bottom:14px; }
.logic ul { margin:6px 0 0 18px; padding:0; }
.logic li { margin:4px 0; font-size:13px; line-height:1.45; }
.logic li b { font-weight:600; }
.logic .live { font:600 9.5px var(--mono); color:var(--positive-ink);
               background:var(--positive-soft); border-radius:3px; padding:1px 5px; margin-left:6px;
               letter-spacing:.06em; vertical-align:middle; }
.logic table.kv { border-collapse:collapse; margin:6px 0 2px; }
.logic table.kv td { padding:2px 10px 2px 0; font-size:12.5px; vertical-align:top; }
.logic table.kv td:first-child { font-weight:600; white-space:nowrap; }
.logic .sw { display:inline-block; width:12px; height:12px; border-radius:3px;
             vertical-align:-2px; margin-right:5px; border:1px solid rgba(var(--ink-rgb),.12); }
.logic .codes { display:grid; grid-template-columns:repeat(auto-fill, minmax(21rem, 1fr));
                gap:2px 18px; margin-top:6px; }
.logic .codes div { font-size:12.5px; line-height:1.4; }
.logic .codes .mono { font-weight:600; margin-right:6px; }

/* an incomplete set (Haoming, 2026-09-15): a full-timer's whole week with
   fewer working days than the rhythm says — outlined red, whatever the cause */
.cal td.c.wk-short { position:relative; background:var(--danger-soft); }
/* the frame is an overlay ABOVE the shift pills (Haoming's catch: an inset
   shadow sat under them) but BELOW the sticky name column (2), header and
   footer (3) and the hover pop (6) — a framed row scrolling under the
   footer must slide beneath it, not over it (Haoming's catch, 2026-09-15) */
.cal td.c.wk-short::after { content:""; position:absolute; inset:0; z-index:1;
    pointer-events:none; border-top:2px solid var(--danger); border-bottom:2px solid var(--danger); }
.cal td.c.wk-short.wk-start::after { border-left:2px solid var(--danger); }
.cal td.c.wk-short.wk-end::after { border-right:2px solid var(--danger); }

/* the Draft rail's pre-flight list (Haoming's Side Rail, 2026-09-15) */
.pf-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:8px; }
.pf-count { display:inline-flex; align-items:center; justify-content:center; min-width:20px;
            height:20px; padding:0 6px; border-radius:10px; background:var(--ink); color:var(--white);
            font:600 11px var(--mono); }
.pf-list { display:flex; flex-direction:column; gap:8px; }
.pf-check { display:flex; gap:9px; align-items:flex-start; padding:9px 11px;
            border:1px solid var(--divider); border-radius:9px; }
.pf-check.ok { background:var(--positive-soft); border-color:var(--positive-line); }
.pf-check.warn { background:var(--warn-soft); border-color:var(--warn-line); }
.pf-icon { flex:none; width:18px; height:18px; border-radius:50%; display:inline-flex;
           align-items:center; justify-content:center; font-size:11px; font-weight:700;
           color:var(--white); margin-top:1px; }
.pf-check.ok .pf-icon { background:var(--positive); }
.pf-check.warn .pf-icon { background:var(--warn); }
.pf-body { min-width:0; }
.pf-title { font-weight:600; font-size:12.5px; line-height:1.3; }
.pf-sub { font-size:11.5px; color:var(--ink-2); line-height:1.4; margin-top:2px; }
.pf-more > summary { list-style:none; cursor:pointer; font-size:11px; color:var(--interactive);
                     margin-top:4px; }
.pf-more > summary::-webkit-details-marker { display:none; }
.pf-more > summary::before { content:"▸ "; }
.pf-more[open] > summary::before { content:"▾ "; }
.pf-items { margin:4px 0 0; padding:0 0 0 14px; font-size:11px; color:var(--ink-2); line-height:1.4; }
.amx-fold > summary { list-style:none; cursor:pointer; }
.amx-fold > summary::-webkit-details-marker { display:none; }

/* the Draft panel (Haoming's Panel A, 2026-10-28): the rail as one surface,
   the body scrolling under a bottom fade, the foot pinned; hairline
   sections, three mono numbers, the failing checks first and the passes
   folded, the two steps to move on, one full-width button with its
   consequence under it. The chart's tokens only — the mock's zinc and teal
   stay in the mock. */
/* every step is the panel since slice four (2026-10-28): the rail itself is
   the one surface, no padding of its own, the sections' hairlines running
   edge to edge */
.results.plan-page .plan-rail { padding:0; gap:0; }
/* the body is a column: head, numbers, the tiles, the steps, the journal.
   The tiles are the one part that gives way (as the pre-flight card was):
   they shrink to a floor so the steps and the foot keep their place and
   scroll inside themselves under the fade; only when the fixed parts
   outgrow the space — a short window, Inputs' codes fold opened — does
   the body itself scroll, under the same fade, its bar hidden too */
.pnl-body { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; overflow-y:auto;
            scrollbar-width:none; }
.pnl-body::-webkit-scrollbar { display:none; }
.pnl-body > * { flex:none; }
.pnl-body::after { content:""; flex:none; display:block; position:sticky; bottom:0; height:44px; margin-top:-44px;
                   pointer-events:none; opacity:0; transition:opacity 160ms ease;
                   background:linear-gradient(to bottom, rgba(var(--white-rgb),0), var(--surface)); }
.pnl-body.more::after { opacity:1; }
.pnl-body > .pf-sec { flex:1 1 auto; min-height:170px; display:flex; flex-direction:column; }
.pf-roll { flex:1 1 auto; min-height:0; overflow-y:auto; scrollbar-width:none; }
.pf-roll::-webkit-scrollbar { display:none; }
.pf-roll::after { content:""; display:block; position:sticky; bottom:0; height:44px; margin-top:-44px;
                  pointer-events:none; opacity:0; transition:opacity 160ms ease;
                  background:linear-gradient(to bottom, rgba(var(--white-rgb),0), var(--surface)); }
.pf-roll.more::after { opacity:1; }
.pnl-hd { padding:16px 16px 12px; border-bottom:1px solid var(--divider); }
.pnl-title { margin:4px 0 0; font-size:17px; font-weight:700; letter-spacing:-.01em; line-height:1.25; }
.pnl-hd p { margin:5px 0 0; font-size:12.5px; color:var(--ink-2); line-height:1.45; }
.pnl-stat3 { display:grid; grid-template-columns:repeat(3, 1fr); border-bottom:1px solid var(--divider); }
.pnl-stat3 div { padding:10px 10px 10px 16px; min-width:0; }
.pnl-stat3 div + div { border-left:1px solid var(--divider); padding-left:12px; }
.pnl-stat3 b { display:block; font:700 20px var(--mono); letter-spacing:-.02em; line-height:1.2; }
.pnl-stat3 b.red { color:var(--danger); }
.pnl-stat3 span { display:block; font-size:11px; color:var(--muted); line-height:1.3; margin-top:2px; }
.pnl-sec { padding:12px 16px; border-bottom:1px solid var(--divider); }
.pnl-sec:last-child { border-bottom:0; }
/* Inputs (slice two): the three doors as rows — a glyph, a title, a line,
   the button at the right; a window link reads as a link; the codes fold */
.pnl-row { display:flex; gap:9px; align-items:flex-start; padding:9px 0; border-top:1px solid var(--divider-light); }
.pnl-sec > .pnl-row:first-of-type { border-top:0; }
.pnl-ic { flex:none; width:20px; height:20px; border-radius:50%; background:var(--chip); color:var(--ink-2);
          display:inline-flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; margin-top:1px; }
.pnl-tx { flex:1; min-width:0; }
.pnl-tx b { display:block; font-size:12.5px; line-height:1.3; }
.pnl-tx > span { display:block; font-size:11.5px; color:var(--ink-2); line-height:1.4; margin-top:2px; }
.pnl-tx > span b { display:inline; font-size:inherit; }
.pnl-row > .gbtn-xs { flex:none; margin-top:1px; }
.pnl-a { margin:3px 0 0; }
.pnl-a button { background:none; border:0; padding:0; font:inherit; font-size:11.5px; color:var(--interactive);
                cursor:pointer; text-align:left; line-height:1.4; }
.pnl-a button:hover { text-decoration:underline; }
.pnl-fold > summary { list-style:none; cursor:pointer; display:flex; align-items:center; gap:9px; font-size:12.5px; }
.pnl-fold > summary::-webkit-details-marker { display:none; }
.pnl-fold .chev { margin-left:auto; color:var(--muted); font-size:15px; line-height:1; transition:transform 150ms ease; }
.pnl-fold[open] > summary .chev { transform:rotate(90deg); }
/* Publish and Confirm (slice three): a line under a kicker, the diff log
   and its button inside a section */
.pnl-line { margin:6px 0 0; font-size:11.5px; color:var(--ink-2); line-height:1.4; }
.pnl-sec > form { margin-top:8px; }
.pnl-sec > .offer-list { margin:8px 0 0; }
.pnl-codes-h { margin:10px 0 4px; font-size:11.5px; color:var(--ink-2); }
.pnl-codes { margin:0; display:flex; flex-wrap:wrap; gap:4px; }
.pnl-codes span { font:600 11px var(--mono); padding:1px 6px; border:1px solid var(--divider); border-radius:4px; background:var(--subtle); }
@media (prefers-reduced-motion: reduce) { .pnl-fold .chev { transition:none; } }
.pnl-steps { display:flex; flex-direction:column; gap:8px; margin-top:8px; }
.pnl-step { display:flex; align-items:center; gap:9px; font-size:12.5px; }
.pnl-step .n { flex:none; width:20px; height:20px; border-radius:50%; border:1.5px solid var(--border-absent);
               display:inline-flex; align-items:center; justify-content:center; font:500 10.5px var(--mono); }
.pnl-step.done .n { background:var(--positive); border-color:var(--positive); color:var(--white); }
.pnl-step-acts { margin-left:auto; display:flex; gap:6px; flex:none; }
.pnl-step-acts form { margin:0; }
.gbtn-xs { padding:3px 8px; font-size:11px; border-radius:6px; }
.pnl-foot { flex:none; border-top:1px solid var(--divider); padding:12px 16px 14px; }
.pnl-foot form { margin:0; }
.pnl-go { width:100%; justify-content:center; padding:11px 18px; font-size:14px; }
.pnl-go:disabled { opacity:.45; cursor:not-allowed; }
.pnl-go:disabled:hover { background:var(--go); }
.pnl-foot small { display:block; text-align:center; color:var(--muted); margin-top:7px; font-size:12px; line-height:1.4; }
.pnl-foot .pnl-back { margin-top:6px; text-align:center; }
.pnl-back button { background:none; border:0; padding:0; font:inherit; font-size:12px; color:var(--interactive); cursor:pointer; }
.pnl-back button:hover { text-decoration:underline; }

/* Settings (2026-09-15, Haoming's mock): tabs by area, rows with the
   explanation left and the control right, the targets as steppers in the
   footer's grid with their cost, the lettering as two previews, a save
   bar only when something differs from saved */
/* the page fills the content pane so the save bar sits at its foot, above
   the footer line; sticky keeps it there when a tab grows past the pane */
.set-results { display:flex; flex-direction:column; }
.set-page { flex:1; display:flex; flex-direction:column; }
.set-tabs, .set-panel, .set-stamp { max-width:56rem; }   /* the reading width; the bar runs wider */
.set-form { flex:1; display:flex; flex-direction:column; }
.set-form[hidden] { display:none; }   /* the Access tab hides the form whole — the flex rule must not win over `hidden` */
.set-tabs { display:flex; gap:4px; border-bottom:1px solid var(--divider); margin-bottom:16px; }
.set-tab { padding:8px 12px; font-size:13px; font-weight:600; color:var(--ink-2);
           text-decoration:none; border-bottom:2px solid transparent; margin-bottom:-1px; }
.set-tab:hover { color:var(--ink); }
.set-tab.on { color:var(--ink); border-bottom-color:var(--ink); }
.set-soon-tag { font:500 10px var(--mono); color:var(--muted); letter-spacing:.04em; }
.set-card { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:18px 28px;
            align-items:start; background:var(--surface); border:1px solid var(--divider);
            border-radius:9px; padding:16px 18px; margin-bottom:12px;
            transition:background .15s, border-color .15s; }
.set-card.dirty { background:var(--warn-soft); border-color:var(--warn-line); }
.set-what h3 { margin:0 0 6px; font-size:14px; }
.set-what p { margin:0; font-size:12.5px; color:var(--ink-2); line-height:1.5; }
.set-what .set-applies { margin-top:8px; color:var(--muted); font-size:11.5px; }
/* a one-month change standing on the targets card, and the box that asks how long a change is for (2026-11-10) */
.set-what .set-month { margin-top:8px; color:var(--ink); }
.set-what .set-month .btn { margin-left:6px; }
.set-month-note { color:var(--muted); }
.tgt-moves { list-style:none; margin:14px 0 0; padding:0; }
.tgt-moves li { display:flex; justify-content:space-between; padding:5px 0; font-size:13.5px; color:var(--ink); }
.tgt-moves li b { font:600 13.5px var(--mono); }
.tgt-scopes { display:grid; grid-template-columns:1fr 1fr; gap:8px 10px; margin-top:18px; }
.tgt-scopes .gbtn { justify-content:center; }
.tgt-scopes small { grid-column:1; font-size:11.5px; line-height:1.5; color:var(--muted); }
.modal.gate-box.confirm .tgt-skipped { margin-top:12px; }
.tgt-grid { display:grid; grid-template-columns:auto 1fr 1fr; gap:8px 14px; align-items:start; }
.tgt-h { font:600 10px var(--mono); letter-spacing:.06em; color:var(--muted);
         text-transform:uppercase; align-self:center; }
.tgt-cell { display:flex; flex-direction:column; gap:4px; }
.step { display:inline-flex; border:1px solid var(--divider); border-radius:7px; background:var(--white); overflow:hidden; }
.step button { border:0; background:transparent; width:26px; font-size:15px; color:var(--ink-2); cursor:pointer; }
.step button:hover { background:var(--chip); color:var(--ink); }
.step input { width:2.6rem; border:0; border-left:1px solid var(--divider); border-right:1px solid var(--divider);
              text-align:center; font:600 14px var(--mono); color:var(--ink); padding:5px 0; }
.step-reset { border:0; background:transparent; padding:0; font-size:11px; color:var(--interactive);
              cursor:pointer; text-align:left; line-height:14px; }
.step-reset[hidden] { display:block; visibility:hidden; }   /* keeps its line: the rows never jump */
.step-cost { font-size:11px; color:var(--muted); min-height:14px; }
.set-previews { display:flex; gap:12px; flex-wrap:wrap; }
.lp { position:relative; display:flex; flex-direction:column; gap:6px; padding:10px 12px;
      border:1.5px solid var(--divider); border-radius:9px; cursor:pointer; background:var(--white); }
.lp:hover { border-color:var(--ink-2); }
.lp.on { border-color:var(--ink); }
.lp input { position:absolute; opacity:0; pointer-events:none; }
.lp-week { display:flex; }
.lp-cell { width:26px; height:20px; line-height:20px; font:700 9.5px var(--mono);
           text-align:center; color:var(--ink); }
.lp-cell.rb-start { border-radius:5px 0 0 5px; }
.lp-cell.rb-end { border-radius:0 5px 5px 0; }
.lp-cell.rb-solo { border-radius:5px; }
.lp-label { font-size:12.5px; font-weight:600; color:var(--ink); }
.lp-note { font-size:11px; color:var(--muted); }
.set-soon { background:var(--surface); border:1px dashed var(--border-absent); border-radius:9px; padding:18px; }
.set-soon h3 { margin:0 0 6px; font-size:14px; }
.set-soon p { margin:0; font-size:12.5px; color:var(--ink-2); }
.set-bar { display:flex; justify-content:flex-end; align-items:center; gap:14px; flex-wrap:wrap;
           margin-top:auto; position:sticky; bottom:0; padding:12px 16px; background:var(--warn-soft); border:1px solid var(--warn-line); border-radius:9px; }
.set-bar[hidden] { display:none; }   /* display:flex would beat the attribute */
.set-actions { display:flex; gap:8px; }
.set-stamp { margin:12px 0 0; font-size:12px; color:var(--ink-2); text-align:right; }   /* bottom right (Haoming, 2026-09-30) */

/* The Review month's quiet bar (Haoming's 6b mock, 2026-09-16): nothing has a
   box until it is on or hovered; the roles are underline tabs with counts;
   the row filters fold into one Filters button with a badge and a Clear. */
.band.quiet { gap:14px; }
.band.quiet .screen-title { margin-right:2px; }
.qnav { display:inline-flex; gap:2px; align-items:center; }
.qnav a { color:var(--muted); text-decoration:none; padding:4px 5px; border-radius:6px; font-size:12.5px; }
.qnav a:hover { color:var(--ink); background:var(--sunken); }
.qtabs { display:inline-flex; gap:14px; margin-left:6px; }
.qtab { padding:7px 1px 5px; color:var(--ink-2); text-decoration:none; font-weight:600; font-size:13.5px;
        border-bottom:2px solid transparent; }
.qtab:hover { color:var(--ink); }
.qtab.on { color:var(--ink); border-bottom-color:var(--ink); }
.qcount { color:var(--ink-2); font-weight:500; font-size:11.5px; margin-left:2px; }
.qfilters { position:static; }   /* the panel anchors to the whole right-hand cluster */
.qsep { width:1px; height:18px; background:var(--divider); margin:0 2px; }
.qfilters summary { list-style:none; cursor:pointer; font-weight:600; font-size:13px; color:var(--ink-2);
                    padding:6px 9px; border-radius:7px; user-select:none; }
.qfilters summary::-webkit-details-marker { display:none; }
.qfilters summary:focus-visible { outline:2px solid var(--interactive); outline-offset:2px; }
.qfilters summary:hover, .qfilters[open] summary { color:var(--ink); background:var(--sunken); }
.qfilters.on summary { color:var(--ink); }
.qbadge { display:inline-block; min-width:16px; padding:0 5px; border-radius:8px; font:600 10.5px var(--mono);
          background:var(--ink); color:var(--white); text-align:center; vertical-align:1px; }
.qcaret { font-size:12px; color:var(--muted); margin-left:3px; }
.qmenu { position:absolute; right:0; top:calc(100% + 8px); z-index:40;
         width:300px; max-width:calc(100vw - 24px); padding:10px 14px 8px;
         background:var(--surface); border:1px solid var(--divider); border-radius:9px;
         box-shadow:0 8px 22px rgba(var(--ink-rgb),.14); }
.qhead { margin:2px 0 6px; font:600 10.5px var(--mono); letter-spacing:.12em;
         color:var(--muted); text-transform:uppercase; }
.qopt { display:flex; align-items:center; gap:10px; padding:8px 2px; text-decoration:none; color:var(--ink);
        font-weight:500; font-size:14px; white-space:nowrap; border-radius:6px; }
.qopt:hover { background:var(--sunken); }
.qbox { flex:none; width:16px; height:16px; border:1.5px solid var(--border-absent); border-radius:4px;
        background:var(--white); position:relative; }
.qopt.on .qbox { background:var(--ink); border-color:var(--ink); }
.qopt.on .qbox::after { content:"✓"; position:absolute; inset:0; color:var(--white); font-size:11px;
                        line-height:14px; text-align:center; font-weight:700; }
.qtag { margin-left:auto; font:500 11px var(--mono); color:var(--muted); letter-spacing:.04em; }
.qfoot { display:flex; justify-content:space-between; align-items:center; margin-top:6px; padding-top:8px;
         border-top:1px solid var(--divider); font-size:13px; color:var(--muted); }
.qkey { padding:8px 2px 2px; border-top:1px solid var(--divider); margin-top:4px; }
.qkey h3 { margin:0 0 4px; font:600 10px var(--mono); letter-spacing:.06em; color:var(--muted); text-transform:uppercase; }
.qkey p { margin:3px 0; font-size:12px; color:var(--ink-2); display:flex; align-items:center; gap:7px; }
.qkey .lg-swatch { flex:none; width:14px; height:14px; border-radius:3px; }
.qclear { color:var(--danger); text-decoration:none; font-weight:600; font-size:13px; }
.qclear.off { color:var(--border-absent); }
.qright { gap:14px; position:relative; }
.qstat { color:var(--ink-2); font-size:13px; white-space:nowrap; }
.qstat small { font:600 10px var(--mono); color:var(--muted); letter-spacing:.06em; margin-right:3px; }
.qstat b { font-weight:700; color:var(--ink); }
.qdot { display:inline-block; width:7px; height:7px; border-radius:50%; background:var(--absent); margin-right:5px; vertical-align:1px; }   /* missing data reads grey, never a warning */
.qdot.warn { background:var(--danger); }   /* a cell a human must clear */
.qrows { margin:0 0 4px; padding-left:10px; font:600 10.5px/22px var(--mono); letter-spacing:.08em; color:var(--muted); }   /* the line is button-tall from the start: Save & tell arriving never moves the grid */
.qsource { margin-left:14px; font-weight:500; letter-spacing:.04em; }   /* where this month came from */

/* the Calendar's month title (2026-09-16): the grid page's title drops down
   every imported month, in the planning page's own menu shape — no box */
.month-dd { position:relative; display:inline-flex; }
details.dd > summary.month-pick { border:0; background:transparent; padding:0 4px 0 0; border-radius:6px;
    font:600 19px var(--sans); letter-spacing:-.01em; color:var(--ink); gap:6px; }
details.dd > summary.month-pick:hover { color:var(--interactive); }
.month-pick .dd-caret { font-size:12px; }
.dd-all { display:block; margin-top:4px; padding:8px 10px; border-top:1px solid var(--divider);
          color:var(--interactive); text-decoration:none; font:600 12px var(--sans); }
.dd-all:hover { background:var(--sunken); }

/* The Calendar fits the screen (Haoming, 2026-09-16): like the planning
   stages, the flex chain hands .cal-scroll its exact height, so the grid is
   the page's one scroller and its pinned header and footer are always on
   screen; the needs-a-human and not-linked cards keep a capped strip below. */
/* The soft entrance (Haoming, 2026-09-17): on a real page load the grid
   block — Planning with its rail, the Calendar — is there at once and
   settles: half to full opacity and a 5px rise over 220ms on the house
   curve. No fill mode, so the transform is gone the moment it ends and
   nothing pinned or fixed inside ever gets a new containing block; a
   tap's in-place patch never replays it. */
.page-scroll > .results.plan-page, .page-scroll > .results.cal-page {
  animation:soft-in 220ms cubic-bezier(.2,0,0,1); }
@keyframes soft-in { from { opacity:.5; transform:translateY(5px); } }
/* and again on a Regenerate before adoption (2026-10-28): the grid block
   alone is swapped in fresh and settles the same way; the rest holds still */
.plan-cal-wrap .cal-wrap.fresh { animation:soft-in 220ms cubic-bezier(.2,0,0,1); }
@media (prefers-reduced-motion: reduce) {
  .page-scroll > .results.plan-page, .page-scroll > .results.cal-page,
  .plan-cal-wrap .cal-wrap.fresh { animation:none; }
}
.page-scroll > .results.cal-page { flex:1 1 0; min-height:0; display:flex; flex-direction:column; }
/* the Rostered switch off (2026-09-21): a quiet tag on the name cell */
.cal .who-tag { display:inline-block; margin-left:5px; font:500 8.5px var(--mono);
                letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
/* placed by hand (Haoming, 2026-09-18): a thin black border on a shift
   Sister put there herself — her hand against the generator's at a glance;
   the grown hover pill keeps it under its own shadow */
.cal td.c.hand span { box-shadow:inset 0 0 0 1.5px var(--ink); }
.cal td.c.hand[data-mk]:hover span { box-shadow:inset 0 0 0 1.5px var(--ink), 0 3px 10px rgba(var(--ink-rgb),.22); }
/* the wrong address (2026-09-17): the robot, centred, and a way home */
/* full screen, no shell (2026-09-29): the same ground as the sign-in page */
.lost-page { margin:0; min-height:100vh; display:grid; place-items:center; background:var(--page);
             font-family:var(--sans); color:var(--ink); }
.lost { text-align:center; padding:40px 20px 60px; }
.lost img { width:min(300px, 60vw); border-radius:14px; }
.lost h1 { font:600 20px var(--sans); margin:18px 0 6px; color:var(--ink); }
.lost .detail { margin:0 0 6px; color:var(--muted); font-size:13px; }
.lost .btn { display:inline-block; margin-top:14px; text-decoration:none; }
.results.cal-page .qrows { flex:none; }
.results.cal-page .cal-wrap { flex:1 1 0; min-height:0; display:flex; flex-direction:column; }
.results.cal-page .cal-scroll { flex:1 1 0; min-height:0; max-height:none; }
@media (max-width:1100px) {
        /* stacked layout: back to one normal page scroll */
        .page-scroll > .results.cal-page { display:block; }
        .results.cal-page .cal-wrap { display:block; }
        .results.cal-page .cal-scroll { max-height:calc(100vh - 115px); }
}

/* Save & tell staff (2026-09-17): the button beside the month's note, the
   done line after a save, and the box's list of who hears what */
.qtell { margin-left:12px; vertical-align:middle; }
/* Undo beside Save & tell (2026-11-11): the quiet one of the pair */
.qundo { margin-left:12px; vertical-align:middle; }
.qundo + .qtell { margin-left:6px; }
.modal.gate-box .undo-left { margin-top:8px; color:var(--muted); }
/* Download, at the right of the bar (2026-09-30): an icon, the word in the hover and for screen readers */
.qrows .qdown { float:right; margin-right:6px; display:inline-flex; align-items:center; justify-content:center;
                width:24px; height:22px; border-radius:6px; color:var(--ink-2); }
.qrows .qdown:hover { background:var(--chip); color:var(--interactive); }
.qdone { margin-left:12px; color:var(--positive-ink); font-weight:600; letter-spacing:.02em; }
/* Not delivered (2026-10-13): the red words on the line are a button in the
   line's own type — the tally stays green, only the failure in danger ink */
.qnd { all:unset; cursor:pointer; color:var(--danger-ink); font:inherit; letter-spacing:inherit; font-weight:600; }
.qnd:hover { color:var(--danger); }
.tell-list { list-style:none; margin:0; padding:0 24px 6px; max-height:40vh; overflow:auto; font-size:13px; }
.tell-list li { display:flex; gap:12px; align-items:baseline; padding:7px 0; border-top:1px solid var(--divider); }
.tell-list li b { white-space:nowrap; }   /* a long list of changes never breaks the name */
.tell-list li span { color:var(--ink-2); }
.tell-list small { display:block; margin-top:2px; font-size:11.5px; color:var(--muted); }   /* Tried 13/10 16:42 */
#nd-box .gate-title + .tell-list { margin-top:10px; }   /* no sub-line: the list needs its own room under the title */
.who-list { max-height:22rem; }   /* the sweep batch by person: about ten rows, then it scrolls (2026-09-17) */

/* --- the admin side's door and the roles (slice (a), 2026-09-28) ------------
   The sign-in page is one card on the page ground; the sidebar's foot names
   who is signed in and the role they act as; the person page's Role row
   holds the grant and revoke forms; the Access tab lists who holds what. */
.signin-page { margin:0; min-height:100vh; display:grid; place-items:center;
               background:var(--page); font-family:var(--sans); color:var(--ink); }
.signin-card { width:min(26rem, calc(100vw - 32px)); background:var(--surface);
               border:1px solid var(--divider); border-radius:12px; padding:28px 28px 24px; }
.signin-brand { margin:0 0 4px; font:600 10px var(--mono); letter-spacing:.1em;
                text-transform:uppercase; color:var(--muted); }
.signin-card h1 { margin:0 0 18px; font:700 22px var(--sans); letter-spacing:-.01em; }
.signin-btn { display:block; text-align:center; text-decoration:none; padding:10px 14px; font-size:13.5px; }
.signin-note { margin:0 0 14px; font-size:12.5px; line-height:1.5; color:var(--ink-2); }
.signin-note.warn { color:var(--danger-ink); background:var(--danger-soft);
                    border:1px solid var(--danger-line); border-radius:8px; padding:8px 12px; }
.signin-dev { margin-top:22px; padding-top:16px; border-top:1px solid var(--divider); }
.signin-section { margin:0 0 8px; font:600 10px var(--mono); letter-spacing:.1em;
                  text-transform:uppercase; color:var(--muted); }
.signin-dev input[type=search] { width:100%; box-sizing:border-box; padding:8px 10px; font:inherit;
                                 font-size:13px; border:1px solid var(--divider); border-radius:7px; }
.signin-dev form { margin:0 0 8px; }
.signin-row { display:flex; justify-content:space-between; width:100%; padding:9px 10px; margin:0;
              font:inherit; font-size:13px; text-align:left; background:none; color:inherit;
              border:0; border-bottom:1px solid var(--divider); cursor:pointer; }
.signin-row:hover { color:var(--interactive); }
.signin-row .mono { color:var(--muted); font-size:11px; }
/* what to call you (2026-10-01): the same card — one field, the button, a quiet way past */
.known-form { margin:0; display:flex; flex-direction:column; gap:10px; }
.known-form input[type=text] { width:100%; box-sizing:border-box; padding:10px 12px; font:inherit;
                               font-size:15px; color:var(--ink); background:var(--surface);
                               border:1px solid var(--divider); border-radius:7px; }
.known-form .signin-btn { width:100%; cursor:pointer; font-family:inherit; }
.known-skip { align-self:center; margin-top:2px; padding:4px 8px; font:inherit; font-size:12.5px;
              color:var(--muted); background:none; border:0; cursor:pointer; text-decoration:none; }
.known-skip:hover { color:var(--interactive); }
/* the greeting's own link to that card */
.dash-hello { display:flex; align-items:baseline; gap:10px; }
.greet-change { font-size:12px; color:var(--muted); text-decoration:none; }
.greet-change:hover { color:var(--interactive); }
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }

.side-foot { margin-top:auto; padding:12px 14px 14px; border-top:1px solid var(--divider);
             display:flex; align-items:center; justify-content:space-between; gap:8px; }
.side-who { font-size:12.5px; font-weight:600; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }   /* Inter runs wider: a long name trims rather than wraps (the title has it whole) */
.side-who small { display:block; font-weight:500; font-size:11px; color:var(--muted); }
.side-foot form { margin:0; }
.side-out { background:none; border:1px solid var(--divider); border-radius:6px; padding:4px 8px;
            font:inherit; font-size:11.5px; color:var(--ink-2); cursor:pointer;
            white-space:nowrap; flex:none; }   /* never "Sign / out" beside a long name */
.side-out:hover { border-color:var(--interactive); color:var(--interactive); }

.role-row { display:flex; flex-wrap:wrap; justify-content:flex-end; align-items:center; gap:6px; }
.role-row form { margin:0; display:inline-flex; gap:6px; align-items:center; }
.role-row select { font:inherit; font-size:12px; padding:3px 6px; border:1px solid var(--divider);
                   border-radius:6px; background:var(--surface); }

.access-list { display:flex; flex-direction:column; }
.access-row { display:flex; align-items:baseline; gap:10px; padding:8px 0;
              border-bottom:1px solid var(--divider); font-size:12.5px; }
.access-row a { font-weight:600; color:inherit; text-decoration:none; }
.access-row a:hover { color:var(--interactive); }
.access-role { font:600 10.5px var(--mono); letter-spacing:.06em; text-transform:uppercase;
               color:var(--ink-2); background:var(--chip); border-radius:5px; padding:2px 7px; }
.access-row small { margin-left:auto; color:var(--muted); font-size:11px; }
.access-row b { font-weight:600; }
.access-mail { margin-left:0; color:var(--muted); font-size:11px; }
.access-act { margin-left:auto; display:inline-flex; align-items:center; gap:6px; }
.access-act form { margin:0; }
/* the account's Edit box (2026-11-11): two labelled fields in the confirm box's clothes */
.modal.gate-box.confirm .account-gap { margin-top:12px; }
.modal.gate-box.confirm .account-note { margin-top:10px; font-size:12px; color:var(--muted); }
.modal.gate-box.confirm .gate-why[readonly] { color:var(--muted); background:var(--sunken); }
.access-add { display:flex; flex-wrap:wrap; gap:6px; align-items:center; padding-top:12px; }
.access-add input, .access-add select { font:inherit; font-size:12px; padding:5px 8px;
                                        border:1px solid var(--divider); border-radius:6px; }
.access-add input { min-width:9rem; }

/* a reader's page (roles slice (b), 2026-09-28): the write controls are not
   there — every posting form and button, the dialog openers, the save bar;
   `.keep` marks the forms a reader still needs (Sign out, the settings
   values, read as a form) */
.readonly form[method="post" i]:not(.keep), .readonly [hx-post], .readonly [hx-delete],
.readonly [data-open], .readonly .set-bar { display:none !important; }
.readonly .set-form :is(input, select, button) { pointer-events:none; }

/* the Access tab's two views (2026-09-30): a segmented switch, the who-list
   with titles and an × to revoke, the read-only roles table */
.access-seg { margin:0 0 14px; }
.access-who { flex-wrap:wrap; }
.access-titles { display:inline-flex; flex-wrap:wrap; align-items:center; gap:4px 6px; }
.access-inline { margin:0 4px 0 -4px; }
.access-x { background:none; border:0; padding:0 2px; font:600 13px var(--sans);
            color:var(--muted); cursor:pointer; line-height:1; }
.access-x:hover { color:var(--danger); }
.access-matrix { border-collapse:collapse; width:100%; font-size:12.5px; }
.access-matrix th, .access-matrix td { padding:7px 10px; border-bottom:1px solid var(--divider); text-align:left; }
.access-matrix thead th { font:600 10.5px var(--mono); letter-spacing:.06em;
                          text-transform:uppercase; color:var(--muted); }
.access-matrix tbody th { font-weight:600; }
.access-matrix td.m-full { color:var(--positive-ink); font-weight:600; }
.access-matrix td.m-read { color:var(--ink-2); }
.access-matrix td.m-none { color:var(--absent); }

/* public holidays (2026-09-30): the date header on the grids, the Hospital
   tab's list; system alerts: one row each, a mailbox (2026-10-13) — a dot
   on the rows new since the last visit, the resolved ones muted with
   their ending */
.cal thead tr.dom th.ph { background:var(--holiday-soft); color:var(--holiday-ink); font-weight:700;
                          border-radius:4px; }   /* the whole date cell tinted; outranks the header's own ink */
.cal thead tr.dom th.ph { cursor:pointer; }
/* the click-to-name label above a holiday's date cell (2026-09-30) */
.peek-ph { position:absolute; transform:translate(-50%, -100%); padding:6px 10px; border-radius:8px;
           background:var(--ink); color:var(--white); font:600 12px/1.2 var(--sans);
           white-space:nowrap; pointer-events:none; z-index:60; opacity:0;
           --peek-in:120ms; transition:opacity var(--peek-in) ease-out; }
.peek-ph.on { opacity:1; }
@media (prefers-reduced-motion: reduce) { .peek-ph { transition:none; } }
.ph-year { margin:8px 0 2px; font:600 10.5px var(--mono); letter-spacing:.08em;
           text-transform:uppercase; color:var(--muted); }
.ph-day { min-width:7.5rem; color:var(--ink-2); font-size:11.5px; }
.ph-check { margin-top:10px; }
.alerts-sheet { max-width:64rem; padding:4px 16px; }
.alert-row { display:flex; align-items:baseline; gap:12px; padding:9px 0; border-bottom:1px solid var(--divider);
             font-size:12.5px; }
.alert-row::before { content:""; flex:none; align-self:center; width:7px; height:7px; border-radius:50%; }   /* Mail's dot: its place kept on every row */
.alert-row.unread::before { background:var(--interactive); }
.alert-row.unread .alert-msg { font-weight:600; }
.alert-row.resolved { color:var(--muted); }
.alert-when { flex:none; font-size:11px; color:var(--muted); }
.alert-kind { flex:none; font:600 10.5px var(--mono); letter-spacing:.06em; text-transform:uppercase;
              background:var(--danger-soft); color:var(--danger-ink); border-radius:5px; padding:2px 7px; }
.alert-row.resolved .alert-kind { background:var(--chip); color:var(--ink-2); }
.alert-msg { flex:1; min-width:0; }
.alert-end { flex:none; font-size:11px; }
.alert-act { flex:none; margin:0; }
