/* Tokens from docs/design/staff-directory/README.md. The colour semantics do
     safety work — see "Colour Semantics" there before changing any of these. */
  :root {
    --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;
    --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;
    --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 "Instrument Sans", system-ui, sans-serif;
    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:"IBM Plex Mono", ui-monospace, monospace; }

  /* 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 "Instrument Sans", sans-serif; 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; }
  @media (max-width:900px) {
    .app { flex-direction:column; height:auto; min-height:100vh; }
    .side { width:auto; border-right:none; border-bottom:1px solid var(--divider);
            overflow-y:visible; }
    .page-scroll { overflow-y:visible; }
  }

  /* 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 "IBM Plex Mono", monospace; 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 "Instrument Sans", sans-serif; 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 "IBM Plex Mono", monospace;
             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 "Instrument Sans", sans-serif; }
  .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 "IBM Plex Mono", monospace; }
  /* 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 "IBM Plex Mono", monospace; }
  .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 "IBM Plex Mono", monospace; }
  .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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace;
            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 "IBM Plex Mono", monospace;
             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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "Instrument Sans", sans-serif;
                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 "IBM Plex Mono", monospace; 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); } }

.col-head { font:600 11px "IBM Plex Mono", monospace; 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; }
.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 "Instrument Sans", sans-serif; 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 "Instrument Sans", sans-serif; border:1px solid var(--divider);
  border-radius:4px; padding:3px 6px; background:var(--white); color:var(--ink); }
.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 "Instrument Sans", sans-serif; 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; }
.add-form .warn-box { margin-bottom:0; }

/* 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "Instrument Sans", sans-serif; 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 "IBM Plex Mono", monospace;
             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 "Instrument Sans", sans-serif; 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 "IBM Plex Mono", monospace; 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); }
.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 "IBM Plex Mono", monospace !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 "Instrument Sans", sans-serif;
                letter-spacing:-.01em; }  /* the house screen-title size */
.dash-sub { margin:4px 0 0; color:var(--muted); font-size:13px; }
.dash-cards { display:grid; grid-template-columns:repeat(3, 1fr); gap:14px; }
.dash-main { display:grid; grid-template-columns:2fr 1fr; gap:14px; }
.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 "IBM Plex Mono", monospace;
           letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.ph-tall { min-height:260px; }
@media (max-width:1100px) {
  .dash-cards, .dash-main { grid-template-columns:1fr; }
}

/* 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 .plan-advance { margin-top:auto;
        border-top:1px solid var(--divider); padding-top:12px;
        text-align:right; }
/* the pre-flight card is the ONLY card that gives way: it scrolls inside
   itself, every other card keeps its height, so nothing is clipped and a
   long list never pushes into the advance card (Side Rail, 2026-09-15) */
.results.plan-page .plan-rail .card { flex:none; }
.results.plan-page .plan-rail .pf-card { flex:1 1 auto; min-height:160px; overflow-y:auto; }
.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, .plan-advance { padding:14px 16px; }
.plan-stage-kicker { font:600 10.5px "IBM Plex Mono", monospace; 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); }
.plan-advance form { margin-top:8px; }
@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); }
.plan-peek { padding:10px 14px; font-size:12.5px; background:var(--band); }
.plan-peek a { color: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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace;
    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 "Instrument Sans", sans-serif; 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 "IBM Plex Mono", monospace; 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 { margin:4px 24px 6px; font:700 22px "Instrument Sans", sans-serif;
              letter-spacing:-.01em; }
.modal.gate-box .gate-sub { margin:0 24px 14px; font-size:12.5px; line-height:1.55;
              color:var(--ink-2); }
.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 "Instrument Sans", sans-serif; }
.gate-stat span { display:block; font:600 12px "Instrument Sans", sans-serif; }
.gate-stat small { display:block; margin-top:3px; font-size:11px; color:var(--muted); }
.gate-list-head { padding:14px 24px 4px; font:600 10px "IBM Plex Mono", monospace;
                  letter-spacing:.1em; text-transform:uppercase; }
.gate-list-head span { margin-left:8px; font:500 11px "Instrument Sans", sans-serif;
                       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; }
.modal.gate-box:focus { outline:none; }
.gate-grp { display:flex; align-items:center; gap:10px; margin:10px 0 4px;
            font:600 10px "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; }
.gate-chips { flex:1; display:flex; flex-wrap:wrap; gap:6px; }
.gate-slots { flex:none; font:500 11px "IBM Plex Mono", monospace; 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 "Instrument Sans", sans-serif; }
.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-scroll { margin:4px 24px 0; font-size:11px; color:var(--muted); }
.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 "Instrument Sans", sans-serif;
        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 "Instrument Sans", sans-serif;
         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 "Instrument Sans", sans-serif;
        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 "Instrument Sans", sans-serif; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace;
                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 "IBM Plex Mono", monospace; 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 "Instrument Sans", sans-serif; }
.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 "Instrument Sans", sans-serif; }
/* 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace;
        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; }
.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 */
.adv-row { display:flex; flex-wrap:nowrap; justify-content:flex-end; align-items:stretch;
           gap:6px; margin-top:8px; }
.adv-row form { margin:0; min-width:0; }
.adv-row .gbtn { padding:8px 12px; font-size:12.5px; }
.adv-row .gbtn-stack { align-items:flex-start; padding:6px 12px; }
.adv-row .gbtn-stack small { font-size:9.5px; white-space:normal; line-height:1.25; }
/* 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 "IBM Plex Mono", monospace; 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); }
/* the early door card in the stage-1 rail */
.ldoor { margin:4px 0 6px; padding:10px 12px; border:1px solid var(--divider);
         border-radius:8px; background:var(--subtle); }
.ldoor form { margin-top:8px; }

/* 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, for now (2026-09-04): under 1000px the app blurs behind a
   plain notice. Removed when the mobile-friendly pass lands. */
.desktop-only { display:none; }
@media (max-width:999px) {
  .desktop-only { display:flex; position:fixed; inset:0; z-index:1000;
                  align-items:center; justify-content:center; padding:24px;
                  background:rgba(var(--ink-rgb),.35); backdrop-filter:blur(6px);
                  -webkit-backdrop-filter:blur(6px); }
  .desktop-only-box { background:var(--white); border-radius:12px; padding:22px 24px;
                      max-width:22rem; box-shadow:0 8px 40px rgba(var(--ink-rgb),.25);
                      display:flex; flex-direction:column; gap:8px; }
  .desktop-only-box b { font-size:16px; }
  .desktop-only-box span { font-size:13px; color:var(--ink-2); line-height:1.5; }
}
@media print { .desktop-only { display:none !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 "Instrument Sans", sans-serif; 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 "Instrument Sans", sans-serif; }
/* 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace;
                           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 "Instrument Sans", sans-serif; }
.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 "Instrument Sans", sans-serif; 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 .toc { display:flex; flex-wrap:wrap; gap:6px; margin:0 0 4px; }
.logic .toc a { text-decoration:none; }
.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 .since { font:600 9.5px "IBM Plex Mono", monospace; color:var(--muted);
                margin-left:5px; letter-spacing:.04em; }
.logic .live { font:600 9.5px "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; }
.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; }

/* 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 "IBM Plex Mono", monospace; 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; }
.tgt-grid { display:grid; grid-template-columns:auto 1fr 1fr; gap:8px 14px; align-items:start; }
.tgt-h { font:600 10px "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace;
           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 "IBM Plex Mono", monospace;
          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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "IBM Plex Mono", monospace; 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 "Instrument Sans", sans-serif; 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 "Instrument Sans", sans-serif; }
.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); } }
@media (prefers-reduced-motion: reduce) {
  .page-scroll > .results.plan-page, .page-scroll > .results.cal-page { 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 "IBM Plex Mono", monospace;
                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:"Instrument Sans", sans-serif; 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 "Instrument Sans", sans-serif; 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; }
/* 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; }
.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 span { color:var(--ink-2); }
.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:"Instrument Sans", sans-serif; 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 "IBM Plex Mono", monospace; letter-spacing:.1em;
                text-transform:uppercase; color:var(--muted); }
.signin-card h1 { margin:0 0 18px; font:700 22px "Instrument Sans", sans-serif; 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 "IBM Plex Mono", monospace; 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; }
.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 "IBM Plex Mono", monospace; 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; }
.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 "Instrument Sans", sans-serif;
            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 "IBM Plex Mono", monospace; 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, acknowledged ones muted */
.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 "Instrument Sans", sans-serif;
           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 "IBM Plex Mono", monospace; 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.acked { color:var(--muted); }
.alert-when { flex:none; font-size:11px; color:var(--muted); }
.alert-kind { flex:none; font:600 10.5px "IBM Plex Mono", monospace; letter-spacing:.06em; text-transform:uppercase;
              background:var(--danger-soft); color:var(--danger-ink); border-radius:5px; padding:2px 7px; }
.alert-row.acked .alert-kind { background:var(--chip); color:var(--ink-2); }
.alert-msg { flex:1; min-width:0; }
.alert-ack { flex:none; font-size:11px; }
.alert-act { flex:none; margin:0; }
