  :root{
    --bg:#e8fccf; --surface:#FCFAF4; --surface-2:#F1ECE1; --line:#E3DCCB;
    /* THE ICON PALETTE, sampled straight out of the six reference drawings
       rather than guessed at. Every icon in the app is built from these seven
       and nothing else, which is the only reason thirty separate drawings look
       like one set.

       --ic-gap is not a colour of its own: it is whatever the icon is sitting
       ON. It punches the white channel between a badge and the shape under it.
       A surface that is not a card has to restate it, or the gap gets drawn in
       the wrong colour and the badge looks pasted on. */
    --ic-teal:#2E7E6F; --ic-mint:#E7F0CD; --ic-slate:#587C80; --ic-paper:#FBF9F3;
    --ic-shade:#CED6AF; --ic-shadow:#E9E9E9; --ic-ink:#5D5D69; --ic-gap:#FCFAF4;
    /* The dashboard's own ground. Separate from --ic-teal because an icon and
       a full-page panel want opposite things from a dark theme: a 20px shape
       needs to get BRIGHTER to stay legible, a wall of colour needs to get
       darker or it lights the whole room. In light mode they agree. */
    --ph-ground:#2E7E6F; --ph-heading:#2F4057;
    /* Text colours that clear WCAG's 4.5:1 on every ground the app has: the
       page, a card, a grey pill, a tinted chip. The secondary grey sat at
       4.2-4.4, teal on a teal chip at 4.2 and coral text at 3.3. */
    --text:#2A2723; --muted:#6B665B; --teal:#2B7466; --teal-dim:#E4EFE8;
    --coral:#AE4C30; --coral-dim:#FBE9E1;
    /* A colour behind white text. The same as the colour itself here; in the
       dark theme the colour brightens to be read ON the dark, and white on it
       fell to 2.6:1, so the fill keeps a deeper shade. */
    --teal-fill:var(--teal); --coral-fill:var(--coral);
    /* Late: a dose or an observation past its time. */
    --late:#B3261E; --amber:#C68D2C; --amber-dim:#FBF1DD;
    --page-bg:#EDE8DC; --danger-bg:#FDECEC; --danger-border:#F3B9B9; --danger-text:#8A2020;
    --amber-text:#7A5A17; --coral-text-strong:#8A3A22; --coral-text-body:#6B4230;
    /* Outline buttons draw their border in this, NOT in --line. --line is the
       divider colour: on a card it lands at about 1.3:1 against --surface, which
       is invisible as a control boundary. This clears 3:1 in both themes. */
    --btn-border:#8A8471;
    /* Chart tokens. --chart-1..3 are an ordinal ramp on the brand teal: one hue,
       monotone OKLCH lightness, steps 0.10 apart. They are numbered by the bucket
       they encode — 1 is the soonest — not by lightness, so the same token means
       the same thing in both themes and the rendering code never asks which theme
       it is in. Generated at fixed lightness and checked, not eyeballed: here the
       middle step IS --teal, and the three sit at 7.19 / 4.70 / 3.15:1 against
       --surface, so every segment clears the 3:1 mark floor on its own.
       --chart-track is the unfilled remainder of the ring — a lighter step of the
       same hue at 1.73:1, enough to read as a track without competing with the
       fill it is measuring against. */
    --chart-1:#026052; --chart-2:#2F7D6E; --chart-3:#4F9B8B; --chart-track:#83CFBE;
    /* A dental chart draws what is already in the mouth in blue and what needs
       doing in red (--coral); 6.2:1 and 6.3:1 against --surface. */
    --tooth-resto:#2F62A8; --tooth-sealant:#A9C8EC;
  }
  html[data-theme="dark"]{
    --bg:#1C1B19; --surface:#26251F; --surface-2:#2E2C25; --line:#3A382F;
    /* Dark mode restates seven values. This is the whole argument for drawing
       these rather than shipping the PNGs: a bitmap baked at #2E7E6F on cream
       is the wrong drawing here and there is no fixing it except shipping every
       icon a second time. The shadow inverts -- a light-grey offset under a
       shape on a dark card reads as a halo, not a shadow. */
    --ic-teal:#4FAF9B; --ic-mint:#DCE9BE; --ic-slate:#7FA2A6; --ic-paper:#F4F2EA;
    --ic-shade:#B4C296; --ic-shadow:rgba(0,0,0,.38); --ic-ink:#43434E; --ic-gap:#26251F;
    --ph-ground:#1F5E51; --ph-heading:#DDE4EC;
    --text:#EDEAE2; --muted:#9A968A; --teal:#4FAF9B; --teal-dim:#1F332E; --teal-fill:#2E7E6F; --coral-fill:#B4532F; --late:#F28B82;
    --coral:#E8886A; --coral-dim:#3A2620; --amber:#D9A94A; --amber-dim:#3A3020;
    --page-bg:#121110; --danger-bg:#3A1E1E; --danger-border:#5C2E2E; --danger-text:#F5B4B4;
    --amber-text:#E8C97A; --coral-text-strong:#F0A98C; --coral-text-body:#D9A085;
    --btn-border:#7A7766;
    --chart-1:#4FAF9B; --chart-2:#288E7B; --chart-3:#006E5D; --chart-track:#005447; --tooth-resto:#7AA8EA; --tooth-sealant:#34557D;
  }
  /* Native browser chrome inside <input type="time/date"> — the little clock
     and calendar icons — otherwise renders dark by default regardless of
     page theme, making it invisible against a dark input background. */
  html[data-theme="dark"] input[type="time"],
  html[data-theme="dark"] input[type="date"]{ color-scheme: dark; }
  @media (prefers-color-scheme: dark){
    html[data-theme="system"]{
      --bg:#1C1B19; --surface:#26251F; --surface-2:#2E2C25; --line:#3A382F;
      /* Dark mode restates seven values. This is the whole argument for drawing
         these rather than shipping the PNGs: a bitmap baked at #2E7E6F on cream
         is the wrong drawing here and there is no fixing it except shipping every
         icon a second time. The shadow inverts -- a light-grey offset under a
         shape on a dark card reads as a halo, not a shadow. */
      --ic-teal:#4FAF9B; --ic-mint:#DCE9BE; --ic-slate:#7FA2A6; --ic-paper:#F4F2EA;
      --ic-shade:#B4C296; --ic-shadow:rgba(0,0,0,.38); --ic-ink:#43434E; --ic-gap:#26251F;
      --ph-ground:#1F5E51; --ph-heading:#DDE4EC; --ph-heading:#DDE4EC;
      --text:#EDEAE2; --muted:#9A968A; --teal:#4FAF9B; --teal-dim:#1F332E; --teal-fill:#2E7E6F; --coral-fill:#B4532F; --late:#F28B82;
      --coral:#E8886A; --coral-dim:#3A2620; --amber:#D9A94A; --amber-dim:#3A3020;
      --page-bg:#121110; --danger-bg:#3A1E1E; --danger-border:#5C2E2E; --danger-text:#F5B4B4;
      --amber-text:#E8C97A; --coral-text-strong:#F0A98C; --coral-text-body:#D9A085;
      --btn-border:#7A7766;
      --chart-1:#4FAF9B; --chart-2:#288E7B; --chart-3:#006E5D; --chart-track:#005447; --tooth-resto:#7AA8EA; --tooth-sealant:#34557D;
    }
    html[data-theme="system"] input[type="time"],
    html[data-theme="system"] input[type="date"]{ color-scheme: dark; }
  }
  *{box-sizing:border-box;}
  html,body{margin:0;padding:0;height:100%;}
  body{background:var(--page-bg); font-family:'Inter',sans-serif; color:var(--text); display:flex; min-height:100vh; padding:24px 12px; transition:background .2s;}
  .phone{width:390px; max-width:94vw; height:calc(100vh - 48px); max-height:844px; margin:auto; background:var(--bg); border-radius:32px; border:10px solid #1F1D19; box-shadow:0 40px 80px -20px rgba(0,0,0,.45); overflow:hidden; position:relative; display:flex; flex-direction:column;}
  /* Stated once, so anything that needs to break out of this padding can pull
     back by exactly it instead of guessing. */
  .screen{--sp-x:22px; --sp-y:30px;
          padding:var(--sp-y) var(--sp-x); overflow-y:auto; flex:1;
          -webkit-overflow-scrolling:touch; position:relative;}

  /* Scrollbars, without the grey gutter.

     Every scrolling area drew the browser's default bar: a light grey track
     running the full height beside the content. Inside a rounded phone frame
     that reads as a seam rather than a control, and it was visible whether or
     not anything was being scrolled.

     The TRACK goes fully transparent — that is the grey. The THUMB stays, at
     low opacity, because it is the only thing telling somebody how far down a
     long list they are, and on the horizontally scrolling rows it is the only
     hint there is more to the right. Kept deliberately faint rather than
     removed: invisible scrollbars are a real accessibility problem, not a
     style choice.

     Firefox uses scrollbar-width/scrollbar-color; WebKit and Blink use the
     pseudo-elements. Both are written out because neither covers the other,
     and mobile browsers overlay their own anyway. */
  *{ scrollbar-width: thin; scrollbar-color: rgba(122,117,106,0.28) transparent; }
  ::-webkit-scrollbar{ width:7px; height:7px; }
  ::-webkit-scrollbar-track{ background:transparent; }
  ::-webkit-scrollbar-corner{ background:transparent; }
  ::-webkit-scrollbar-thumb{ background:rgba(122,117,106,0.28); border-radius:4px; }
  ::-webkit-scrollbar-thumb:hover{ background:rgba(122,117,106,0.45); }
  html[data-theme="dark"] *{ scrollbar-color: rgba(237,234,226,0.24) transparent; }
  html[data-theme="dark"] ::-webkit-scrollbar-thumb{ background:rgba(237,234,226,0.24); }
  html[data-theme="dark"] ::-webkit-scrollbar-thumb:hover{ background:rgba(237,234,226,0.40); }
  @media (prefers-color-scheme: dark){
    html[data-theme="system"] *{ scrollbar-color: rgba(237,234,226,0.24) transparent; }
    html[data-theme="system"] ::-webkit-scrollbar-thumb{ background:rgba(237,234,226,0.24); }
    html[data-theme="system"] ::-webkit-scrollbar-thumb:hover{ background:rgba(237,234,226,0.40); }
  }
  .brand{font-family:'Fraunces'; font-weight:700; font-size:16px; display:flex; align-items:center; gap:7px; margin-bottom:4px;}
  .back-nav{width:34px; height:34px; border-radius:50%; background:var(--surface); border:1px solid var(--line); display:flex; align-items:center; justify-content:center; font-size:19px; font-weight:700; color:var(--text); cursor:pointer; margin-bottom:18px; line-height:1;}
  #bottom-tab-bar{position:absolute; left:0; right:0; bottom:0; display:flex; justify-content:space-around; padding:10px 0 14px; background:var(--surface); border-top:1px solid var(--line); z-index:50;}
  .screen.tabbar-space{padding-bottom:88px;}
  #bottom-tab-bar.hidden{display:none !important;}
  .tab-btn2{display:flex; flex-direction:column; align-items:center; gap:2px; cursor:pointer; color:var(--muted); background:none; border:none; font-family:'Inter'; padding:2px 10px; transition:color .18s ease;}
  .tab-btn2 .tab-icon2{font-size:19px; transition:transform .18s ease;}
  .tab-btn2.active{color:var(--teal);}
  .tab-btn2.active .tab-icon2{transform:translateY(-2px);}
  .tab-btn2 .tab-label2{font-size:9.5px; font-weight:700;}
  .tab-screen-anim{transition:opacity .2s ease, transform .2s ease;}
  .auth-collapse{overflow:hidden; max-height:110px; opacity:1; transition:max-height .28s ease, opacity .22s ease, margin .28s ease;}
  .auth-collapse.collapsed{max-height:0; opacity:0; margin-top:0 !important; margin-bottom:0 !important; pointer-events:none;}
  .auth-fade-text{transition:opacity .15s ease;}
  .auth-fade-text.fading{opacity:0;}
  .tab-fade-out{opacity:0 !important; transform:translateY(-6px);}
  .tab-fade-in-start{opacity:0 !important; transform:translateY(6px);}
  .connections-details summary{ list-style:none; }
  .connections-details summary::-webkit-details-marker{ display:none; }
  .connections-details summary::before{ content:'▸ '; }
  .connections-details[open] summary::before{ content:'▾ '; }
  /* Kept: nothing uses it now, but a rule this small is cheaper to leave
     than to prove nothing anywhere wants a plain mark. */
  .brand .dot{width:8px; height:8px; border-radius:50%; background:var(--teal-fill);}
  /* Sized off the wordmark so the pair scales together, and slightly taller
     than the cap height because a crest sitting exactly on the baseline reads
     as too small next to a serif. */
  .brand .brand-mark{width:1.38em; height:1.38em; vertical-align:-.28em;}
  .sub{color:var(--muted); font-size:13.5px; margin:0 0 22px; line-height:1.5;}
  /* A status line with nothing in it is not a spacer. These paragraphs are
     empty until something is worth saying, but they still carry .sub's 22px
     bottom margin, so every one of them left a band of dead space under the
     control it belongs to — most visibly under "Generate slots", where the
     card just looked like it had a hole in the bottom of it. */
  p.sub[id$="-status"]:empty{display:none;}
  /* A status line reporting a RESULT, not progress. Muted grey is the colour of
     "still thinking", so a line saying thirty days of slots had just been
     written looked identical to one saying it was working on it. Two classes
     deep so it beats .sub's colour without reaching for !important. */
  .sub.status-ok{color:var(--teal); font-weight:700;}
  .sub.status-bad{color:var(--coral); font-weight:700;}
  label{font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); display:block; margin-bottom:6px;}
  /* 16px, not 15px, and that one pixel is load-bearing: iOS Safari zooms the
     page in whenever a focused field is smaller than 16px, and the usual
     "fix" for that is user-scalable=no on the viewport — which also takes
     pinch-zoom away from everyone. Sizing the fields at 16px removes the
     reason for the zoom block, so both behaviours can be correct at once. */
  input{width:100%; padding:14px; border-radius:12px; border:1px solid var(--line); font-size:16px; margin-bottom:14px; font-family:'Inter', sans-serif; background:var(--surface); color:var(--text);}
  select{width:100%; padding:14px; border-radius:12px; border:1px solid var(--line); font-size:16px; margin-bottom:14px; font-family:'Inter', sans-serif; background:var(--surface); color:var(--text);}
  textarea{width:100%; padding:14px; border-radius:12px; border:1px solid var(--line); font-size:16px; margin-bottom:14px; font-family:'Inter', sans-serif; background:var(--surface); color:var(--text); resize:vertical;}
  input::placeholder{color:var(--muted);}
  .btn{width:100%; border:none; border-radius:14px; padding:15px; font-weight:700; font-size:15px; cursor:pointer; margin-bottom:10px; text-align:center;}
  .btn-teal{background:var(--teal-fill); color:#fff;}
  .btn-outline{background:transparent; border:1px solid var(--btn-border); color:var(--text);}
  /* A button mid-request. Saving appointment settings and generating slots both
     go to the network before anything on screen changes, and with no busy state
     the button read as dead — the reason a working Save was reported broken.
     The pointer change matters as much as the fade: it is what says "this is
     running", not "this is unavailable". */
  .btn:disabled{opacity:.6; cursor:progress;}
  /* Applied by the blanket reactivity wrapper, which does not change the label
     — so the pulse is the whole signal that something is happening, and it has
     to be visible without being a distraction. */
  .btn-busy{animation:btn-pulse 1s ease-in-out infinite;}
  @keyframes btn-pulse{0%,100%{opacity:.6;} 50%{opacity:.35;}}
  /* The companion to .btn-busy. That one says "working"; this says "done".
     Both are needed: a revoke is irreversible from the admin's side and takes
     a moment, so without a finish signal the only feedback is a toast that may
     already have gone, and the natural reaction is to press it again.
     Deliberately brief -- a button that stays lit is a button somebody
     presses twice. */
  .btn-done{animation:btn-done-flash .55s ease-out 1;
    border-color:var(--teal)!important; color:var(--teal)!important;}
  @keyframes btn-done-flash{
    0%{transform:scale(1); opacity:.7;}
    35%{transform:scale(1.035); opacity:1;}
    100%{transform:scale(1); opacity:1;}
  }
  @media (prefers-reduced-motion: reduce){
    .btn-busy{animation:none; opacity:.5;}
    /* The colour and the label still change, so the message survives without
       the movement. */
    .btn-done{animation:none;}
  }
  .btn-google{background:#fff; border:1px solid #DADCE0; color:#3C4043; display:flex; align-items:center; justify-content:center; gap:10px;}
  .btn-apple{background:#000; border:1px solid #000; color:#fff; display:flex; align-items:center; justify-content:center; gap:8px;}
  .divider{display:flex; align-items:center; gap:10px; margin:16px 0; color:var(--muted); font-size:12px;}
  .divider::before, .divider::after{content:''; flex:1; height:1px; background:var(--line);}
  .role-pick{display:flex; gap:10px; margin-bottom:16px;}
  .role-card{flex:1; border:2px solid var(--line); border-radius:14px; padding:20px 10px; text-align:center; cursor:pointer;}
  .role-card.selected{border-color:var(--teal); background:var(--teal-dim);}
  .role-card .ico{font-size:30px; margin-bottom:8px;}
  .role-card .name{font-weight:700; font-size:14px;}
  .card{background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:16px; margin-bottom:12px;}
  .tip-section{background:var(--surface); border:1px solid var(--line); border-radius:16px; margin-bottom:12px; overflow:hidden;}
  .tip-section summary{padding:16px; font-weight:700; font-size:14.5px; cursor:pointer; list-style:none; display:flex; align-items:center; justify-content:space-between;}
  .tip-section summary::-webkit-details-marker{display:none;}
  .tip-section summary::after{content:'+'; font-size:20px; color:var(--muted); font-weight:400;}
  .tip-section[open] summary::after{content:'−';}
  .tip-section .tip-body{padding:0 16px 16px;}
  .tip-body h4{font-size:12.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); margin:14px 0 6px;}
  .tip-body h4:first-child{margin-top:0;}
  /* Same physical-padding bug as #legal-doc-body ul below — health tips are
     bulleted prose in five languages too. */
  .tip-body ul{margin:0 0 8px; padding-inline-start:20px; padding-inline-end:0;}
  .tip-body li{font-size:13.5px; line-height:1.5; margin-bottom:4px;}
  .tip-body p{font-size:13.5px; line-height:1.5; margin:0 0 8px;}
  #legal-doc-body h3{font-size:15px; font-weight:700; margin:20px 0 8px;}
  #legal-doc-body h3:first-child{margin-top:0;}
  #legal-doc-body p{font-size:13.5px; line-height:1.6; margin:0 0 10px; color:var(--text);}
  /* Logical, not physical. padding-left indents the wrong side in Arabic and
     Urdu: the browser puts its own 40px default on the right for the marker,
     and the explicit 20px on the left then becomes dead space the text can
     never use. The bullets ended up in a narrower column than the paragraphs
     around them, wrapping early and reading as misaligned against the prose.
     padding-inline-start indents the marker side in both directions, and the
     indent is the same 20px in every language instead of 20 one way and 40 the
     other. */
  #legal-doc-body ul{margin:0 0 10px; padding-inline-start:20px; padding-inline-end:0;}
  #legal-doc-body li{font-size:13.5px; line-height:1.6; margin-bottom:6px;}
  #legal-doc-body a{color:var(--teal);}
  .emergency-banner{background:var(--danger-bg); border:1px solid var(--danger-border); border-radius:12px; padding:12px 14px; font-size:13px; line-height:1.5; color:var(--danger-text); margin-bottom:16px;}
  .tab-row{display:flex; gap:6px; margin-bottom:14px; background:var(--surface); border:1px solid var(--line); border-radius:12px; padding:4px;}
  /* Written when every tab was a <div>. A <button> carries the browser's own
     border and background, which read as a blurry double outline inside the
     pill. Neutralised here rather than in the markup so both element types
     look identical and the next one added cannot get it wrong. .tab-btn.active
     comes after this, so its teal background still wins. */
  .tab-btn{flex:1; text-align:center; padding:9px 4px; border-radius:9px; font-size:13px; font-weight:700; cursor:pointer; color:var(--muted);
    border:none; background:none; font-family:inherit; -webkit-appearance:none; appearance:none;}
  .section-label{font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); margin:14px 0 6px;}
  .map-filter-chip{font-size:12px; font-weight:700; padding:7px 12px; border-radius:20px; background:var(--surface); border:1px solid var(--line); color:var(--muted); cursor:pointer;}
  .map-filter-chip.active{background:var(--teal-dim); border-color:var(--teal); color:var(--text);}
  /* The assistant thread. Same bubble language as the home-visit messages, so
     one conversation in this app looks like another. */
  .ai-turn{border-radius:14px; padding:11px 13px; margin-bottom:8px; font-size:13.5px; line-height:1.55; white-space:pre-wrap; overflow-wrap:anywhere;}
  .ai-mine{background:var(--teal-fill); color:#fff; margin-inline-start:38px;}
  .ai-theirs{background:var(--surface); border:1px solid var(--line); color:var(--text); margin-inline-end:38px;}
  .ai-thinking{color:var(--muted); font-style:italic;}
  .ai-left{font-size:12px; margin:2px 0 8px; text-align:center;}
  /* The free times when the desk books somebody in. */
  .book-times{display:grid; grid-template-columns:repeat(auto-fill, minmax(84px, 1fr)); gap:6px; margin-bottom:12px;}
  .book-time{min-height:40px; border:1px solid var(--line); border-radius:10px; background:var(--surface); color:var(--text); font:inherit; font-size:13px; font-weight:700; cursor:pointer;}
  .book-time.on{background:var(--teal-fill); border-color:var(--teal-fill); color:#fff;}
  .ai-composer{position:sticky; bottom:0; background:var(--bg); padding-top:8px; display:flex; flex-direction:column; gap:8px;}
  .ai-composer textarea{margin-bottom:0;}

  /* ======================================================= ICONS & LANDING ===
     An icon is a <svg class="ic"><use href="#i-name"/></svg>. It sits on the
     text baseline like the emoji it replaced, so nothing around it had to move.
     vertical-align rather than flex: these appear mid-sentence in a dozen
     places and a flex parent would have reflowed every one of them. */
  .ic{width:1.35em; height:1.35em; vertical-align:-.3em; flex:0 0 auto;}
  .ic-sm{width:1.1em; height:1.1em; vertical-align:-.2em;}
  .ic-lg{width:44px; height:44px; vertical-align:middle;}

  /* AN ICON ON A SOLID BRAND PANEL
     These drawings are teal on a light ground. Put one on a teal card and the
     teal half disappears into the card -- which is how the patient card ended
     up showing a bare chevron where a house was meant to be. Rather than
     redrawing anything, the panel restates the palette: what was teal becomes
     white, what was mint becomes a wash of it, and the gap is punched in the
     panel's own colour. */
  /* .btn-teal is in the selector so this applies without anybody remembering:
     a teal button is a brand panel too, and the one that exists today puts a
     map pin on it -- which would have shown a floating dot where the pin body
     sank into the button. */
  .on-brand, .btn-teal{
    --ic-teal:#FFFFFF;
    --ic-mint:rgba(255,255,255,.30);
    --ic-slate:rgba(255,255,255,.72);
    --ic-paper:rgba(255,255,255,.88);
    --ic-shade:rgba(255,255,255,.18);
    --ic-shadow:rgba(0,0,0,.16);
    --ic-ink:rgba(255,255,255,.82);
    --ic-gap:var(--teal-fill);
  }

  /* THE PHONE'S OWN SCROLLBAR
     The note above about invisible scrollbars stands, and it is about pages.
     This is a phone-shaped viewport, where a real device draws an overlay bar
     that fades away; a permanent 7px gutter down the inside of the frame is a
     simulation artefact, not a control anybody wanted.

     Scoped to .screen itself, so the wide tables inside it and every other
     scroller in the product keep theirs. Wheel, touch, and the keyboard --
     arrows, Page Down, space -- all still scroll. What is lost is dragging the
     thumb with a mouse, which is the trade being made knowingly. */
  .screen{ scrollbar-width: none; }
  .screen::-webkit-scrollbar{ width:0; height:0; }

  /* The physician landing page.
     Two surfaces: a teal hero, and a mint sheet that rises over it. The sheet's
     rounded top is the "smooth interface" between them -- it overlaps the hero
     by its own corner radius so there is no seam, only a curve. */
  /* THE PAGE IS THE DARK GREEN
     The teal lives on the screen itself while this view is open, so it covers
     the whole scrolling area -- including the part above the content that shows
     when somebody rubber-bands the list at the top. The hero keeps a background
     of its own only as a fallback for the moment before the class lands. */
  /* Green behind the hero, cream from well inside the sheet downward, painted
     on the scrolling area itself (attached to its content). The cream under a
     short list used to come from 600px of padding on the sheet, which a
     scroll container counts as content whatever the margins say -- so the
     dashboard scrolled half a screen into nothing. A background adds no
     scroll at all. */
  .screen.ph-dash{background:var(--ph-ground) linear-gradient(var(--ph-ground) 0, var(--ph-ground) 420px, var(--bg) 420px) local;}
  /* The green band is two thirds of the screen's width tall -- 309px of 465
     in the layout, measured off it rather than guessed. It was sitting at
     four tenths, which is what made it read as cramped. The top margin still
     cancels .screen's padding; only the padding grew. */
  .ph-hero{background:var(--ph-ground); color:#fff; text-align:center; position:relative;
           margin:calc(-1 * var(--sp-y)) calc(-1 * var(--sp-x)) 0;
           padding:40px var(--sp-x) 55px;}
  /* Centring this was wrong: it made the wordmark a heading over the greeting
     instead of the mark it is. Dropping the override leaves the base .brand
     rule, which is flex with no justify-content -- so it starts where the text
     direction starts, and Arabic gets it on the right without a second rule.
     The greeting below it stays centred; only the wordmark moves. */
  .ph-hero .brand{color:#fff; margin-bottom:55px;}
  .ph-hero .brand .dot{background:var(--ic-mint);}
  /* Bigger than it was, because the layout's greeting carries the whole band
     and 27px left it floating in the middle of the green with nothing to do. */
  .ph-hero h1{font-family:'Lora',Georgia,serif; font-size:36px; line-height:1.22;
              margin:0 0 26px; font-weight:700;}
  .ph-hero .ph-date{font-size:15px; opacity:.9; margin:0;}

  /* The cream sheet lying on the green. It overlaps the hero by its own corner
     radius, which is what turns the join into a curve rather than a seam.
     Under a short list the cream carries on below it because .screen.ph-dash
     paints cream there, not because the sheet is stretched: stretching it
     (600px of padding, then a 60vh floor) is what let the page scroll into
     empty space below the last card. */
  .ph-sheet{background:var(--bg); position:relative;
            margin:-30px calc(-1 * var(--sp-x)) 0;
            padding:20px var(--sp-x) 6px;
            border-radius:30px 30px 0 0;}
  .ph-clinic{display:flex; align-items:center; justify-content:center; gap:9px;
             font-family:'Lora',Georgia,serif; font-size:19px; font-weight:700;
             color:var(--ic-teal); margin:0 0 18px;}
  .ph-clinic .ic{width:26px; height:26px; vertical-align:middle;}
  /* "Patients" is a heading in the layout -- centred, serif, dark, and set in
     the same family as "Your Clinic" above it. It had been rendered as a
     section-label: eleven px, uppercase, grey and left-aligned, which is the
     app's eyebrow style and reads as a form label rather than as the title of
     the thing under it. The colour is its own token because the layout uses a
     cool slate here against the warm near-black the rest of the app is set in,
     and matching one to the other would lose the distinction on purpose. */
  .ph-section{font-family:'Lora',Georgia,serif; font-size:19px; font-weight:700;
              color:var(--ph-heading); text-align:center; margin:34px 0 12px;}

  /* Label above the drawing, as in the layout: the word is what somebody scans
     for and the icon is what they recognise a moment later. */
  .ph-grid{display:grid; grid-template-columns:1fr 1fr; gap:13px; margin:20px 0 4px;}
  .ph-cat{background:var(--surface); border-radius:20px; padding:15px 10px 12px;
          display:flex; flex-direction:column; align-items:center; gap:8px;
          cursor:pointer; border:none; width:100%; font-family:'Inter',sans-serif;
          /* The shadow the reference drawings have: soft, straight down, no
             spread. Two stops -- a wide soft one for the lift and a tight one to
             keep the bottom edge from dissolving into the page. Tinted with the
             brand teal rather than black, which is why it reads as depth on a
             green ground instead of grime. */
          box-shadow:0 6px 16px rgba(46,126,111,.17), 0 2px 4px rgba(46,126,111,.10);}
  .ph-cat-label{font-size:14.5px; color:var(--text); font-weight:600;}
  .ph-cat .ic{width:56px; height:56px; vertical-align:middle;}
  /* The gap inside a category icon is punched in the colour of the card it sits
     on, not the page. Without this the badges carry a page-coloured halo. */
  .ph-cat{--ic-gap:var(--surface);}

  /* THE ARRIVAL
     The sheet rises over the hero on open. It is the one moment the two
     surfaces are seen as separate things, which is what makes the join legible
     afterwards. 460ms: long enough to read as deliberate, short enough that
     somebody opening the app to check one number is not waiting on it.
     The hero settles at the same time rather than after -- staggering them
     makes the page look like it is loading in pieces. */
  @keyframes ph-rise{from{transform:translateY(26px); opacity:0;} to{transform:none; opacity:1;}}
  @keyframes ph-settle{from{transform:translateY(-10px); opacity:0;} to{transform:none; opacity:1;}}
  .ph-animate .ph-sheet{animation:ph-rise .46s cubic-bezier(.22,.9,.3,1) both;}
  .ph-animate .ph-hero > *{animation:ph-settle .42s cubic-bezier(.22,.9,.3,1) both;}
  .ph-animate .ph-hero > *:nth-child(2){animation-delay:.05s;}
  .ph-animate .ph-hero > *:nth-child(3){animation-delay:.09s;}
  /* The cards arrive after the sheet they are sitting on, not with it. */
  .ph-animate .ph-cat{animation:ph-rise .40s cubic-bezier(.22,.9,.3,1) both;}
  .ph-animate .ph-cat:nth-child(1),.ph-animate .ph-cat:nth-child(2){animation-delay:.16s;}
  .ph-animate .ph-cat:nth-child(3),.ph-animate .ph-cat:nth-child(4){animation-delay:.22s;}
  .ph-animate .ph-cat:nth-child(5),.ph-animate .ph-cat:nth-child(6){animation-delay:.28s;}

  /* Somebody who has asked their device to stop moving things has asked for a
     reason -- vestibular disorders are the usual one. They get the page, at
     rest, with nothing hidden. */
  @media (prefers-reduced-motion: reduce){
    .ph-animate .ph-sheet,.ph-animate .ph-hero > *,.ph-animate .ph-cat{animation:none;}
  }

  /* A patient on the landing list. */
  .ph-plist{background:var(--surface); border-radius:16px; padding:2px 12px; margin-bottom:12px;}
  .ph-prow{display:flex; align-items:center; gap:10px; padding:11px 0;
           border-bottom:1px solid var(--line); cursor:pointer;}
  .ph-prow:last-child{border-bottom:none;}
  .ph-prow-main{flex:1 1 auto; min-width:0;}
  .ph-prow-name{font-weight:700; font-size:14px; color:var(--text);}
  .ph-prow-meds{font-size:11.5px; color:var(--muted); margin-inline-start:6px; font-weight:500;}
  .ph-prow-sub{font-size:11.5px; color:var(--muted); white-space:nowrap;
               overflow:hidden; text-overflow:ellipsis; margin-top:2px;}
  /* A real button rather than a tapped <span>. It toggles something, so it has
     to be reachable by keyboard and announce its state -- the old one was a
     span holding a star emoji, which a screen reader read out as the word
     "star" whether it was on or off. */
  .ph-fav{background:none; border:none; padding:4px; cursor:pointer; line-height:0;
          flex:0 0 auto; color:var(--ic-teal);}
  .ph-fav .ic{width:22px; height:22px;}


  .ai-composer-row{display:flex; gap:8px; align-items:stretch;}
  /* The camera keeps its own width and the Ask button takes the rest: the
     common action stays the big target, and attaching never moves it. */
  .ai-attach-btn{width:auto; flex:0 0 auto; padding:0 16px; font-size:17px; line-height:1;}
  .ai-composer-row .btn-teal{flex:1 1 auto;}
  .ai-attach{display:flex; align-items:center; gap:10px; padding:8px;
             border:1px solid var(--line); border-radius:12px; background:var(--surface);}
  .ai-attach img{width:44px; height:44px; object-fit:cover; border-radius:8px;}
  /* What was sent, inside the bubble that sent it. Capped in height so a tall
     receipt does not push the reply off the screen. */
  .ai-shot{display:block; max-width:180px; max-height:220px; border-radius:10px;
           margin-bottom:8px; object-fit:cover;}
  /* One line off a receipt. A rule between rather than a box around each: this
     is a list to read down, and eleven boxes read as eleven separate things. */
  .ai-rcpt-line{padding:9px 0; border-top:1px solid var(--line);}
  .ai-rcpt-line:first-of-type{border-top:none;}
  .ai-rcpt-off{opacity:.45;}
  .ai-rcpt-head{display:flex; align-items:center; gap:8px;}
  .ai-rcpt-desc{flex:1 1 auto; font-size:13px; overflow-wrap:anywhere;}
  .ai-rcpt-amt{flex:0 0 auto; font-size:13px; font-weight:600;}
  /* A real button, not a styled div: it toggles something, so it has to be
     reachable by keyboard and announce itself as pressed. */
  .ai-rcpt-tick{flex:0 0 auto; width:22px; height:22px; padding:0; border-radius:6px;
                border:1.5px solid var(--teal); background:none; color:var(--teal);
                font-size:13px; line-height:1; cursor:pointer;}
  .ai-rcpt-tick[aria-pressed="true"]{background:var(--teal-fill); color:#fff;}
  /* Why a line is not counted, under the line it belongs to. Amber rather than
     grey: this is a decision somebody should notice and can reverse, not a
     detail to skim past. */
  .ai-rcpt-why{margin-top:4px; padding-inline-start:30px; font-size:11.5px; color:var(--amber-text);}
  .ai-rcpt-route{display:flex; gap:6px; margin-top:6px; padding-inline-start:30px;}
  .ai-rcpt-sel{margin:0; padding:5px 8px; font-size:11.5px; width:auto; flex:0 1 auto;}
  /* The button an answer ends with. Sits under the bubble it belongs to and
     indented to match it, so it reads as part of that reply rather than a
     control belonging to the page. */
  .ai-goto{width:auto; margin:-2px 38px 10px 0; padding:8px 13px; font-size:12.5px;}
  /* A write the assistant wants to make. Set apart from its bubbles on
     purpose: this is not the assistant talking, it is the app asking. */
  .ai-proposal{border-color:var(--teal); margin-inline-end:0;}
  /* One delivery of one item. Separated rather than boxed: these sit inside a
     form that is already a column of fields, and a card round each would read
     as four unrelated things instead of one list. */
  .stock-batch-row{padding-top:10px; border-top:1px solid var(--line);}
  .stock-batch-row:first-child{padding-top:0; border-top:none;}
  /* Drug lookup results. A <button> per row, not a div: it is a control, and
     one that gets tapped with a thumb — hence the generous hit area rather
     than a dense list. text-align:start (not left) so Arabic and Urdu read
     from the correct edge without a second rule. */
  .drug-results{margin:-4px 0 12px; border:1px solid var(--line); border-radius:12px; overflow:hidden; background:var(--surface);}
  .drug-result{display:block; width:100%; text-align:start; font-family:inherit; -webkit-appearance:none; appearance:none;
    background:none; border:none; border-bottom:1px solid var(--line); padding:10px 12px; cursor:pointer; color:var(--text);}
  .drug-result:last-child{border-bottom:none;}
  .drug-result:hover,.drug-result:focus-visible{background:var(--surface-2);}
  .drug-brand{display:inline; font-weight:700; font-size:13px;}
  .drug-price{float:inline-end; font-size:11.5px; color:var(--muted); font-family:'IBM Plex Mono',monospace;}
  .drug-meta{display:block; font-size:11.5px; color:var(--teal); margin-top:1px;}
  .drug-generic{display:block; font-size:11px; color:var(--muted); margin-top:1px;}
  /* Carried on the row itself, not only on the form after picking: the
     decision about which name to use is made HERE, in the list. */
  .till-line{padding:10px 0; border-top:1px solid var(--line);}
  .till-line:first-child{padding-top:0; border-top:none;}
  /* Square, thumb-sized, and not stretched by the flex row they sit in — a
     quantity control gets tapped hundreds of times a day. */
  button.till-qty{margin:0; width:38px; min-width:38px; flex:0 0 38px; padding:7px 0; font-size:14px; line-height:1;}
  @media print{
    #bottom-tab-bar, .back-nav, .btn{display:none !important;}
    .card{border:none; box-shadow:none;}
    /* A receipt printed from the dark theme came out white-on-black: a page of
       toner, and unreadable on the thermal paper most counters actually use.
       The screen theme is a preference; paper is not. */
    html, body{background:#fff !important; color:#000 !important;}
    #till-receipt-paper, #till-receipt-paper *{
      background:#fff !important; color:#000 !important;
    }
    /* Borders drawn with theme variables vanish on white. */
    #till-receipt-paper [style*="border-top"]{border-top:1px solid #000 !important;}
    /* Roll paper is narrow. Left-aligned and full width beats a centred card
       with margins that a 58mm printer would clip. */
    #till-receipt-paper{max-width:none !important; margin:0 !important; padding:0 !important;}
    @page{margin:6mm;}
  }
  .drug-unverified{display:inline-block; margin-top:4px; font-size:10.5px; font-weight:700;
    color:var(--danger-text); background:var(--danger-bg); border:1px solid var(--danger-border);
    border-radius:6px; padding:1px 6px;}
  /* The filter chip as a <button>, which is what it should always have been:
     it is a control, and a div gets neither keyboard focus nor a role. Same
     neutralisation .tab-btn needs, for the same reason. */
  button.map-filter-chip{font-family:inherit; -webkit-appearance:none; appearance:none;}
  .tab-btn.active{background:var(--teal-fill); color:#fff;}
  .ems-card{background:var(--danger-bg); border:1px solid var(--danger-border); border-radius:14px; padding:14px 16px; margin-bottom:14px; display:flex; align-items:center; justify-content:space-between; gap:10px;}
  .ems-card .ems-label{font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--danger-text); font-weight:700;}
  .ems-card .ems-number{font-size:22px; font-weight:800; color:var(--danger-text); font-family:'IBM Plex Mono',monospace;}
  .ems-call-btn{background:#C23B3B; color:#fff; border:none; border-radius:10px; padding:10px 16px; font-weight:700; font-size:13px; cursor:pointer; text-decoration:none; display:flex; align-items:center; justify-content:center; gap:6px; white-space:nowrap; flex-shrink:0;}
  .cond-row{display:flex; align-items:flex-start; gap:10px; padding:12px 4px; border-bottom:1px solid var(--line);}
  .cond-row:last-child{border-bottom:none;}
  .cond-row input{width:18px; height:18px; flex-shrink:0; margin-top:1px;}
  .file-input-hidden{opacity:0; position:absolute; width:0.1px; height:0.1px; overflow:hidden; z-index:-1;}
  .file-input-label{display:inline-block; width:auto; cursor:pointer; padding:8px 16px; font-size:13px;}
  #view-loading{
    position:absolute; inset:0; z-index:50;
    background:var(--bg);
    display:flex; align-items:center; justify-content:center;
    animation:splashArrive .4s ease-out;
  }
  #view-loading img{
    width:62%; max-width:220px; height:auto;
    /* Pinned so the box can't reflow when the dark variant is swapped in
       below: a replaced element loses its intrinsic ratio for a frame while
       the new source decodes. Matches splash.png's real 600x471. */
    aspect-ratio:600/471;
    animation:splashLogoSettle .6s cubic-bezier(.2,.8,.2,1);
  }
  /* splash.png is drawn for a light page: its wordmark is near-black (1.13:1
     against the dark background — invisible) and the green mark is 2.43:1,
     under the 3:1 WCAG floor for graphics. splash-dark.png is the same artwork
     re-lit — the wordmark mapped to --text, the mark kept on its exact brand
     hue and only lightened — giving 13.2:1 and 10.1:1. Only the used file is
     fetched, so this costs nothing in the theme that doesn't need it.
     Mirrors how the theme variables are declared: an explicit dark choice,
     plus "system" resolving to dark. */
  html[data-theme="dark"] #view-loading img{ content:url('splash-dark.png'); }
  @media (prefers-color-scheme: dark){
    html[data-theme="system"] #view-loading img{ content:url('splash-dark.png'); }
  }
  @keyframes splashArrive{ from{opacity:0;} to{opacity:1;} }
  @keyframes splashLogoSettle{ from{opacity:0; transform:translateY(8px) scale(.97);} to{opacity:1; transform:translateY(0) scale(1);} }
  @media (prefers-reduced-motion: reduce){
    #view-loading, #view-loading img{ animation:none; }
  }
  @keyframes spin{ from{transform:translate(-50%,20px) rotate(0deg);} to{transform:translate(-50%,20px) rotate(360deg);} }
  .no-spinner::-webkit-outer-spin-button, .no-spinner::-webkit-inner-spin-button{-webkit-appearance:none; margin:0;}
  .no-spinner{-moz-appearance:textfield;}
  .theme-row{display:flex; align-items:center; justify-content:space-between; padding:14px 4px; border-bottom:1px solid var(--line); cursor:pointer;}
  .theme-row:last-child{border-bottom:none;}
  .theme-row .radio-dot{width:20px; height:20px; border-radius:50%; border:2px solid var(--line); flex-shrink:0; position:relative;}
  .theme-row.selected .radio-dot{border-color:var(--teal);}
  .theme-row.selected .radio-dot::after{content:''; position:absolute; inset:3px; border-radius:50%; background:var(--teal-fill);}
  .settings-row{display:flex; align-items:center; justify-content:space-between; padding:13px 4px; border-bottom:1px solid var(--line); cursor:pointer;}
  .settings-row:last-child{border-bottom:none;}
  .settings-row .chev{color:var(--muted); font-size:16px;}
  .settings-row.info{cursor:default;}
  .settings-row.danger{color:var(--coral);}
  .settings-cat-title{font-weight:700; font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); margin:18px 4px 8px;}
  .settings-cat-title:first-child{margin-top:0;}
  .med-row{display:flex; align-items:center; gap:12px; padding:12px; border:1px solid var(--line); border-radius:14px; margin-bottom:8px; background:var(--surface); cursor:pointer;}
  .med-check{width:26px; height:26px; border-radius:50%; border:2px solid var(--teal); flex-shrink:0; display:flex; align-items:center; justify-content:center; font-size:14px;}
  .med-check.done{background:var(--teal-fill); color:#fff;}
  .med-name{font-weight:700; font-size:14.5px;}
  .med-meta{font-size:12px; color:var(--muted);}
  .med-row.taken{opacity:.55;}
  .med-row.taken .med-name{text-decoration:line-through;}
  .med-card{border:1px solid var(--line); border-radius:14px; margin-bottom:10px; background:var(--surface); padding:12px 14px;}
  .med-card-header{margin-bottom:6px;}
  .med-card .med-row{padding:9px 4px; margin-bottom:0; border:none; border-radius:0; background:transparent; border-top:1px solid var(--line); gap:10px;}
  .med-card .med-row:first-of-type{border-top:none;}
  .quick-check-card{border:1px solid var(--teal); border-radius:14px; margin-bottom:8px; background:var(--teal-dim); padding:12px 14px;}
  .quick-check-card.all-done{border-color:var(--line); background:var(--surface); opacity:.6; padding:9px 14px;}
  .quick-check-header{display:flex; align-items:center; justify-content:space-between; gap:10px; cursor:pointer;}
  .quick-check-detail{margin-top:8px; padding-top:8px; border-top:1px solid var(--line);}
  .quick-check-detail .med-row{padding:6px 4px; margin-bottom:0; border:none; background:transparent;}
  .status-banner{display:flex; align-items:center; gap:10px; background:var(--teal-dim); border-radius:14px; padding:12px 14px; margin-bottom:14px; font-size:13.5px;}
  .alert-card{border:1px solid var(--coral); background:var(--coral-dim); border-radius:14px; padding:14px; margin-bottom:10px;}
  .alert-title{font-weight:700; font-size:13.5px; color:var(--coral-text-strong);}
  .alert-body{font-size:12px; color:var(--coral-text-body); margin-top:2px;}
  .req-card{border:1px solid var(--amber); background:var(--amber-dim); border-radius:14px; padding:14px; margin-bottom:10px;}
  .req-title{font-weight:700; font-size:13.5px; color:var(--amber-text); margin-bottom:8px;}
  .req-actions{display:flex; gap:8px;}
  .req-actions .btn{padding:10px; margin-bottom:0; font-size:13px;}
  /* .btn-outline draws its border in --line, which is the divider colour for a
     normal surface. On a request card that colour sits almost on top of
     --amber-dim, so Deny read as bare text next to a solid Approve button and
     did not look tappable at all. Borrowing the card's own accent gives it a
     visible edge without turning it into a second primary action. */
  .req-actions .btn-outline{border-color:var(--amber); color:var(--amber-text);}
  /* The generic `monospace` fallback matters offline: the Google Fonts
     stylesheet is external and isn't precached, so with no fallback a
     connection code rendered in the default proportional font — wide enough,
     at 18 characters, to overflow the card. */
  .code-display{font-family:'IBM Plex Mono', monospace; font-size:22px; font-weight:700; letter-spacing:.08em; text-align:center; background:var(--surface); border:1px dashed var(--teal); border-radius:12px; padding:16px; margin-bottom:16px; color:var(--teal);}
  .pill{font-family:'IBM Plex Mono', monospace; font-size:11px; color:var(--muted); background:var(--surface); border:1px solid var(--line); padding:5px 10px; border-radius:100px; display:inline-block; margin-bottom:14px;}
  /* ---- Appointment analytics ----------------------------------------------
     A meter, an ordinal stacked bar, and three stat tiles. Every figure the
     marks encode is also printed as text beside them, so nothing is reachable
     only by looking at a colour. */
  .stat-ring{position:relative; width:170px; height:170px; margin:2px auto 12px;}
  /* -90deg starts the arc at twelve o'clock. It stays clockwise under RTL —
     a progress ring reads as a clock face, not as running text. */
  .stat-ring svg{width:100%; height:100%; transform:rotate(-90deg); display:block;}
  .stat-ring .ring-track{fill:none; stroke:var(--chart-track); stroke-width:13;}
  .stat-ring .ring-fill{fill:none; stroke:var(--teal); stroke-width:13; stroke-linecap:round;}
  .stat-ring .ring-center{position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; text-align:center;}
  /* Proportional figures, not tabular: at 48px, equal-width digits leave a
     number like 121 looking loose. Sans, not the display face — a serif hero
     figure reads as decoration rather than as data. */
  /* line-height 1.2, not 1: at 48px the font's own line box is taller than the
     em, so a 1.0 box leaves the glyphs overflowing their container. */
  .stat-ring .ring-value{font-size:48px; font-weight:700; line-height:1.2; font-family:'Inter',sans-serif;}
  .stat-ring .ring-unit{font-size:12px; color:var(--muted);}
  /* The 2px gap is the separator between segments — surface showing through,
     not a stroke drawn around each one. */
  .stat-bar{display:flex; gap:2px; height:10px; margin:2px 0 14px;}
  .stat-bar > span{display:block; min-width:3px;}
  /* Logical corners, so the rounded ends stay on the outside under RTL, where
     the flex row reverses and :first-child sits on the right. */
  .stat-bar > span:first-child{border-start-start-radius:5px; border-end-start-radius:5px;}
  .stat-bar > span:last-child{border-start-end-radius:5px; border-end-end-radius:5px;}
  .stat-legend{display:flex; align-items:center; gap:9px; padding:8px 0; border-bottom:1px solid var(--line); font-size:13px;}
  .stat-legend:last-child{border-bottom:none;}
  .stat-legend .swatch{width:10px; height:10px; border-radius:3px; flex-shrink:0;}
  .stat-legend .legend-value{margin-left:auto; font-weight:700; font-variant-numeric:tabular-nums;}
  .stat-legend.legend-total{font-weight:700;}
  .stat-tiles{display:grid; grid-template-columns:repeat(3,1fr); gap:8px; margin-bottom:10px;}
  .stat-tile{background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:14px 6px; text-align:center;}
  .stat-tile .tile-value{font-size:24px; font-weight:700; line-height:1.1;}
  .stat-tile .tile-label{font-size:11px; color:var(--muted); margin-top:4px; line-height:1.3;}
  /* A tile that leads somewhere. The chevron is the affordance — there is no
     hover on a phone, so it has to be visible without one. */
  /* Money goes in rows, not in the three-up tile grid the counts use. A tile is
     ~98px wide on a 390px screen, which is fine for "13" and nowhere near
     enough for an amount in a currency quoted in millions — LBP totals pushed
     the grid wide enough to scroll the whole page sideways. A row gives the
     amount the full width, and overflow-wrap keeps even an absurd one inside
     the card. */
  .money-row{display:flex; align-items:baseline; justify-content:space-between; gap:12px; padding:9px 0; border-bottom:1px solid var(--line);}
  .money-row:last-child{border-bottom:none;}
  .money-row .money-label{font-size:13px; color:var(--muted); flex-shrink:0;}
  .money-row .money-value{font-weight:700; font-size:15px; text-align:end; min-width:0; overflow-wrap:anywhere;}
  .money-row .money-value.big{font-size:22px;}
  /* Six monthly columns. Capped well under the 24px mark ceiling and given a
     track of the same hue as the ring's, so an empty month still reads as a
     month rather than as missing data. The current month is the accent; the
     five behind it are one step back, which is emphasis rather than six
     competing colours. */
  .month-bars{display:flex; align-items:flex-end; gap:8px; height:104px;}
  .month-bar{flex:1; display:flex; flex-direction:column; align-items:center; gap:6px; height:100%;}
  .month-bar-track{flex:1; width:100%; max-width:22px; background:var(--surface-2); border-radius:5px; display:flex; align-items:flex-end; overflow:hidden;}
  .month-bar-fill{width:100%; background:var(--chart-3); border-radius:5px 5px 0 0;}
  .month-bar-fill.current{background:var(--teal-fill);}
  .month-bar-label{font-size:10px; color:var(--muted); white-space:nowrap;}
  /* A ranked list — products by revenue, expense categories by spend. The bar
     sits *under* the label rather than beside it: product names and category
     names both run long, and on a 390px screen a side-by-side layout squeezes
     either the name or the bar down to nothing. One hue throughout, because
     rank is already carried by the order and the length; colouring thirteen
     expense categories differently would be thirteen meanings nobody asked for. */
  .rank-row{padding:9px 0; border-bottom:1px solid var(--line);}
  .rank-row:last-child{border-bottom:none;}
  .rank-head{display:flex; align-items:baseline; justify-content:space-between; gap:10px;}
  .rank-name{font-size:13px; font-weight:600; min-width:0; overflow-wrap:anywhere;}
  .rank-value{font-size:12px; color:var(--muted); flex-shrink:0; white-space:nowrap;}
  /* display:flex, not a block with a %-width child — a flex item lays out along
     the inline direction, so the fill grows from the right under RTL without a
     separate rule. */
  .rank-track{display:flex; height:6px; border-radius:3px; background:var(--surface-2); margin-top:6px; overflow:hidden;}
  .rank-fill{background:var(--chart-2); border-radius:3px;}
  /* ---------- Search across Profile and App settings (settings-search.js) ----------
     One line tall until something is typed: on a phone the box costs room on
     the screen it sits on, so it takes as little as it can. */
  .ss-box{margin:0 0 12px;}
  .ss-field{display:flex; align-items:center; gap:8px; background:var(--surface); border:1px solid var(--line);
    border-radius:12px; padding:0 12px;}
  .ss-field .ic{width:16px; height:16px; color:var(--muted); flex-shrink:0;}
  .ss-input{border:none; background:transparent; margin:0; padding:10px 0; font-size:14px; flex:1; min-width:0; box-shadow:none;}
  .ss-input:focus{outline:none;}
  .ss-field:focus-within{border-color:var(--teal);}
  .ss-results{background:var(--surface); border:1px solid var(--line); border-radius:12px; margin-top:6px; overflow:hidden;}
  .ss-hit-row{display:flex; flex-direction:column; align-items:flex-start; gap:1px; width:100%; margin:0; padding:10px 12px;
    background:none; border:none; border-top:1px solid var(--line); text-align:start; cursor:pointer; font-family:inherit; color:var(--text);}
  .ss-hit-row:first-child{border-top:none;}
  .ss-hit-row:hover, .ss-hit-row:focus-visible{background:var(--teal-dim);}
  .ss-hit-title{font-size:13.5px; font-weight:600;}
  .ss-hit-where{font-size:11.5px; color:var(--muted);}
  .ss-none{margin:0; padding:10px 12px; font-size:12.5px;}
  /* The row a search took somebody to, lit long enough for the eye to land. */
  @keyframes ss-flash{0%,60%{box-shadow:0 0 0 3px var(--teal); background-color:var(--teal-dim);} 100%{box-shadow:0 0 0 0 transparent;}}
  .ss-flash{animation:ss-flash 2.2s ease-out; border-radius:12px;}
  @media (prefers-reduced-motion: reduce){ .ss-flash{animation:none; box-shadow:0 0 0 3px var(--teal);} }

  /* ---------- The patient chart (chart/*.js) ---------- */
  .cx-card-head{display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:6px;}
  .cx-card-title{font-weight:700; font-size:13.5px; display:flex; align-items:center; gap:6px;}
  .cx-section-head{display:flex; align-items:center; justify-content:space-between; gap:10px; margin:16px 0 8px;}
  .cx-head-btn{width:auto; margin:0; padding:9px 14px; font-size:13px; display:inline-flex; align-items:center; gap:6px;}
  .cx-link{background:none; border:none; padding:4px 0; margin:0; width:auto; color:var(--teal); font-weight:700; font-size:12.5px; cursor:pointer; font-family:inherit;}
  .cx-link.cx-block{display:block; text-align:start;}
  .cx-danger-text{color:var(--coral);}
  .btn.cx-danger{color:var(--coral); border-color:var(--coral);}
  .cx-small-btn{padding:9px 0; font-size:12.5px; margin:8px 0 0;}
  .cx-row{display:flex; justify-content:space-between; gap:12px; padding:7px 0; border-top:1px solid var(--line); font-size:13px;}
  .cx-row > span:first-child{color:var(--muted); flex-shrink:0; max-width:48%;}
  .cx-row > span:last-child{text-align:end; min-width:0; overflow-wrap:anywhere;}
  .cx-tap{cursor:pointer;}
  .cx-chips{display:flex; flex-wrap:wrap; gap:6px; margin:6px 0 8px;}
  .cx-center{justify-content:center; text-align:center;}
  .cx-chip{border:1px solid var(--line); background:var(--surface); color:var(--text); border-radius:999px; padding:6px 12px; font-size:12.5px; font-weight:600; cursor:pointer; width:auto; margin:0; font-family:inherit;}
  .cx-chip.on{background:var(--teal-fill); border-color:var(--teal); color:#fff;}
  .cx-chip.st-condition{border-color:var(--coral); color:var(--coral-text-strong);}
  .cx-chip.st-restoration{border-color:var(--tooth-resto); color:var(--tooth-resto);}
  .cx-pill{display:inline-flex; align-items:center; gap:4px; font-size:10.5px; font-weight:700; padding:2px 8px; border-radius:999px; text-transform:uppercase; letter-spacing:.04em; white-space:nowrap;}
  .cx-pill .ic{width:11px; height:11px;}
  .cx-pill.signed{background:var(--teal-dim); color:var(--teal);}
  .cx-pill.draft{background:var(--amber-dim); color:var(--amber-text);}
  .cx-pill.error{background:var(--danger-bg); color:var(--danger-text);}
  .cx-pill.legacy{background:var(--surface-2); color:var(--muted);}
  .cx-visit{cursor:pointer;}
  .cx-visit.in-error{opacity:.6;}
  .cx-visit.in-error .med-name, .in-error .cx-field-text{text-decoration:line-through;}
  .cx-visit-top{display:flex; justify-content:space-between; align-items:center; gap:8px; margin-bottom:3px;}
  .cx-visit-date{font-family:'IBM Plex Mono',monospace; font-size:11.5px; color:var(--muted);}
  .cx-clamp{display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; overflow-wrap:anywhere;}
  .cx-tags{display:flex; flex-wrap:wrap; gap:4px 10px; margin-top:4px;}
  .cx-who{margin-top:3px; font-style:italic;}
  .cx-month{font-size:11px; font-weight:700; color:var(--muted); margin:12px 2px 6px; font-family:'IBM Plex Mono',monospace;}
  .cx-search{margin-bottom:8px;}
  .cx-trends summary{cursor:pointer;}
  .cx-trend-row{display:grid; grid-template-columns:1fr auto auto; gap:8px; align-items:center; padding:6px 0; border-top:1px solid var(--line);}
  .cx-trend-label{font-size:12.5px; color:var(--muted);}
  .cx-trend-val{text-align:end; font-size:13px; display:flex; flex-direction:column;}
  .cx-trend-val span{font-size:10.5px; color:var(--muted);}
  .cx-spark{display:block; max-width:100%; height:auto;}
  .cx-banner{margin-bottom:12px;}
  .cx-banner-alert{color:var(--danger-text); font-weight:700; font-size:12.5px; margin-top:4px;}
  .cx-banner-allergy{margin-top:4px; font-size:12.5px;}
  .cx-allergy-hit{color:var(--danger-text); font-weight:700;}
  .cx-allergy-unknown{color:var(--amber-text); font-weight:600;}
  .cx-two{display:grid; grid-template-columns:1fr 1fr; gap:8px;}
  .cx-three{display:grid; grid-template-columns:1fr 1fr 1fr; gap:8px;}
  .cx-two > *, .cx-three > *{min-width:0;}
  .cx-vitals{display:grid; grid-template-columns:repeat(auto-fill, minmax(92px, 1fr)); gap:6px; margin-bottom:10px;}
  .cx-vital label{margin:0 0 3px; font-size:10.5px;}
  .cx-vital input, .cx-vital select{margin:0; padding:9px; font-size:14px;}
  .cx-soap-head{display:flex; align-items:center; gap:8px; font-weight:700; font-size:13.5px; margin-bottom:6px;}
  .cx-soap-letter{width:24px; height:24px; border-radius:7px; background:var(--teal-fill); color:#fff; display:inline-flex; align-items:center; justify-content:center; font-size:12.5px; font-weight:800; flex-shrink:0;}
  .cx-tpl-fields{border-inline-start:3px solid var(--teal-dim); padding-inline-start:10px; margin-bottom:6px;}
  .cx-opts{display:flex; flex-wrap:wrap; gap:6px; margin-bottom:12px; align-items:center;}
  .cx-opt{display:inline-flex; align-items:center; gap:6px; border:1px solid var(--line); border-radius:10px; padding:6px 10px; font-size:13px; margin:0; cursor:pointer; background:var(--surface);}
  /* An option is a choice, not a form label: it keeps its own case. */
  .cx-opt{text-transform:none; letter-spacing:normal; font-weight:600; color:var(--text);}
  .cx-opt input{width:auto; margin:0;}
  .cx-scale .cx-opt{padding:6px 8px;}
  .cx-unit{display:flex; align-items:center; gap:6px;}
  .cx-unit input{flex:1; min-width:0;}
  .cx-unit span{color:var(--muted); font-size:12px;}
  .cx-field{padding:7px 0; border-top:1px solid var(--line);}
  .cx-field-label{font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted);}
  .cx-field-text{font-size:13.5px; margin-top:2px; white-space:pre-wrap; overflow-wrap:anywhere; user-select:text;}
  .cx-was{display:block; font-style:normal; font-size:10.5px; color:var(--muted);}
  .cx-sigline{margin-top:4px;}
  .cx-editor-actions{margin:6px 0 20px;}
  .cx-error-banner{background:var(--danger-bg); border:1px solid var(--danger-border); color:var(--danger-text); border-radius:12px; padding:10px 12px; font-size:12.5px; font-weight:600; margin-bottom:10px;}
  .cx-addendum{border-inline-start:4px solid var(--teal);}
  .cx-addendum.correction{border-inline-start-color:var(--amber);}
  .cx-addendum.enteredInError{border-inline-start-color:var(--coral);}
  .cx-addendum-kind{font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin-bottom:2px;}
  .cx-alerts{margin-bottom:12px;}
  .cx-alert{display:flex; align-items:flex-start; gap:8px; border-radius:12px; padding:10px 12px; margin-bottom:6px; font-size:13px; font-weight:600;}
  .cx-alert.high{background:var(--danger-bg); border:1px solid var(--danger-border); color:var(--danger-text);}
  .cx-alert.info{background:var(--amber-dim); border:1px solid var(--amber); color:var(--amber-text);}
  .cx-alert-text{flex:1; min-width:0; overflow-wrap:anywhere;}
  .cx-alert-by{font-size:10.5px; font-weight:500; opacity:.8; margin-top:2px;}
  .cx-x{background:none; border:none; width:auto; margin:0; padding:0 4px; font-size:18px; line-height:1; color:inherit; cursor:pointer;}
  .cx-change-line{font-size:13px; margin:3px 0; overflow-wrap:anywhere;}
  .cx-change-line s{color:var(--muted);}
  .cx-change-was, .cx-change-now{font-size:12.5px; white-space:pre-wrap; overflow-wrap:anywhere; padding:6px 0;}
  .cx-change-was span, .cx-change-now span{display:block; font-size:10.5px; font-weight:700; text-transform:uppercase; color:var(--muted);}
  .cx-vx{padding:7px 0; border-top:1px solid var(--line); font-size:13px;}
  .cx-dose{margin-top:8px; border:1px solid var(--line); border-radius:12px; padding:8px 10px;}
  .cx-dose summary{cursor:pointer; font-weight:700; font-size:12.5px;}
  .cx-dose input{margin-bottom:0;}
  .cx-dose label{font-size:10.5px; margin:6px 0 3px;}
  .cx-dose-out{font-weight:800; font-size:15px; margin-top:8px; color:var(--teal);}
  .cx-more{margin:6px 0 14px;}
  .cx-more summary{cursor:pointer; font-weight:700; font-size:13px; color:var(--teal); padding:6px 0;}
  .cx-sheet{max-width:380px; max-height:86vh; display:flex; flex-direction:column;}
  .cx-sheet-body{overflow-y:auto; -webkit-overflow-scrolling:touch; flex:1; padding-bottom:4px;}
  .cx-sheet-body label{font-size:12px;}
  .cx-sheet-error{color:var(--danger-text); font-size:12px; font-weight:600; margin:6px 0 0;}
  .cx-sheet-actions{margin-top:10px;}
  .cx-sheet-actions .btn{padding:11px; font-size:14px; margin-bottom:6px;}
  .cx-seg{display:inline-flex; border:1px solid var(--line); border-radius:10px; overflow:hidden; flex-shrink:0;}
  .cx-seg button{background:var(--surface); border:none; width:auto; margin:0; padding:5px 10px; font-size:11.5px; font-weight:700; color:var(--muted); cursor:pointer; font-family:inherit;}
  .cx-seg button.on{background:var(--teal-fill); color:#fff;}
  .cx-seg-wide{display:flex; margin:4px 0 10px;}
  .cx-seg-wide button{flex:1;}
  /* The tooth chart is a picture of a mouth: never mirrored for a
     right-to-left language. */
  .cx-odonto{direction:ltr;}
  .cx-odonto-label{font-size:10.5px; font-weight:700; color:var(--muted); margin:8px 0 3px; text-transform:uppercase; letter-spacing:.04em;}
  html[dir="rtl"] .cx-odonto-label{direction:rtl; text-align:right;}
  .cx-odonto-row{display:grid; gap:3px;}
  .cx-tooth{background:none; border:1px solid transparent; border-radius:8px; padding:2px 0; margin:0; width:100%; display:flex; flex-direction:column; align-items:center; gap:1px; cursor:pointer; color:var(--text); font-family:inherit; min-width:0;}
  .cx-tooth:hover, .cx-tooth:focus-visible{border-color:var(--teal);}
  .cx-tooth-num{font-size:10.5px; font-weight:700; color:var(--muted); font-family:'IBM Plex Mono',monospace;}
  .cx-tooth-svg{width:100%; max-width:38px; height:auto; display:block;}
  .cx-tooth-svg polygon, .cx-tooth-svg rect{stroke:var(--muted); stroke-width:1; fill:var(--surface);}
  .cx-tooth-svg .s-cond{fill:var(--coral);}
  .cx-tooth-svg .s-resto{fill:var(--tooth-resto);}
  .cx-tooth-svg .s-sealant{fill:var(--tooth-sealant);}
  .cx-tooth-svg .s-planned{stroke:var(--coral); stroke-width:2.4; stroke-dasharray:3 2;}
  .cx-tooth-svg .s-selected{stroke:var(--teal); stroke-width:3;}
  .cx-tooth-svg.gone polygon, .cx-tooth-svg.gone rect{fill:var(--surface-2); opacity:.55;}
  .cx-tooth-svg .crown-ring{fill:none; stroke:var(--tooth-resto); stroke-width:3;}
  .cx-tooth-svg .gone-x{stroke:var(--muted); stroke-width:2.5;}
  .cx-tooth-svg .planned-x{stroke:var(--coral); stroke-width:3;}
  .cx-tooth-svg.implant polygon, .cx-tooth-svg.implant rect{fill:var(--surface-2);}
  .cx-tooth-svg.pontic polygon, .cx-tooth-svg.pontic rect{fill:var(--surface-2); stroke-dasharray:2 2;}
  .cx-tooth-badges{display:flex; flex-wrap:wrap; justify-content:center; gap:1px; min-height:11px;}
  .cx-tooth-badges i{font-style:normal; font-size:8px; font-weight:800; line-height:1.3; padding:0 2px; border-radius:3px;}
  .cx-tooth-badges .b-exist{background:var(--tooth-resto); color:#fff;}
  .cx-tooth-badges .b-plan{background:var(--coral-fill); color:#fff;}
  .cx-tooth-badges .b-cond{border:1px solid var(--coral); color:var(--coral-text-strong);}
  .cx-tooth-big{width:132px; margin:4px auto 8px; direction:ltr;}
  .cx-tooth-big .cx-tooth-svg{max-width:132px;}
  .cx-tooth-big [data-surface]{cursor:pointer;}
  .cx-legend{display:flex; flex-wrap:wrap; gap:6px 12px; margin-top:8px; font-size:11.5px; color:var(--muted);}
  .cx-legend span{display:inline-flex; align-items:center; gap:5px;}
  .cx-legend i{width:12px; height:12px; border-radius:3px; display:inline-block; border:1px solid var(--line);}
  .cx-legend .lg-cond{background:var(--coral-fill);}
  .cx-legend .lg-resto{background:var(--tooth-resto);}
  .cx-legend .lg-plan{border:2px dashed var(--coral); background:transparent;}
  .cx-legend .lg-gone{background:var(--surface-2);}
  .cx-legend .lg-bop{background:var(--coral-fill); border-radius:50%;}
  .cx-legend .lg-sup{background:var(--amber); border-radius:50%;}
  .cx-legend .lg-plq{background:var(--chart-3); border-radius:50%;}
  .cx-phase{display:flex; justify-content:space-between; font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin:12px 0 4px;}
  .cx-tx{padding:8px 0; border-top:1px solid var(--line); cursor:pointer;}
  .cx-tx-main{display:flex; justify-content:space-between; gap:10px; font-size:13px; font-weight:600;}
  .cx-tx-fee{font-family:'IBM Plex Mono',monospace; flex-shrink:0;}
  .cx-tx.done .cx-tx-main{color:var(--teal);}
  .cx-tx.declined .cx-tx-main, .cx-tx.cancelled .cx-tx-main{color:var(--muted); text-decoration:line-through;}
  /* The periodontal grid scrolls sideways inside its own box; the row labels
     stay put while it does. */
  .pc-wrap{overflow-x:auto; -webkit-overflow-scrolling:touch; border:1px solid var(--line); border-radius:12px; background:var(--surface); margin-bottom:10px; direction:ltr;}
  .pc-table{border-collapse:collapse; font-size:12px;}
  .pc-table th{position:sticky; left:0; z-index:1; background:var(--surface-2); font-size:10px; font-weight:700; color:var(--muted); text-align:left; padding:2px 6px; white-space:nowrap; border-right:1px solid var(--line);}
  .pc-table td{padding:1px; text-align:center; min-width:22px;}
  .pc-table td:nth-child(3n+1){border-right:1px solid var(--line);}
  .pc-in{width:22px; height:24px; padding:0; margin:0; border:1px solid transparent; border-radius:5px; text-align:center; font-size:13px; font-weight:600; background:var(--surface-2); color:var(--text); font-family:'IBM Plex Mono',monospace;}
  .pc-in:focus{border-color:var(--teal); background:var(--teal-dim); outline:none;}
  .pc-in::placeholder{color:var(--muted); opacity:.45;}
  .pc-in.mid, .pc-cal.mid{color:var(--amber-text);}
  .pc-in.deep, .pc-cal.deep{color:var(--coral); font-weight:800;}
  .pc-in:disabled{opacity:.3;}
  .pc-furc{width:16px;}
  .pc-wide .pc-in{width:28px;}
  .pc-cal{font-size:11px; color:var(--muted); font-family:'IBM Plex Mono',monospace;}
  .pc-num button{background:var(--surface-2); border:none; width:100%; margin:0; padding:3px 0; border-radius:5px; font-weight:800; font-size:11.5px; cursor:pointer; color:var(--text); font-family:'IBM Plex Mono',monospace;}
  .pc-num.gone button{text-decoration:line-through; color:var(--muted); opacity:.6;}
  .pc-num.implant button{background:var(--teal-dim);}
  .pc-dot{width:14px; height:14px; padding:0; margin:2px auto; border-radius:50%; border:1px solid var(--line); background:transparent; display:block; cursor:pointer;}
  .pc-dot.bop-b{background:var(--coral-fill); border-color:var(--coral);}
  .pc-dot.bop-s{background:var(--amber); border-color:var(--amber);}
  .pc-dot.bop-bs{background:radial-gradient(circle, var(--amber) 35%, var(--coral) 36%); border-color:var(--coral);}
  .pc-dot.plq-on{background:var(--chart-3); border-color:var(--chart-3);}
  .pc-dot:disabled{opacity:.25;}
  .cx-fe{border:1px solid var(--line); border-radius:12px; padding:10px; margin-bottom:8px; background:var(--surface-2);}
  .cx-fe input, .cx-fe select, .cx-fe textarea{margin-bottom:6px;}
  .fe-actions{display:flex; gap:14px; justify-content:flex-end;}
  /* A printed visit or treatment plan: only the sheet reaches the paper,
     black on white whatever the screen theme. */
  #cx-print{display:none;}
  .cx-print-head{display:flex; justify-content:space-between; align-items:baseline; border-bottom:2px solid #000; padding-bottom:6pt; margin-bottom:6pt;}
  .cx-print-practice{font-weight:800; font-size:14pt;}
  .cx-print-title{font-weight:700;}
  .cx-print-id{width:100%; border-collapse:collapse; margin-bottom:8pt; font-size:10pt;}
  .cx-print-id td{padding:3pt 4pt; border:1px solid #999;}
  .cx-print-table{width:100%; border-collapse:collapse; font-size:10pt;}
  .cx-print-table th, .cx-print-table td{border:1px solid #999; padding:4pt; text-align:start;}
  .cx-print-phase td{font-weight:700;}
  .cx-print-foot{font-size:9pt; margin-top:10pt;}
  .cx-print-error{font-weight:800; border:2px solid #000; padding:6pt;}
  @media print{
    body.cx-printing > *:not(#cx-print){display:none !important;}
    body.cx-printing #cx-print{display:block; font-size:11pt;}
    #cx-print, #cx-print *{color:#000 !important; background:transparent !important;}
    #cx-print .card{border:none; padding:0; margin:0 0 8pt;}
    #cx-print .cx-row, #cx-print .cx-field{border-top:1px solid #bbb;}
    #cx-print .cx-soap-letter{border:1px solid #000;}
  }
  .stat-tile.tappable{cursor:pointer;}
  .stat-tile .tile-chev{color:var(--teal); font-weight:700;}
  html[dir="rtl"] .stat-tile .tile-chev{display:inline-block; transform:scaleX(-1);}
  .hidden{display:none !important;}
  .footer-link{text-align:center; font-size:12px; color:var(--muted); margin-top:16px; cursor:pointer; text-decoration:underline;}
  .draft-row{display:flex; align-items:center; justify-content:space-between; padding:10px 12px; border:1px solid var(--line); border-radius:12px; margin-bottom:8px; background:var(--surface);}
  .draft-row .del{color:var(--coral); font-weight:700; cursor:pointer; font-size:13px;}
  .add-box{background:var(--surface-2); border:1px dashed var(--line); border-radius:14px; padding:14px; margin-bottom:14px;}
  .top-row{display:flex; justify-content:space-between; align-items:center; margin-bottom:4px;}
  .icon-btn{background:none; border:none; font-size:18px; cursor:pointer; color:var(--muted);}
  .patient-card{display:flex; align-items:center; gap:12px; padding:14px; border:1px solid var(--line); border-radius:16px; margin-bottom:10px; background:var(--surface); cursor:pointer;}
  .patient-avatar{width:44px; height:44px; border-radius:50%; background:var(--teal-dim); display:flex; align-items:center; justify-content:center; font-size:19px; flex-shrink:0;}
  /* A physician's profile photo fills the avatar circle when one loads; the
     emoji stays as the fallback until then, and if the fetch fails. */
  .patient-avatar img{width:100%; height:100%; border-radius:50%; object-fit:cover; display:block;}
  .patient-name{font-weight:700; font-size:14.5px;}
  .patient-progress{font-size:12px; color:var(--muted);}
  .patient-progress.alert{color:var(--coral); font-weight:600;}
  .chev{margin-left:auto; color:var(--muted); font-size:16px;}
  .error-msg{color:var(--coral); font-size:12.5px; margin:-8px 0 12px;}
  .spinner-note{text-align:center; color:var(--muted); font-size:13px; padding:40px 0;}
  /* Toast notifications (replaces showToast()) */
  #toast-host{position:fixed; left:0; right:0; bottom:0; z-index:2000; display:flex; flex-direction:column; align-items:center; gap:8px; padding:0 16px 20px; pointer-events:none;}
  .app-toast{max-width:340px; width:auto; background:var(--text); color:var(--surface); font-size:13.5px; line-height:1.4; font-weight:500; padding:12px 16px; border-radius:12px; box-shadow:0 8px 24px -6px rgba(0,0,0,.4); opacity:0; transform:translateY(12px); transition:opacity .25s ease, transform .25s ease; pointer-events:auto;}
  .app-toast.toast-in{opacity:1; transform:translateY(0);}
  .app-toast.toast-error{background:var(--danger-text); color:#fff;}
  .app-toast.toast-success{background:var(--teal-fill); color:#fff;}
  /* Confirm dialog (replaces confirm()) */
  .app-confirm-backdrop{position:fixed; inset:0; background:rgba(0,0,0,0.55); z-index:2100; display:flex; align-items:center; justify-content:center; padding:24px; opacity:0; transition:opacity .2s ease;}
  .app-confirm-backdrop.confirm-in{opacity:1;}
  .app-confirm-box{background:var(--surface); border:1px solid var(--line); border-radius:20px; max-width:340px; width:100%; padding:22px 20px 18px; box-shadow:0 24px 60px -16px rgba(0,0,0,.5); transform:scale(.96); transition:transform .2s ease;}
  .app-confirm-backdrop.confirm-in .app-confirm-box{transform:scale(1);}
  .app-confirm-msg{font-size:14.5px; line-height:1.5; color:var(--text); margin-bottom:18px;}
  .app-confirm-row{display:flex; gap:10px; justify-content:flex-end;}
  .app-confirm-cancel, .app-confirm-ok{font-family:'Inter',sans-serif; font-size:13.5px; font-weight:600; padding:9px 16px; border-radius:10px; cursor:pointer; border:1px solid var(--line);}
  .app-confirm-cancel{background:var(--surface-2); color:var(--text);}
  .app-confirm-ok{background:var(--teal-fill); color:#fff; border-color:var(--teal);}
  .app-confirm-ok.danger{background:var(--coral-fill); border-color:var(--coral);}
  /* ---- Shared device lock -------------------------------------------------
     A ward machine with nobody at it. Sits BELOW the toast host and the confirm
     dialog on purpose: the keypad that unlocks it is a confirm dialog, so a
     lock drawn above one would cover the only way out of itself.

     Deliberately plain. This is the screen a nurse sees forty times in a shift,
     and the fastest thing to read is a list of names in a calm colour. Nothing
     animates in: an entrance is charming once and then it is a delay. */
  .device-lock{position:fixed; inset:0; z-index:1900; background:var(--page-bg);
    display:flex; align-items:center; justify-content:center; padding:24px; overflow-y:auto;}
  .device-lock-inner{width:100%; max-width:360px; margin:auto;}
  .device-lock-mark{width:44px; height:44px; border-radius:14px; background:var(--teal-dim);
    display:flex; align-items:center; justify-content:center; margin:0 auto 14px;}
  .device-lock-mark .ic{width:22px; height:22px;}
  .device-lock-title{font-size:18px; font-weight:700; color:var(--text); text-align:center;}
  .device-lock-why{text-align:center; margin:6px 0 18px; font-size:13px;}
  .device-lock-foot{text-align:center; margin:16px 0 0; font-size:11.5px; opacity:.75;}
  .device-lock-list{background:var(--surface); border:1px solid var(--line);
    border-radius:16px; overflow:hidden;}
  /* A whole row is the target, not a word inside it. These are tapped in a
     hurry, sometimes through a glove. */
  .device-lock-person{display:flex; align-items:center; gap:10px; width:100%;
    padding:14px 16px; background:none; border:0; border-bottom:1px solid var(--line);
    font-family:'Inter',sans-serif; font-size:14.5px; font-weight:600; color:var(--text);
    text-align:start; cursor:pointer;}
  .device-lock-person:last-child{border-bottom:none;}
  .device-lock-person:hover{background:var(--surface-2);}
  .device-lock-person-name{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .device-lock-out{margin:14px 0 0; font-size:12.5px; padding:8px 12px; opacity:.8;}
  /* ---- Allergies ----------------------------------------------------------
     The strip says one of four things and is coloured by which: something that
     could kill, something worth knowing, nobody has asked, or somebody
     actually checked. The fourth is the only one that is reassurance, and it
     is the only one in the calm colour -- an amber "not recorded" must not be
     mistakable at a glance for a green all-clear. */
  .allergy-strip{display:flex; align-items:center; gap:9px; padding:10px 12px;
    border-radius:14px; font-size:13px; line-height:1.4; margin:0 0 12px;
    border:1px solid var(--line); background:var(--surface-2); color:var(--text);}
  .allergy-strip .ic{flex:0 0 auto; width:18px; height:18px;}
  .allergy-strip span{flex:1; min-width:0;}
  .allergy-strip-btn{width:auto; margin:0; padding:5px 10px; font-size:12px; flex:0 0 auto;}
  .allergy-severe{background:var(--coral-dim); border-color:var(--coral); color:var(--coral-text-body);}
  .allergy-known{background:var(--amber-dim); border-color:var(--amber); color:var(--amber-text);}
  .allergy-unknown{background:var(--amber-dim); border-color:var(--amber); color:var(--amber-text);}
  .allergy-none{background:var(--teal-dim); border-color:var(--teal); color:var(--text);}
  /* Where the list came from, under the strip. Quiet, because it qualifies the
     strip rather than competing with it. */
  .allergy-foot{font-size:11.5px; line-height:1.45; color:var(--muted); margin:-6px 4px 12px;}
  /* The file viewer. The banner is sticky, so page six of a long PDF still says
     whose it is. */
  .fv-banner{position:sticky; top:0; z-index:5; background:var(--surface); border:1px solid var(--line);
    border-inline-start:4px solid var(--teal); border-radius:12px; padding:10px 12px; margin:0 0 10px;}
  .fv-who{display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:14.5px;}
  .fv-id{font-family:'IBM Plex Mono',monospace; font-size:12px; color:var(--muted);}
  .fv-what{font-size:12.5px; color:var(--muted); margin-top:3px;}
  .fv-warn{color:var(--amber-text);}
  .fv-count{display:flex; align-items:center; gap:8px; margin-top:8px; font-size:12px;}
  .fv-tools{display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin:0 0 10px;}
  .fv-tool{width:auto; min-width:38px; margin:0; padding:6px 10px; font-size:13px; font-weight:700;
    border-radius:10px; border:1px solid var(--line); background:var(--surface); color:var(--text); cursor:pointer;}
  .fv-tool[disabled]{opacity:.45; cursor:default;}
  .fv-tool[aria-pressed="true"]{background:var(--teal-fill); border-color:var(--teal); color:#fff;}
  .fv-range{display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--muted); margin:0;}
  .fv-range input{width:90px; margin:0;}
  .fv-canvas{position:relative; height:62vh; overflow:hidden; border-radius:12px; background:#111;
    touch-action:none; cursor:grab; display:flex; align-items:center; justify-content:center;}
  .fv-canvas img{max-width:100%; max-height:100%; transform-origin:center center; user-select:none;}
  .fv-pdf{width:100%; height:70vh; border:1px solid var(--line); border-radius:12px; background:#fff;}
  .lab-file-link{background:none; border:none; padding:0; margin:0 10px 0 0; width:auto; color:var(--teal);
    font-size:11px; font-weight:700; cursor:pointer; font-family:inherit;}

  /* Reactions are picked, not typed. Twenty chips read faster than a select,
     and more than one is usual. */
  .allergy-reactions{display:flex; flex-wrap:wrap; gap:6px;}
  .allergy-chip{font-family:'Inter',sans-serif; font-size:12px; font-weight:600;
    padding:6px 11px; border-radius:999px; cursor:pointer;
    border:1px solid var(--line); background:var(--surface); color:var(--muted);}
  .allergy-chip.on{background:var(--teal-fill); border-color:var(--teal); color:#fff;}
  /* The ones that make an allergy blocking are marked before they are chosen,
     so picking "anaphylaxis" is not a surprise later. */
  .allergy-chip.severe{border-color:var(--coral); color:var(--coral-text-strong);}
  .allergy-chip.severe.on{background:var(--coral-fill); border-color:var(--coral); color:#fff;}
  .allergy-remove{width:auto; margin:0; padding:4px 9px; font-size:11.5px;
    color:var(--coral); border-color:var(--coral); flex:0 0 auto;}

  /* What the alert lists. Scrolls rather than growing the dialog past the
     screen: five flagged lines must not push the reason box out of reach. */
  .allergy-alert-list{max-height:170px; overflow-y:auto; margin:4px 0 0;
    border:1px solid var(--line); border-radius:12px;}
  .allergy-alert-row{padding:8px 11px; border-bottom:1px solid var(--line); font-size:13px;}
  .allergy-alert-row:last-child{border-bottom:none;}
  .allergy-alert-row.severe{background:var(--coral-dim); color:var(--coral-text-body);}
  /* ---- Problem list -------------------------------------------------------
     Codes are set in a monospace pill so the eye can skip them: a clinician
     reads the name, a claim reads the code, and neither should have to wade
     through the other. */
  .problem-row{display:flex; align-items:flex-start; gap:9px; padding:8px 0;
    border-bottom:1px solid var(--line);}
  .problem-row:last-child{border-bottom:none;}
  .problem-row.past{opacity:.62;}
  .problem-code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:10.5px;
    background:var(--surface-2); border:1px solid var(--line); border-radius:6px;
    padding:1px 5px; color:var(--muted); white-space:nowrap;}
  /* Provisional and differential are marked in the list itself. A possibility
     that looks like a settled diagnosis is how somebody carries a label for a
     decade because a registrar once wondered. */
  .problem-tag{font-size:10.5px; font-weight:600; text-transform:uppercase;
    letter-spacing:.04em; color:var(--amber-text); background:var(--amber-dim);
    border-radius:6px; padding:1px 6px; margin-inline-start:6px; white-space:nowrap;}
  .problem-past{margin-top:8px;}
  .problem-past summary{font-size:12px; color:var(--muted); cursor:pointer; padding:4px 0;}
  .problem-edit-btn{width:auto; margin:0; padding:4px 10px; font-size:11.5px; flex:0 0 auto;}
  /* One tap adds it. Disabled rather than hidden when it is already on the
     list, so the answer to "why is this not here" is on the screen. */
  .problem-hit{display:flex; align-items:center; gap:8px; width:100%; text-align:start;
    padding:9px 11px; margin:0 0 6px; border-radius:10px; cursor:pointer;
    border:1px solid var(--line); background:var(--surface);
    font-family:'Inter',sans-serif; font-size:13px; font-weight:600; color:var(--text);}
  .problem-hit:hover{background:var(--surface-2);}
  .problem-hit.already{opacity:.55; cursor:default;}
  /* ---- Results inbox count --------------------------------------------------
     Coral, because it only ever counts things that need a person. Hidden at
     zero rather than showing "0": an empty badge is not news. */
  .inbox-badge{display:inline-block; min-width:20px; padding:0 7px; margin-inline-start:6px;
    border-radius:999px; background:var(--coral-fill); color:#fff; font-size:11px; font-weight:700;
    line-height:18px; text-align:center; vertical-align:middle;}
  /* ---- RTL support (Arabic) ------------------------------------------------
     The layout is almost entirely flexbox + gap, which mirrors automatically
     under dir="rtl". These rules fix the few physical-direction cases that
     don't auto-flip: the auto-margin that pushes list chevrons to the end,
     the chevron glyph itself, and any explicit left/right text alignment. */
  html[dir="rtl"] .chev{margin-left:0; margin-right:auto; transform:scaleX(-1);}
  /* Same auto-margin case as .chev — it pushes the legend's value to the end
     of the row, which is the left edge once the row reverses. */
  html[dir="rtl"] .stat-legend .legend-value{margin-left:0; margin-right:auto;}
  html[dir="rtl"] .app-confirm-row{justify-content:flex-start;}
  html[dir="rtl"] body, html[dir="rtl"] input, html[dir="rtl"] textarea,
  html[dir="rtl"] select, html[dir="rtl"] button{text-align:right;}
  html[dir="rtl"] .btn{text-align:center;}
  html[dir="rtl"] .sub, html[dir="rtl"] .med-meta, html[dir="rtl"] .patient-progress{text-align:right;}
  /* Latin-script content (emails, medication names, phone numbers, the brand
     name) should stay LTR even inside an RTL page, so digits and Latin text
     don't get visually reordered. Apply .ltr-content where such values render. */
  html[dir="rtl"] .ltr-content{direction:ltr; text-align:right; unicode-bidi:embed;}
  html[dir="rtl"] input[type="email"], html[dir="rtl"] input[type="tel"],
  html[dir="rtl"] input[type="time"], html[dir="rtl"] input[type="date"],
  html[dir="rtl"] input[type="number"]{direction:ltr; text-align:right;}

  /* The confirmation state on a save button. Teal so it reads as success, and
     it replaces the label for two seconds rather than sitting alongside it. */
  .btn-saved{background:var(--teal-fill) !important; color:#fff !important; border-color:var(--teal) !important;}

  /* Voice notes. Native <audio controls> cannot be styled and renders as a
     near-invisible strip on a dark bubble, which is what it was doing. */
  .voice-player{display:flex; align-items:center; gap:9px; min-width:190px; padding:2px 0;}
  .vp-play{width:32px; height:32px; flex-shrink:0; border-radius:50%; border:none; cursor:pointer;
    background:rgba(255,255,255,.22); color:#fff; font-size:13px; line-height:1; padding:0;
    display:flex; align-items:center; justify-content:center;}
  /* On the incoming (grey) bubble the light-on-light circle would vanish. */
  .voice-player:not(.vp-mine) .vp-play{background:var(--teal-fill); color:#fff;}
  .vp-track{position:relative; flex:1; min-width:0; height:24px; cursor:pointer;}
  .vp-bars{position:absolute; inset:0; display:flex; align-items:center; gap:2px;}
  .vp-bars span{flex:1; border-radius:2px; background:currentColor; opacity:.32;
    transition:opacity .12s linear;}
  /* Progress is the bars lighting up, not a block drawn over them: a full-height
     overlay stood proud of every bar shorter than the track. */
  .vp-bars span.played{opacity:1;}
  .vp-time{flex-shrink:0; font-size:11.5px; opacity:.85; font-variant-numeric:tabular-nums;}
  /* The live-recording dot. Motion is the signal, so it is removed rather than
     frozen for anybody who has asked for less of it. */
  .rec-dot{width:11px; height:11px; border-radius:50%; background:var(--coral-fill); flex-shrink:0;
    animation:rec-pulse 1.1s ease-in-out infinite;}
  @keyframes rec-pulse{0%,100%{opacity:1; transform:scale(1);} 50%{opacity:.35; transform:scale(.82);}}
  @media (prefers-reduced-motion: reduce){ .rec-dot{animation:none;} }


/* ===========================================================================
   PRESS FEEDBACK
   ===========================================================================

   Nothing in this app acknowledged a tap. Not one :active rule existed in 551
   lines, across 101 screens and 556 tappable elements. On a phone that reads as
   a dead interface: somebody presses Save, nothing moves, and the honest
   assumption is that the press missed. So they press again -- which on a slow
   connection is how one appointment becomes two.

   WHY THIS IS A RULE AND NOT A PASS OVER EVERY SCREEN

   101 screens, and more of them rendered from template strings in app.js than
   written in index.html. Styling them one at a time would be wrong the first
   time somebody adds a screen, and there would be no way to know which one was
   missed. Selecting on what makes a thing tappable instead -- being a button, or
   carrying an onclick, or claiming the button role -- covers every screen that
   exists and every screen that does not exist yet.

   WHY :active AND NOT :hover

   :hover on a touchscreen sticks: the browser leaves the state applied after the
   finger lifts, so the last thing tapped stays lit until something else is
   tapped. :active is the press itself and releases on its own.

   THE 0.97 IS DELIBERATE

   Large enough to see at arm's length in daylight, small enough that a full-width
   button does not visibly shove the layout. Paired with a brightness change so
   the feedback survives for anyone who cannot perceive a 3% size change, and so
   it still reads on the small icon buttons where scale alone is nearly invisible.
   ========================================================================= */

button,
[onclick],
[role="button"],
.btn, .back-nav, .tab-btn, .tab-btn2, .icon-btn, .settings-row, .theme-row {
  /* Kills the 300ms wait a browser leaves in case a tap becomes a double-tap.
     Without it the animation starts a third of a second after the finger, which
     reads as lag rather than as feedback. */
  touch-action: manipulation;
  /* The grey box a mobile browser paints over a tap. Removed because this file
     now provides feedback of its own, and two overlapping effects look like a
     rendering fault. */
  -webkit-tap-highlight-color: transparent;
  transition: transform .09s ease-out, filter .09s ease-out, opacity .09s ease-out;
}

button:active,
[onclick]:active,
[role="button"]:active,
.btn:active, .back-nav:active, .tab-btn:active, .tab-btn2:active,
.icon-btn:active, .settings-row:active, .theme-row:active {
  transform: scale(.97);
  filter: brightness(.92);
}

/* A button that is busy or unavailable must not pretend to accept a press.
   Without this the press animation says "done" while the handler is still
   waiting or was never going to run. */
button:disabled:active,
button[disabled]:active,
.btn:disabled:active,
[onclick][disabled]:active,
[aria-disabled="true"]:active {
  transform: none;
  filter: none;
}

/* A row in a list is a wide, flat target; scaling one looks like the list is
   breathing. A wash of colour is the same acknowledgement without the movement. */
.settings-row:active, .theme-row:active, .req-row:active, .list-row:active {
  transform: none;
  background: var(--press-wash, rgba(127,127,127,.14));
}

/* Keyboard users get the same acknowledgement, and only keyboard users -- :focus
   alone would leave a ring behind after every tap on a phone. */
button:focus-visible,
[onclick]:focus-visible,
[role="button"]:focus-visible,
.btn:focus-visible, .back-nav:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

/* Motion is the part some people cannot tolerate; acknowledgement is not. The
   scale goes, the brightness stays, so a press still answers. */
@media (prefers-reduced-motion: reduce) {
  button, [onclick], [role="button"], .btn, .back-nav, .tab-btn, .tab-btn2,
  .icon-btn, .settings-row, .theme-row { transition: filter .09s ease-out; }
  button:active, [onclick]:active, [role="button"]:active, .btn:active,
  .back-nav:active, .tab-btn:active, .tab-btn2:active, .icon-btn:active {
    transform: none;
    filter: brightness(.9);
  }
}


/* The offline banner. Bottom rather than top: the top of every screen in this
   app is a back arrow or a heading somebody is about to tap, and a bar that
   pushes those down moves the target after they have aimed at it. */
#offline-banner{
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 74px);
  background: var(--amber, #d9a441); color: #1c1405;
  padding: 8px 16px; border-radius: 999px;
  font-size: 13px; font-weight: 600; z-index: 60;
  box-shadow: 0 4px 16px rgba(0,0,0,.28);
  max-width: calc(100% - 32px); text-align: center;
}
@media print { #offline-banner{ display: none !important; } }

/* An inline text link is the one tappable thing that must NOT scale. A link sits
   inside a sentence, and a transform on it shoves the words around it -- the text
   appears to twitch rather than the link appearing to press. So these get the
   acknowledgement without the movement.

   A link styled as a button (the tel: link on the emergency card carries
   class="btn") is caught by the button rule above and keeps the full press,
   which is right: it looks like a button, so it should behave like one. */
a[href]{ -webkit-tap-highlight-color: transparent; transition: opacity .09s ease-out; }
a[href]:not(.btn):active{ opacity: .6; transform: none; }

/* The barcode field: the whole width, so its hint is never cut off on a
   phone, with Scan and Add as two equal buttons under it -- a thumb's width
   each, and quieter than Save so the form still has one main button. */
.scan-field{margin-bottom:8px;}
.scan-actions{display:flex; gap:8px; margin-bottom:14px;}
.scan-actions .btn{flex:1; min-width:0; margin:0; display:inline-flex; align-items:center; justify-content:center; gap:6px;}
.scan-box{max-width:380px;}
.scan-view{position:relative; border-radius:14px; overflow:hidden; background:#000; aspect-ratio:4/3;}
.scan-view video{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;}
.scan-guide{position:absolute; left:9%; right:9%; top:27%; bottom:27%; border:2px solid rgba(255,255,255,.92); border-radius:12px; box-shadow:0 0 0 999px rgba(0,0,0,.30);}
.scan-hint{text-align:center; font-size:12.5px; margin:10px 0 6px;}

/* Department chips on a new patient file. Big enough to hit with a thumb on
   the first try (44px), and they stretch to fill each row so a short list
   reads as a set of buttons rather than scattered tags. */
.dept-find{margin-bottom:8px;}
.dept-chips{display:flex; flex-wrap:wrap; gap:8px; margin:2px 0 14px;}
.dept-chip{flex:1 1 auto; min-height:44px; padding:10px 16px; border-radius:14px; border:1px solid var(--line); background:var(--surface); color:var(--text);
  font-family:inherit; font-size:14px; font-weight:600; line-height:1.25; cursor:pointer; -webkit-appearance:none; appearance:none; text-align:center;}
.dept-chip.on{background:var(--teal-fill); border-color:var(--teal); color:#fff;}
.dept-chip.other{border-style:dashed; color:var(--muted);}
.dept-chip.other.on{border-style:solid; color:#fff;}
.dept-chip:focus-visible{outline:2px solid var(--teal); outline-offset:2px;}

/* A date or time box beside another in a row would not shrink below the width
   its picker asks for, so on a phone the pair ran past the card and the whole
   form scrolled sideways (New patient file: 22px at 375 wide). */
input[type="date"], input[type="time"]{min-width:0;}

/* What a field needs you to know, under it rather than inside it. A hint in
   the box is cut off on a phone and gone the moment you start typing, which is
   exactly when a password rule or "leave blank for" is needed. */
.field-note{font-size:12px; margin:-10px 0 14px;}

/* ---------- Consults ----------
   Rows that read as a worklist: what is waiting on you is tinted, what is
   overdue is edged in coral, and urgency is a word as well as a colour. */
.cs-tabs{display:flex; gap:6px; margin:10px 0;}
.cs-tab{flex:1; min-height:40px; border:1px solid var(--line); background:var(--surface); color:var(--text); border-radius:12px;
  font-family:inherit; font-size:13px; font-weight:700; cursor:pointer; -webkit-appearance:none; appearance:none;}
.cs-tab.on{background:var(--teal-fill); border-color:var(--teal); color:#fff;}
.cs-tab-n{display:inline-block; min-width:18px; padding:0 5px; border-radius:9px; background:rgba(0,0,0,.12); font-size:11px; margin-inline-start:4px;}
.cs-row{display:block; width:100%; text-align:start; border:1px solid var(--line); background:var(--surface); color:var(--text);
  border-radius:16px; padding:12px 14px; margin:0 0 10px; cursor:pointer; font-family:inherit; -webkit-appearance:none; appearance:none;}
.cs-row-action{background:var(--teal-dim); border-color:var(--teal);}
.cs-row-overdue{border-inline-start:4px solid var(--coral);}
.cs-row-top{display:flex; align-items:center; gap:6px; margin-bottom:6px; flex-wrap:wrap;}
.cs-row-spacer{flex:1;}
.cs-row-patient{font-weight:700; font-size:14.5px;}
.cs-row-bits{font-weight:500; font-size:12px; color:var(--muted);}
.cs-row-q{font-size:13px; margin-top:4px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;}
.cs-row-meta{font-size:11.5px; color:var(--muted); margin-top:6px;}
.cs-row-act{font-size:12px; font-weight:700; color:var(--teal); margin-top:4px;}
.cs-empty{padding:24px 8px; text-align:center;}
.cs-chip{display:inline-flex; align-items:center; gap:4px; padding:3px 9px; border-radius:999px; font-size:11px; font-weight:700;
  border:1px solid var(--line); background:var(--surface); color:var(--muted); white-space:nowrap;}
.cs-kind{font-size:12px; font-weight:700; color:var(--text);}
.cs-kind-lg{font-size:15px;}
.cs-st-requested{color:var(--amber-text); border-color:var(--amber-text);}
.cs-st-accepted{color:var(--teal); border-color:var(--teal);}
.cs-st-answered{background:var(--teal-fill); border-color:var(--teal); color:#fff;}
.cs-st-closed{color:var(--muted);}
.cs-st-declined, .cs-st-cancelled{color:var(--coral-text-strong); border-color:var(--coral);}
.cs-overdue{background:var(--coral-fill); border-color:var(--coral); color:#fff;}
.cs-urg-urgent{background:var(--amber-text); border-color:var(--amber-text); color:var(--bg);}
.cs-urg-emergency{background:var(--coral-fill); border-color:var(--coral); color:#fff;}
.cs-head{margin:2px 0 10px;}
.cs-head-chips{display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
.cs-due{font-size:12.5px; color:var(--muted); margin-top:6px; font-weight:600;}
.cs-overdue-text{color:var(--coral-text-strong);}
.cs-callout{display:flex; gap:8px; align-items:flex-start; padding:10px 12px; border-radius:12px; margin:0 0 12px; font-size:13px;
  background:var(--teal-dim); border:1px solid var(--line);}
.cs-callout-danger{background:transparent; border:1.5px solid var(--coral); color:var(--coral-text-strong); font-weight:700;}
.cs-patient-name{font-weight:700; font-size:16px; margin-bottom:2px;}
.cs-consent{color:var(--teal); font-weight:600;}
.cs-chart-btn{margin:10px 0 0; display:inline-flex; align-items:center; justify-content:center; gap:6px;}
.cs-question{font-size:15px; font-weight:600; line-height:1.4; white-space:pre-wrap;}
.cs-text{font-size:13.5px; line-height:1.45; white-space:pre-wrap; overflow-wrap:anywhere;}
.cs-sub-label{font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin:12px 0 4px;}
.cs-sub-label:first-child{margin-top:0;}
.cs-teeth{display:flex; flex-wrap:wrap; gap:4px;}
.cs-teeth-row{display:grid; grid-template-columns:repeat(8, minmax(0, 1fr)); gap:4px;}
.cs-quad-label{font-size:10.5px; font-weight:700; color:var(--muted); margin:4px 0 2px; text-transform:uppercase; letter-spacing:.04em;}
.cs-tooth{padding:2px 8px; border-radius:8px; background:var(--teal-dim); font-weight:700; font-size:12px;}
.cs-teeth-pick{display:flex; flex-direction:column; gap:4px; margin-bottom:12px; overflow-x:auto;}
.cs-tooth-btn{min-width:0; width:100%; min-height:36px; border:1px solid var(--line); background:var(--surface); color:var(--text); border-radius:8px;
  font-family:inherit; font-size:12px; font-weight:700; cursor:pointer; -webkit-appearance:none; appearance:none; padding:0 4px;}
.cs-tooth-btn.on{background:var(--teal-fill); border-color:var(--teal); color:#fff;}
.cs-recs, .cs-actions-list{margin:4px 0 0; padding-inline-start:20px;}
.cs-recs li, .cs-actions-list li{margin:0 0 6px; font-size:13.5px; line-height:1.4;}
.cs-signed{font-size:12px; color:var(--muted); margin-top:12px; font-style:italic;}
.cs-thread{display:flex; flex-direction:column; gap:8px;}
.cs-note{padding:8px 10px; border-radius:12px; background:var(--surface-2, var(--bg));}
.cs-note-con{border-inline-start:3px solid var(--teal);}
.cs-note-req{border-inline-start:3px solid var(--line);}
.cs-note-who{font-size:11.5px; color:var(--muted); font-weight:600; margin-bottom:2px;}
.cs-timeline{margin:0; padding-inline-start:18px;}
.cs-timeline li{margin:0 0 6px;}
.cs-tl-step{font-weight:700; font-size:13px; display:block;}
.cs-tl-when{font-size:11.5px; color:var(--muted);}
.cs-closed-line{display:flex; gap:6px; align-items:center; font-size:12.5px;}
.cs-declined{border-color:var(--coral);}
.cs-actions{display:flex; flex-direction:column; gap:8px; margin:14px 0 8px;}
.cs-actions .btn{margin:0;}
.cs-sev-stable{color:var(--teal); border-color:var(--teal);}
.cs-sev-watcher{background:var(--amber-text); border-color:var(--amber-text); color:var(--bg);}
.cs-sev-unstable{background:var(--coral-fill); border-color:var(--coral); color:#fff;}
.cs-owner{font-size:10.5px;}
.cs-team-head{font-weight:700; font-size:13.5px; margin-bottom:8px; display:flex; gap:6px; align-items:center;}
.cs-team-row{display:flex; align-items:center; justify-content:space-between; gap:10px; padding:8px 0; border-top:1px solid var(--line);}
.cs-team-row:first-of-type{border-top:0;}
.cs-team-who{min-width:0;}
.cs-team-label{font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted);}
.cs-team-gap{margin-top:10px;}
.cs-team-name{font-weight:600; font-size:13.5px; overflow-wrap:anywhere;}
.cs-team-btns{display:flex; gap:6px; flex-shrink:0;}
.cs-mini{margin:0; width:auto; min-height:36px; padding:0 12px; font-size:12.5px; flex-shrink:0;}
.cs-muted{color:var(--muted); font-weight:500;}
.cs-link{background:none; border:0; padding:4px 0; color:var(--muted); font-family:inherit; font-size:12px; text-decoration:underline; cursor:pointer;}
.cs-mini-row{display:flex; width:100%; align-items:center; justify-content:space-between; gap:8px; padding:8px 0; border:0; border-top:1px solid var(--line);
  background:none; color:var(--text); font-family:inherit; font-size:13px; text-align:start; cursor:pointer;}
.cs-mini-row > span:first-child{display:flex; align-items:center; gap:6px; flex-wrap:wrap; min-width:0;}
.cs-team-past summary{font-size:12px; color:var(--muted); cursor:pointer; padding:8px 0 2px;}
.cs-team-asks{display:flex; flex-direction:column; gap:8px; margin-top:12px;}
.cs-team-asks .btn{margin:0;}
.cs-banner-resp{font-weight:700;}
.cs-pick-list{display:flex; flex-direction:column; gap:6px; margin:0 0 14px;}
.cs-pick{display:flex; flex-direction:column; align-items:flex-start; gap:2px; width:100%; min-height:48px; padding:8px 12px; border-radius:12px;
  border:1px solid var(--line); background:var(--surface); color:var(--text); font-family:inherit; text-align:start; cursor:pointer; -webkit-appearance:none; appearance:none;}
.cs-pick.on{border-color:var(--teal); background:var(--teal-dim);}
.cs-pick-name{font-weight:700; font-size:14px;}
.cs-pick-meta{font-size:12px; color:var(--muted);}
.cs-found{margin:0 0 14px; cursor:default;}
.cs-code-row{display:flex; gap:8px; margin-bottom:8px;}
.cs-code-row input{flex:1; min-width:0; margin:0; text-transform:uppercase;}
.cs-code-row .btn{margin:0; width:auto; flex:0 0 auto; padding:0 16px;}
.cs-urgency{display:flex; flex-direction:column; gap:6px; margin:0 0 12px;}
.cs-urg-opt{display:flex; justify-content:space-between; align-items:center; gap:10px; width:100%; min-height:48px; padding:8px 14px; border-radius:12px;
  border:1px solid var(--line); background:var(--surface); color:var(--text); font-family:inherit; cursor:pointer; text-align:start; -webkit-appearance:none; appearance:none;}
.cs-urg-opt.on{border-width:2px;}
.cs-urg-opt-routine.on{border-color:var(--teal); background:var(--teal-dim);}
.cs-urg-opt-urgent.on{border-color:var(--amber-text);}
.cs-urg-opt-emergency.on{border-color:var(--coral);}
.cs-urg-name{font-weight:700; font-size:14px;}
.cs-urg-hint{font-size:12px; color:var(--muted);}
.cs-check{display:flex; align-items:flex-start; gap:10px; margin:12px 0 4px; font-size:13px; font-weight:600; cursor:pointer; text-transform:none; letter-spacing:0;}
.cs-check input{width:20px; height:20px; flex-shrink:0; margin:0;}
.cs-check-danger span{color:var(--coral-text-strong);}
/* The text of an action or a recommendation gets the whole width; its kind
   and the remove button share the line beside it, so neither squeezes the
   words into a box too small to type in. */
.cs-ho-action, .cs-rec-row{display:grid; grid-template-columns:1fr auto; gap:6px; margin-bottom:10px; padding-bottom:10px; border-bottom:1px solid var(--line);}
.cs-ho-action input{grid-column:1 / -1; grid-row:1; margin:0; min-width:0;}
.cs-ho-action select{grid-column:1; grid-row:2; margin:0; min-width:0;}
.cs-ho-action .cs-x{grid-column:2; grid-row:2;}
.cs-rec-row select{grid-column:1; grid-row:1; margin:0; min-width:0;}
.cs-rec-row .cs-x{grid-column:2; grid-row:1;}
.cs-rec-row textarea{grid-column:1 / -1; grid-row:2; margin:0; min-width:0;}
.cs-x{margin:0; width:auto; min-width:40px; padding:0 10px; flex-shrink:0;}
.cs-kind-help, .cs-ipass{margin-top:-4px;}
.cs-pt-answer{border-top:1px solid var(--line); padding:8px 0;}
.cs-pt-answer summary{font-size:13px; font-weight:600; cursor:pointer;}
.cs-print-block{margin:10px 0;}
.cs-print-label{font-size:10pt; font-weight:700; text-transform:uppercase;}
.cs-print-text{white-space:pre-wrap; font-size:11pt;}
.cs-print-sign{margin-top:18px; font-style:italic;}
/* Records the asker points to: a row each, opened in place. */
.cs-ptr-pick{display:flex; flex-direction:column; gap:6px; margin:0 0 14px;}
.cs-ptr-opt, .cs-ptr-row{display:flex; align-items:center; gap:10px; width:100%; min-height:48px; padding:8px 12px; border-radius:12px;
  border:1px solid var(--line); background:var(--surface); color:var(--text); font-family:inherit; text-align:start; cursor:pointer; -webkit-appearance:none; appearance:none;}
.cs-ptr-opt.on{border-color:var(--teal); background:var(--teal-dim);}
.cs-ptr-opt .ic, .cs-ptr-row .ic{flex-shrink:0; color:var(--teal);}
.cs-ptr-text{display:flex; flex-direction:column; gap:2px; min-width:0; flex:1;}
.cs-ptr-label{font-weight:600; font-size:13.5px; overflow-wrap:anywhere;}
.cs-ptr-meta{font-size:11.5px; color:var(--muted);}
.cs-ptrs{display:flex; flex-direction:column; gap:8px;}
.cs-ptr-row{border:0; padding:4px 0; min-height:44px; background:none;}
.cs-ptr + .cs-ptr{border-top:1px solid var(--line); padding-top:8px;}
.cs-ptr-toggle{flex-shrink:0; font-size:12px; font-weight:700; color:var(--teal);}
.cs-ptr-body{margin-top:6px;}
.cs-ptr-body .card{margin-bottom:8px;}
.cs-ptr-sign{font-size:11.5px; margin:4px 0 0;}
/* What was done about each recommendation. */
.cs-recs-head{display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap;}
.cs-fol-summary{font-size:11px; font-weight:700; text-transform:none; letter-spacing:0; color:var(--amber-text);}
.cs-fol-summary.all{color:var(--teal);}
.cs-fol-state{display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:4px;}
.cs-fol-done .cs-chip{background:var(--teal-fill); border-color:var(--teal); color:#fff;}
.cs-fol-later .cs-chip{color:var(--amber-text); border-color:var(--amber-text);}
.cs-fol-notDoing .cs-chip{color:var(--coral-text-strong); border-color:var(--coral);}
.cs-fol-who{font-size:11.5px; color:var(--muted);}
.cs-fol-note{flex-basis:100%; font-size:12.5px; color:var(--text); white-space:pre-wrap; overflow-wrap:anywhere;}
.cs-fol-btns{display:flex; flex-wrap:wrap; gap:6px; margin-top:6px;}
.cs-fol-btn{min-height:36px; padding:0 12px; border-radius:999px; border:1px solid var(--line); background:var(--surface); color:var(--text);
  font-family:inherit; font-size:12.5px; font-weight:600; cursor:pointer; display:inline-flex; align-items:center; gap:5px; -webkit-appearance:none; appearance:none;}
.cs-fol-btn.on{border-color:var(--teal); background:var(--teal-dim); color:var(--teal);}
.cs-fol-go{border-color:var(--teal); color:var(--teal);}
.cs-fol-undecided{color:var(--amber-text); font-weight:600;}
/* Passed on. */
.cs-fwd-list{max-height:40vh; overflow-y:auto;}
.cs-fwd-line + .cs-fwd-line{border-top:1px solid var(--line); padding-top:8px; margin-top:8px;}
/* How the loop is closing. */
.cs-kpi{border:1px solid var(--line); border-radius:12px; background:var(--surface); padding:0 12px; margin:0 0 10px;}
.cs-kpi summary{min-height:44px; display:flex; align-items:center; font-size:13px; font-weight:700; cursor:pointer;}
.cs-kpi-cols{display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:12px; padding-bottom:4px;}
.cs-kpi-head{font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin-bottom:4px;}
.cs-kpi-row{display:flex; justify-content:space-between; align-items:baseline; gap:8px; padding:5px 0; border-top:1px solid var(--line); font-size:12.5px;}
.cs-kpi-row b{font-size:13.5px; white-space:nowrap;}
.cs-kpi-row.warn b{color:var(--coral-text-strong);}
.cs-kpi-note{font-size:11px; margin:6px 0 10px;}
/* A letter to a doctor outside Steadwell: who, how to reach them, where it stands. */
.cs-ext-card{margin-top:10px; padding-top:10px; border-top:1px solid var(--line);}
.cs-ext-tag{display:flex; align-items:center; gap:6px; font-size:12px; font-weight:700; color:var(--amber-text); margin-bottom:6px;}
.cs-ext-contact{display:flex; flex-wrap:wrap; gap:6px; margin:4px 0 6px;}
.cs-ext-contact .btn{display:inline-flex; align-items:center; gap:6px; text-decoration:none;}

/* ---------- Bringing patients over (chart/import.js) ---------- */
.imp-ways{display:grid; gap:12px;}
@media (min-width:600px){ .imp-ways{grid-template-columns:repeat(2, minmax(0, 1fr));} }
.imp-way{display:flex; flex-direction:column; gap:4px; cursor:pointer; margin:0; position:relative;}
.imp-way > .ic{width:28px; height:28px; color:var(--teal); margin-bottom:4px;}
.imp-way .med-meta{flex:1;}
.imp-way-btn{display:block; margin:12px 0 0;}
.imp-way:focus-within{outline:2px solid var(--teal); outline-offset:2px;}
.imp-map{display:grid; gap:10px 16px;}
@media (min-width:600px){ .imp-map{grid-template-columns:repeat(2, minmax(0, 1fr));} }
.imp-field{display:flex; flex-direction:column; gap:4px; font-size:12px; font-weight:700; color:var(--muted); margin:0;}
.imp-field select{margin:0; font-weight:400; color:var(--text);}
.imp-warn{background:var(--amber-dim); border:1px solid var(--amber); color:var(--amber-text); border-radius:12px; padding:10px 12px;
  font-size:12.5px; margin:0 0 12px;}
.imp-check{display:flex; align-items:center; gap:8px; font-size:13px; font-weight:600; margin:12px 0 0; color:var(--text);}
.imp-check span{cursor:pointer;}
.imp-check input{width:18px; height:18px; margin:0; flex-shrink:0;}
.imp-table-wrap{overflow-x:auto; border:1px solid var(--line); border-radius:14px; background:var(--surface); margin-bottom:12px;}
.imp-table{width:100%; border-collapse:collapse; font-size:12.5px;}
.imp-table th{text-align:start; font-size:10.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--muted);
  padding:10px 10px 8px; border-bottom:1px solid var(--line); white-space:nowrap; position:sticky; top:0; background:var(--surface);}
.imp-table td{padding:9px 10px; border-bottom:1px solid var(--line); vertical-align:top;}
.imp-table tr:last-child td{border-bottom:0;}
.imp-table td input[type="checkbox"]{width:18px; height:18px; margin:0;}
/* A fingertip is not a mouse pointer: on a touch screen no tick box or round
   choice is under 24px, whatever size it was given. */
@media (pointer:coarse){ input[type="checkbox"], input[type="radio"]{min-width:24px; min-height:24px;} }
.imp-num{font-variant-numeric:tabular-nums; white-space:nowrap;}
.imp-chip{display:inline-block; padding:3px 8px; border-radius:999px; font-size:11.5px; font-weight:700; line-height:1.35;}
.imp-ok .imp-chip{background:var(--teal-dim); color:var(--teal);}
.imp-dup .imp-chip{background:var(--amber-dim); color:var(--amber-text);}
.imp-bad .imp-chip{background:var(--danger-bg); color:var(--danger-text);}
.imp-bad td{color:var(--muted);}
/* On a phone a table of seven columns is a strip to scroll sideways through.
   Each row becomes a card: who and the row number, then the date of birth and
   sex, the phone, and what is wrong, if anything. */
@media (max-width:599px){
  .imp-table-wrap{overflow:visible;}
  .imp-table thead{display:none;}
  .imp-table tbody{display:block;}
  .imp-table tr{display:grid; grid-template-columns:26px minmax(0, 1fr) auto; column-gap:10px; row-gap:3px;
    grid-template-areas:"c n r" "c d x" "c p p" "c s s"; padding:11px 12px; border-bottom:1px solid var(--line);}
  .imp-table tr:last-child{border-bottom:0;}
  .imp-table td{display:block; padding:0; border:0;}
  .imp-table td:empty{display:none;}
  .imp-table td:nth-child(1){grid-area:c; padding-top:2px;}
  .imp-table td:nth-child(2){grid-area:r; color:var(--muted); font-size:11.5px;}
  .imp-table td:nth-child(3){grid-area:n; min-width:0; overflow-wrap:anywhere;}
  .imp-table td:nth-child(4){grid-area:d;}
  .imp-table td:nth-child(5){grid-area:x; color:var(--muted);}
  .imp-table td:nth-child(6){grid-area:p; color:var(--muted);}
  .imp-table td:nth-child(7){grid-area:s; margin-top:3px;}
  .imp-table tr.imp-empty{display:block;}
}
.imp-bar{height:8px; border-radius:999px; background:var(--surface-2); overflow:hidden; margin:12px 0 8px;}
.imp-bar > div{height:100%; background:var(--teal-fill); transition:width .25s ease;}
.imp-two{display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:0 12px;}
.imp-file-btn{display:flex; align-items:center; justify-content:center; gap:8px; position:relative;}
.imp-pages{display:grid; grid-template-columns:repeat(auto-fill, minmax(96px, 1fr)); gap:10px; margin-bottom:12px;}
.imp-page{border:1px solid var(--line); border-radius:12px; overflow:hidden; background:var(--surface);}
.imp-page img, .imp-page-pdf{display:block; width:100%; aspect-ratio:3 / 4; object-fit:cover; background:var(--surface-2);}
.imp-page-pdf{display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px; font-size:12px; font-weight:700; color:var(--muted);}
.imp-page-bar{display:flex; align-items:center; gap:2px; padding:4px 6px; font-size:12px; font-weight:700;}
.imp-page-bar span{flex:1;}
.imp-page-bar button{border:0; background:none; color:var(--text); font-size:15px; min-width:26px; min-height:26px; border-radius:8px; cursor:pointer;}
.imp-page-bar button:disabled{color:var(--line); cursor:default;}
.imp-page-bar button:last-child{color:var(--coral);}
.imp-count{display:inline-block; background:var(--teal-dim); color:var(--teal); font-weight:700; font-size:12.5px; border-radius:999px;
  padding:5px 12px; margin:0 0 10px;}

/* ---------- Two-step sign-in and the away lock (twostep.js, lock.js) ---------- */
.ts-code{font-family:'IBM Plex Mono', monospace; font-size:22px; letter-spacing:.32em; text-align:center; font-weight:600;}
.ts-code.backup{letter-spacing:.14em; text-transform:uppercase;}
.ts-status{min-height:18px; margin:4px 0 10px; font-size:12.5px; color:var(--coral-text-strong);}
.ts-pill{display:inline-block; margin-inline-start:6px; padding:2px 8px; border-radius:999px; font-size:11px; font-weight:700;
  background:var(--surface-2); color:var(--muted); vertical-align:1px;}
.ts-pill.on{background:var(--teal-dim); color:var(--teal);}
.ts-setup{display:grid; grid-template-columns:150px minmax(0, 1fr); gap:16px; align-items:start; margin-bottom:12px;}
@media (max-width:420px){ .ts-setup{grid-template-columns:1fr;} .ts-qr{max-width:180px;} }
.ts-qr{background:#fff; border:1px solid var(--line); border-radius:12px; padding:6px; aspect-ratio:1 / 1;}
.ts-qr svg{display:block; width:100%; height:100%;}
.ts-key{font-family:'IBM Plex Mono', monospace; font-size:14px; font-weight:600; letter-spacing:.06em; word-break:break-all;
  background:var(--surface-2); border-radius:10px; padding:8px 10px; margin:4px 0 12px;}
.ts-codes{display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:6px; margin-bottom:12px;}
.ts-codes code{font-family:'IBM Plex Mono', monospace; font-size:14px; font-weight:600; text-align:center; padding:8px;
  background:var(--surface-2); border-radius:10px; letter-spacing:.06em;}
#app-lock{position:fixed; inset:0; z-index:10000; display:flex; align-items:center; justify-content:center; padding:20px;
  background:color-mix(in srgb, var(--bg) 82%, transparent); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);}
.lock-box{width:100%; max-width:380px; background:var(--surface); border:1px solid var(--line); border-radius:20px; padding:26px 22px 20px;
  box-shadow:0 30px 70px -30px rgba(0,0,0,.45); text-align:center;}
.lock-mark{width:40px; height:40px; color:var(--teal); margin-bottom:8px;}
.lock-title{font-family:'Fraunces'; font-weight:700; font-size:21px; color:var(--text);}
.lock-who{font-size:13px; color:var(--muted); margin:2px 0 12px; overflow-wrap:anywhere;}
.lock-box input{text-align:center;}
/* The parts of the lock card below "Lock now", each set apart by a rule. */
.lock-pin-setting{margin-top:14px; padding-top:12px; border-top:1px solid var(--line);}
.lock-blur{filter:blur(18px); pointer-events:none; user-select:none;}
@media print{ #app-lock, .lock-blur{display:none !important;} }

/* ---------- Wards, observations, ward medicines (chart/ward.js, obs.js, mar.js) ----------
   The early-warning colours are the RCP chart's: nothing, then yellow, amber,
   red as a sign scores 1, 2, 3. They mean the same in both themes. */
:root{--news-1:#F6E7A1; --news-2:#F5BE84; --news-3:#E98F86; --news-ink:#2A2723;}
.news-badge{display:inline-block; margin-inline-start:6px; padding:2px 8px; border-radius:999px; font-size:11.5px; font-weight:800;
  font-variant-numeric:tabular-nums; background:var(--teal-dim); color:var(--teal); vertical-align:1px; white-space:nowrap;}
.news-badge.band-lowMedium{background:var(--news-2); color:var(--news-ink);}
.news-badge.band-medium{background:var(--news-2); color:var(--news-ink);}
.news-badge.band-high{background:#C0392B; color:#fff;}
.ward-census{display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:10px; margin-bottom:12px;}
.ward-census > div{background:var(--surface); border:1px solid var(--line); border-radius:14px; padding:10px 12px;}
.ward-census b{display:block; font-size:22px; font-variant-numeric:tabular-nums; color:var(--text);}
.ward-census span{font-size:11.5px; color:var(--muted); font-weight:600;}
.ward-census .warn{border-color:var(--coral);} .ward-census .warn b{color:var(--coral);}
@media (max-width:420px){ .ward-census{grid-template-columns:repeat(2, minmax(0, 1fr));} }
.ward-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(178px, 1fr)); gap:10px; margin-bottom:12px;}
.ward-bed{display:flex; flex-direction:column; gap:3px; text-align:start; width:100%; min-height:118px; padding:10px 12px;
  border-radius:14px; border:1px solid var(--line); background:var(--surface); color:var(--text); font:inherit; cursor:default;}
.ward-bed.in{cursor:pointer; border-inline-start:5px solid var(--teal);}
.ward-bed.in.band-lowMedium, .ward-bed.in.band-medium{border-inline-start-color:#E08A3C;}
.ward-bed.in.band-high{border-inline-start-color:#C0392B; box-shadow:0 0 0 1px #C0392B inset;}
.ward-bed.free{border-style:dashed; background:transparent; justify-content:space-between;}
.ward-bed-top{display:flex; align-items:center; justify-content:space-between; gap:6px;}
.ward-bed-label{font-family:'IBM Plex Mono', monospace; font-weight:700; font-size:13px; color:var(--muted);}
.ward-free{font-size:12px; color:var(--muted);}
.ward-name{font-weight:700; font-size:14px; line-height:1.25; overflow-wrap:anywhere;}
.ward-meta{font-size:12px; color:var(--muted);}
.ward-foot{display:flex; flex-wrap:wrap; gap:6px; margin-top:auto; font-size:11.5px; font-weight:700;}
.ward-obs{color:var(--teal);} .ward-obs.late{color:var(--coral);} .ward-obs.none{color:var(--muted); font-weight:600;}
.ward-cs{color:var(--amber-text); background:var(--amber-dim); border-radius:999px; padding:0 7px;}
.ward-admit{margin:6px 0 0; padding:8px; font-size:13px;}
.ward-picks{max-height:240px; overflow:auto; margin:4px 0 6px;}
.ward-pick{display:flex; align-items:flex-start; gap:8px; padding:8px; border-radius:10px; cursor:pointer; text-transform:none; letter-spacing:0;
  font-size:13px; font-weight:600; color:var(--text); margin:0;}
.ward-pick:hover{background:var(--surface-2);}
.ward-pick input{width:18px; height:18px; flex:0 0 18px; margin:2px 0 0; padding:0; min-height:0;}
.ward-pick span{display:flex; flex-direction:column;}
.ward-stay{border-color:var(--teal); background:var(--teal-dim);}
.ward-past{margin:4px 0 12px;}
.ward-round-btn{margin:0 0 12px;}
.ward-seen{color:var(--teal);} .ward-home{color:var(--muted);}
.round-census{grid-template-columns:repeat(3, minmax(0, 1fr));}
.round-row{padding:12px 14px;}
.round-row.seen{border-color:var(--teal); background:var(--teal-dim);}
.round-top{display:flex; align-items:center; gap:10px;}
.round-name{flex:1 1 auto; min-width:0; text-align:start; border:0; background:none; padding:0; font:inherit; font-weight:700; font-size:14.5px;
  color:var(--text); cursor:pointer; overflow-wrap:anywhere;}
.round-name:hover{color:var(--teal);}
.round-seen{font-size:12.5px; font-weight:600; color:var(--teal); margin-top:4px;}
.round-go{margin:10px 0 0; padding:9px;}
.round-last{background:var(--surface-2); border-radius:12px; padding:8px 10px; margin:0 0 10px;}
.round-note{border-top:1px solid var(--line); padding:8px 0 4px;}
.round-note:first-of-type{border-top:0;}
.round-note.withdrawn{opacity:.6;}
.round-note p{margin:4px 0;}
.round-job{display:flex; align-items:flex-start; gap:8px; margin:4px 0; text-transform:none; letter-spacing:0; font-size:13px; font-weight:600; color:var(--text);}
.round-job input{width:18px; height:18px; flex:0 0 18px; margin:1px 0 0; padding:0; min-height:0;}
.round-job.done span{text-decoration:line-through; color:var(--muted);}
.round-job em{font-style:normal; font-weight:500; font-size:11.5px; text-decoration:none; display:inline-block;}
.round-withdraw{padding:4px 0;}
.order-pills{display:inline-flex; flex-wrap:wrap; justify-content:flex-end; gap:6px;}
.payer-card.warn{border-color:var(--coral);} .payer-card.ok{border-color:var(--teal);}
.payer-line{font-size:13.5px;}
.payer-note{margin:4px 0;}
.payer-steps{display:flex; flex-wrap:wrap; gap:8px; margin-top:10px;}
.payer-steps .btn{flex:1 1 150px; margin:0;}
.payer-hist{border-top:1px solid var(--line); margin-top:10px; padding-top:6px;}
.payer-hist-row{display:flex; flex-wrap:wrap; justify-content:space-between; gap:4px 10px; font-size:12px; padding:4px 0;}
.payer-agree{display:flex; align-items:flex-start; gap:8px; text-transform:none; letter-spacing:0; font-size:13px; font-weight:600; color:var(--text);}
.payer-agree input{width:18px; height:18px; flex:0 0 18px; margin:1px 0 0; padding:0; min-height:0;}
.ward-past-row{display:flex; flex-direction:column; gap:2px; width:100%; text-align:start; padding:9px 12px; margin:0 0 6px; border:1px solid var(--line);
  border-radius:12px; background:var(--surface); color:var(--text); font-size:13px; cursor:pointer;}
.ward-past-row span{font-size:12px; color:var(--muted);}
.ward-past-row:hover{border-color:var(--teal);}
.cx-print-pre{white-space:pre-wrap;}
.obs-latest{border-radius:12px; padding:10px 12px; margin:6px 0 10px; background:var(--surface-2); font-size:13px;}
.obs-latest.band-lowMedium, .obs-latest.band-medium{background:#FBE3C6; color:var(--news-ink);}
.obs-latest.band-high{background:#F7D0CB; color:var(--news-ink); border:1px solid #C0392B;}
.obs-latest .med-meta{color:inherit; opacity:.8;}
.obs-due{font-size:12px; font-weight:700; margin-top:2px;} .obs-due.late{color:var(--late);}
.obs-wrap{overflow-x:auto; margin:0 0 10px;}
.obs-grid{border-collapse:collapse; font-size:12px; font-variant-numeric:tabular-nums; min-width:100%;}
.obs-grid th, .obs-grid td{border:1px solid var(--line); padding:5px 6px; text-align:center; white-space:nowrap;}
.obs-grid tbody th{text-align:start; font-weight:700; color:var(--muted); background:var(--surface);}
.obs-grid thead th{background:var(--surface);}
.obs-grid thead button{border:0; background:none; font:inherit; font-weight:700; color:var(--text); cursor:pointer; display:flex; flex-direction:column; align-items:center; width:100%;}
.obs-grid thead button span{font-size:10.5px; color:var(--muted); font-weight:600;}
.obs-grid td.s1{background:var(--news-1); color:var(--news-ink);}
.obs-grid td.s2{background:var(--news-2); color:var(--news-ink);}
.obs-grid td.s3{background:var(--news-3); color:var(--news-ink); font-weight:800;}
.obs-grid .obs-total td{font-weight:800;}
.obs-grid .obs-total td.band-lowMedium, .obs-grid .obs-total td.band-medium{background:var(--news-2); color:var(--news-ink);}
.obs-grid .obs-total td.band-high{background:#C0392B; color:#fff;}
.obs-gap{color:var(--line);}
.obs-form{display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:0 12px;}
.obs-form input, .obs-form select{margin-bottom:10px;}
.obs-label{display:block; font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin-bottom:6px;}
.obs-seg{display:flex; gap:6px; margin-bottom:10px; flex-wrap:wrap;}
.obs-seg label{flex:1 1 auto; display:flex; align-items:center; gap:6px; margin:0; padding:9px 10px; border:1px solid var(--line); border-radius:12px;
  text-transform:none; letter-spacing:0; font-size:13px; font-weight:600; color:var(--text); cursor:pointer; background:var(--surface);}
.obs-seg label:has(input:checked){border-color:var(--teal); background:var(--teal-dim);}
.obs-seg label input{width:18px; height:18px; flex:0 0 18px; margin:0; padding:0; min-height:0;}
.obs-bp > div{display:flex; align-items:center; gap:6px;}
.obs-bp > div input{min-width:0;}
.obs-live{margin-top:6px; padding:10px 12px; border-radius:12px; background:var(--surface-2); font-size:13px; min-height:42px;}
.mar-sum{display:flex; flex-wrap:wrap; gap:8px; margin:4px 0 10px; font-size:12px; font-weight:700; color:var(--muted);}
.mar-sum .late{color:var(--late);} .mar-sum .due{color:var(--teal);}
.mar-row{display:grid; grid-template-columns:minmax(0, 1.2fr) minmax(0, 2fr) auto; gap:10px; align-items:center; padding:10px 0; border-top:1px solid var(--line);}
.mar-row.stopped{grid-template-columns:1fr; opacity:.7;}
@media (max-width:700px){ .mar-row{grid-template-columns:1fr auto;} .mar-row .mar-doses, .mar-row .mar-prn{grid-column:1 / -1; grid-row:2;} }
.mar-drug b{font-size:13.5px;}
.mar-warn{color:var(--coral-text-strong);}
.mar-doses{display:flex; flex-wrap:wrap; gap:6px;}
.mar-dose{display:flex; flex-direction:column; align-items:center; min-width:62px; padding:5px 8px; border-radius:10px; border:1px solid var(--line);
  background:var(--surface); color:var(--text); font:inherit; font-size:11.5px; cursor:pointer; line-height:1.2;}
.mar-dose b{font-variant-numeric:tabular-nums; font-size:12.5px;}
.mar-dose span{font-size:10.5px; color:var(--muted);}
.mar-dose.coming{opacity:.75;}
.mar-dose.due{border-color:var(--teal); box-shadow:0 0 0 1px var(--teal) inset;}
.mar-dose.overdue{border-color:var(--late); background:var(--danger-bg); color:var(--danger-text);} .mar-dose.overdue span{color:var(--danger-text);}
.mar-dose.given{background:var(--teal-dim); border-color:var(--teal);} .mar-dose.given span{color:var(--teal); font-weight:700;}
.mar-dose.held, .mar-dose.refused, .mar-dose.notAvailable, .mar-dose.omitted{background:var(--amber-dim); border-color:var(--amber);}
.mar-prn{display:flex; align-items:center; gap:10px; flex-wrap:wrap;}
.mar-give{width:auto; margin:0; padding:7px 16px;}
.mar-stop{border:0; background:none; color:var(--coral); font:inherit; font-size:12px; font-weight:700; cursor:pointer; padding:6px;}
.mar-outcomes{margin-bottom:10px;}

/* ---------- The theatre list (chart/theatre.js) ---------- */
.or-day{display:flex; align-items:center; gap:8px; margin:0 0 10px;}
.or-day .btn{width:auto; margin:0; padding:8px 14px;}
.or-day-name{flex:1 1 auto; text-align:center; font-size:15px;}
.or-actions{display:flex; flex-wrap:wrap; gap:8px; margin:0 0 12px;}
.or-actions .btn{flex:1 1 160px; margin:0;}
.or-census{grid-template-columns:repeat(4, minmax(0, 1fr));}
.or-case{padding:12px 14px; border-inline-start:5px solid var(--line);}
.or-case.st-arrived{border-inline-start-color:#8E8A84;}
.or-case.st-inTheatre{border-inline-start-color:var(--teal);}
.or-case.st-recovery{border-inline-start-color:#E08A3C;}
.or-case.st-done{opacity:.75;}
.or-case.st-cancelled{opacity:.55;}
.or-top{display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
.or-time{font-family:'IBM Plex Mono', monospace; font-weight:700; font-size:15px;}
.or-pill{display:inline-block; padding:2px 9px; border-radius:999px; font-size:11.5px; font-weight:700; background:var(--surface-2); color:var(--text);}
.or-pill.st-inTheatre{background:var(--teal-fill); color:#fff;}
.or-pill.st-recovery{background:#E08A3C; color:#fff;}
.or-pill.st-done{background:var(--teal-dim); color:var(--teal);}
.or-pill.st-cancelled{background:var(--surface-2); color:var(--muted);}
.or-pill.urgent{background:var(--coral-fill); color:#fff;}
.or-no{margin-inline-start:auto; font-family:'IBM Plex Mono', monospace; font-size:12px; color:var(--muted);}
.or-proc{font-size:13.5px; margin:4px 0 2px;}
.or-checks{display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; font-size:11.5px; font-weight:700;}
.or-checks span{padding:2px 8px; border-radius:999px; border:1px dashed var(--line); color:var(--muted);}
.or-checks span.on{border-style:solid; border-color:var(--teal); color:var(--teal); background:var(--teal-dim);}
.or-buttons{display:flex; flex-wrap:wrap; gap:8px; margin-top:10px;}
.or-buttons .btn{flex:1 1 140px; margin:0; padding:9px;}
.or-item{margin:0 0 10px;}
.or-item > span{display:block; font-size:13px; font-weight:600; margin-bottom:4px;}
.or-item .or-chart{display:block; font-style:normal; font-size:12px; color:var(--coral); margin:-2px 0 4px;}
.or-item-check{margin:0 0 8px;}
.or-chart-row{display:flex; align-items:flex-start; justify-content:space-between; gap:8px; padding:8px 0; border-top:1px solid var(--line); font-size:13px;}
.or-chart-row:first-of-type{border-top:0;}
.ward-or{color:var(--teal);}
.ward-risk{color:var(--coral);}
.ward-tools{display:flex; flex-wrap:wrap; gap:8px;}
.ward-tools .btn{flex:1 1 180px;}

/* ---------- The nurse's card (chart/nursing.js) ---------- */
.nur-row{display:flex; align-items:flex-start; justify-content:space-between; gap:10px; padding:9px 0; border-top:1px solid var(--line);}
.nur-row:first-of-type{border-top:0;}
.nur-main{min-width:0; font-size:13px;}
.nur-val{font-size:13.5px; margin-top:2px;}
.nur-neg{color:var(--coral);}
.nur-band.high, .nur-band.veryHigh{color:var(--coral);}
.nur-band.moderate, .nur-band.atRisk{color:#E08A3C;}
.nur-acts{display:flex; flex-direction:column; gap:6px; flex:0 0 auto;}
.nur-btn{margin:0; padding:7px 12px; font-size:12.5px; width:auto;}
.nur-toggle{padding:2px 0 6px;}
.nur-list{margin:0 0 6px;}
.nur-entry{display:flex; align-items:center; justify-content:space-between; gap:8px; font-size:12.5px; padding:3px 0;}
.nur-scale label{flex:0 0 auto; min-width:44px; justify-content:center;}
.nur-opts label{flex:1 1 100%;}

/* ---------- The wall screens (chart/display.js) ---------- */
#wall{position:fixed; inset:0; z-index:1800; overflow:auto; background:#111312; color:#F4F1EA; padding:18px 22px 28px;
  font-size:16px; -webkit-font-smoothing:antialiased;}
.wall-head{display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin:0 0 16px;}
.wall-title{font-size:24px; font-weight:800; flex:1 1 auto; min-width:0;}
.wall-clock{font-family:'IBM Plex Mono', monospace; font-size:30px; font-weight:700;}
.wall-tools{display:flex; flex-wrap:wrap; gap:8px; align-items:center;}
.wall-privacy{display:inline-flex; border:1px solid #3A3D3B; border-radius:12px; overflow:hidden;}
.wall-privacy button, .wall-btn{background:transparent; color:#F4F1EA; border:0; padding:8px 12px; font:inherit; font-size:13px; font-weight:700; cursor:pointer;}
.wall-privacy button.on{background:#2A7F6F; color:#fff;}
.wall-btn{border:1px solid #3A3D3B; border-radius:12px;}
.wall-ward{margin:0 0 18px;}
.wall-ward-name{font-size:14px; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:#A8A49C; margin:0 0 8px;}
.wall-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); gap:12px;}
.wall-bed{background:#1C1F1D; border:1px solid #2E322F; border-radius:16px; padding:12px 14px; min-height:150px; display:flex; flex-direction:column; gap:4px;
  border-inline-start:6px solid #2A7F6F;}
.wall-bed.free{border-style:dashed; border-inline-start-width:1px; opacity:.55; min-height:0;}
.wall-bed.band-lowMedium, .wall-bed.band-medium{border-inline-start-color:#E08A3C;}
.wall-bed.band-high{border-inline-start-color:#E0483A; box-shadow:0 0 0 2px #E0483A inset;}
.wall-bed-top{display:flex; align-items:center; justify-content:space-between;}
.wall-bed-no{font-family:'IBM Plex Mono', monospace; font-weight:800; font-size:18px; color:#A8A49C;}
.wall-free{font-size:14px; color:#A8A49C;}
.wall-name{font-size:21px; font-weight:800; line-height:1.2; overflow-wrap:anywhere;}
.wall-meta{font-size:14px; color:#C9C5BD;}
.wall-dx{font-size:15px; color:#F4F1EA; overflow-wrap:anywhere;}
.wall-obs{font-size:14px; font-weight:700; color:#7FD3C2;}
.wall-obs.late{color:#FF8A7A;}
.wall-obs.none{color:#A8A49C; font-weight:600;}
.wall-flags{display:flex; flex-wrap:wrap; gap:6px; margin-top:auto;}
.wall-flag{font-size:12.5px; font-weight:800; padding:3px 9px; border-radius:999px; background:#2E322F; color:#F4F1EA;}
.wall-flag.allergy{background:#E0483A; color:#fff;}
.wall-flag.unknown{background:#5B4A2A; color:#F6E7A1;}
.wall-flag.falls{background:#E08A3C; color:#111;}
.wall-flag.pressure{background:#B8673A; color:#fff;}
.wall-flag.theatre{background:#2A7F6F; color:#fff;}
.wall-flag.home{background:#34495E; color:#fff;}
.wall-flag.seen{background:#244A40; color:#BFE9DD;}
.wall-case{display:grid; grid-template-columns:76px minmax(0, 1fr) auto auto; align-items:center; gap:14px; background:#1C1F1D; border:1px solid #2E322F;
  border-radius:14px; padding:12px 16px; margin:0 0 8px; border-inline-start:8px solid #6B6862;}
.wall-case.st-arrived{border-inline-start-color:#A8A49C;}
.wall-case.st-inTheatre{border-inline-start-color:#2A9D8A;}
.wall-case.st-recovery{border-inline-start-color:#E08A3C;}
.wall-case.st-done{border-inline-start-color:#34495E; opacity:.75;}
.wall-time{font-family:'IBM Plex Mono', monospace; font-size:22px; font-weight:800;}
.wall-who b{font-size:20px;}
.wall-who .wall-meta{display:block;}
.wall-no{font-family:'IBM Plex Mono', monospace; color:#A8A49C; font-size:15px;}
.wall-stage{font-size:17px; font-weight:800;}
.wall-case.st-inTheatre .wall-stage{color:#7FD3C2;}
.wall-case.st-recovery .wall-stage{color:#F5BE84;}
.wall-checks{display:flex; gap:5px;}
.wall-checks i{width:12px; height:12px; border-radius:50%; border:2px solid #6B6862;}
.wall-checks i.on{background:#2A9D8A; border-color:#2A9D8A;}
.wall-family{display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:12px;}
.wall-family .wall-case{grid-template-columns:auto 1fr;}
.wall-family .wall-no{font-size:34px; color:#F4F1EA; font-weight:800;}
.wall-family-key{color:#A8A49C; font-size:15px; margin:0 0 12px;}
.ho-patient{padding:12px 14px; border-inline-start:5px solid var(--teal);}
.ho-patient.band-lowMedium, .ho-patient.band-medium{border-inline-start-color:#E08A3C;}
.ho-patient.band-high{border-inline-start-color:#C0392B;}
.ho-head{display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:6px; font-size:14.5px;}
.ho-sbar{display:grid; grid-template-columns:24px minmax(0, 1fr); gap:8px; padding:5px 0; border-top:1px solid var(--line);}
.ho-k{font-family:'IBM Plex Mono', monospace; font-weight:800; color:var(--teal); font-size:14px;}
.ho-line{font-size:13px; line-height:1.45;}
.ho-line b{font-weight:700;}
#cx-print .ho-patient{border:1px solid #000; border-inline-start:4px solid #000; padding:6pt; margin:0 0 6pt; break-inside:avoid;}
#cx-print .ho-sbar{border-top:1px solid #999;}
.cd-drug{display:flex; flex-wrap:wrap; align-items:center; gap:6px 12px; width:100%; text-align:start; cursor:pointer; font:inherit; color:var(--text);}
.cd-drug-name{flex:1 1 220px; font-weight:700; font-size:14px;}
.cd-bal{font-family:'IBM Plex Mono', monospace; font-weight:700;}
.cd-due{font-size:12px; font-weight:700; color:var(--coral);}
.cd-big{font-family:'IBM Plex Mono', monospace; font-size:24px; font-weight:800; margin-top:4px;}
.cd-table-wrap{overflow-x:auto; border:1px solid var(--line); border-radius:14px; background:var(--surface);}
.cd-table{width:100%; border-collapse:collapse; font-size:12.5px;}
.cd-table th, .cd-table td{padding:8px 10px; border-bottom:1px solid var(--line); text-align:start; vertical-align:top;}
.cd-table th{font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted);}
.cd-table .num{text-align:end; font-family:'IBM Plex Mono', monospace; white-space:nowrap;}
.cd-table .cd-when{white-space:nowrap; font-size:12px;}
.cd-table tr.cd-off td{background:color-mix(in srgb, var(--coral) 14%, transparent);}
#cx-print .cd-print th, #cx-print .cd-print td{border:1px solid #000; padding:3pt 4pt; font-size:9pt;}
.wall-empty{font-size:20px; color:#A8A49C; text-align:center; padding:40px 0;}
@media (max-width:600px){
  #wall{padding:14px;}
  .wall-title{font-size:19px;}
  .wall-clock{font-size:22px;}
  .wall-case{grid-template-columns:60px minmax(0, 1fr);}
  .wall-case .wall-stage, .wall-case .wall-checks{grid-column:2;}
}

/* Supplying against a prescription (chart/dispense.js) */
.rxd-head{font-weight:800; font-size:13.5px; margin-bottom:2px;}
.rxd-supply{border-inline-start:4px solid var(--amber);}
.rxd-supply.rxd-full{border-inline-start-color:var(--teal);}
.rxd-line{display:flex; flex-wrap:wrap; justify-content:space-between; gap:2px 12px; font-size:12.5px; padding:5px 0; border-top:1px solid var(--line);}
.rxd-line span:last-child{color:var(--amber-text); font-weight:700;}
.rxd-line.done span:last-child{color:var(--teal);}
.rxd-nosub{display:inline-block; font-size:11.5px; font-weight:700; color:var(--coral-text-strong); margin-top:2px;}
.rxd-code{text-align:center;}
.rxd-qr{width:220px; max-width:100%; margin:6px auto 8px; padding:8px; background:#fff; border-radius:12px;}
.rxd-qr svg{display:block; width:100%; height:auto;}
.rxd-code-text{font-family:'IBM Plex Mono', monospace; font-size:17px; font-weight:700; letter-spacing:.06em; margin:0 0 8px; word-break:break-all;}
.rxd-problem{color:var(--coral-text-strong); font-weight:700; font-size:13px;}
.rxd-pick{border:1px solid var(--line); border-radius:12px; padding:8px 10px; margin:0 0 8px;}
.rxd-pick.done{opacity:.6;}
.rxd-pick-head{display:flex; align-items:flex-start; gap:8px; text-transform:none; letter-spacing:0; font-size:13px; color:var(--text); margin:0 0 4px;}
.rxd-pick-head input{width:18px; height:18px; flex:0 0 18px; margin:2px 0 0; padding:0; min-height:0;}
.rxd-pick-head > span{display:flex; flex-direction:column; gap:1px; min-width:0;}
.rxd-till{margin-top:6px;}
.rxd-till-btns{display:flex; flex-wrap:wrap; gap:6px;}
.rxd-till-btns .btn{flex:1 1 130px; margin:0; padding:7px 4px; font-size:11.5px;}
.rxd-month{display:flex; align-items:center; justify-content:space-between; gap:10px; margin:0 0 10px;}
.rxd-month .btn{flex:0 0 44px; margin:0; padding:6px 0;}

/* Orders to suppliers (chart/purchasing.js) */
.po-card{display:flex; flex-direction:column; gap:2px; width:100%; text-align:start; cursor:pointer; font:inherit; color:var(--text);}
.po-card-top{display:flex; align-items:center; justify-content:space-between; gap:10px;}
.po-num{font-family:'IBM Plex Mono', monospace; font-weight:700; font-size:12.5px;}
.po-sup{font-weight:700; font-size:14px;}
.po-pill{font-size:11px; font-weight:800; padding:2px 8px; border-radius:999px; background:var(--surface-2); color:var(--muted); white-space:nowrap;}
.po-pill.po-sent{background:var(--amber-dim); color:var(--amber-text);}
.po-pill.po-part{background:var(--amber-dim); color:var(--amber-text);}
.po-pill.po-received{background:var(--teal-dim); color:var(--teal);}
.po-pill.po-cancelled, .po-pill.po-closed{background:var(--coral-dim); color:var(--coral-text-strong);}
.po-onorder{font-size:11.5px; font-weight:700; color:var(--amber-text); margin-top:2px;}
.po-line input{margin-bottom:6px;}
.po-line-nums{display:flex; gap:8px; align-items:flex-end;}
.po-line-nums label{flex:1 1 0; min-width:0; margin:0; font-size:11px;}
.po-line-nums input{margin:2px 0 0;}
.po-line-nums .btn{flex:0 0 44px; margin:0; padding:9px 0;}
.po-hit{display:flex; justify-content:space-between; gap:10px; width:100%; margin:0 0 6px; padding:8px 10px; text-align:start;}
.po-error{color:var(--coral-text-strong); font-weight:700;}
.po-preview{white-space:pre-wrap; font:inherit; font-size:12.5px; background:var(--surface-2); border-radius:10px; padding:10px; margin:0 0 8px; max-height:40vh; overflow:auto;}
.po-rline{border-top:1px solid var(--line); padding:8px 0 2px;}
.po-rline-head{display:flex; justify-content:space-between; gap:10px; margin-bottom:4px;}
.po-problem{font-size:12px; font-weight:700; color:var(--amber-text);}
.po-why{color:var(--coral-text-strong);}
.cd-table tr.po-owed td{background:color-mix(in srgb, var(--amber) 12%, transparent);}
html[dir="rtl"] .rxd-month .btn{transform:scaleX(-1);}

/* A text link that does something: tall enough to tap (WCAG 2.2 asks 24px;
   this gives 36), the look of the link it replaces. */
.link-btn{display:inline-flex; align-items:center; min-height:36px; padding:6px 0; margin:0; border:0; background:none;
  color:var(--teal); font:700 12.5px 'Inter', sans-serif; cursor:pointer; width:auto; text-align:start;}
.link-btn:focus-visible{outline:2px solid var(--teal); outline-offset:2px; border-radius:6px;}

/* ---------- Big enough to tap ----------
   WCAG 2.2 asks 24px for anything pressed; a fingertip wants more. These
   raise the small ones without moving the page around them. */
/* Text that does something when pressed: the touch area grows by the padding,
   and the negative margin gives it back, so the line it sits in is unchanged.
   Not the map's filter chips: they are spans too, already padded to size, and
   this took their padding and pulled each one into the next. */
span[onclick]:not(.map-filter-chip){display:inline-block; padding:6px 4px; margin:-6px -4px;}
.cx-link{display:inline-flex; align-items:center; min-height:32px;}
.btn{min-height:32px;}
.footer-link{padding:8px 0; margin-top:8px;}
