/* Pride Dental front desk - shared theme for every page.
   Monochrome by design: whites, blacks and greys carry the interface, in
   light and dark. Colour is spent only where it means something: the accent
   marks what is interactive (hover, selected, focus, the hovered chart mark)
   and one red is reserved for urgent. An explicit choice (data-theme on
   <html>, saved by theme.js) always beats the system setting.
   Chart greys were checked with the dataviz validator (--ordinal, both modes). */
:root {
  --paper:#faf6f0; --surface:#FFFFFF; --surface-2:#fdf8f1; --surface-3:#efe9e0;
  --ink:#1c1714; --ink-2:#4a4038; --muted:#7c6a58;
  --line:#e5e5e2; --line-strong:#d8d2c8;
  --accent:#2563eb; --accent-soft:#eaf1ff;
  --urgent:#b91c1c; --urgent-soft:#fee2e2;
  --c1:#1c1714; --c2:#a3927f;
  --o1:#d8d2c8; --o2:#a3927f; --o3:#7c6a58; --o4:#4a4038; --o5:#1c1714;
  --grid:#efe9e0; --axis:#d8d2c8; --scrim:rgba(17,17,17,.45);
  --shadow:0 1px 2px rgba(17,17,17,.04);
  --radius:12px;
  --ui:"Inter", ui-sans-serif, system-ui, "Segoe UI", -apple-system, "Helvetica Neue", Arial, sans-serif;
  --mono:ui-monospace, "Cascadia Mono", "SF Mono", Consolas, "Liberation Mono", monospace;
  /* names the older pages still use */
  --scrub:var(--ink); --scrub-ink:var(--paper); --scrub-soft:var(--surface-3);
  --warn:var(--ink); --warn-soft:var(--surface-3);
  --ok:var(--ink); --ok-soft:var(--surface-3);
  --btn-bg:#2563eb; --btn-ink:#ffffff;   /* the one blue action: the same pin in both themes, 5.2:1 */
  --blue:var(--ink-2); --blue-soft:var(--surface-3);
  --green:var(--ink); --green-soft:var(--surface-3);
  --red:var(--urgent); --red-soft:var(--urgent-soft);
  --amber:var(--ink); --amber-soft:var(--surface-3);
  color-scheme:light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:#0b0b0c; --surface:#141416; --surface-2:#1c1a19; --surface-3:#26231e;
    --ink:#f4f4f5; --ink-2:#a8a29e; --muted:#968c82;
    --line:#2a2a2e; --line-strong:#3a3a40;
    --accent:#60a5fa; --accent-soft:#1c2a4a;
    --urgent:#f87171; --urgent-soft:#2a1616;
    --c1:#f4f4f5; --c2:#78716c;
    --o1:#3a3a40; --o2:#78716c; --o3:#968c82; --o4:#a8a29e; --o5:#f4f4f5;
    --grid:#26231e; --axis:#3a3a40; --scrim:rgba(0,0,0,.6);
    --shadow:0 1px 2px rgba(0,0,0,.4);
    color-scheme:dark;
  }
}
:root[data-theme="dark"] {
  --paper:#0b0b0c; --surface:#141416; --surface-2:#1c1a19; --surface-3:#26231e;
  --ink:#f4f4f5; --ink-2:#a8a29e; --muted:#968c82;
  --line:#2a2a2e; --line-strong:#3a3a40;
  --accent:#60a5fa; --accent-soft:#1c2a4a;
  --urgent:#f87171; --urgent-soft:#2a1616;
  --c1:#f4f4f5; --c2:#78716c;
  --o1:#3a3a40; --o2:#78716c; --o3:#968c82; --o4:#a8a29e; --o5:#f4f4f5;
  --grid:#26231e; --axis:#3a3a40; --scrim:rgba(0,0,0,.6);
  --shadow:0 1px 2px rgba(0,0,0,.4);
  color-scheme:dark;
}

*{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);font:14px/1.5 var(--ui);-webkit-font-smoothing:antialiased;letter-spacing:-.005em}
button,input,select,textarea{font:inherit;color:inherit}
a{color:inherit}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
::selection{background:var(--accent-soft)}

/* ---- masthead ---- */
.top{display:flex;align-items:center;gap:14px;padding:0 24px;height:60px;background:var(--surface);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:40}
.brand{display:flex;align-items:baseline;gap:8px;min-width:0;margin-right:10px;text-decoration:none}
.brand b{font-size:15px;font-weight:600;letter-spacing:-.02em}
.brand span,.muted{color:var(--muted);font-size:12px;white-space:nowrap}
/* .muted is nowrap because it is usually a short label beside something
   else, where wrapping mid-phrase looks broken. A PARAGRAPH of muted
   text is the opposite case: nowrap forces one long line that runs
   past the card. Found on the schedule page's landline card, which
   held 860px of sentence in a 468px box. */
p.muted{white-space:normal}
.spacer{flex:1}
.nav{display:flex;gap:2px;height:100%;align-self:stretch}
.nav a{display:flex;align-items:center;padding:0 12px;color:var(--ink-2);text-decoration:none;font-size:13.5px;position:relative;white-space:nowrap}
.nav a:hover{color:var(--ink)}
.nav a[aria-current="page"]{color:var(--ink);font-weight:600}
.nav a[aria-current="page"]::after{content:"";position:absolute;left:12px;right:12px;bottom:-1px;height:2px;background:var(--ink)}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 14px;border:1px solid var(--line-strong);border-radius:9px;background:var(--surface);color:var(--ink);text-decoration:none;cursor:pointer;line-height:1.3;font-weight:500;transition:border-color .12s,background .12s,color .12s}
.btn:hover{border-color:var(--accent);color:var(--ink)}
.btn.primary{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.btn.primary:hover{background:var(--btn-bg);border-color:var(--btn-bg);color:var(--btn-ink)}
/* An action that ends something: rejecting an applicant, closing a case. It is
   outlined rather than filled, because it should read as available, not as the
   thing to press. */
.btn.danger{color:var(--urgent);border-color:var(--urgent)}
.btn.danger:hover{background:var(--urgent);color:#fff;border-color:var(--urgent)}
.btn.danger:disabled{opacity:.55}
/* A floor for every small button. The card versions below already set 34-40px
   because this is used standing up at a touch monitor; the row versions never
   got the same treatment, and a table row is where most clicking happens. */
.btn.small{padding:6px 11px;font-size:12.5px;border-radius:7px;white-space:nowrap;min-height:32px}
.btn.icon{padding:0;width:34px;height:34px}
.btn.icon svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.theme-toggle .moon{display:none}
:root[data-theme="dark"] .theme-toggle .sun{display:none}
:root[data-theme="dark"] .theme-toggle .moon{display:block}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .theme-toggle .sun{display:none}
  :root:not([data-theme="light"]) .theme-toggle .moon{display:block}
}
.who{color:var(--muted);font-size:12px;white-space:nowrap;font-family:var(--ui)}

/* ---- pills: outlined by default; only "new" and "urgent" stand out ---- */
.pill{display:inline-block;padding:2px 9px;border-radius:999px;font-size:11.5px;font-weight:500;border:1px solid var(--line-strong);color:var(--ink-2);white-space:nowrap;background:transparent}
.pill.new,.pill.ready{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.pill.Urgent,.pill.High,.pill.emergency{color:var(--urgent);border-color:var(--urgent)}
.pill.enquiry,.pill.meta,.pill.voicemail,.pill.manual,.pill.returning,.pill.review{color:var(--ink);border-color:var(--line-strong)}
.pill.unknown{border-style:dashed;color:var(--muted)}
/* Insurance verdicts. "No answer" is dashed on purpose: it must not read like
   a decision, because it is the state that means telephone the carrier. */
.pill.ok{color:var(--ok);border-color:var(--ok);font-weight:600}
.pill.bad{color:var(--urgent);border-color:var(--urgent)}
.pill.warn{border-style:dashed;color:var(--muted)}
.pill.spam,.pill.lost,.pill.done,.pill.completed,.pill.error{color:var(--muted)}

/* ---- page frame ---- */
/* Tightened 18 Sep 2026. Every page opened with a headline the size of a
   browser tab bar and 40px of space around it before the first row of work.
   A person looking at this screen already knows which page they clicked. */
/* The page title, hidden wherever the sidebar is showing.
 *
 * Every section opened with a heading repeating the sidebar entry that is
 * already highlighted two inches to the left, on screens whose whole job is
 * showing rows of work. It stays in the markup rather than being deleted:
 * below 900px the sidebar collapses to a bar with no highlighted row, and
 * the heading is then the only thing saying which page this is. Screen
 * readers keep it either way. */
@media (min-width:900px){
  :is(body.has-sidebar, html.pd-sidebar body) .page-head h1{position:absolute;width:1px;height:1px;
    padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
  /* With the title gone the head row is often empty, so it stops taking a gap. */
  :is(body.has-sidebar, html.pd-sidebar body) .page-head:empty,
  :is(body.has-sidebar, html.pd-sidebar body) .page-head.headline{margin:0;padding:0}
}

.page{padding:16px 24px 40px;display:grid;gap:14px;max-width:1600px;margin:0 auto;width:100%;min-width:0}
/* A grid child is min-width:auto by default, so one wide table stretches the
   whole page rather than scrolling in its own box. */
.page > *{min-width:0}
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.page-head h1{margin:0;font-size:22px;font-weight:600;letter-spacing:-.02em}
.page-head.headline{padding:0;align-items:flex-end}
.page-head.headline h1{font-size:26px;letter-spacing:-.025em;line-height:1.15}
.page-head .eyebrow{margin:0 0 6px;font-size:12px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.page-head .lede{margin:8px 0 0;font-size:15px;color:var(--ink-2);max-width:60ch}
.head-side{display:flex;align-items:center;gap:12px;font-size:12.5px}
.page-head p{margin:2px 0 0;color:var(--muted);font-size:13px}
.page-head select.btn{padding-right:12px}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);min-width:0}
.label{font-size:12px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2);margin:0 0 6px}

/* ---- summary strip (follow-up page) ---- */
/* The four counts stay put while the list scrolls. They are the answer to
   "how much is waiting", which is the thing somebody keeps glancing at
   while working down the rows, and it scrolled away after four of them. */
.strip{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;
  position:sticky;top:var(--topbar-h,60px);z-index:31;
  background:var(--paper);padding:2px 0 8px}
.strip .card{padding:16px 18px;display:flex;flex-direction:column;gap:2px}
.strip .v{font-size:30px;font-weight:600;line-height:1.05;letter-spacing:-.03em;margin:0}
.strip .v.urgent{color:var(--urgent)}
.strip .d{font-size:13px;color:var(--ink-2);margin:0}

/* ---- analytics tiles ---- */
.hero{display:grid;grid-template-columns:minmax(280px,1.2fr) repeat(4,minmax(0,1fr));gap:12px}
/* A row of plain numbers, all equal weight, unlike .hero which leads with one
   big card. Used where five figures matter the same amount. */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:16px}
/* A heading that divides one page into two things being measured. */
.section-head{margin:34px 0 2px;font-size:18px;letter-spacing:-.01em;font-weight:650}
.section-sub{margin:0 0 14px;color:var(--muted);font-size:13.5px;max-width:70ch}
.hero .card{padding:18px 20px}
.big{font-size:56px;font-weight:600;line-height:1;letter-spacing:-.04em;margin:2px 0 8px}
.caption{color:var(--muted);margin:-2px 0 6px}
.sub{color:var(--ink-2);font-size:12.5px;margin:0}
.sub b{color:var(--urgent);font-weight:600}
.sub .stale{font-weight:600;color:var(--ink)}
.kpi .v{font-size:30px;font-weight:600;line-height:1.1;letter-spacing:-.03em;margin:0}
.kpi .d{font-size:13px;color:var(--ink-2);margin:4px 0 0;display:flex;gap:6px;align-items:center}
.kpi .d.up{color:var(--ink)}
.kpi .spark{display:block;width:100%;height:32px;margin-top:10px}
.kpi .spark path{fill:none;stroke:var(--line-strong);stroke-width:2;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke}
.kpi .spark .last{fill:var(--ink);stroke:var(--surface);stroke-width:2;vector-effect:non-scaling-stroke}
.pipe{margin-top:16px}
.pipe .track{display:flex;height:8px;border-radius:4px;overflow:hidden;gap:2px;background:var(--surface-3)}
.pipe .seg{height:100%;min-width:0}
.pipe .legend{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:8px;font-size:12px;color:var(--ink-2)}
.pipe .legend i{display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:6px;vertical-align:-1px}
.pipe .legend b{color:var(--ink);font-weight:600}

/* ---- charts ---- */
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.cards.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.chart{padding:18px 20px 14px;position:relative;display:flex;flex-direction:column;min-width:0}
.chart h2{margin:0;font-size:14px;font-weight:600;letter-spacing:-.01em}
.chart .hint{margin:2px 0 12px;font-size:12px;color:var(--muted)}
.chart .legend{display:flex;gap:14px;font-size:12px;color:var(--ink-2);margin:0 0 10px}
.chart .legend i{display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:6px;vertical-align:-1px}
.chart svg{display:block;width:100%;overflow:visible}
.chart svg text{font-family:var(--ui);font-size:11px;fill:var(--muted)}
.chart svg text.val{fill:var(--ink);font-weight:600}
.chart svg text.cat{fill:var(--ink)}
.chart svg .grid{stroke:var(--grid);stroke-width:1}
.chart svg .base{stroke:var(--axis);stroke-width:1}
.chart svg .hit{fill:transparent;cursor:default;outline:none}
.chart svg .hit:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.chart svg .mark{transition:opacity .12s,fill .12s}
.chart svg .mark.hot{fill:var(--accent)!important}
.chart svg .mark.dim{opacity:.45}
.chart .tip{position:absolute;pointer-events:none;background:var(--ink);color:var(--paper);padding:7px 10px;border-radius:8px;font-size:12px;line-height:1.35;white-space:nowrap;opacity:0;transition:opacity .1s;z-index:3}
.chart .tip.on{opacity:1}
.chart .tip b{font-size:13px;font-weight:600}
.chart .tip i{display:inline-block;width:10px;height:3px;border-radius:2px;margin:0 6px 3px 0;vertical-align:middle}
.chart details{margin-top:8px;font-size:12px;color:var(--muted)}
.chart details summary{cursor:pointer}
.chart details table{width:100%;border-collapse:collapse;margin-top:6px;font-size:12px;color:var(--ink)}
.chart details td,.chart details th{padding:4px 6px;border-bottom:1px solid var(--line);text-align:left}
.chart details td:last-child,.chart details th:last-child{text-align:right;font-variant-numeric:tabular-nums}
.chart .empty-note{color:var(--muted);font-size:12.5px;padding:24px 0;text-align:center}

/* ---- filters + tables ---- */
.bar{display:flex;gap:9px;align-items:center;flex-wrap:wrap}
.bar input,.bar select{padding:9px 12px;background:var(--surface);border:1px solid var(--line-strong);border-radius:9px;transition:border-color .12s}
.bar input:hover,.bar select:hover{border-color:var(--accent)}
.bar input{width:min(300px,100%)}
.bar .count{color:var(--muted);font-size:12.5px;font-variant-numeric:tabular-nums}
.page > .bar,body > .bar{position:sticky;top:calc(var(--topbar-h,60px) + var(--strip-h,0px));z-index:30;margin:0 -24px;padding:10px 24px;background:var(--paper);border-bottom:1px solid var(--line)}
body > .bar{margin:0;padding:10px 24px}
.work{overflow:visible}
/* The table scrolls inside its own box, at every width.
   It was overflow-x:visible above 1200px on the theory that a wide screen
   fits a 1180px table. It does not: the sidebar is 236px and the page has
   padding, so a 1280px window overflowed by 161px and the WHOLE PAGE
   scrolled sideways, taking the sidebar and the header with it. Measured in
   a browser at 1440, 1280, 1100 and 420. min-width:0 is what lets a grid or
   flex child shrink below its content at all. */
.work{min-width:0}
.work .scroll{overflow-x:auto;max-width:100%}
.work table{width:100%;border-collapse:collapse;min-width:1080px}
.work th{padding:11px 14px;background:var(--surface);border-bottom:1px solid var(--line);text-align:left;font-size:12px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-2);font-weight:600;white-space:nowrap;position:sticky;top:calc(var(--topbar-h,60px) + var(--strip-h,0px) + var(--filters-h,58px));z-index:10}
.work th.num{text-align:right}
.work td{padding:12px 14px;border-bottom:1px solid var(--line);vertical-align:top;font-size:13.5px}
.work tbody tr{cursor:pointer;transition:background .1s}
.work tbody tr:hover{background:var(--surface-2)}
.work tbody tr:last-child td{border-bottom:0}
.work .name{font-weight:600;letter-spacing:-.01em}
.work .mono{font-family:var(--mono);font-size:12px;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink-2)}
.work .summary{max-width:34ch;color:var(--ink-2)}
.work .age{font-family:var(--mono);font-size:12px;font-variant-numeric:tabular-nums;color:var(--muted);white-space:nowrap}
.work .age.stale{color:var(--ink);font-weight:600}
.work tr.urgent td:first-child{box-shadow:inset 3px 0 0 var(--urgent)}
.work .empty{padding:48px 22px;text-align:center;color:var(--muted)}
.work .num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
#campaigns tbody tr{cursor:default}
#campaigns table{min-width:860px}

/* ---- send-link dialog ---- */
.modal{position:fixed;inset:0;background:var(--scrim);display:none;align-items:center;justify-content:center;padding:20px;z-index:60}
.modal.open{display:flex}
.dialog{width:min(560px,100%);background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:22px 24px;max-height:calc(100vh - 40px);overflow:auto}
.dialog h2{margin:0 0 2px;font-size:18px;letter-spacing:-.02em}
.dialog .to{color:var(--muted);font-size:12.5px;margin:0 0 14px}
.dialog .seg{display:inline-flex;border:1px solid var(--line-strong);border-radius:9px;overflow:hidden;margin:0 0 12px}
.dialog .seg button{padding:7px 14px;border:0;background:var(--surface);cursor:pointer;font-size:13px}
.dialog .seg button[aria-pressed="true"]{background:var(--ink);color:var(--paper);font-weight:600}
.dialog .seg button:disabled{color:var(--muted);cursor:not-allowed}
.dialog label{display:block;font-size:12px;color:var(--muted);margin:10px 0 4px}
.dialog textarea,.dialog input{width:100%;padding:9px 11px;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:9px}
.dialog textarea{min-height:120px;resize:vertical;line-height:1.45}
.dialog .actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
/* Two fields on a line where they are genuinely one thing (first/last name,
   phone/email), so the add form is not a long single column of boxes. Falls
   to one column on a phone, where side-by-side inputs are unusable. */
.dialog .row.two{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.dialog .row.two label{margin-top:10px}
@media (max-width:520px){.dialog .row.two{grid-template-columns:1fr;gap:0}}
/* Selects were never styled inside a dialog, so the one in the add form
   would have rendered as a raw OS control, light-on-light in dark mode. */
.dialog select{width:100%;padding:9px 11px;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:9px;color:inherit}
.dialog textarea#add-message{min-height:72px}
/* "optional" beside a field name has to look like an aside, or it reads as
   part of the label: "Email optional" as one phrase. Lighter and smaller
   than the label it follows. */
.dialog label .note{margin:0 0 0 4px;display:inline;font-size:11px;opacity:.72;font-weight:400}

.dialog .note{font-size:12px;color:var(--muted);margin:14px 0 0}

/* ---- marketing ---- */
.connect{padding:24px 26px;max-width:760px}
.connect h2{margin:0 0 4px;font-size:18px;letter-spacing:-.02em}
.connect p{margin:0 0 14px;color:var(--ink-2)}
.connect ol{margin:0;padding-left:20px;display:grid;gap:10px;color:var(--ink-2)}
.connect li b{color:var(--ink)}
.connect code{font-family:var(--mono);font-size:12px;background:var(--surface-3);padding:1px 6px;border-radius:5px}
.status-line{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--muted)}
.status-line i{width:8px;height:8px;border-radius:50%;background:var(--line-strong);display:inline-block}
.status-line i.on{background:var(--ink)}
.status-line i.bad{background:var(--urgent)}

/* ---- older pages (enquiries, voicemails, registrations): keep them in step ---- */
body .wrap{overflow:visible;box-shadow:var(--shadow)}
body .wrap{min-width:0}
body .wrap .scroll{overflow-x:auto;max-width:100%}
body .wrap thead th{position:sticky;top:calc(var(--topbar-h,60px) + var(--strip-h,0px) + var(--filters-h,58px));z-index:10;background:var(--surface)}
body .stat{box-shadow:var(--shadow)}
body .stat strong{font-family:var(--ui)!important;letter-spacing:-.02em}

@media (max-width:1100px){.hero{grid-template-columns:1fr 1fr}.hero .card:first-child{grid-column:1/-1}.cards,.cards.two{grid-template-columns:1fr}.strip{grid-template-columns:1fr 1fr}}
@media (max-width:820px){.top{height:auto;padding:10px 16px;flex-wrap:wrap;gap:8px}.nav{order:5;width:100%;overflow-x:auto;height:40px}.who{display:none}}
@media (max-width:720px){
  .page{padding-left:16px;padding-right:16px}.page > .bar{margin:0 -16px;padding:10px 16px}
  .work table,.work tbody{display:block;min-width:0}.work thead{display:none}
  .work tbody tr{display:grid;grid-template-columns:1fr 1fr;padding:9px 10px;border-bottom:1px solid var(--line)}
  .work td{min-width:0;padding:5px 7px;border:0;white-space:normal}
  .work td::before{content:attr(data-label);display:block;margin-bottom:2px;font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
  .work td[data-label="Next step"],.work td[data-label="Action"]{grid-column:1/-1}
  .work .summary{max-width:none}
}
@media print{.top,.bar,.modal{display:none}.card{box-shadow:none}}

/* ---- follow-up queue: cards, not rows ---- */
.queue{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:14px}
.item{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:18px 20px 16px;display:flex;flex-direction:column;gap:12px;min-width:0;position:relative;transition:border-color .12s,box-shadow .12s}
.item:hover{border-color:var(--line-strong);box-shadow:0 2px 10px rgba(0,0,0,.05)}
.item:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.item.urgent{box-shadow:inset 3px 0 0 var(--urgent)}
.item.closed{opacity:.6}
.item-top{display:flex;justify-content:space-between;gap:12px;align-items:flex-start}
.item-who{min-width:0}
.item-name{margin:0;font-size:17px;font-weight:600;letter-spacing:-.015em;line-height:1.25;overflow-wrap:anywhere}
.item-contact{margin-top:3px;font-size:13px;color:var(--ink-2);display:flex;flex-wrap:wrap;gap:0 8px;align-items:center}
.item-contact a{color:var(--ink-2);text-decoration:none;font-variant-numeric:tabular-nums}
.item-contact a:hover{color:var(--accent);text-decoration:underline}
.item-contact .dot{width:3px;height:3px;border-radius:50%;background:var(--line-strong);display:inline-block}
.item-wait{text-align:right;flex:none;line-height:1.1}
.item-wait b{display:block;font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--muted)}
.item-wait span{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}
.item-wait.stale b{color:var(--ink)}
.item.urgent .item-wait b{color:var(--urgent)}
.item-meta{display:flex;flex-wrap:wrap;gap:6px;align-items:center;font-size:12px;color:var(--muted)}
.item-when{margin-left:auto;font-variant-numeric:tabular-nums;white-space:nowrap}
.item-body{display:grid;gap:4px}
.item-request{font-size:14.5px;font-weight:600;text-transform:capitalize;letter-spacing:-.01em}
.item-snippet{margin:0;font-size:13.5px;line-height:1.5;color:var(--ink-2);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.item-next{font-size:13px;color:var(--ink-2);padding:9px 12px;background:var(--surface-2);border-radius:9px;display:flex;gap:10px;align-items:baseline}
.item-next span{font-size:10.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);flex:none}
/* Who an enquiry might already be. Amber, not red: it is a question for the
   desk, not an emergency, and red is reserved for urgent. Every class is
   prefixed lead-match because this stylesheet is shared by thirty-one pages
   and a generic name inherits another page's layout without a word. */
.lead-match{margin:4px 0 2px;padding:11px 12px;border:1px solid var(--amber);background:var(--amber-soft);border-radius:9px;min-width:0}
.lead-match-head{font-size:10.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2);margin-bottom:8px}
.lead-match-list{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.lead-match-one{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px 12px;align-items:center;padding:9px 11px;background:var(--surface);border:1px solid var(--line);border-radius:8px}
.lead-match-who{font-weight:600;font-size:13.5px;min-width:0}
.lead-match-who a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--line-strong);text-underline-offset:3px}
.lead-match-status{margin-left:7px;font-size:10.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;padding:1px 7px;border-radius:999px;border:1px solid var(--line-strong);color:var(--muted)}
.lead-match-facts{grid-column:1;font-size:12.5px;color:var(--ink-2);min-width:0}
.lead-match-why{grid-column:1;font-size:12px;color:var(--muted)}
.lead-match-one .btn{grid-column:2;grid-row:1 / span 3}
.lead-match-note,.lead-match-done{margin:0;font-size:13px;line-height:1.5;color:var(--ink-2)}
@media (max-width:640px){
  /* The button goes under the facts. Beside them it squeezes a date of birth
     onto three lines, and that date is the thing being compared. */
  .lead-match-one{grid-template-columns:minmax(0,1fr)}
  .lead-match-one .btn{grid-column:1;grid-row:auto;justify-self:start;margin-top:6px}
}
/* "What next?" on a lead: the button, and the answer that replaces it. */
.item-ai{margin-top:2px}
.ai-ask{font:inherit;font-size:12.5px;padding:6px 11px;border:1px dashed var(--line-strong);border-radius:8px;background:none;color:var(--ink-2);cursor:pointer}
.ai-ask:hover{border-style:solid;border-color:var(--green);color:var(--ink)}
.ai-working{font-size:12.5px;color:var(--muted)}
.ai-answer{padding:10px 12px;background:var(--surface-2);border-radius:9px;display:grid;gap:5px}
.ai-step{font-weight:600;font-size:13.5px}
.ai-urgency{justify-self:start;font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;padding:1px 7px;border-radius:999px;border:1px solid var(--line-strong);color:var(--ink-2)}
.ai-urgency.urgent,.ai-urgency.high{color:var(--urgent);border-color:var(--urgent);background:var(--urgent-soft)}
.ai-by{position:absolute;right:12px;font:10px var(--mono);text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.ai-answer{position:relative}
.ai-summary,.ai-why,.ai-note{margin:0;font-size:13px;line-height:1.5;color:var(--ink-2)}
.ai-why{color:var(--muted);font-size:12.5px}
.ai-note{color:var(--muted);font-size:12px;font-style:italic}
.ai-error{font-size:12.5px;color:var(--red)}
.item-actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto;padding-top:4px}
.item-actions .btn.small{min-height:34px;padding:6px 10px}
.item-actions .more{min-width:0;width:auto;padding:6px 24px 6px 10px;background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);background-position:calc(100% - 14px) 14px,calc(100% - 10px) 14px;background-size:4px 4px;background-repeat:no-repeat;appearance:none;-webkit-appearance:none}
.queue.compact{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:10px}
.queue.compact .item{padding:12px 14px 12px;gap:8px}
.queue.compact .item-name{font-size:15px}
.queue.compact .item-snippet{-webkit-line-clamp:2;font-size:13px}
.queue.compact .item-next{padding:6px 10px}
.queue.compact .item-actions .btn.small{min-height:30px;padding:4px 10px;font-size:12px}
.empty{padding:40px 24px;text-align:center;color:var(--muted);display:grid;gap:4px}
.empty b{color:var(--ink);font-size:15px}
.seg.small{display:inline-flex;border:1px solid var(--line-strong);border-radius:9px;overflow:hidden}
.seg.small button{padding:7px 12px;border:0;background:var(--surface);cursor:pointer;font-size:12.5px;color:var(--ink-2)}
.seg.small button[aria-pressed="true"]{background:var(--ink);color:var(--paper);font-weight:600}
/* The "how did the call go?" bar on Patient intake.
   Namespaced pd-callback, not .callback or .call-bar: this stylesheet is
   shared by 31 pages and a generic name here silently inherits another
   page's layout. Sits above the toast so the two never overlap, and stays
   until it is answered, because the answer comes when the call ends. */
.pd-callback{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);
  background:var(--surface);color:var(--ink);border:1px solid var(--line-strong);
  padding:12px 16px;border-radius:14px;z-index:75;
  box-shadow:0 10px 30px rgba(0,0,0,.28);max-width:calc(100vw - 32px)}
.pd-callback-ask{margin:0 0 9px;font-size:13.5px}
.pd-callback-row{display:flex;flex-wrap:wrap;gap:8px}
.pd-callback .btn{font-size:13px}
.pd-callback .btn.quiet{border-color:transparent;color:var(--muted)}
.pd-callback .btn.quiet:hover{color:var(--ink)}
.pd-callback .muted{color:var(--muted);font-weight:400}
/* The second row of the bar: a note, and when to come back. Shown only for
   the outcomes that need one more thing said, so the common case stays one
   press. */
.pd-callback-more{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:10px;padding-top:10px;border-top:1px solid var(--line)}
.pd-callback-more textarea{flex:1 1 260px;min-height:44px;resize:vertical;font:inherit;font-size:13px;padding:8px 10px;border:1px solid var(--line-strong);border-radius:8px;background:var(--paper);color:var(--ink)}
.pd-callback-when{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted)}
.pd-callback-when select{font:inherit;font-size:13px;padding:6px 8px;border:1px solid var(--line-strong);border-radius:8px;background:var(--paper);color:var(--ink)}

/* WHAT TO DO: the row's reason for existing, in one box on the expanded row.
   Namespaced pd-what, because this stylesheet serves 31 pages. */
.pd-what{margin:10px 0;padding:10px 12px;border:1px solid var(--line-strong);border-radius:10px;background:var(--surface)}
.pd-what-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.pd-what-line{margin:8px 0 0;font-size:13px;color:var(--ink-2)}
.pd-what-line b{color:var(--ink)}
.pd-what-missing{margin:8px 0 0;display:flex;flex-wrap:wrap;gap:8px 14px;align-items:center;font-size:13px;color:var(--muted)}
.pd-what-missing > span{display:inline-flex;align-items:center;gap:8px}

/* The booking screen. Uses the shared .modal and .dialog; everything below
   is its own. It shows what is BOOKED and says so: a row with nobody in it
   reads "nothing booked", never "free", because nothing records who is
   working (see book.js). */
.pd-book .dialog{max-width:660px;width:calc(100vw - 32px)}
.pd-book-dialog h2{margin:0 0 4px}
.pd-book-said{margin:0 0 10px;color:var(--ink-2);font-size:13.5px}
.pd-book-days{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}
.pd-book-chip{font:inherit;font-size:12.5px;padding:5px 10px;border-radius:999px;border:1px solid var(--line-strong);background:var(--surface);color:var(--ink-2);cursor:pointer}
.pd-book-chip.said{border-color:var(--brand,#0891B2);color:var(--brand,#0891B2)}
.pd-book-chip.on{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.pd-book-nav{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.pd-book-nav b{font-size:15px}
.pd-book-grid{max-height:min(46vh,420px);overflow-y:auto;border:1px solid var(--line);border-radius:10px;background:var(--paper)}
.pd-book-grid > p{margin:0;padding:10px 12px;font-size:13px}
.pd-book-row{display:grid;grid-template-columns:52px 1fr auto;align-items:center;gap:10px;padding:5px 10px;border-bottom:1px solid var(--line);font-size:13px;min-height:36px}
.pd-book-row:last-child{border-bottom:0}
.pd-book-row.empty{background:var(--surface)}
.pd-book-row.picked{background:color-mix(in srgb,var(--brand,#0891B2) 14%,transparent)}
.pd-book-time{color:var(--muted);font-size:12.5px}
.pd-book-who{display:flex;flex-wrap:wrap;gap:6px;min-width:0}
.pd-book-appt{background:var(--surface-3,var(--surface-2));border-radius:6px;padding:2px 7px;white-space:nowrap}
.pd-book-appt small{color:var(--muted);margin-left:3px}
.pd-book-here{visibility:hidden}
.pd-book-row:hover .pd-book-here,.pd-book-row.empty .pd-book-here,.pd-book-row.picked .pd-book-here{visibility:visible}
.pd-book-opts{display:flex;flex-wrap:wrap;gap:12px;margin:12px 0 6px;font-size:13px;color:var(--muted)}
.pd-book-opts label{display:flex;align-items:center;gap:6px}
.pd-book-opts label.grow{flex:1 1 200px}
.pd-book-opts input,.pd-book-opts select{font:inherit;font-size:13px;padding:6px 8px;border:1px solid var(--line-strong);border-radius:8px;background:var(--paper);color:var(--ink);flex:1 1 auto;min-width:0}
.pd-book-warn{margin:6px 0 10px;font-size:12.5px;color:var(--warn,#b4500e)}
.pd-book-error{color:var(--urgent)}
.pd-book-foot{display:flex;align-items:center;gap:10px;justify-content:flex-end;flex-wrap:wrap}
.pd-book-foot .muted{margin-right:auto;font-size:13px}
@media (max-width:640px){
  .pd-book-row{grid-template-columns:44px 1fr auto}
  .pd-book-here{visibility:visible}
  .pd-book .dialog{width:calc(100vw - 16px)}
}
/* On a phone it is full width at the bottom, clear of the tab bar, because
   that is the screen somebody is actually holding when they ring back. */
@media (max-width:640px){
  .pd-callback{left:12px;right:12px;transform:none;bottom:calc(72px + env(safe-area-inset-bottom, 0px))}
  .pd-callback-row .btn{flex:1 1 auto}
}
.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--ink);color:var(--paper);padding:10px 12px 10px 16px;border-radius:12px;display:flex;align-items:center;gap:12px;font-size:13.5px;z-index:70;box-shadow:0 8px 24px rgba(0,0,0,.25);max-width:calc(100vw - 32px)}
.toast .btn.small{background:transparent;color:var(--paper);border-color:rgba(255,255,255,.35)}
.toast .btn.small:hover{border-color:#fff}
body.loading .queue{opacity:.6;transition:opacity .2s}
@media (max-width:1100px){.queue,.queue.compact{grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}}
@media (max-width:720px){.queue,.queue.compact{grid-template-columns:1fr}.page-head.headline h1{font-size:28px}.item-when{margin-left:0;width:100%}
  /* On a phone the filter block is taller than the screen can spare, so it scrolls with the page. */
  .page > .bar{position:static;margin:0;padding:0;border-bottom:0;background:transparent}
  .bar .seg.small,.bar .spacer{display:none}.bar input{width:100%}}

/* ---- list view: the same actions in a row ---- */
.row-actions{display:flex;gap:5px;flex-wrap:nowrap}
/* Scoped to the work table it was written for. As a bare id selector it hit
   every page using id="list" - five of them, for entirely different things -
   and was dragging the insurance coverage tables out to 1180px, which pushed
   the money columns away from the category they belong to. insurance.css had
   to cap its wrapper at 520px to fight it, which is why those cards showed a
   narrow table beside a thousand pixels of nothing. */
.work#list table,#list table.work{min-width:1180px}
.row-actions .btn.small{padding:7px 11px;font-size:12.5px;min-height:34px}
.row-actions .more{min-width:0;width:auto;padding:4px 22px 4px 9px;appearance:none;-webkit-appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);background-position:calc(100% - 12px) 12px,calc(100% - 8px) 12px;background-size:4px 4px;background-repeat:no-repeat}
.work tr.closed{opacity:.6}
.work td .mono a{color:inherit;text-decoration:none}
.work td .mono a:hover{color:var(--accent)}
/* ---- board view: one column per stage ---- */
.board{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;align-items:start}
.board:has(.column:nth-child(4)){grid-template-columns:repeat(4,minmax(0,1fr))}
.column{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius);padding:10px;min-width:0}
.column-head{display:flex;align-items:center;justify-content:space-between;padding:6px 8px 10px}
.column-head h2{margin:0;font-size:13px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--ink-2)}
.column-head .count{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:1px 8px}
.column-body{display:grid;gap:10px}
.column .item{padding:14px 16px 14px;gap:10px}
.column .item-name{font-size:15.5px}
.column .item-snippet{-webkit-line-clamp:2;font-size:13px}
.column-empty{margin:0;padding:22px 8px;text-align:center;color:var(--muted);font-size:13px}
.board.compact .item{padding:10px 12px;gap:7px}
.board.compact .item-snippet{display:none}
.board.compact .item-next{display:none}
@media (max-width:1100px){.board,.board:has(.column:nth-child(4)){grid-template-columns:1fr 1fr}}
@media (max-width:720px){.board,.board:has(.column:nth-child(4)){grid-template-columns:1fr}.bar .seg.small[aria-label="View"]{display:inline-flex}}

/* ---- settings ---- */
.settings .section-title{margin:26px 0 4px;font-size:16px;font-weight:600;letter-spacing:-.01em}
.settings .section-lede{margin:0 0 12px;color:var(--ink-2);font-size:13.5px;max-width:72ch}
.settings .banner{padding:12px 16px;border:1px solid var(--line-strong);border-radius:10px;background:var(--surface);font-size:13.5px}
.settings .banner.ok{border-color:var(--ink)}
.settings .banner.bad{border-color:var(--urgent);color:var(--urgent)}
.mailbox{padding:20px 22px;display:flex;flex-direction:column;gap:8px}
.mailbox-top{display:flex;justify-content:space-between;gap:12px;align-items:flex-start}
.mailbox h3{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em}
.mailbox-who{margin:2px 0 0;font-size:13px;color:var(--ink-2);overflow-wrap:anywhere}
.mailbox-blurb{margin:0;color:var(--ink-2);font-size:13.5px}
.mailbox-meta{margin:0;color:var(--muted);font-size:12.5px}
.mailbox-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:6px}
.btn.quiet{color:var(--muted)}
.mailbox-result{margin:0;font-size:13px;color:var(--ink-2)}
.mailbox-result.ok{color:var(--ink)}
.mailbox-result.bad{color:var(--urgent)}
.facts{padding:6px 22px}
.fact{display:grid;grid-template-columns:200px 1fr;gap:12px;padding:12px 0;border-bottom:1px solid var(--line);font-size:13.5px}
.fact:last-of-type{border-bottom:0}
.fact-label{color:var(--muted)}
.fact-value{color:var(--ink);overflow-wrap:anywhere}
.fact-value.bad{color:var(--urgent)}
.fact-value .status-line{font-size:13.5px;color:var(--ink)}
.facts-note{margin:0;padding:10px 0 12px;color:var(--muted);font-size:12.5px;border-top:1px solid var(--line)}
@media (max-width:640px){.fact{grid-template-columns:1fr;gap:4px}}
.mailbox-actions .btn:disabled{opacity:.45;cursor:not-allowed}


/* ---- practice pages (schedule, patients, recall, claims, referrals, reports) ---- */
.nav details.more{position:relative;display:flex;align-items:center;height:100%}
.nav details.more summary{list-style:none;cursor:pointer;display:flex;align-items:center;padding:0 12px;color:var(--ink-2);font-size:13.5px;height:100%;white-space:nowrap}
.nav details.more summary::-webkit-details-marker{display:none}
.nav details.more summary::after{content:"";display:inline-block;width:6px;height:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);margin:-3px 0 0 7px}
.nav details.more:hover summary,.nav details.more[open] summary{color:var(--ink)}
.nav details.more.current summary{color:var(--ink);font-weight:600}
.nav details.more .menu{position:absolute;top:calc(100% - 1px);left:0;min-width:180px;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,.12);padding:6px;display:grid;z-index:50}
.nav details.more .menu a{padding:8px 12px;border-radius:7px;height:auto}
.nav details.more .menu a:hover{background:var(--surface-2)}
.nav details.more .menu a[aria-current="page"]::after{display:none}
.sample{display:flex;gap:10px;align-items:center;padding:8px 14px;border:1px dashed var(--line-strong);border-radius:9px;font-size:12.5px;color:var(--ink-2);background:var(--surface)}
.sample b{font-weight:600;color:var(--ink)}
.sample a{color:var(--ink-2)}
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tabs button{border:0;background:transparent;padding:10px 12px;color:var(--ink-2);cursor:pointer;font-size:13.5px;white-space:nowrap;position:relative;border-radius:0}
.tabs button:hover{color:var(--ink)}
.tabs button[aria-selected="true"]{color:var(--ink);font-weight:600}
.tabs button[aria-selected="true"]::after{content:"";position:absolute;left:12px;right:12px;bottom:-1px;height:2px;background:var(--ink)}
.tabs button .n{margin-left:6px;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.drawer-scrim{position:fixed;inset:0;background:var(--scrim);z-index:55;display:none}
.drawer-scrim.open{display:block}
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(520px,100%);background:var(--surface);border-left:1px solid var(--line);z-index:56;transform:translateX(100%);transition:transform .18s ease;overflow:auto;display:flex;flex-direction:column}
.drawer.open{transform:none}
.drawer-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:18px 22px 12px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--surface);z-index:1}
.drawer-head h2{margin:0;font-size:18px;font-weight:600;letter-spacing:-.02em}
.drawer-body{padding:16px 22px 24px;display:grid;gap:16px;align-content:start}
.kv{display:grid;grid-template-columns:140px 1fr;gap:6px 12px;font-size:13.5px;margin:0}
.kv dt{color:var(--muted);margin:0}
.kv dd{margin:0;overflow-wrap:anywhere}
.avatar{width:40px;height:40px;border-radius:50%;background:var(--surface-3);color:var(--ink);display:inline-flex;align-items:center;justify-content:center;font-weight:600;font-size:13px;flex:none;letter-spacing:.02em}
.avatar.lg{width:56px;height:56px;font-size:18px}
.status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--line-strong);margin-right:6px;vertical-align:1px}
.status-dot.booked{background:var(--o1)}.status-dot.confirmed{background:var(--o3)}.status-dot.arrived{background:var(--o4)}.status-dot.seated{background:var(--ink)}.status-dot.completed{background:var(--ink);opacity:.35}.status-dot.no-show,.status-dot.cancelled{background:var(--urgent)}
.money{font-variant-numeric:tabular-nums;white-space:nowrap}
.money.neg{color:var(--muted)}
.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.tbl th{text-align:left;padding:9px 12px;font-size:12px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-2);font-weight:600;border-bottom:1px solid var(--line);white-space:nowrap}
.tbl td{padding:10px 12px;border-bottom:1px solid var(--line);vertical-align:top}
.tbl tr:last-child td{border-bottom:0}
.tbl .num,.tbl th.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.tbl tbody tr.click{cursor:pointer}
.tbl tbody tr.click:hover{background:var(--surface-2)}
.card > .card-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:14px 18px 10px}
.card > .card-head h2{margin:0;font-size:14px;font-weight:600}
.card > .card-head .hint{font-size:12px;color:var(--muted)}
.card > .card-body{padding:0 18px 16px}
.split{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:18px;align-items:start}
@media (max-width:1100px){.split{grid-template-columns:1fr}}
@media (max-width:820px){.nav details.more .menu{position:static;box-shadow:none;border:0;display:flex;padding:0;gap:2px}.nav details.more{display:contents}.nav details.more summary{display:none}}

/* ---- the sidebar ----
   Built by theme.js from each page's header. Sections sit in groups down the
   left, in the order a patient moves through the practice. Under 900px the
   same header becomes a slim bar and the groups slide in as a drawer. A page
   whose script fails keeps its plain top bar, because none of this applies
   until the body carries .has-sidebar. */
:root{--side-w:236px}
:is(body.has-sidebar, html.pd-sidebar body){padding-left:var(--side-w)}
:is(body.has-sidebar, html.pd-sidebar body) .top{position:fixed;top:0;left:0;bottom:0;width:var(--side-w);height:auto;padding:0;gap:0;flex-direction:column;align-items:stretch;flex-wrap:nowrap;border-right:1px solid var(--line);border-bottom:0;background:var(--surface);z-index:40;overflow:hidden}
/* The practice name is not shown on the sidebar. On a tool only this practice
   signs into it told nobody anything, while taking the most valuable space on
   every screen; the running costs take that space instead. It stays in the
   markup for the narrow layout below, where the sidebar collapses to a bar and
   there is nothing else to say which app this is. */
:is(body.has-sidebar, html.pd-sidebar body) .side-brand .brand{display:none}
/* With the practice name hidden this bar held nothing but the menu button,
   which read as a stray control floating in an empty strip. On a wide screen
   the sidebar IS the menu, so there is nothing for that button to open and the
   whole bar goes. Both come back below 900px, where the sidebar collapses and
   the button is the only way to reach the sections. */
:is(body.has-sidebar, html.pd-sidebar body) .side-brand{display:none}
.side-brand{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:16px 16px 14px;border-bottom:1px solid var(--line);flex:none}
.side-brand .brand{margin:0;flex-direction:column;align-items:flex-start;gap:1px}
.side-brand .brand b{font-size:15px}
.side-brand .brand span{font-size:11.5px}
.side-menu{display:none}
:is(body.has-sidebar, html.pd-sidebar body) .nav{display:flex;flex-direction:column;flex:1 1 auto;height:auto;align-self:auto;gap:0;padding:10px 10px 12px;overflow-y:auto;overflow-x:hidden;order:0;width:auto}
.side-nav .group{display:grid;gap:1px;padding:4px 0 6px}
.side-nav .group + .group{border-top:1px solid var(--line)}
.side-nav .group-label{margin:6px 10px 3px;font-size:10.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
:is(body.has-sidebar, html.pd-sidebar body) .nav a{display:flex;align-items:center;gap:11px;height:auto;padding:8px 10px;border-radius:8px;font-size:14px;color:var(--ink-2);white-space:nowrap;position:relative;transition:background .1s,color .1s}
:is(body.has-sidebar, html.pd-sidebar body) .nav a:hover{background:var(--surface-2);color:var(--ink)}
:is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"]{background:var(--surface-3);color:var(--ink);font-weight:600}
:is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"]::after{content:"";position:absolute;left:0;right:auto;top:7px;bottom:7px;width:3px;height:auto;border-radius:2px;background:var(--ink)}
.side-nav a svg{width:17px;height:17px;flex:none;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;opacity:.8}
.side-nav a[aria-current="page"] svg{opacity:1}
.side-nav a .t{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}
.side-nav a .badge{flex:none;font-size:11px;font-weight:600;font-variant-numeric:tabular-nums;line-height:1;padding:3px 7px;border-radius:999px;background:var(--ink);color:var(--paper)}

/* ------------------------------------------------- sidebar, tightened ---
 *
 * The column had grown past the height of a laptop screen, so Settings and
 * the sign-out sat below the fold and the whole thing scrolled inside its
 * own scrollbar. Nothing was removed to fix that: the rows, the group gaps
 * and the boxes each gave back a few pixels, which together are enough to
 * land the full list on a 900px screen.
 *
 * The other change is the current row. A 3px bar against a tinted
 * background was the only thing saying "you are here", and on the tinted
 * background of a work box it nearly vanished. It is now the brand colour
 * and full height, which reads at a glance without adding weight. */
.side-nav .group{padding:2px 0 4px}
.side-nav .group-label{margin:5px 10px 2px;font-size:10px}
:is(body.has-sidebar, html.pd-sidebar body) .nav a{padding:6px 10px;gap:10px;font-size:13.5px}
.work-box{padding:4px 4px;margin:0 6px 10px}

/* You are here: the brand colour, edge to edge of the row. */
:is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"]::after{
  top:4px;bottom:4px;width:3px;background:var(--brand,#0891B2)}
:is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"] svg{
  color:var(--brand,#0891B2)}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) :is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"]::after{background:#22D3EE}
  :root:not([data-theme="light"]) :is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"] svg{color:#22D3EE}
}
:root[data-theme="dark"] :is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"]::after{background:#22D3EE}
:root[data-theme="dark"] :is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"] svg{color:#22D3EE}

/* A badge is a count of work owed, so it should not shout louder than the
   row it belongs to. Solid ink on every one of them turned the column into
   a row of black pills; only the urgent ones keep that weight. */
.side-nav a .badge{background:var(--surface-3);color:var(--ink-2);font-weight:600}
.side-nav a[aria-current="page"] .badge{background:var(--ink);color:var(--paper)}
.side-nav a:hover .badge{background:var(--line-strong);color:var(--ink)}
.side-foot{display:flex;align-items:center;gap:8px;padding:12px 14px;border-top:1px solid var(--line);flex:none;background:var(--surface)}
.side-foot .who{display:block;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:12px}
.side-foot .btn{flex:none}
.side-foot .btn:not(.icon){padding:6px 10px;font-size:12.5px}
.side-scrim{display:none}
/* the old dropdown has no job once the groups exist */
:is(body.has-sidebar, html.pd-sidebar body) .nav details.more{display:none}
/* The page sits against the sidebar, not centred in what is left. On a wide
   monitor centring opens a dead gutter between the two, and the eye has to
   cross it on every glance from the sections to the work. The width limit
   stays so a row of cards does not stretch to eight across. */
:is(body.has-sidebar, html.pd-sidebar body) .page{max-width:1600px;margin:0}
/* There is no bar across the top in this layout, so nothing should be reserved
   for one. Every sticky heading offsets itself by var(--topbar-h,60px), and
   that 60px fallback applies for the moment before theme.js has measured
   anything, and for good if it never runs. The heading is then pushed 60px
   below where it belongs and lands on top of the first row of the table, which
   is what put the column names underneath the first patient's name.
   Only above 900px: below that the sidebar folds back into a real 56px bar
   across the top, and that one does need the space. */
@media (min-width:900px){:is(body.has-sidebar, html.pd-sidebar body){--topbar-h:0px}}

@media (max-width:899px){
  :is(body.has-sidebar, html.pd-sidebar body){padding-left:0}
  :is(body.has-sidebar, html.pd-sidebar body) .top{position:sticky;top:0;left:auto;bottom:auto;width:auto;height:56px;flex-direction:row;align-items:center;padding:0 12px 0 16px;border-right:0;border-bottom:1px solid var(--line);overflow:visible}
  /* display is restated because the wide layout sets it to none: without it
     the narrow bar loses both the name and the only button that opens the
     sections, leaving no way to navigate at all. */
  :is(body.has-sidebar, html.pd-sidebar body) .side-brand{display:flex}
  .side-brand{flex:1 1 auto;padding:0;border:0;justify-content:flex-start;gap:12px}
  /* The name comes back here. The sidebar has collapsed to a bar, so without
     it there is nothing on screen saying which app this is. */
  :is(body.has-sidebar, html.pd-sidebar body) .side-brand .brand{display:flex}
  .side-brand .brand{flex-direction:row;align-items:baseline;gap:8px}
  /* The meters do not fit in a 56px bar beside the name and the menu, and a
     squeezed gauge is worse than none. They are in the drawer with the
     sections, which is where somebody on a phone goes looking anyway. */
  .side-meters{order:5;width:100%;margin:0 0 10px}
  .side-menu{display:inline-flex;order:-1}
  .side-menu svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
  :is(body.has-sidebar, html.pd-sidebar body) .nav{position:fixed;top:56px;left:0;bottom:0;width:min(300px,86vw);background:var(--surface);border-right:1px solid var(--line);padding:8px 10px 16px;transform:translateX(-100%);transition:transform .18s ease;z-index:45;box-shadow:0 12px 40px rgba(0,0,0,.25)}
  body.nav-open .nav{transform:none}
  .side-scrim{position:fixed;left:0;right:0;top:56px;bottom:0;background:var(--scrim);z-index:44}
  body.nav-open .side-scrim{display:block}
  .side-foot{padding:0;border:0;background:transparent;gap:6px}
  .side-foot .who{display:none}
  body.nav-open{overflow:hidden}
}
@media (prefers-reduced-motion:reduce){:is(body.has-sidebar, html.pd-sidebar body) .nav{transition:none}}
@media print{:is(body.has-sidebar, html.pd-sidebar body){padding-left:0}:is(body.has-sidebar, html.pd-sidebar body) .top{display:none}}

/* ---- insurance on a follow-up card ----
   Colour carries meaning here, so it stays within the monochrome rule: the
   accent only appears when a plan is genuinely confirmed, and the urgent red
   only when the insurer said no. Everything uncertain stays grey, because a
   check we could not complete must not read as either good or bad news. */
.item-ins{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-top:10px;padding:8px 10px;border:1px solid var(--line);border-radius:9px;background:var(--surface-2);font-size:12.5px;line-height:1.4}
.item-ins b{font-weight:600;color:var(--ink);white-space:nowrap}
.item-ins span{color:var(--ink-2);min-width:0}
.item-ins::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--line-strong);flex:none;align-self:center}
.item-ins.ok::before{background:var(--ink)}
.item-ins.ok{border-color:var(--line-strong)}
.item-ins.bad::before{background:var(--urgent)}
.item-ins.bad b,.item-ins.bad span{color:var(--urgent)}
.item-ins.bad{border-color:var(--urgent)}
.item-ins.warn span{color:var(--muted)}
.item-ins.pending span{color:var(--muted)}
.queue.compact .item-ins{margin-top:6px;padding:5px 8px;font-size:12px}

/* ---- a lead, opened in place ----
   The table says who is waiting; clicking a row opens that lead underneath it
   rather than sending anyone to another page, so the queue keeps its place. */
/* ---- signals: the line of plain words under a name on the lead list ----
   "in pain · 2nd try · Aetna verified". These are the facts that decide who
   is rung first, and they were computed and discarded before reaching the
   screen. Sized to be read at a glance, not squinted at. */
.sub-line{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-top:5px}
.sigs{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}
.sig{display:inline-flex;align-items:center;padding:1px 9px;border-radius:999px;
  border:1px solid var(--line-strong);font-size:12px;font-weight:600;color:var(--ink-2);
  white-space:nowrap;line-height:1.7}
/* bad is a problem with the patient, warn is a problem with us, ok reassures. */
.sig.bad{color:var(--urgent);border-color:var(--urgent)}
.sig.warn{color:var(--warn,#b4500e);border-color:var(--warn,#b4500e)}
.sig.ok{color:var(--ok);border-color:var(--line-strong)}

/* Ageing, measured against what this KIND of request may wait, so a day on
   somebody in pain does not look like a day on a cleaning request. */
.age.warm{color:var(--warn,#b4500e);font-weight:600}
.age.late{color:var(--urgent);font-weight:700}
/* When they got in touch, in the first column. A queue is read as a log:
   when, then who, then what. Narrow and fixed so the dates line up down the
   page and the eye can run them without reading each one. */
.work td.contacted{width:120px;white-space:nowrap;color:var(--ink-2);font-size:12.5px;
  vertical-align:top;padding-top:16px}

.lead-row.late td:first-child{box-shadow:inset 3px 0 0 var(--urgent)}
.lead-row.warm td:first-child{box-shadow:inset 3px 0 0 var(--warn,#b4500e)}

/* What the row needs doing, as a verb, in its own column so the eye can run
   down the list without reading anything else. */
.lead-row .row-do{width:86px;text-align:right}
.do-next{display:inline-block;padding:3px 11px;border-radius:8px;border:1px solid var(--ink);
  background:var(--ink);color:var(--paper);font-size:12.5px;font-weight:650;white-space:nowrap}

/* The steps for this kind of work.
   This used to be a numbered list whose done rows drew a tick through
   ::before. That tick was a corrupted character, the two literal
   characters "¹3" where a ✓ was meant, so every completed step on the
   leads page has been showing "¹3" beside it. The whole block is gone:
   the stepper is defined once, further down, where the rows carry a real
   tick button. Keeping a second definition here is what let the broken
   marker survive a redesign of the component.
   .lead-steps and .step-flag now live under "the stepper". */
.lead-steps li.done{color:var(--muted)}
.btn[disabled]{opacity:.45;cursor:not-allowed;text-decoration:line-through}

/* The four kinds of work, in one box at the top of the sidebar.
   Boxed so that what somebody came here to DO is separated from the
   reference pages they only occasionally open. */
/* The tooth, at the top of the sections. The only thing on this sidebar that
   is the practice rather than the software, and the reason the column of grey
   labels does not read as a settings menu. */
/* The practice mark, and the way back to the overview.
   It is a link, so it gets a link's affordances: a hover state, a real
   focus ring, and a pointer. Without them it reads as decoration and
   nobody discovers it is clickable. */
.side-mark{display:flex;align-items:center;gap:9px;padding:6px 10px 10px;
  border-bottom:1px solid var(--line);margin:0 0 8px;
  text-decoration:none;border-radius:9px;
  transition:background .12s ease}
.side-mark:hover{background:var(--surface-2,rgba(128,128,128,.10))}
.side-mark:focus-visible{outline:2px solid var(--brand,#0891B2);outline-offset:2px}
.side-mark:hover span{color:var(--brand,#0891B2)}
/* The mark is now an <a> inside .nav, so the generic sidebar-row rules
   below would give it a row's padding, font size and current-page bar. It
   keeps its own shape. */
:is(body.has-sidebar, html.pd-sidebar body) .nav a.side-mark{
  padding:6px 10px 10px;gap:9px;font-size:inherit;border-radius:9px}
:is(body.has-sidebar, html.pd-sidebar body) .nav a.side-mark[aria-current="page"]::after{display:none}
/* The tooth is a SOLID shape, and .side-nav a svg above sets fill:none and
   a stroke for the line-drawn section icons. Once the mark became an <a>
   inside .nav it inherited that and rendered as a hollow outline, nearly
   invisible on the light background. Restated here at a specificity that
   wins, rather than by reordering rules other pages depend on. */
.side-nav a.side-mark svg{fill:var(--brand,#0891B2);stroke:none;opacity:1;width:20px;height:20px}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .side-nav a.side-mark svg{fill:#22D3EE}
}
:root[data-theme="dark"] .side-nav a.side-mark svg{fill:#22D3EE}
.side-mark svg{width:20px;height:20px;flex:none;fill:var(--brand,#0891B2);stroke:none}
.side-mark span{font-size:14px;font-weight:650;letter-spacing:-.01em;color:var(--ink)}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .side-mark svg{fill:#22D3EE}
}
:root[data-theme="dark"] .side-mark svg{fill:#22D3EE}

.work-box{border:1px solid var(--line-strong);border-radius:11px;background:var(--surface);
  padding:6px 4px;margin:0 6px 14px}
.work-box .group{margin:0}

.work-box .group-label{padding-left:10px;margin-bottom:2px}

/* Insurance as a column. Three answers in one cell, in the order somebody
   asks them: has anyone checked, was DENTAL confirmed, and how much is left.
   The money is the point: a tick says the plan exists, the number says what
   can be promised on the telephone. */
.ins{display:flex;flex-direction:column;gap:1px;line-height:1.3}
.ins b{font-size:13px;font-weight:600;color:var(--ink)}
.ins span{font-size:12px;color:var(--muted)}
.ins-ok span{color:var(--ok);font-weight:600}
.ins-warn span{color:var(--warn,#b4500e);font-weight:600}
.ins-bad span{color:var(--urgent);font-weight:600}
/* Dashed, because nothing has been asked yet: it is a job, not an answer. */
.ins-todo span{color:var(--warn,#b4500e);font-weight:600}
.ins-none{font-size:12.5px;color:var(--muted)}

/* What the row NEEDS, not where it has got to. "New" is a fact about filing
   that nobody can act on; "Make appointment" is the job. */
.next-thing{display:inline-block;font-size:13px;font-weight:600;white-space:nowrap;color:var(--ink-2)}
.next-thing.ok{color:var(--ok)}
.next-thing.warn{color:var(--warn,#b4500e)}
.next-thing.bad{color:var(--urgent)}
.next-thing.muted{color:var(--muted);font-weight:500}

/* A person name that opens their record. Underlined only on hover so a list
   of names does not read as a wall of links, but the cursor and the underline
   both say it is one before anybody clicks. */
/* The same idea on the Work screen, where a row is a button and cannot hold
   a link. Quiet until hovered, so it does not compete with the name. */
.to-person{font-size:11.5px;color:var(--muted);border:1px solid var(--line-strong);
  border-radius:999px;padding:0 8px;margin-left:8px;white-space:nowrap;cursor:pointer}
.to-person:hover{color:var(--ink);border-color:var(--ink)}

.person-link{color:inherit;text-decoration:none;border-bottom:1px solid transparent}
.person-link:hover{border-bottom-color:currentColor}
.person-link:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}

.lead-row{cursor:pointer}
.lead-row:hover{background:var(--hover,rgba(127,127,127,.06))}
.lead-row .row-open{width:34px;text-align:right}
.chev{display:inline-block;width:8px;height:8px;border-right:1.6px solid var(--muted);border-bottom:1.6px solid var(--muted);transform:rotate(45deg) translate(-2px,-2px);transition:transform .14s ease}
.lead-row.open .chev{transform:rotate(-135deg) translate(-3px,-3px)}
.lead-row.open{background:var(--surface)}
.lead-row.open td{border-bottom-color:transparent}
.lead-detail > td{padding:0 14px 18px;background:var(--surface)}
.lead-panel{display:flex;flex-wrap:wrap;gap:18px 28px;align-items:flex-start;padding:4px 0 2px}
.lead-panel-main{flex:1 1 380px;min-width:0;display:grid;gap:8px}
.lead-panel-side{flex:0 1 auto;display:grid;gap:10px}

/* ---- the buttons on a lead ----
   These are the things the desk does all day, on a screen it uses standing up
   and often on a touch monitor, so they are a proper size and the one that
   moves the lead on is the filled one. */
.item-actions .btn,.lead-panel .btn{min-height:40px;padding:9px 16px;font-size:14px;border-radius:9px}
.item-actions .btn.call,.lead-panel .btn.call{font-weight:600}
.lead-panel .more,.item-actions .more{padding-right:30px;background-position:calc(100% - 16px) 17px,calc(100% - 12px) 17px}
.item-ask{display:flex;align-items:center;flex-wrap:wrap;gap:8px;color:var(--muted);font-size:13px}
.item-ask .btn.small{min-height:32px}
.item-ask .btn[aria-pressed="true"]{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---- "Beta" on the sections that run on sample data ----
   Those screens show phone numbers, chart numbers, medical alerts and
   balances, and they are convincing enough that someone could start
   telephoning invented numbers. The banner at the top of each page scrolls
   away; the nav is on screen at the moment a person chooses where to go, so
   the warning belongs here too. Quiet enough not to shout, present enough to
   be read before the click. */
.side-nav a .beta{margin-left:auto;padding:1px 6px;border:1px solid var(--line-strong);border-radius:999px;font-size:9px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);line-height:1.6;flex:none}
.side-nav a[aria-current="page"] .beta{border-color:currentColor;color:inherit;opacity:.7}

/* Dictation ------------------------------------------------------------
   A microphone tucked into the corner of any box that holds prose. It sits
   inside the field rather than beside it, so adding one never reflows a
   form that was laid out without it. */
/* The wrapper slots into whatever laid the field out before it existed:
   a grid cell in .field, a flex row elsewhere. min-width:0 keeps it from
   refusing to shrink inside either one. */
.dictate-wrap { position: relative; display: block; min-width: 0; width: 100%; }
.dictate-wrap > input,
.dictate-wrap > textarea { width: 100%; }
/* Room for the button, so long text never slides underneath it. */
.dictate-wrap > textarea { padding-right: 34px; }
.dictate-wrap > input { padding-right: 32px; }

.dictate-btn {
  position: absolute; top: 6px; right: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0;
  border: 1px solid transparent; border-radius: 6px;
  background: transparent; color: var(--muted);
  cursor: pointer; opacity: .55;
  transition: opacity .12s ease, color .12s ease, background .12s ease;
}
/* A single-line input is short enough that the button should centre in it. */
.dictate-wrap > input + .dictate-btn { top: 50%; transform: translateY(-50%); }

.dictate-btn:hover { opacity: 1; color: var(--ink); background: var(--surface-3); }
.dictate-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; opacity: 1; }

/* Listening has to be unmistakable: this is a live microphone. */
.dictate-btn.listening {
  opacity: 1; color: var(--urgent);
  background: var(--urgent-soft); border-color: var(--urgent);
  animation: dictate-pulse 1.4s ease-in-out infinite;
}
@keyframes dictate-pulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--urgent-soft); }
  50%      { box-shadow: 0 0 0 4px var(--urgent-soft); }
}
@media (prefers-reduced-motion: reduce) {
  .dictate-btn.listening { animation: none; }
}

/* A lead nobody answered for three months. It stays in the list, because
   deleting somebody's enquiry is not ours to do, but it should never look
   like today's work: muted, and the whole row set back a little. */
.pill.cold { color: var(--muted); border-style: dashed; border-color: var(--line-strong); }
.item.cold-item, tr.cold-item { opacity: .62; }
.item.cold-item:hover, tr.cold-item:hover { opacity: 1; }

/* ---- sorting by clicking a column ----
   The heading is the control, so it has to look like one: a pointer, a hover,
   and an arrow on the column currently doing the sorting. */
.work thead th[data-sort]{cursor:pointer;user-select:none;white-space:nowrap}
.work thead th[data-sort]:hover{color:var(--ink)}
.work thead th[data-sort]::after{content:"";display:inline-block;width:0;height:0;margin-left:6px;vertical-align:middle;
  border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:5px solid transparent}
.work thead th.sorted{color:var(--ink)}
.work thead th.sorted::after{border-bottom-color:var(--ink)}
.work thead th.sorted.desc::after{border-bottom:0;border-top:5px solid var(--ink)}

/* ---- the counts at the top double as filters ----
   They are buttons now, so they have to look pressable and show which one is
   on. Everything else about the card stays as it was. */
.strip button.card{appearance:none;font:inherit;color:inherit;text-align:left;cursor:pointer;width:100%;
  border:1px solid var(--line);transition:border-color .12s,background .12s}
.strip button.card:hover{border-color:var(--line-strong)}
.strip button.card:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.strip button.card.picked{border-color:var(--ink);background:var(--surface)}
.strip button.card.picked .label{color:var(--ink)}
.strip button.card.picked::after{content:"filtering";display:block;margin-top:6px;font-size:10.5px;
  letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}

/* ---- today's AI spending, at the top of the sidebar ----
   A gauge is only worth having if it is seen without being looked for, so it
   sits under the brand on every page rather than only on Administration.
   Quiet by default: this is a number to glance at, not a warning. */
/* Two meters across the top of the sidebar. Side by side because they are
   different kinds of money and stacking them pushed the sections below the
   fold; adding them together would hide both. At 168px of sidebar each, the
   figures stay readable and the numerals are tabular so they do not jitter as
   they update. */
/* In network beside out of network. Two columns on purpose: one figure invites
   reading the better of the two and quoting it, and the gap between them is
   what a patient actually needs to be told. */
.cover-table table{border-collapse:collapse;width:100%;font-size:12.5px;margin:2px 0 0}
.cover-table th{text-align:left;font-weight:600;padding:3px 8px 3px 0;color:var(--ink)}
.cover-table thead th{font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--muted);font-weight:650;padding-bottom:4px}
.cover-table td{padding:3px 8px 3px 0;color:var(--ink-2);white-space:nowrap}
.cover-table tbody tr + tr th,.cover-table tbody tr + tr td{border-top:1px solid var(--line)}
.cover-table .not-covered{color:var(--muted)}
.cover-table .note{font-size:11.5px;margin:6px 0 0}

/* The spend box is a section, so it highlights like one. */
:is(body.has-sidebar, html.pd-sidebar body) .side-meter[aria-current="page"]{background:var(--surface-3);
  border-color:var(--line-strong)}
:is(body.has-sidebar, html.pd-sidebar body) .side-meter[aria-current="page"] .side-meter-label{color:var(--ink)}
/* Sitting inside the scrolling list now rather than pinned above it, so it
   takes the same side margins as the boxes below it. */
:is(body.has-sidebar, html.pd-sidebar body) .side-meters{margin:0 6px 10px}

.side-meters{display:flex;gap:7px;margin:0 0 4px}
.side-meters .side-meter{flex:1 1 0;min-width:0;margin:0}
/* One visible meter takes the full width rather than sitting half-empty. */
.side-meters .side-meter:only-child{flex-basis:100%}
.side-meter .side-meter-sub{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Checks draw on a prepaid balance with no cap, so the bar is pace, not a
   limit. Muted on purpose: it must not read as a gauge filling towards a
   ceiling the way the AI one does. */
.side-meter.is-checks .side-meter-fill{background:var(--muted)}
/* Tightened 17 Sep 2026. This sat above the sections and pushed them below
   the fold on a laptop, so the navigation scrolled while a spending figure
   held the top of the screen. It is a glance, not a report: the number, a
   bar, one line underneath. */
.side-meter{display:none;position:relative;flex-direction:column;gap:4px;
  margin:0 10px 8px;padding:8px 10px;
  border:1px solid var(--line);border-radius:10px;background:var(--surface);
  text-decoration:none;color:inherit;transition:border-color .12s}
:is(body.has-sidebar, html.pd-sidebar body) .side-meter:not([hidden]){display:flex}
.side-meter:hover{border-color:var(--line-strong)}
.side-meter-top{display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.side-meter-label{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);white-space:nowrap}
.side-meter-value{font-family:var(--mono);font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ink)}
.side-meter-track{height:4px;border-radius:999px;background:var(--line);overflow:hidden}
.side-meter-fill{display:block;height:100%;width:0;border-radius:999px;background:var(--ink);
  transition:width .3s ease,background .2s}
.side-meter-sub{font-size:10.5px;color:var(--muted)}
/* Nearly out, out, and not answering are three different things. */
.side-meter.is-high .side-meter-fill{background:var(--warn,#b8860b)}
.side-meter.is-full .side-meter-fill{background:var(--urgent)}
.side-meter.is-down{border-color:var(--urgent)}
.side-meter.is-down .side-meter-sub{color:var(--urgent)}
.side-meter.is-down .side-meter-fill{background:var(--urgent)}

/* ---------------------------------------------- the confirm-send dialog ---
   Shows a message before it is sent, and lets somebody change it. Styled here
   rather than per page because several pages open it and they must not drift
   into looking like different dialogs. */
.cs-back{position:fixed;inset:0;z-index:200;background:var(--scrim,rgba(0,0,0,.55));
  display:grid;place-items:center;padding:20px}
.cs-back[hidden]{display:none}
.cs-box{background:var(--surface);border:1px solid var(--line-strong);border-radius:14px;
  width:min(620px,100%);max-height:90vh;overflow:auto;box-shadow:0 20px 60px rgba(0,0,0,.35)}
.cs-head{padding:18px 22px 12px;border-bottom:1px solid var(--line)}
.cs-head h2{margin:0 0 3px;font-size:19px;letter-spacing:-.01em}
.cs-to{margin:0;color:var(--muted);font-size:13px}
.cs-body{padding:16px 22px;display:grid;gap:13px}
.cs-field{display:grid;gap:5px}
.cs-field > span{font-size:12px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);font-weight:650}
.cs-field input,.cs-field textarea{width:100%;padding:10px 12px;border:1px solid var(--line);
  border-radius:8px;background:var(--surface-2);color:var(--ink);
  font:14px/1.6 var(--ui);resize:vertical}
.cs-field textarea{min-height:170px}
.cs-field input:focus,.cs-field textarea:focus{outline:2px solid var(--green);outline-offset:-1px}
.cs-note{margin:0;color:var(--muted);font-size:12.5px;line-height:1.5}
.cs-foot{display:flex;gap:10px;align-items:center;padding:14px 22px 18px;
  border-top:1px solid var(--line);flex-wrap:wrap}
.cs-go{padding:9px 17px;border:1px solid transparent;border-radius:8px;
  background:var(--green);color:#fff;font:650 14px var(--ui);cursor:pointer}
.cs-go:hover{filter:brightness(1.08)}
.cs-cancel{padding:9px 15px;border:1px solid var(--line-strong);border-radius:8px;
  background:var(--surface);color:var(--ink);font:14px var(--ui);cursor:pointer}
.cs-cancel:hover{border-color:var(--ink-2)}
.cs-say{font-size:12.5px;color:var(--muted);margin-left:auto}
.cs-say.bad{color:var(--urgent)}
@media (max-width:560px){
  .cs-box{width:100%}
  .cs-foot .cs-go,.cs-foot .cs-cancel{flex:1 1 auto}
  .cs-say{flex:1 1 100%;margin-left:0;order:3}
}

/* A voicemail's recording, on the row. Kept narrow so it reads as one detail
   of the row rather than taking it over. */
.item-audio { display: flex; align-items: center; gap: 8px; margin: 8px 0; }
.item-audio audio { height: 32px; max-width: 320px; flex: 1 1 auto; }
.item-audio .len { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* What the row is waiting for, in words rather than a status code. */
.item-working {
  display: flex; align-items: center; gap: 7px;
  margin: 6px 0; font-size: 12.5px; color: var(--muted);
}
.item-working .spin {
  width: 11px; height: 11px; flex: none;
  border: 2px solid var(--line-strong); border-top-color: var(--ink-2);
  border-radius: 50%; animation: item-spin .9s linear infinite;
}
/* A recording that could not be typed out: worth noticing, not an alarm. */
.item-working.bad { color: var(--warn, #b4500e); }
@keyframes item-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .item-working .spin { animation: none; } }

/* ---- Spending page ---- */
/* Three periods as buttons. Picking one changes the page below, so they are
   real controls and have to look pressable rather than like read-only cards. */
.period-picker{margin-bottom:14px}
.period{display:flex;flex-direction:column;align-items:flex-start;gap:0;
  text-align:left;cursor:pointer;font:inherit;color:inherit;width:100%;
  transition:border-color .12s ease,background .12s ease}
.period:hover{border-color:var(--line-strong)}
.period .lab{font-size:12px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.period .v{font-size:30px;font-weight:600;letter-spacing:-.03em;margin:5px 0 0;
  font-variant-numeric:tabular-nums}
.period .d{font-size:12px;color:var(--muted);margin:4px 0 0}
.period[aria-pressed="true"]{border-color:var(--ink);background:var(--surface-2,var(--surface))}
.period[aria-pressed="true"] .lab{color:var(--ink)}
.period:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

.bhead{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:10px}
.bhead h2{margin:0}
.bhead-total{font-size:22px;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}

/* The proportion bar, reusing the .pipe shape already used elsewhere. */
.pipe .track{display:flex;height:10px;border-radius:5px;overflow:hidden;gap:2px;
  background:var(--surface-3)}
.pipe .seg{height:100%;min-width:2px}
.pipe .legend{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:11px;
  font-size:12.5px;color:var(--ink-2)}
.pipe .legend i{display:inline-block;width:10px;height:10px;border-radius:2px;
  margin-right:7px;vertical-align:-1px}
.pipe .legend b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}

.pill.est{border-style:dashed}

/* ---- Spending table ----
   .table was never defined anywhere, so this fell back to the browser default:
   13px Times, cramped rows, and grey on grey. Everything here is deliberate. */
.spend-table{width:100%;border-collapse:collapse;font-size:15px;table-layout:auto}
.spend-table thead th{text-align:left;font-size:12px;letter-spacing:.07em;
  text-transform:uppercase;color:var(--muted);font-weight:600;
  padding:0 20px 10px 0;border-bottom:1px solid var(--line);white-space:nowrap}
.spend-table td{padding:12px 20px 12px 0;border-bottom:1px solid var(--line);
  color:var(--ink);vertical-align:baseline}
.spend-table tbody tr:last-child td{border-bottom:0}

/* A budget names itself once, above its own services. */
.spend-table .group-row th{font-size:15px;letter-spacing:0;text-transform:none;
  color:var(--ink);font-weight:650;padding:22px 20px 8px 0;border-bottom:0;text-align:left}
.spend-table .group-row td{padding:22px 20px 8px 0;border-bottom:0;font-weight:650;
  font-size:16px;font-variant-numeric:tabular-nums}
.spend-table .group-row:first-child th,
.spend-table .group-row:first-child td{padding-top:4px}

.spend-table .indent{padding-left:20px}
/* The account and the count are supporting detail, but they still have to be
   readable: ink-2, not muted, which is too faint at this size. */
.spend-table td.muted{color:var(--ink-2)}
.spend-table .num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.spend-table td.num{font-size:15.5px}

@media (max-width:760px){
  .spend-table{font-size:14px}
  .spend-table thead th,.spend-table td{padding-right:12px}
  .spend-table .indent{padding-left:12px}
}

/* ---- Spending page: nothing on it below 13px ----
   The page inherited .muted at 12px, .pill at 11.5px and uppercase headers at
   11px. Small grey text on a grey card is the one thing this page cannot
   afford, because every figure on it is a number somebody has to read exactly.
   Scoped to the page so no other screen shifts. */
.page-spending{font-size:15px}
.page-spending .muted{font-size:14px;color:var(--ink-2)}
.page-spending .pill{font-size:12.5px;padding:3px 10px}
.page-spending .card h2{font-size:17px}
.page-spending .pairs dt{font-size:15px}
.page-spending .pairs dd{font-size:14.5px;color:var(--ink-2)}
.page-spending .page-head p{font-size:14.5px}

.page-spending .period .lab{font-size:12.5px;letter-spacing:.06em}
.page-spending .period .v{font-size:36px}
.page-spending .period .d{font-size:13.5px}

.page-spending .bhead h2{font-size:17px}
.page-spending .bhead-total{font-size:25px}
.page-spending .pipe .legend{font-size:14px}
.page-spending .pipe .legend b{font-size:15px}

.page-spending .spend-table{font-size:15.5px}
.page-spending .spend-table thead th{font-size:12.5px;letter-spacing:.05em}
.page-spending .spend-table td{font-size:15.5px}
.page-spending .spend-table td.muted{font-size:15px;color:var(--ink-2)}
.page-spending .spend-table .group-row th{font-size:16.5px}
.page-spending .spend-table .group-row td{font-size:17px}
.page-spending .spend-table td.num{font-size:16px}

@media (max-width:760px){
  .page-spending .period .v{font-size:30px}
  .page-spending .spend-table{font-size:14.5px}
  .page-spending .spend-table td{font-size:14.5px}
}

/* The sidebar meter's way into the page.
 *
 * It used to be its own row under a divider, which cost about 30px of the
 * space the sections need: the sidebar scrolled on a laptop with only four
 * groups in it. The whole meter is already a link, so the arrow belongs
 * beside the label rather than under everything as a second invitation to
 * click the thing you are hovering over. */
.side-meter-more{position:absolute;right:11px;top:9px;font-size:12px;color:var(--muted);
  border:0;padding:0;line-height:1}
/* Only the arrow: the words are what took the room, and the arrow with the
   whole card being a link says the same thing. */
.side-meter-more{font-size:0}
.side-meter-more::after{content:"\2192";font-size:13px}
.side-meter:hover .side-meter-more{color:var(--ink)}

/* ---- moving between sections ----
 *
 * Every section is its own HTML page, so clicking the nav makes the browser
 * throw the current document away and build the next one. Even with the page
 * prerendered and its data already in hand, that teardown shows as a white
 * flash: the old screen goes, and the new one paints a frame later.
 *
 * A cross-document view transition hands that moment to the browser. It keeps
 * a picture of the outgoing page on screen and cross-fades to the incoming
 * one, so the flash never happens. The alternative was rewriting all twenty
 * pages to mount into a shared shell, which is days of work and risks screens
 * that currently work; this is a stylesheet rule.
 *
 * The chrome that is on every page - the top bar and the sidebar - is named,
 * so the browser matches it across the two documents and holds it perfectly
 * still while only the content under it changes. That is what makes it read
 * as one application rather than a sequence of pages.
 *
 * 90ms because this is a tool people use all day: long enough to remove the
 * blink, short enough that nobody waits on it. */
@view-transition { navigation: auto; }

::view-transition-group(root) { animation-duration: 90ms; }
::view-transition-old(root) { animation: vt-out 90ms ease both; }
::view-transition-new(root) { animation: vt-in 90ms ease both; }

@keyframes vt-out { to { opacity: 0 } }
@keyframes vt-in { from { opacity: 0 } }

/* Held still across the navigation rather than cross-faded with the content. */
.top { view-transition-name: pd-topbar; }
:is(body.has-sidebar, html.pd-sidebar body) .nav { view-transition-name: pd-sidebar; }

/* A held element must not animate at all, or it drifts while the page changes. */
::view-transition-old(pd-topbar), ::view-transition-new(pd-topbar),
::view-transition-old(pd-sidebar), ::view-transition-new(pd-sidebar) {
  animation: none;
  mix-blend-mode: normal;
}

/* Somebody who asks for less motion gets the instant swap, which is still
   flash-free: the transition happens, it just does not fade. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation: none !important;
  }
}

/* ---- the shell (shell.js) ----
   Only <main> is replaced when you move between sections; the sidebar is the
   same element all day. Two small things make that read as deliberate rather
   than as a page that failed to reload:

   A navigation in flight dims the content very slightly and after a beat, so a
   fast section (most of them, served from a warm cache in single-digit
   milliseconds) shows no state at all. Flashing a spinner for 8ms is worse
   than showing nothing: it reads as a stutter. The delay is what makes it
   honest - it appears only when there is genuinely a wait. */
.pd-loading main{opacity:.55;transition:opacity .12s ease .14s}
@media (prefers-reduced-motion:reduce){.pd-loading main{transition:none}}

/* The bar across the top of the viewport, for the same reason: it is the only
   evidence a click was heard when the sidebar cannot change. */
html.pd-shell body::before{content:"";position:fixed;top:0;left:0;right:0;height:2px;
  background:var(--accent,#2563eb);transform:scaleX(0);transform-origin:0 50%;
  z-index:200;pointer-events:none;opacity:0}
html.pd-shell body.pd-loading::before{opacity:1;
  animation:pd-progress 1.6s cubic-bezier(.2,.8,.3,1) .14s forwards}
@keyframes pd-progress{0%{transform:scaleX(0)}60%{transform:scaleX(.7)}100%{transform:scaleX(.92)}}
@media (prefers-reduced-motion:reduce){html.pd-shell body.pd-loading::before{animation:none;transform:scaleX(.6)}}

/* ---- the ask bar (askbar.js) ----
   Across the top of every section. Given real width and a light surface so it
   reads as a place to type rather than as another filter chip: it is the one
   control on the page that takes a sentence. */
.ask{margin:0 0 14px}
/* On the pages built from bare divs (no <main>) the bar carries the page
   gutter itself, matching the 22px the queue's own rows use. */
.ask.ask-bare{margin:14px 22px 0}
@media (max-width:820px){.ask.ask-bare{margin:12px 16px 0}}
.ask-in{display:flex;align-items:center;gap:10px;padding:0 14px;height:46px;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  transition:border-color .12s,box-shadow .12s}
.ask-in:focus-within{border-color:var(--accent,#2563eb);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent,#2563eb) 18%,transparent)}
.ask-mark{width:18px;height:18px;flex:none;fill:none;stroke:var(--muted);stroke-width:1.6;
  stroke-linejoin:round}
.ask-in:focus-within .ask-mark{stroke:var(--accent,#2563eb)}
.ask input{flex:1 1 auto;min-width:0;border:0;background:transparent;outline:0;
  font:inherit;font-size:14.5px;color:var(--ink);height:100%}
.ask input::placeholder{color:var(--muted)}
.ask input::-webkit-search-cancel-button{-webkit-appearance:none}
.ask-key{flex:none;font-family:var(--ui);font-size:11px;color:var(--muted);
  border:1px solid var(--line);border-radius:5px;padding:2px 6px;line-height:1.3}
.ask-in:focus-within .ask-key{opacity:0}
.ask-said{margin:7px 2px 0;font-size:12.5px;color:var(--muted)}
.ask-said.wait{color:var(--warn,#b45309)}
/* An ANSWER is not a filter hint. It is a sentence somebody reads at a desk
   with a patient waiting, so it gets the size and the line height of prose
   and room to run to two lines. Switched on 20 Sep 2026, when the bar
   stopped saying questions were not answered yet. */
.ask-said.ok{
  color:var(--ink);font-size:14.5px;line-height:1.5;
  margin-top:9px;padding:10px 13px;max-width:78ch;
  background:var(--surface);border:1px solid var(--line);border-radius:9px;
}
/* The tools that live IN the bar: the microphone dictate.js hangs here and
   the "what can I ask?" button. Sized and spaced to read as part of one
   control rather than a row of buttons bolted to the end of a box.
   Names are ask- prefixed on purpose: theme.css is shared by all 31 pages
   and a generic name inherits somebody else's layout (see .fact, which
   cost an hour on the patient record on 20 Sep 2026). */
.ask-what{flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;padding:0;border:0;border-radius:8px;background:transparent;
  color:var(--muted);cursor:pointer;transition:color .12s,background .12s}
.ask-what svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.ask-what:hover{color:var(--ink);background:var(--surface-3)}
.ask-what[aria-expanded="true"]{color:var(--accent,#2563eb);background:var(--accent-soft)}
/* The microphone, sized to match the button beside it.
 *
 * dictate.js wraps the input and positions the button ABSOLUTELY inside
 * that wrapper (theme.css:817), centred on a single-line input. That
 * mechanism is left alone: the wrapper only has to become the flexible
 * child of the bar so the input still fills the row.
 *
 * Two earlier attempts are worth not repeating. `display:contents` on the
 * wrapper dropped the button out of the row and it rendered 229px BELOW
 * the bar. Forcing `position:static` on the button fought the absolute
 * rule above and left it 7px ABOVE the bar. Both times the element
 * existed, had a size and sat inside the viewport, so a check for those
 * three things passed while nothing was on screen. */
.ask-in .dictate-wrap{flex:1 1 auto;min-width:0;display:flex;align-items:center}
.ask-in .dictate-wrap > input{flex:1 1 auto;min-width:0;height:100%}
/* Right-hand room for the mic, so it never sits on top of the text. */
.ask-in .dictate-wrap > input{padding-right:34px}
.ask-in .dictate-btn{width:30px;height:30px;border-radius:8px;right:2px}

.ask-in.is-thinking .ask-mark{stroke:var(--accent,#2563eb);animation:ask-pulse .9s ease-in-out infinite}
@keyframes ask-pulse{50%{opacity:.3}}

/* The chips: what it can answer, shown while the box is empty and focused,
   and again on a miss. Drawn from the map, never typed here. */
.ask-hint{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:8px 2px 0;font-size:12.5px;color:var(--muted)}
.ask-hint[hidden]{display:none}
.ask-hint-label{flex:none}
.ask-chips{display:flex;gap:6px;flex-wrap:wrap}
.ask-chip{appearance:none;font:inherit;font-size:12.5px;line-height:1.3;padding:5px 11px;border:1px solid var(--line);border-radius:999px;background:var(--surface);color:var(--ink-2);cursor:pointer;transition:border-color .12s,color .12s}
.ask-chip:hover{border-color:var(--accent,#2563eb);color:var(--ink)}

/* The answer card. Under the bar, in the shell, so it survives section
   swaps like the bar does. One number, one sentence, one link, and the
   reading and the cost in small type at the foot. */
.ask-card{position:relative;margin:10px 0 0;padding:16px 18px 12px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow)}
.ask-card[hidden]{display:none}
.ask-close{position:absolute;top:8px;right:10px;appearance:none;border:0;background:transparent;color:var(--muted);font-size:20px;line-height:1;width:28px;height:28px;border-radius:7px;cursor:pointer}
.ask-close:hover{background:var(--surface-3);color:var(--ink)}
.ask-top{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap;padding-right:28px}
.ask-main{flex:1 1 320px;min-width:0}
.ask-num{margin:0;font-size:34px;font-weight:600;line-height:1.05;letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:var(--ink);overflow-wrap:anywhere}
.ask-sent{margin:5px 0 0;font-size:14px;color:var(--ink)}
.ask-sub{margin:6px 0 0;font-size:12.5px;color:var(--ink-2)}
.ask-sub .btn{margin-top:2px}
.ask-link{flex:none;align-self:flex-start;margin-top:4px}
.ask-facts{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px 18px;margin:12px 0 0;padding:12px 0 0;border-top:1px solid var(--line)}
.ask-facts div{min-width:0}
.ask-facts dt{font-size:11.5px;color:var(--muted);margin:0}
.ask-facts dd{margin:2px 0 0;font-size:13.5px;color:var(--ink);overflow-wrap:anywhere}
.ask-rows{margin:12px 0 0;overflow:auto;border-top:1px solid var(--line)}
.ask-rows table{width:100%;border-collapse:collapse;font-size:13px}
.ask-rows th{text-align:left;font-weight:500;color:var(--muted);font-size:11.5px;padding:8px 8px 5px;border-bottom:1px solid var(--line);white-space:nowrap;text-transform:capitalize}
.ask-rows td{padding:6px 8px;border-bottom:1px solid var(--line);white-space:nowrap;max-width:280px;overflow:hidden;text-overflow:ellipsis}
.ask-rows tr:last-child td{border-bottom:0}
.ask-rows th.num,.ask-rows td.num{text-align:right;font-variant-numeric:tabular-nums}
.ask-rows td a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--line-strong)}
.ask-rows td a:hover{border-color:var(--accent,#2563eb)}
.ask-pick{list-style:none;margin:10px 0 0;padding:0;display:grid;gap:6px;grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
.ask-pick button{appearance:none;font:inherit;width:100%;text-align:left;padding:9px 12px;border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--ink);cursor:pointer;display:flex;flex-direction:column;gap:2px}
.ask-pick button:hover{border-color:var(--accent,#2563eb)}
.ask-pick button span{font-size:12px;color:var(--muted)}
.ask-foot{display:flex;gap:14px;flex-wrap:wrap;margin:12px 0 0;padding-top:8px;border-top:1px solid var(--line);font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.ask-foot .read{flex:1 1 240px;min-width:0}
.ask-foot .bad{color:var(--urgent)}
.ask-misses{margin:6px 0 0;padding-left:18px;font-size:13px;line-height:1.6}
.ask-misses .mono{font-family:var(--mono);font-size:11.5px;margin-right:6px}
@media (max-width:820px){
  .ask-key{display:none}
  .ask-card{padding:14px 14px 10px}
  .ask-num{font-size:28px}
  .ask-top{padding-right:24px}
  .ask-link{align-self:auto}
  .ask-rows td{max-width:180px}
}

/* ---- how they reached us (contacts.mjs) ----
   A quiet column. It is scanned for one value at a time ("which of these were
   calls"), never read across, so it is deliberately low-contrast: shouting
   the route would compete with the name and the waiting time, which are what
   the row is actually about. */
.chan{display:inline-block;font-size:12px;color:var(--ink-2);
  background:var(--surface-2);border:1px solid var(--line);border-radius:999px;
  padding:2px 9px;white-space:nowrap}
/* The two that mean somebody is owed a call back carry a little more weight. */
.chan-voicemail,.chan-phone{color:var(--ink);border-color:var(--line-2,var(--line))}
.chan-walkin{color:var(--ink)}

/* ---- a name the records supplied, not the caller ----
   The whole point is that this is visibly NOT the same as a name somebody
   gave. It has to be readable and it has to be secondary: a screen that shows
   a found surname exactly like a given one is claiming more than it knows. */
.from-record{display:inline-block;margin-left:7px;font-size:10.5px;
  text-transform:uppercase;letter-spacing:.04em;font-weight:600;
  color:var(--muted);border:1px solid var(--line);border-radius:4px;
  padding:1px 5px;vertical-align:1px;cursor:help}
.from-record.maybe{color:var(--warn,#b45309);
  border-color:color-mix(in srgb,var(--warn,#b45309) 40%,transparent)}
.from-record.ask{color:var(--warn,#b45309);text-transform:none;letter-spacing:0;
  border-color:color-mix(in srgb,var(--warn,#b45309) 40%,transparent)}

/* ---- who is on this number, inside the contact dialog ---- */
.who-found{margin:2px 0 10px;font-size:13px;color:var(--muted);line-height:1.45}
.who-found.ok{color:var(--good,#15803d)}
.who-found.maybe,.who-found.ask{color:var(--warn,#b45309)}
.who-choices{display:flex;flex-wrap:wrap;gap:7px;margin:0 0 12px}
.who-choices .who-pick{display:inline-flex;align-items:baseline;gap:7px}
.who-choices .dob{font-size:11.5px;color:var(--muted);font-family:var(--mono,ui-monospace,monospace)}

/* ---- tags on a person (tags.mjs) ----
   A chip beside the name, everywhere the name appears. The medical alert is
   red and first; "do not text" is red and switches a button off; the rest are
   quiet. A chip is a fact somebody chose, so it reads a shade stronger than
   the rule-assigned case chips beside it. */
.ptag{display:inline-flex;align-items:center;gap:4px;margin-left:6px;font-size:12px;
  font-weight:500;line-height:1;padding:3px 8px;border-radius:999px;
  background:var(--surface-2);color:var(--ink-2);border:1px solid var(--line);
  vertical-align:1px;white-space:nowrap;max-width:220px}
.ptag.alert{background:var(--danger-bg,#f9e9e7);color:var(--danger,#b0322a);border-color:transparent;font-weight:600}
.ptag.block{background:var(--danger-bg,#f9e9e7);color:var(--danger,#b0322a);border-color:transparent}
.ptag.warn{background:var(--warn-bg,#f8efe0);color:var(--warn,#a86a12);border-color:transparent}
.ptag.more{color:var(--muted)}
.ptag.add{cursor:pointer;color:var(--muted);padding:3px 9px;font-size:14px;line-height:1;background:transparent;border-style:dashed}
.ptag.add:hover{color:var(--ink);border-color:var(--ink)}
.ptag-x{appearance:none;border:0;background:transparent;color:inherit;opacity:.55;cursor:pointer;
  padding:0 0 0 2px;font-size:13px;line-height:1}
.ptag-x:hover{opacity:1}
.ptags{display:flex;flex-wrap:wrap;gap:4px 0;margin:6px 0 0;align-items:center}
.ptags .ptag:first-child{margin-left:0}

/* ---- the note box ----
   Always present, never a form. Rows of the journey are read; this is
   written, so it sits apart from them with a little air. */
.note-box{display:flex;gap:8px;align-items:flex-start;margin:8px 0 12px}
.note-box textarea{flex:1 1 auto;min-height:44px;resize:vertical;font:inherit;font-size:14px;
  padding:8px 10px;border:1px solid var(--line);border-radius:8px;background:var(--surface);color:var(--ink)}
.note-box textarea:focus{outline:2px solid var(--accent,#2563eb);outline-offset:1px;border-color:transparent}

/* ---- the stepper ----
   Each step is a tick a person presses. The next one is bold with a flag;
   done ones fade. An "auto" step is one the system does, so it shows the
   word rather than pretending somebody has to press it. */
/* A run of work, not a checklist.
   Rebuilt 2026-09-20. Before this it was seven rows of identical weight
   with the ticks floating unconnected, so nothing said how far along the
   work was or which row to act on. Now: a spine joins the ticks into one
   sequence, the next step is ringed and carries the only bold text, done
   steps recede but keep their mark, and "auto" sits with the step it
   describes rather than floated to the far right away from it.
   The old tick also drew its checkmark in a hardcoded green on a light
   green fill, which in dark mode was an invisible mark on a white blob.
   It is ink-on-paper now, so it works in both themes. */
/* list-style:none on the OL as well as the LI: an <ol> still paints its
   markers otherwise, and they showed up as stray numerals beside the
   ticks once the rows became flex containers. */
.lead-steps{list-style:none;margin:0;padding:0;position:relative}
.lead-steps li::marker{content:none}
/* Flex, not grid: the name sits beside its tick and the flag and auto
   marker follow it on the same line, wrapping under only when the row runs
   out of width. A grid put each of them on a row of its own and stretched
   them to the full column, which turned two small labels into two bars. */
.lead-steps li{position:relative;display:flex;flex-wrap:wrap;align-items:center;
  gap:4px 9px;padding:7px 0;border:0;list-style:none}
.lead-steps li::before{content:none}
/* The spine, behind the ticks. Stops short at each end so it does not
   dangle past the first and last tick. */
.lead-steps::before{content:"";position:absolute;left:11px;top:16px;bottom:16px;width:2px;
  background:var(--line);border-radius:2px}
/* One step on its own needs no spine to join. */
.lead-steps:has(li:only-child)::before{content:none}
.step-tick{appearance:none;width:24px;height:24px;flex:none;border-radius:50%;
  border:2px solid var(--line-strong);background:var(--surface);cursor:pointer;
  display:inline-grid;place-items:center;padding:0;position:relative;z-index:1;
  transition:border-color .12s,background .12s}
.step-tick::after{content:"";width:10px;height:5.5px;border-left:2px solid var(--paper);
  border-bottom:2px solid var(--paper);transform:rotate(-45deg) translate(1px,-1px);opacity:0}
.step-tick[aria-pressed="true"]{border-color:var(--ink);background:var(--ink)}
.step-tick[aria-pressed="true"]::after{opacity:1}
.step-tick:hover{border-color:var(--ink)}
.step-tick:focus-visible{outline:2px solid var(--accent,#2563eb);outline-offset:2px}
span.step-tick{cursor:default;opacity:.45}
/* The live step: a ring rather than a colour, so it reads as "here" without
   competing with the red the rest of the dashboard reserves for urgent. */
.lead-steps li.now .step-tick{border-color:var(--ink);box-shadow:0 0 0 4px var(--surface-3)}
.step-name{font-size:13.5px;line-height:1.45;color:var(--ink-2)}
.lead-steps li.done .step-name{color:var(--muted)}
.lead-steps li.now .step-name{font-weight:600;color:var(--ink);font-size:14.5px;
  letter-spacing:-.01em}
/* The flag and the auto marker sit under the name, on their own line, so a
   long step does not push them off the edge. */
/* Both markers are chips that hug their text: flex:none stops the row
   stretching them across the whole line. */
.step-flag{flex:none;font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;
  background:var(--ink);color:var(--paper);border:0;border-radius:99px;padding:2px 8px;
  font-weight:600;line-height:1.5}
.step-auto{flex:none;margin:0;font-size:10.5px;letter-spacing:.06em;line-height:1.5;
  text-transform:uppercase;color:var(--muted);border:1px dashed var(--line-strong);
  border-radius:99px;padding:1px 7px}
.step-name{flex:0 1 auto}
.step-note{font-size:12.5px;margin:10px 0 0;color:var(--muted)}
/* Tap targets: on a phone the whole step is the button. */
@media (max-width:899px){
  .lead-steps li{min-height:44px}
  .step-tick{width:28px;height:28px}
}

/* ---- the phone tab bar (theme.js) ----
   Five tabs along the bottom, where a thumb is. Hidden on a wide screen,
   where the sidebar does the job. The body gets bottom padding so the last
   row of any list clears the bar. */
.tabbar{display:none}
@media (max-width:899px){
  .tabbar{display:grid;grid-template-columns:repeat(5,1fr);position:fixed;left:0;right:0;bottom:0;
    height:calc(58px + env(safe-area-inset-bottom,0px));padding-bottom:env(safe-area-inset-bottom,0px);
    background:var(--surface);border-top:1px solid var(--line);z-index:50}
  .tabbar a{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    font-size:11px;font-weight:500;color:var(--muted);text-decoration:none;position:relative;
    -webkit-tap-highlight-color:transparent}
  .tabbar a svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
  .tabbar a[aria-current="page"]{color:var(--ink)}
  .tabbar a[aria-current="page"]::before{content:"";position:absolute;top:0;left:22%;right:22%;height:2px;background:var(--ink);border-radius:2px}
  .tab-dot{position:absolute;top:8px;left:calc(50% + 8px);width:8px;height:8px;border-radius:50%;background:var(--danger,#b0322a)}
  body.has-tabbar{padding-bottom:calc(66px + env(safe-area-inset-bottom,0px))}
  /* The hamburger drawer stays for the long tail, but it is no longer the
     only way anywhere, so the spend meter can come out of the phone's top
     bar: it is an owner's number, and the owner has the More tab. */
  body.has-tabbar .side-meters{display:none}
}

/* ---- a lead, opened, on a phone ----
   The expanded row takes the whole screen. On a monitor it stays an
   expanded row under its line in the list, which is right when there is a
   list beside it to come back to; on a phone there is nothing beside it,
   and a half-height sheet over a list you cannot see is worse than a page.
   The Back button is inserted by leads.js; the three action buttons are
   pinned so they never scroll away. */
.lead-back{display:none}
@media (max-width:899px){
  body.lead-open{overflow:hidden}
  body.lead-open .lead-detail:not([hidden]){position:fixed;inset:0;z-index:60;background:var(--surface);
    overflow:auto;display:block;padding-bottom:calc(80px + env(safe-area-inset-bottom,0px))}
  body.lead-open .lead-detail:not([hidden]) > td{display:block;padding:12px 16px 24px}
  .lead-back{display:inline-flex;margin:4px 0 10px;font-size:15px}
  body.lead-open .lead-panel{display:block}
  body.lead-open .lead-panel-side{position:sticky;top:0;z-index:1;background:var(--surface);
    padding:8px 0 10px;margin:0 0 8px;border-bottom:1px solid var(--line)}
  body.lead-open .item-actions .btn{min-height:44px;padding:0 18px;font-size:15px}
  body.lead-open .item-actions{display:flex;flex-wrap:wrap;gap:8px}
  /* The card view on a phone: one card per row already; make the whole card
     the tap and give the action button room. */
  .queue .card.item .item-actions .btn{min-height:40px}
  /* Rows: name and number on their own lines, one action at the right. */
  .lead-row td[data-label="Contacted"]{font-size:12px}
}

/* ---- a phone: the answer first, the furniture folded ----
   The four tiles and five dropdowns cost 650px before the first patient on
   a phone. They become one line of numbers, a chip row that does what the
   tiles do, and the search box. The dropdowns live behind the search: type
   "voicemail" or "urgent" and the list narrows the same way. */
.strip-line{display:none}
@media (max-width:899px){
  .page > .strip{display:none}
  .strip-line{display:block;margin:0 0 10px}
  .strip-nums{display:block;font-size:13px;color:var(--muted);margin:0 0 8px;line-height:1.5}
  .strip-nums b{color:var(--ink);font-weight:600}
  .strip-nums b.hot{color:var(--danger,#b0322a)}
  .strip-chips{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;padding-bottom:2px;-webkit-overflow-scrolling:touch}
  .strip-chips::-webkit-scrollbar{display:none}
  .strip-chips .chip{flex:none;font-size:13px;padding:7px 12px;border-radius:999px;border:1px solid var(--line);
    background:var(--surface);color:var(--ink-2);white-space:nowrap;min-height:36px}
  .strip-chips .chip.on{background:var(--ink);color:var(--surface);border-color:var(--ink)}
  .strip-chips .chip.hot:not(.on){color:var(--danger,#b0322a)}
  /* The filter dropdowns fold away on a phone; search does their job. */
  .page > .bar select{display:none}
  .page > .bar{gap:8px}
  .page > .bar .seg{display:none}
  .page > .bar #count{display:none}
}

/* ---- the intake row on a phone ----
   The generic stacked-cell rule turns every cell into a labelled box, so a
   row read "CONTACTED / REQUEST" with no person on it. This is the row the
   anatomy drawing asked for: name and one chip, number and channel, one
   action at the right, 66px, the whole row a tap. Scoped to #list-rows so
   the other tables keep the generic rule. */
@media (max-width:899px){
  #list-rows tr.lead-row{display:grid;grid-template-columns:1fr auto;grid-template-areas:"who do" "sub do";
    column-gap:10px;row-gap:2px;align-items:center;padding:10px 12px 10px 14px;min-height:66px;
    border-bottom:1px solid var(--line);position:relative}
  #list-rows tr.lead-row.late::before,#list-rows tr.lead-row.urgent::before{content:"";position:absolute;left:0;top:8px;bottom:8px;width:3px;border-radius:2px;background:var(--danger,#b0322a)}
  #list-rows tr.lead-row > td{display:block;padding:0;border:0;min-width:0}
  #list-rows tr.lead-row > td::before{content:none}
  #list-rows td[data-label="Contact"]{grid-area:who}
  #list-rows td[data-label="Contact"] .name{font-size:16px;font-weight:600;line-height:1.25;white-space:normal}
  #list-rows td[data-label="Contact"] .name .from-record{display:none}
  #list-rows td[data-label="Contact"] .sub-line{display:flex;flex-wrap:wrap;gap:4px 8px;align-items:center;margin-top:3px;font-size:13px}
  /* The one chip that changes what you do stays; the rest are on the open lead. */
  #list-rows td[data-label="Contact"] .sub-line .sig:not(:first-of-type){display:none}
  #list-rows td[data-label="Request"]{grid-area:sub;font-size:13px;color:var(--muted)}
  #list-rows td[data-label="Request"]::before{content:none}
  #list-rows td.row-do{grid-area:do;align-self:center}
  #list-rows td.row-do .do-next{display:none}
  /* The generic .work td rule sets display:block LATER in the file, and a
     later equal-specificity rule wins. These have to outrank it, so they
     carry the table selector too. */
  .work #list-rows td[data-label="Contacted"],.work #list-rows td[data-label="How"],.work #list-rows td[data-label="Waiting"],
  .work #list-rows td[data-label="Insurance"],.work #list-rows td[data-label="Next"],.work #list-rows td.row-open{display:none}
  /* The action lives on the row itself on a phone: pulled from the panel's
     first button by leads.js into .row-do, sized for a thumb. */
  #list-rows td.row-do .btn{min-height:40px;min-width:76px;padding:0 14px;font-size:14px;border-radius:20px}
  #list-rows tr.lead-detail > td{grid-column:1/-1}
}
/* The name at the top of an open lead: hidden on a monitor, where the row
   above already says who; shown on a phone, where the row is off screen. */
.lead-panel-who{display:none}
@media (max-width:899px){
  .lead-panel-who{display:block;margin:0 0 10px}
  .lead-panel-who .name{font-size:20px;font-weight:600;line-height:1.2}
  .lead-panel-who .sub-line{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:4px;font-size:13px;color:var(--muted)}
}
/* The row's action: text on a monitor, a button on a phone. */
.row-act{display:none}
@media (max-width:899px){
  .row-act{display:inline-flex;align-items:center;justify-content:center}
  #list-rows td.row-do .do-next{display:none}
}

/* ---- a patient's chart: years, visits, insurers ----
 *
 * The shape follows the data. The busiest chart in this practice holds 1,341
 * ledger lines across 467 separate days, so a visit is a row and a year is a
 * line until somebody opens it. Treatment and money sit in the same visit but
 * read differently on purpose: a clinician scans the procedure column and the
 * desk scans the amounts. */
.visits { display: grid; gap: 0; }
.visit { display: grid; grid-template-columns: 92px 1fr; gap: 12px; padding: 9px 0; border-top: 1px solid var(--line); }
.visit:first-child { border-top: 0; }
.visit-when { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; padding-top: 2px; white-space: nowrap; }
.visit-what { min-width: 0; }
.tx { display: grid; grid-template-columns: 62px 1fr auto; gap: 8px; align-items: baseline; font-size: 13.5px; padding: 1px 0; }
.tx .cdt { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.tx .cdt.none { color: transparent; }
.tx-what { min-width: 0; overflow-wrap: anywhere; }
.tx-amt { font-variant-numeric: tabular-nums; color: var(--ink-2); white-space: nowrap; }
.visit-money { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 3px; }
.visit-money .pay { font-size: 12px; color: var(--muted); white-space: nowrap; }
.visit-money .pay b { font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* A year nobody has opened is one line. 22 of these is a readable history;
   22 years of visits expanded is 467 rows nobody reads. */
.year-rows { margin-top: 4px; }
.year-row {
  display: grid; grid-template-columns: 54px 1fr auto; gap: 10px; align-items: baseline;
  width: 100%; text-align: left; background: none; border: 0; border-top: 1px solid var(--line);
  padding: 7px 0; cursor: pointer; color: inherit; font: inherit;
}
.year-row:hover { background: var(--surface-2); }
.year-row:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.year-n { font-weight: 600; font-variant-numeric: tabular-nums; }
.year-v { color: var(--muted); font-size: 13px; }
.year-m { color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.year-row[aria-expanded="true"] .year-n { color: var(--ink); }
.year-body { padding: 2px 0 8px; }

/* Who has actually paid, from the ledger rather than the carrier file. */
.ins-history { border-top: 1px solid var(--line); padding-top: 9px; margin-top: 9px; }
.ins-title { font-size: 11px; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); margin-bottom: 5px; }
.ins-row { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: baseline; font-size: 13px; padding: 2px 0; }
.ins-row .ins-name { min-width: 0; overflow-wrap: anywhere; }
.ins-row.current .ins-name { font-weight: 600; }
.ins-when { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ins-paid { color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ins-row.muted .ins-name, .ins-row.muted .ins-paid { color: var(--muted); }

@media (max-width: 560px) {
  .visit { grid-template-columns: 1fr; gap: 2px; }
  .visit-when { padding-top: 0; }
  .tx { grid-template-columns: 52px 1fr auto; }
}

/* A job whose caller the records could name. Quiet on purpose: it marks the
   normal case, and the eye should go to the urgent tags beside it. */
.tag.known {
  background: var(--surface-2); border-color: var(--line-strong);
  color: var(--muted); font-weight: 500;
}

/* ---- what happened, in somebody's own words ----
 *
 * Sits above the action buttons on a case, because what gets typed travels
 * with the button that is pressed. A note box below the buttons reads as a
 * separate chore and stays empty, which is how a trail ends up being a queue
 * with nothing written in it. */
.note-lbl {
  display: block; margin: 14px 0 5px;
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); font-weight: 600;
}
.note-in {
  display: block; width: 100%; resize: vertical; min-height: 44px;
  padding: 9px 11px; font: inherit; font-size: 14.5px; line-height: 1.45;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 8px;
}
.note-in:focus { outline: 2px solid var(--ink); outline-offset: -1px; }
.note-in::placeholder { color: var(--muted); }
/* Quieter than the state buttons beside it: saving a note alone is the
   secondary action, and the eye should land on "Mark handled" first. */
.acts .btn.quiet { color: var(--muted); border-style: dashed; }
.acts .btn.quiet:hover { color: var(--ink); border-style: solid; }
.say.wait { color: var(--warn, var(--ink-2)); }

/* ---- the idle lock (shell.js) ----
   Covers everything after fifteen minutes untouched, because these machines
   are in a reception area and the session is a rolling thirty days. It hides
   the records rather than signing anybody out: one click and the desk is
   back where it was. Opaque, not translucent, or the last patient opened is
   still readable through it. */
#pd-lock{position:fixed;inset:0;z-index:9999;background:var(--paper);
  display:flex;align-items:center;justify-content:center;padding:24px}
.pd-lock-card{max-width:420px;text-align:center}
.pd-lock-title{font:600 26px/1.1 var(--ui);letter-spacing:-.02em;margin-bottom:10px}
.pd-lock-sub{color:var(--muted);font-size:14px;margin:0 0 14px;line-height:1.55}
.pd-lock-who{color:var(--ink-2);font-size:13px;margin:0 0 18px}
#pd-lock .btn{padding:10px 18px;font-size:14px}
.pd-lock-out{display:inline-block;margin-top:14px;color:var(--muted);font-size:12.5px}
.pd-lock-out:hover{color:var(--ink)}
@media print{#pd-lock{display:none}}
