/* 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:#4a4038;
  --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;
  --num:var(--ui);
  --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"]):where(:not([data-theme="fun"])) {
    --paper:#0b0b0c; --surface:#141416; --surface-2:#1c1a19; --surface-3:#26231e;
    --ink:#f4f4f5; --ink-2:#dad8d6; --muted:#dad8d6;
    --line:#2a2a2e; --line-strong:#3a3a40;
    --accent:#8ec2ff; --accent-soft:#1c2a4a;
    --urgent:#fca0a0; --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:#dad8d6; --muted:#dad8d6;
  --line:#2a2a2e; --line-strong:#3a3a40;
  --accent:#8ec2ff; --accent-soft:#1c2a4a;
  --urgent:#fca0a0; --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;
}

/* ---- vaporwave ----------------------------------------------------------
 *
 * A sunset over a neon grid: deep indigo paper, magenta and cyan for
 * anything interactive. Chosen by Keith on 1 Oct 2026.
 *
 * STILL A WORKING TOOL. Every pair below was checked for contrast, because
 * this is a screen somebody reads all day while a patient waits. The first
 * check was the old 4.5:1 ratio, which this passed while Keith could not
 * read it ("I can't read any of this stuff", 7 Oct 2026): that ratio
 * flatters light text on a dark ground. Measured since with APCA, which does
 * not, against the darkest card a colour sits on: --ink Lc 93, --ink-2 and
 * --muted (now one colour, two greys was one too many) Lc 80, the accent
 * Lc 64 and urgent Lc 61, both only ever bold or large. They were Lc 62, 43,
 * 48 and 41. The neon is spent on borders, glows and the hovered state,
 * never on body text, which is the trick that makes the aesthetic work
 * without making the numbers hard to read.
 *
 * --urgent stays red rather than becoming another neon. It is the one
 * colour in this interface that means "a person is waiting", and a theme
 * is not a reason to make that ambiguous. */
:root[data-theme="vaporwave"] {
  --paper:#14082b; --surface:#1e0f3c; --surface-2:#2a1550; --surface-3:#3a1d68;
  --ink:#f6edff; --ink-2:#e2d7f7; --muted:#e2d7f7;
  --line:#3f2470; --line-strong:#5b3499;
  --accent:#ffa3e3; --accent-soft:#3d1a52;
  --urgent:#ffa0b2; --urgent-soft:#44122a;
  --c1:#ff6ad5; --c2:#49e0ff;
  --o1:#3f2470; --o2:#7a4fc0; --o3:#a690d8; --o4:#49e0ff; --o5:#ff6ad5;
  --grid:#2a1550; --axis:#5b3499; --scrim:rgba(10,2,24,.7);
  --shadow:0 1px 2px rgba(0,0,0,.5), 0 0 18px rgba(255,106,213,.10);
  --btn-bg:#ff6ad5; --btn-ink:#14082b;
  color-scheme:dark;
}

/* Vaporwave: no white blocks (7 Oct 2026, night). In every other theme a
   chosen or main control is filled with the ink colour; here the ink is
   near-white, so on deep indigo every "Mark done", "Cards", "Ready" and
   sidebar count glared, and the eye that adjusted to them could not read
   the text beside them. Keith: "the button contrasts are really harsh".
   Here a chosen control, a status pill and an outgoing message are a violet
   fill with white words (Lc 99), and the one main action is a darker plum
   with a pink edge (Lc 91) that turns pink on hover. Listed by name because
   each page writes its own chosen state; a new one belongs here too. */
:root[data-theme="vaporwave"]{--v-sel:#4a2585;--v-sel-ink:#ffffff;--v-sel-line:#7a52c4;--v-main:#4a1f63;--v-main-ink:#ffe8f7}
:root[data-theme="vaporwave"] :is(.seg.small button, .dialog .seg button, .item-ask .btn, .bst-views button, .bst-seg, .bst-outs button, .bst-tlf button, .insr-sort button, .drawer .stagerow button, .chips button, .sch-views button, .filters .pill, .soc-views .btn, .viewas-btns button)[aria-pressed="true"],
:root[data-theme="vaporwave"] :is(.pill.new, .pill.ready, .pill.active, .pd-book-chip.on, .strip-chips .chip.on, .sch-pill.s-arrived, .sch-week .sch-day.on, .side-nav a[aria-current="page"] .badge, .do-next, .step-flag, .month-grid .day.today .n, .msg.out .bubble, .bst-msg.out){background:var(--v-sel);color:var(--v-sel-ink);border-color:var(--v-sel-line)}
:root[data-theme="vaporwave"] .bst-seg[aria-pressed="true"] :is(.n, .n b){color:var(--v-sel-ink)}
/* Confirmed is green wherever it shows, as the Schedule's calendar blocks are
   since v97 (schedule.css, --sch-yes-fill). */
:root[data-theme="vaporwave"] .sch-pill.g-confirmed{background:var(--sch-yes-fill,#15803d);color:var(--sch-yes-on,#fff);border-color:var(--sch-yes-fill,#15803d)}
:root[data-theme="vaporwave"] .btn.primary{background:var(--v-main);color:var(--v-main-ink);border-color:var(--btn-bg)}
:root[data-theme="vaporwave"] .btn.primary:hover{background:var(--btn-bg);color:var(--btn-ink);border-color:var(--btn-bg)}

/* ---- fun ---------------------------------------------------------------
 *
 * Powder blue and a smiling tooth: the bright, friendly one. Light rather
 * than dark, so it is the cheerful counterpart to vaporwave rather than a
 * second night mode.
 *
 * Contrast measured, not estimated: --ink on --paper is 11.0:1, --ink on a
 * card 12.3:1, --muted on a card 5.5:1, --accent 4.6:1, the button label
 * on its button 4.6:1. The first --muted I picked (#5c87a3) looked right
 * and measured 3.9:1, which is a fail; the checker caught it. */
:root[data-theme="fun"] {
  --paper:#e8f4fb; --surface:#ffffff; --surface-2:#f2fafe; --surface-3:#d9edf9;
  --ink:#10384f; --ink-2:#214760; --muted:#214760;
  --line:#c3e2f2; --line-strong:#9fd0e8;
  --accent:#0a7ea4; --accent-soft:#d2ecf7;
  --urgent:#c2334d; --urgent-soft:#fde3e7;
  --c1:#0a7ea4; --c2:#f4a6c0;
  --o1:#c3e2f2; --o2:#9fd0e8; --o3:#466d88; --o4:#2d6183; --o5:#10384f;
  --grid:#d9edf9; --axis:#9fd0e8; --scrim:rgba(16,56,79,.4);
  --shadow:0 1px 2px rgba(16,56,79,.08);
  --btn-bg:#0a7ea4; --btn-ink:#ffffff;
  color-scheme:light;
}

*{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);font:1rem/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:1rem;padding:0 1.7143rem;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:.5714rem;min-width:0;margin-right:.7143rem;text-decoration:none}
.brand b{font-size:1.0714rem;font-weight:600;letter-spacing:-.02em}
.brand span,.muted{color:var(--muted);font-size:max(15px,.8571rem);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 .8571rem;color:var(--ink-2);text-decoration:none;font-size:max(15px,.9643rem);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:.4286rem;padding:.5714rem 1rem;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:.4286rem .7857rem;font-size:max(15px,.8929rem);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"]):where(:not([data-theme="fun"])) .theme-toggle .sun{display:none}
  :root:not([data-theme="light"]):where(:not([data-theme="fun"])) .theme-toggle .moon{display:block}
}
.who{color:var(--muted);font-size:max(15px,.8571rem);white-space:nowrap;font-family:var(--ui)}

/* ---- pills: outlined by default; only "new" and "urgent" stand out ---- */
.pill{display:inline-block;padding:2px .6429rem;border-radius:999px;font-size:max(15px,.8214rem);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:1.1429rem 1.7143rem 2.8571rem;display:grid;gap:1rem;max-width:100rem;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:1.1429rem;flex-wrap:wrap}
.page-head h1{margin:0;font-size:1.5714rem;font-weight:600;letter-spacing:-.02em}
.page-head.headline{padding:0;align-items:flex-end}
.page-head.headline h1{font-size:1.8571rem;letter-spacing:-.025em;line-height:1.15}
.page-head .eyebrow{margin:0 0 .4286rem;font-size:max(15px,.8571rem);font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.page-head .lede{margin:.5714rem 0 0;font-size:1.0714rem;color:var(--ink-2);max-width:60ch}
.head-side{display:flex;align-items:center;gap:.8571rem;font-size:max(15px,.8929rem)}
.page-head p{margin:2px 0 0;color:var(--muted);font-size:max(15px,.9286rem)}
.page-head select.btn{padding-right:.8571rem}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);min-width:0}
.label{font-size:max(15px,.8571rem);font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2);margin:0 0 .4286rem}

/* ---- 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:.7143rem;
  position:sticky;top:var(--topbar-h,60px);z-index:31;
  background:var(--paper);padding:2px 0 .5714rem}
.strip .card{padding:1.1429rem 1.2857rem;display:flex;flex-direction:column;gap:2px}
.strip .v{font-size:2.1429rem;font-weight:600;line-height:1.05;letter-spacing:-.03em;margin:0}
.strip .v.urgent{color:var(--urgent)}
.strip .d{font-size:max(15px,.9286rem);color:var(--ink-2);margin:0}

/* ---- analytics tiles ---- */
.hero{display:grid;grid-template-columns:minmax(280px,1.2fr) repeat(4,minmax(0,1fr));gap:.8571rem}
/* 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:.8571rem;margin-bottom:1.1429rem}
/* A heading that divides one page into two things being measured. */
.section-head{margin:2.4286rem 0 2px;font-size:1.2857rem;letter-spacing:-.01em;font-weight:650}
.section-sub{margin:0 0 1rem;color:var(--muted);font-size:max(15px,.9643rem);max-width:70ch}
.hero .card{padding:1.2857rem 1.4286rem}
.big{font-size:4rem;font-weight:600;line-height:1;letter-spacing:-.04em;margin:2px 0 .5714rem}
.caption{color:var(--muted);margin:-2px 0 .4286rem}
.sub{color:var(--ink-2);font-size:max(15px,.8929rem);margin:0}
.sub b{color:var(--urgent);font-weight:600}
.sub .stale{font-weight:600;color:var(--ink)}
.kpi .v{font-size:2.1429rem;font-weight:600;line-height:1.1;letter-spacing:-.03em;margin:0}
.kpi .d{font-size:max(15px,.9286rem);color:var(--ink-2);margin:.2857rem 0 0;display:flex;gap:.4286rem;align-items:center}
.kpi .d.up{color:var(--ink)}
.kpi .spark{display:block;width:100%;height:32px;margin-top:.7143rem}
.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:1.1429rem}
.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:.2857rem 1rem;margin-top:.5714rem;font-size:max(15px,.8571rem);color:var(--ink-2)}
.pipe .legend i{display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:.4286rem;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:.8571rem}
.cards.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.chart{padding:1.2857rem 1.4286rem 1rem;position:relative;display:flex;flex-direction:column;min-width:0}
.chart h2{margin:0;font-size:1rem;font-weight:600;letter-spacing:-.01em}
.chart .hint{margin:2px 0 .8571rem;font-size:max(15px,.8571rem);color:var(--muted)}
.chart .legend{display:flex;gap:1rem;font-size:max(15px,.8571rem);color:var(--ink-2);margin:0 0 .7143rem}
.chart .legend i{display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:.4286rem;vertical-align:-1px}
.chart svg{display:block;width:100%;overflow:visible}
.chart svg text{font-family:var(--ui);font-size:max(12px,.7857rem);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:.5rem .7143rem;border-radius:8px;font-size:max(15px,.8571rem);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:max(15px,.9286rem);font-weight:600}
.chart .tip i{display:inline-block;width:10px;height:3px;border-radius:2px;margin:0 .4286rem 3px 0;vertical-align:middle}
.chart details{margin-top:.5714rem;font-size:max(15px,.8571rem);color:var(--muted)}
.chart details summary{cursor:pointer}
.chart details table{width:100%;border-collapse:collapse;margin-top:.4286rem;font-size:max(15px,.8571rem);color:var(--ink)}
.chart details td,.chart details th{padding:.2857rem .4286rem;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:max(15px,.8929rem);padding:1.7143rem 0;text-align:center}

/* ---- filters + tables ---- */
.bar{display:flex;gap:.6429rem;align-items:center;flex-wrap:wrap}
.bar input,.bar select{padding:.6429rem .8571rem;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:max(15px,.8929rem);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 -1.7143rem;padding:.7143rem 1.7143rem;background:var(--paper);border-bottom:1px solid var(--line)}
body > .bar{margin:0;padding:.7143rem 1.7143rem}
.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:.7857rem 1rem;background:var(--surface);border-bottom:1px solid var(--line);text-align:left;font-size:max(15px,.8571rem);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:.8571rem 1rem;border-bottom:1px solid var(--line);vertical-align:top;font-size:max(15px,.9643rem)}
.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(--num);font-size:max(15px,.8571rem);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(--num);font-size:max(15px,.8571rem);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:3.4286rem 1.5714rem;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:1.4286rem;z-index:60}
.modal.open{display:flex}
.dialog{width:min(560px,100%);background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:1.5714rem 1.7143rem;max-height:calc(100vh - 40px);overflow:auto}
.dialog h2{margin:0 0 2px;font-size:1.2857rem;letter-spacing:-.02em}
.dialog .to{color:var(--muted);font-size:max(15px,.8929rem);margin:0 0 1rem}
.dialog .seg{display:inline-flex;border:1px solid var(--line-strong);border-radius:9px;overflow:hidden;margin:0 0 .8571rem}
.dialog .seg button{padding:.5rem 1rem;border:0;background:var(--surface);cursor:pointer;font-size:max(15px,.9286rem)}
.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:max(15px,.8571rem);color:var(--muted);margin:.7143rem 0 .2857rem}
.dialog textarea,.dialog input{width:100%;padding:.6429rem .7857rem;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:.5714rem;flex-wrap:wrap;margin-top:1rem}
/* 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:.8571rem}
.dialog .row.two label{margin-top:.7143rem}
@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:.6429rem .7857rem;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 .2857rem;display:inline;font-size:max(15px,.7857rem);opacity:.72;font-weight:400}

.dialog .note{font-size:max(15px,.8571rem);color:var(--muted);margin:1rem 0 0}

/* ---- marketing ---- */
.connect{padding:1.7143rem 1.8571rem;max-width:760px}
.connect h2{margin:0 0 .2857rem;font-size:1.2857rem;letter-spacing:-.02em}
.connect p{margin:0 0 1rem;color:var(--ink-2)}
.connect ol{margin:0;padding-left:1.4286rem;display:grid;gap:.7143rem;color:var(--ink-2)}
.connect li b{color:var(--ink)}
.connect code{font-family:var(--mono);font-size:max(15px,.8571rem);background:var(--surface-3);padding:1px .4286rem;border-radius:5px}
.status-line{display:flex;align-items:center;gap:.5714rem;font-size:max(15px,.8929rem);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:.7143rem 1.1429rem;flex-wrap:wrap;gap:.5714rem}.nav{order:5;width:100%;overflow-x:auto;height:40px}.top .who{display:none}}
@media (max-width:720px){
  .page{padding-left:1.1429rem;padding-right:1.1429rem}.page > .bar{margin:0 -1.1429rem;padding:.7143rem 1.1429rem}
  .work table,.work tbody{display:block;min-width:0}.work thead{display:none}
  .work tbody tr{display:grid;grid-template-columns:1fr 1fr;padding:.6429rem .7143rem;border-bottom:1px solid var(--line)}
  .work td{min-width:0;padding:.3571rem .5rem;border:0;white-space:normal}
  .work td::before{content:attr(data-label);display:block;margin-bottom:2px;font-size:max(15px,.7143rem);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:1rem}
.item{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:1.2857rem 1.4286rem 1.1429rem;display:flex;flex-direction:column;gap:.8571rem;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:.8571rem;align-items:flex-start}
.item-who{min-width:0}
.item-name{margin:0;font-size:1.2143rem;font-weight:600;letter-spacing:-.015em;line-height:1.25;overflow-wrap:anywhere}
.item-contact{margin-top:3px;font-size:max(15px,.9286rem);color:var(--ink-2);display:flex;flex-wrap:wrap;gap:0 .5714rem;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:1.0714rem;font-weight:600;font-variant-numeric:tabular-nums;color:var(--muted)}
.item-wait span{font-size:max(15px,.8571rem);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:.4286rem;align-items:center;font-size:max(15px,.8571rem);color:var(--muted)}
.item-when{margin-left:auto;font-variant-numeric:tabular-nums;white-space:nowrap}
.item-body{display:grid;gap:.2857rem}
.item-request{font-size:1.0357rem;font-weight:600;text-transform:capitalize;letter-spacing:-.01em}
.item-snippet{margin:0;font-size:max(15px,.9643rem);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:max(15px,.9286rem);color:var(--ink-2);padding:.6429rem .8571rem;background:var(--surface-2);border-radius:9px;display:flex;gap:.7143rem;align-items:baseline}
.item-next span{font-size:max(15px,.75rem);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:.2857rem 0 2px;padding:.7857rem .8571rem;border:1px solid var(--amber);background:var(--amber-soft);border-radius:9px;min-width:0}
.lead-match-head{font-size:max(15px,.75rem);font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2);margin-bottom:.5714rem}
.lead-match-list{list-style:none;margin:0;padding:0;display:grid;gap:.5714rem}
.lead-match-one{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px .8571rem;align-items:center;padding:.6429rem .7857rem;background:var(--surface);border:1px solid var(--line);border-radius:8px}
.lead-match-who{font-weight:600;font-size:max(15px,.9643rem);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:.5rem;font-size:max(15px,.75rem);font-weight:600;letter-spacing:.05em;text-transform:uppercase;padding:1px .5rem;border-radius:999px;border:1px solid var(--line-strong);color:var(--muted)}
.lead-match-facts{grid-column:1;font-size:max(15px,.8929rem);color:var(--ink-2);min-width:0}
.lead-match-why{grid-column:1;font-size:max(15px,.8571rem);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:max(15px,.9286rem);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:.4286rem}
}
/* "What next?" on a lead: the button, and the answer that replaces it. */
.item-ai{margin-top:2px}
.ai-ask{font:inherit;font-size:max(15px,.8929rem);padding:.4286rem .7857rem;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:max(15px,.8929rem);color:var(--muted)}
.ai-answer{padding:.7143rem .8571rem;background:var(--surface-2);border-radius:9px;display:grid;gap:.3571rem}
.ai-step{font-weight:600;font-size:max(15px,.9643rem)}
.ai-urgency{justify-self:start;font-size:max(15px,.75rem);font-weight:600;letter-spacing:.06em;text-transform:uppercase;padding:1px .5rem;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:max(15px,.7143rem) var(--num);text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.ai-answer{position:relative}
.ai-summary,.ai-why,.ai-note{margin:0;font-size:max(15px,.9286rem);line-height:1.5;color:var(--ink-2)}
.ai-why{color:var(--muted);font-size:max(15px,.8929rem)}
.ai-note{color:var(--muted);font-size:max(15px,.8571rem);font-style:italic}
.ai-error{font-size:max(15px,.8929rem);color:var(--red)}
.item-actions{display:flex;flex-wrap:wrap;gap:.4286rem;margin-top:auto;padding-top:.2857rem}
.item-actions .btn.small{min-height:34px;padding:.4286rem .7143rem}
.item-actions .more{min-width:0;width:auto;padding:.4286rem 1.7143rem .4286rem .7143rem;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:.7143rem}
.queue.compact .item{padding:.8571rem 1rem .8571rem;gap:.5714rem}
.queue.compact .item-name{font-size:1.0714rem}
.queue.compact .item-snippet{-webkit-line-clamp:2;font-size:max(15px,.9286rem)}
.queue.compact .item-next{padding:.4286rem .7143rem}
.queue.compact .item-actions .btn.small{min-height:30px;padding:.2857rem .7143rem;font-size:max(15px,.8571rem)}
.empty{padding:2.8571rem 1.7143rem;text-align:center;color:var(--muted);display:grid;gap:.2857rem}
.empty b{color:var(--ink);font-size:1.0714rem}
.seg.small{display:inline-flex;border:1px solid var(--line-strong);border-radius:9px;overflow:hidden}
.seg.small button{padding:.5rem .8571rem;border:0;background:var(--surface);cursor:pointer;font-size:max(15px,.8929rem);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:.8571rem 1.1429rem;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 .6429rem;font-size:max(15px,.9643rem)}
.pd-callback-row{display:flex;flex-wrap:wrap;gap:.5714rem}
.pd-callback .btn{font-size:max(15px,.9286rem)}
.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:.5714rem;align-items:center;margin-top:.7143rem;padding-top:.7143rem;border-top:1px solid var(--line)}
.pd-callback-more textarea{flex:1 1 260px;min-height:44px;resize:vertical;font:inherit;font-size:max(15px,.9286rem);padding:.5714rem .7143rem;border:1px solid var(--line-strong);border-radius:8px;background:var(--paper);color:var(--ink)}
.pd-callback-when{display:flex;align-items:center;gap:.4286rem;font-size:max(15px,.8929rem);color:var(--muted)}
.pd-callback-when select{font:inherit;font-size:max(15px,.9286rem);padding:.4286rem .5714rem;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:.7143rem 0;padding:.7143rem .8571rem;border:1px solid var(--line-strong);border-radius:10px;background:var(--surface)}
.pd-what-row{display:flex;flex-wrap:wrap;gap:.5714rem;align-items:center}
.pd-what-line{margin:.5714rem 0 0;font-size:max(15px,.9286rem);color:var(--ink-2)}
.pd-what-line b{color:var(--ink)}
.pd-what-missing{margin:.5714rem 0 0;display:flex;flex-wrap:wrap;gap:.5714rem 1rem;align-items:center;font-size:max(15px,.9286rem);color:var(--muted)}
.pd-what-missing > span{display:inline-flex;align-items:center;gap:.5714rem}

/* 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 .2857rem}
.pd-book-said{margin:0 0 .7143rem;color:var(--ink-2);font-size:max(15px,.9643rem)}
.pd-book-days{display:flex;flex-wrap:wrap;gap:.4286rem;margin-bottom:.7143rem}
.pd-book-chip{font:inherit;font-size:max(15px,.8929rem);padding:.3571rem .7143rem;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:.7143rem;margin-bottom:.5714rem}
.pd-book-nav b{font-size:1.0714rem}
.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:.7143rem .8571rem;font-size:max(15px,.9286rem)}
.pd-book-row{display:grid;grid-template-columns:52px 1fr auto;align-items:center;gap:.7143rem;padding:.3571rem .7143rem;border-bottom:1px solid var(--line);font-size:max(15px,.9286rem);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:max(15px,.8929rem)}
.pd-book-who{display:flex;flex-wrap:wrap;gap:.4286rem;min-width:0}
.pd-book-appt{background:var(--surface-3,var(--surface-2));border-radius:6px;padding:2px .5rem;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:.8571rem;margin:.8571rem 0 .4286rem;font-size:max(15px,.9286rem);color:var(--muted)}
.pd-book-opts label{display:flex;align-items:center;gap:.4286rem}
.pd-book-opts label.grow{flex:1 1 200px}
.pd-book-opts input,.pd-book-opts select{font:inherit;font-size:max(15px,.9286rem);padding:.4286rem .5714rem;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:.4286rem 0 .7143rem;font-size:max(15px,.8929rem);color:var(--warn,#b4500e)}
.pd-book-error{color:var(--urgent)}
.pd-book-foot{display:flex;align-items:center;gap:.7143rem;justify-content:flex-end;flex-wrap:wrap}
.pd-book-foot .muted{margin-right:auto;font-size:max(15px,.9286rem)}
@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:.7143rem .8571rem .7143rem 1.1429rem;border-radius:12px;display:flex;align-items:center;gap:.8571rem;font-size:max(15px,.9643rem);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:2rem}.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:.3571rem;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:.5rem .7857rem;font-size:max(15px,.8929rem);min-height:34px}
.row-actions .more{min-width:0;width:auto;padding:.2857rem 1.5714rem .2857rem .6429rem;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:1rem;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:.7143rem;min-width:0}
.column-head{display:flex;align-items:center;justify-content:space-between;padding:.4286rem .5714rem .7143rem}
.column-head h2{margin:0;font-size:max(15px,.9286rem);font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--ink-2)}
.column-head .count{font-size:max(15px,.8571rem);color:var(--muted);font-variant-numeric:tabular-nums;background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:1px .5714rem}
.column-body{display:grid;gap:.7143rem}
.column .item{padding:1rem 1.1429rem 1rem;gap:.7143rem}
.column .item-name{font-size:1.1071rem}
.column .item-snippet{-webkit-line-clamp:2;font-size:max(15px,.9286rem)}
.column-empty{margin:0;padding:1.5714rem .5714rem;text-align:center;color:var(--muted);font-size:max(15px,.9286rem)}
.board.compact .item{padding:.7143rem .8571rem;gap:.5rem}
.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:1.8571rem 0 .2857rem;font-size:1.1429rem;font-weight:600;letter-spacing:-.01em}
.settings .section-lede{margin:0 0 .8571rem;color:var(--ink-2);font-size:max(15px,.9643rem);max-width:72ch}
.settings .banner{padding:.8571rem 1.1429rem;border:1px solid var(--line-strong);border-radius:10px;background:var(--surface);font-size:max(15px,.9643rem)}
.settings .banner.ok{border-color:var(--ink)}
.settings .banner.bad{border-color:var(--urgent);color:var(--urgent)}
.mailbox{padding:1.4286rem 1.5714rem;display:flex;flex-direction:column;gap:.5714rem}
.mailbox-top{display:flex;justify-content:space-between;gap:.8571rem;align-items:flex-start}
.mailbox h3{margin:0;font-size:1.1429rem;font-weight:600;letter-spacing:-.01em}
.mailbox-who{margin:2px 0 0;font-size:max(15px,.9286rem);color:var(--ink-2);overflow-wrap:anywhere}
.mailbox-blurb{margin:0;color:var(--ink-2);font-size:max(15px,.9643rem)}
.mailbox-meta{margin:0;color:var(--muted);font-size:max(15px,.8929rem)}
.mailbox-actions{display:flex;gap:.5714rem;flex-wrap:wrap;margin-top:.4286rem}
.btn.quiet{color:var(--muted)}
.mailbox-result{margin:0;font-size:max(15px,.9286rem);color:var(--ink-2)}
.mailbox-result.ok{color:var(--ink)}
.mailbox-result.bad{color:var(--urgent)}
.facts{padding:.4286rem 1.5714rem}
.fact{display:grid;grid-template-columns:200px 1fr;gap:.8571rem;padding:.8571rem 0;border-bottom:1px solid var(--line);font-size:max(15px,.9643rem)}
.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:max(15px,.9643rem);color:var(--ink)}
.facts-note{margin:0;padding:.7143rem 0 .8571rem;color:var(--muted);font-size:max(15px,.8929rem);border-top:1px solid var(--line)}
@media (max-width:640px){.fact{grid-template-columns:1fr;gap:.2857rem}}
.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 .8571rem;color:var(--ink-2);font-size:max(15px,.9643rem);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 .5rem}
.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:.4286rem;display:grid;z-index:50}
.nav details.more .menu a{padding:.5714rem .8571rem;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:.7143rem;align-items:center;padding:.5714rem 1rem;border:1px dashed var(--line-strong);border-radius:9px;font-size:max(15px,.8929rem);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:.7143rem .8571rem;color:var(--ink-2);cursor:pointer;font-size:max(15px,.9643rem);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:.4286rem;font-size:max(15px,.7857rem);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:.8571rem;padding:1.2857rem 1.5714rem .8571rem;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--surface);z-index:1}
.drawer-head h2{margin:0;font-size:1.2857rem;font-weight:600;letter-spacing:-.02em}
.drawer-body{padding:1.1429rem 1.5714rem 1.7143rem;display:grid;gap:1.1429rem;align-content:start}
.kv{display:grid;grid-template-columns:140px 1fr;gap:.4286rem .8571rem;font-size:max(15px,.9643rem);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:max(15px,.9286rem);flex:none;letter-spacing:.02em}
.avatar.lg{width:56px;height:56px;font-size:1.2857rem}
.status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--line-strong);margin-right:.4286rem;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:max(15px,.9643rem)}
.tbl th{text-align:left;padding:.6429rem .8571rem;font-size:max(15px,.8571rem);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:.7143rem .8571rem;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:.8571rem;padding:1rem 1.2857rem .7143rem}
.card > .card-head h2{margin:0;font-size:1rem;font-weight:600}
.card > .card-head .hint{font-size:max(15px,.8571rem);color:var(--muted)}
.card > .card-body{padding:0 1.2857rem 1.1429rem}
.split{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:1.2857rem;align-items:start}
/* Below 1800px wide the side panel goes under the list (7 Oct 2026). At 340px
   beside it, the panel left the table too narrow: on Recall it hid the days
   overdue, on Referrals the days since referral, on Claims the carriers' last
   column. Under the list its cards sit side by side. */
@media (max-width:1799.98px){.split{grid-template-columns:1fr}.split > :is(.side,.col-side){display:grid;gap:1.2857rem;grid-template-columns:repeat(auto-fill,minmax(20rem,1fr));align-items:start}}
@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:16.857rem}
: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}
/* The theme button beside the tooth mark, at the top of the sidebar (6 Oct 2026). */
.side-markrow{display:flex;align-items:center;justify-content:space-between;gap:.5rem;border-bottom:1px solid var(--line);margin:0 0 .5714rem;padding-right:.4286rem}
.side-markrow .side-mark{border-bottom:0;margin:0;flex:1 1 auto}
.side-markrow .theme-toggle{flex:none}
.side-brand{display:flex;align-items:center;justify-content:space-between;gap:.5714rem;padding:1.1429rem 1.1429rem 1rem;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:1.0714rem}
.side-brand .brand span{font-size:max(15px,.8214rem)}
.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:.7143rem .7143rem .8571rem;overflow-y:auto;overflow-x:hidden;order:0;width:auto}
.side-nav .group{display:grid;gap:1px;padding:.2857rem 0 .4286rem}
.side-nav .group + .group{border-top:1px solid var(--line)}
.side-nav .group-label{margin:.4286rem .7143rem 3px;font-size:max(15px,.75rem);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:.7857rem;height:auto;padding:.5714rem .7143rem;border-radius:8px;font-size:1rem;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:max(15px,.7857rem);font-weight:600;font-variant-numeric:tabular-nums;line-height:1;padding:3px .5rem;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 .2857rem}
.side-nav .group-label{margin:.3571rem .7143rem 2px;font-size:max(15px,.7143rem)}
:is(body.has-sidebar, html.pd-sidebar body) .nav a{padding:.4286rem .7143rem;gap:.7143rem;font-size:max(15px,.9643rem)}
.work-box{padding:.2857rem .2857rem;margin:0 .4286rem .7143rem}

/* 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"]):where(:not([data-theme="fun"])) :is(body.has-sidebar, html.pd-sidebar body) .nav a[aria-current="page"]::after{background:#22D3EE}
  :root:not([data-theme="light"]):where(:not([data-theme="fun"])) :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:.5714rem;padding:.8571rem 1rem;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:max(15px,.8571rem)}
.side-foot .btn{flex:none}
.side-foot .btn:not(.icon){padding:.4286rem .7143rem;font-size:max(15px,.8929rem)}
.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:100rem;margin:0 auto}
/* 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 .8571rem 0 1.1429rem;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:.8571rem}
  /* 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:.5714rem}
  /* 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 .7143rem}
  .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:.5714rem .7143rem 1.1429rem;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:.4286rem}
  .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:.5714rem;flex-wrap:wrap;margin-top:.7143rem;padding:.5714rem .7143rem;border:1px solid var(--line);border-radius:9px;background:var(--surface-2);font-size:max(15px,.8929rem);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:.4286rem;padding:.3571rem .5714rem;font-size:max(15px,.8571rem)}

/* ---- 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:.5rem;flex-wrap:wrap;margin-top:.3571rem}
.sigs{display:inline-flex;align-items:center;gap:.4286rem;flex-wrap:wrap}
.sig{display:inline-flex;align-items:center;padding:1px .6429rem;border-radius:999px;
  border:1px solid var(--line-strong);font-size:max(15px,.8571rem);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:max(15px,.8929rem);
  vertical-align:top;padding-top:1.1429rem}

.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 .7857rem;border-radius:8px;border:1px solid var(--ink);
  background:var(--ink);color:var(--paper);font-size:max(15px,.8929rem);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)}
/* Dim, never crossed out: a struck-through label reads as "deleted" and is
   the hardest text on the page to read (7 Oct 2026). The reason it cannot
   run is on hover, from the button's title. */
.btn[disabled]{opacity:.5;cursor:not-allowed}
/* A long web address or setting name in code wraps rather than pushing the
   page sideways on a phone (Digital ads' setup steps, at the 15px floor). */
main code{overflow-wrap:anywhere}

/* ---- the pop-up card, on every page (theme.js, 7 Oct 2026) ----
   Beside what opened it, inside the window, scrolling inside itself when the
   window is short; its text wraps instead of running past its edge (the
   Schedule's insurance pill did). */
.pd-peek{position:fixed;z-index:90;width:min(25rem,calc(100vw - 16px));max-height:calc(100vh - 16px);overflow:auto;display:grid;gap:.5714rem;
  padding:.8571rem 1rem;background:var(--surface);color:var(--ink);border:1px solid var(--line-strong);border-radius:12px;
  box-shadow:0 14px 36px rgba(0,0,0,.3);font-size:1rem;line-height:1.45;overflow-wrap:anywhere}
.pd-peek[hidden]{display:none}
.pd-peek a:not(.btn){color:var(--ink);text-decoration:underline;text-decoration-color:var(--line-strong);text-underline-offset:3px}
.pd-peek a:not(.btn):hover{text-decoration-color:currentColor}
.pd-peek-head{display:flex;align-items:baseline;gap:.5714rem;flex-wrap:wrap}
.pd-peek-name{font-size:1.1429rem;font-weight:650;line-height:1.25}
.pd-peek-sub,.pd-peek-soft,.pd-peek-wait{color:var(--ink-2)}
.pd-peek-tags{display:flex;gap:.2857rem;flex-wrap:wrap}
.pd-peek-tag{border:1px solid var(--line-strong);border-radius:999px;padding:0 .5714rem}
.pd-peek-tag.alert{border-color:var(--urgent);color:var(--urgent);font-weight:600}
.pd-peek-dl{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.3571rem .8571rem;margin:0;padding-top:.5714rem;border-top:1px solid var(--line)}
.pd-peek-dl dt{color:var(--ink-2)}
.pd-peek-dl dd{margin:0;min-width:0}
.pd-peek-pill{display:inline-block;border:1px solid var(--line-strong);border-radius:999px;padding:0 .5714rem;font-weight:600}
.pd-peek-pill.ok{border-color:var(--ok, var(--ink))}
.pd-peek-pill.warn,.pd-peek-pill.bad{border-color:var(--urgent);color:var(--urgent)}
.pd-peek :is(.pill,.sch-ins,.sch-chip){white-space:normal;max-width:100%;margin-left:0}
.pd-peek-acts{display:flex;gap:.4286rem;flex-wrap:wrap;padding-top:.5714rem;border-top:1px solid var(--line)}

/* 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:.6429rem;padding:.4286rem .7143rem .7143rem;
  border-bottom:1px solid var(--line);margin:0 0 .5714rem;
  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:.4286rem .7143rem .7143rem;gap:.6429rem;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"]):where(:not([data-theme="fun"])) .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:1rem;font-weight:650;letter-spacing:-.01em;color:var(--ink)}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):where(:not([data-theme="fun"])) .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:.4286rem .2857rem;margin:0 .4286rem 1rem}
.work-box .group{margin:0}

.work-box .group-label{padding-left:.7143rem;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:max(15px,.9286rem);font-weight:600;color:var(--ink)}
.ins span{font-size:max(15px,.8571rem);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:max(15px,.8929rem);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:max(15px,.9286rem);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:max(15px,.8214rem);color:var(--muted);border:1px solid var(--line-strong);
  border-radius:999px;padding:0 .5714rem;margin-left:.5714rem;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 1rem 1.2857rem;background:var(--surface)}
.lead-panel{display:flex;flex-wrap:wrap;gap:1.2857rem 2rem;align-items:flex-start;padding:.2857rem 0 2px}
.lead-panel-main{flex:1 1 380px;min-width:0;display:grid;gap:.5714rem}
.lead-panel-side{flex:0 1 auto;display:grid;gap:.7143rem}

/* ---- 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:.6429rem 1.1429rem;font-size:1rem;border-radius:9px}
.item-actions .btn.call,.lead-panel .btn.call{font-weight:600}
.lead-panel .more,.item-actions .more{padding-right:2.1429rem;background-position:calc(100% - 16px) 17px,calc(100% - 12px) 17px}
.item-ask{display:flex;align-items:center;flex-wrap:wrap;gap:.5714rem;color:var(--muted);font-size:max(15px,.9286rem)}
.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 .4286rem;border:1px solid var(--line-strong);border-radius:999px;font-size:max(15px,.6429rem);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: 2.4286rem; }
.dictate-wrap > input { padding-right: 2.2857rem; }

.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); }
/* Quiet, not faint: at .62 a cold row's text scored Lc 42 to 48 (8 Oct 2026). */
.item.cold-item, tr.cold-item { opacity: .8; }
.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:.4286rem;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:.4286rem;font-size:max(15px,.75rem);
  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:max(15px,.8929rem);margin:2px 0 0}
.cover-table th{text-align:left;font-weight:600;padding:3px .5714rem 3px 0;color:var(--ink)}
.cover-table thead th{font-size:max(15px,.75rem);letter-spacing:.05em;text-transform:uppercase;
  color:var(--muted);font-weight:650;padding-bottom:.2857rem}
.cover-table td{padding:3px .5714rem 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:max(15px,.8214rem);margin:.4286rem 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 .4286rem .7143rem}

.side-meters{display:flex;gap:.5rem;margin:0 0 .2857rem}
.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%}
/* Two short lines rather than one cut off: the meter centres its lines, so a
   line wider than the box spilled past both edges and lost its start
   ("…tly marketing · $43.05 this month", 13 Oct 2026). */
.side-meter .side-meter-sub{max-width:100%;align-self:stretch;text-align:center;white-space:normal;text-wrap:balance;overflow-wrap:anywhere}
/* 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:.2857rem;
  margin:0 .7143rem .5714rem;padding:.5714rem .7143rem;
  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:.5714rem}
.side-meter-label{font-size:max(15px,.75rem);letter-spacing:.07em;text-transform:uppercase;color:var(--muted);white-space:nowrap}
.side-meter-value{font-family:var(--num);font-size:1.0714rem;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:max(15px,.75rem);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:1.4286rem}
.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:1.2857rem 1.5714rem .8571rem;border-bottom:1px solid var(--line)}
.cs-head h2{margin:0 0 3px;font-size:1.3571rem;letter-spacing:-.01em}
.cs-to{margin:0;color:var(--muted);font-size:max(15px,.9286rem)}
.cs-body{padding:1.1429rem 1.5714rem;display:grid;gap:.9286rem}
.cs-field{display:grid;gap:.3571rem}
.cs-field > span{font-size:max(15px,.8571rem);text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);font-weight:650}
.cs-field input,.cs-field textarea{width:100%;padding:.7143rem .8571rem;border:1px solid var(--line);
  border-radius:8px;background:var(--surface-2);color:var(--ink);
  font:1rem/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:max(15px,.8929rem);line-height:1.5}
.cs-foot{display:flex;gap:.7143rem;align-items:center;padding:1rem 1.5714rem 1.2857rem;
  border-top:1px solid var(--line);flex-wrap:wrap}
.cs-go{padding:.6429rem 1.2143rem;border:1px solid transparent;border-radius:8px;
  background:var(--green);color:var(--paper);font:650 1rem var(--ui);cursor:pointer}
.cs-go:hover{filter:brightness(1.08)}
.cs-cancel{padding:.6429rem 1.0714rem;border:1px solid var(--line-strong);border-radius:8px;
  background:var(--surface);color:var(--ink);font:1rem var(--ui);cursor:pointer}
.cs-cancel:hover{border-color:var(--ink-2)}
.cs-say{font-size:max(15px,.8929rem);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: .5714rem; margin: .5714rem 0; }
.item-audio audio { height: 32px; max-width: 320px; flex: 1 1 auto; }
.item-audio .len { font-size: max(15px,.8571rem); 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: .5rem;
  margin: .4286rem 0; font-size: max(15px,.8929rem); 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:1rem}
.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:max(15px,.8571rem);letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.period .v{font-size:2.1429rem;font-weight:600;letter-spacing:-.03em;margin:.3571rem 0 0;
  font-variant-numeric:tabular-nums}
.period .d{font-size:max(15px,.8571rem);color:var(--muted);margin:.2857rem 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:.8571rem;margin-bottom:.7143rem}
.bhead h2{margin:0}
.bhead-total{font-size:1.5714rem;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:.4286rem 1.2857rem;margin-top:.7857rem;
  font-size:max(15px,.8929rem);color:var(--ink-2)}
.pipe .legend i{display:inline-block;width:10px;height:10px;border-radius:2px;
  margin-right:.5rem;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. */
/* A wide table scrolls inside its own box rather than pushing the whole page
   sideways on a phone (7 Oct 2026: Insurance was 600px wider than a phone). */
.tbl-wrap{overflow-x:auto;min-width:0;max-width:100%}
.spend-table{width:100%;border-collapse:collapse;font-size:1.0714rem;table-layout:auto}
.spend-table thead th{text-align:left;font-size:max(15px,.8571rem);letter-spacing:.07em;
  text-transform:uppercase;color:var(--muted);font-weight:600;
  padding:0 1.4286rem .7143rem 0;border-bottom:1px solid var(--line);white-space:nowrap}
.spend-table td{padding:.8571rem 1.4286rem .8571rem 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:1.0714rem;letter-spacing:0;text-transform:none;
  color:var(--ink);font-weight:650;padding:1.5714rem 1.4286rem .5714rem 0;border-bottom:0;text-align:left}
.spend-table .group-row td{padding:1.5714rem 1.4286rem .5714rem 0;border-bottom:0;font-weight:650;
  font-size:1.1429rem;font-variant-numeric:tabular-nums}
.spend-table .group-row:first-child th,
.spend-table .group-row:first-child td{padding-top:.2857rem}

.spend-table .indent{padding-left:1.4286rem}
/* 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:1.1071rem}

@media (max-width:760px){
  .spend-table{font-size:1rem}
  .spend-table thead th,.spend-table td{padding-right:.8571rem}
  .spend-table .indent{padding-left:.8571rem}
}

/* ---- 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:1.0714rem}
.page-spending .muted{font-size:1rem;color:var(--ink-2)}
.page-spending .pill{font-size:max(15px,.8929rem);padding:3px .7143rem}
.page-spending .card h2{font-size:1.2143rem}
.page-spending .pairs dt{font-size:1.0714rem}
.page-spending .pairs dd{font-size:1.0357rem;color:var(--ink-2)}
.page-spending .page-head p{font-size:1.0357rem}

.page-spending .period .lab{font-size:max(15px,.8929rem);letter-spacing:.06em}
.page-spending .period .v{font-size:2.5714rem}
.page-spending .period .d{font-size:max(15px,.9643rem)}

.page-spending .bhead h2{font-size:1.2143rem}
.page-spending .bhead-total{font-size:1.7857rem}
.page-spending .pipe .legend{font-size:1rem}
.page-spending .pipe .legend b{font-size:1.0714rem}

.page-spending .spend-table{font-size:1.1071rem}
.page-spending .spend-table thead th{font-size:max(15px,.8929rem);letter-spacing:.05em}
.page-spending .spend-table td{font-size:1.1071rem}
.page-spending .spend-table td.muted{font-size:1.0714rem;color:var(--ink-2)}
.page-spending .spend-table .group-row th{font-size:1.1786rem}
.page-spending .spend-table .group-row td{font-size:1.2143rem}
.page-spending .spend-table td.num{font-size:1.1429rem}

@media (max-width:760px){
  .page-spending .period .v{font-size:2.1429rem}
  .page-spending .spend-table{font-size:1.0357rem}
  .page-spending .spend-table td{font-size:1.0357rem}
}

/* 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:max(15px,.8571rem);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:max(15px,.9286rem)}
.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 1rem}
/* 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:1rem 1.5714rem 0}
@media (max-width:820px){.ask.ask-bare{margin:.8571rem 1.1429rem 0}}
.ask-in{display:flex;align-items:center;gap:.7143rem;padding:0 1rem;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:1.0357rem;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:max(15px,.7857rem);color:var(--muted);
  border:1px solid var(--line);border-radius:5px;padding:2px .4286rem;line-height:1.3}
.ask-in:focus-within .ask-key{opacity:0}
.ask-said{margin:.5rem 2px 0;font-size:max(15px,.8929rem);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:1.0357rem;line-height:1.5;
  margin-top:.6429rem;padding:.7143rem .9286rem;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:2.4286rem}
.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:.5714rem;flex-wrap:wrap;margin:.5714rem 2px 0;font-size:max(15px,.8929rem);color:var(--muted)}
.ask-hint[hidden]{display:none}
.ask-hint-label{flex:none}
.ask-chips{display:flex;gap:.4286rem;flex-wrap:wrap}
.ask-chip{appearance:none;font:inherit;font-size:max(15px,.8929rem);line-height:1.3;padding:.3571rem .7857rem;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:.7143rem 0 0;padding:1.1429rem 1.2857rem .8571rem;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:1.4286rem;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:1rem;flex-wrap:wrap;padding-right:2rem}
.ask-main{flex:1 1 320px;min-width:0}
.ask-num{margin:0;font-size:2.4286rem;font-weight:600;line-height:1.05;letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:var(--ink);overflow-wrap:anywhere}
.ask-sent{margin:.3571rem 0 0;font-size:1rem;color:var(--ink)}
.ask-sub{margin:.4286rem 0 0;font-size:max(15px,.8929rem);color:var(--ink-2)}
.ask-sub .btn{margin-top:2px}
.ask-link{flex:none;align-self:flex-start;margin-top:.2857rem}
.ask-facts{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:.7143rem 1.2857rem;margin:.8571rem 0 0;padding:.8571rem 0 0;border-top:1px solid var(--line)}
.ask-facts div{min-width:0}
.ask-facts dt{font-size:max(15px,.8214rem);color:var(--muted);margin:0}
.ask-facts dd{margin:2px 0 0;font-size:max(15px,.9643rem);color:var(--ink);overflow-wrap:anywhere}
.ask-rows{margin:.8571rem 0 0;overflow:auto;border-top:1px solid var(--line)}
.ask-rows table{width:100%;border-collapse:collapse;font-size:max(15px,.9286rem)}
.ask-rows th{text-align:left;font-weight:500;color:var(--muted);font-size:max(15px,.8214rem);padding:.5714rem .5714rem .3571rem;border-bottom:1px solid var(--line);white-space:nowrap;text-transform:capitalize}
.ask-rows td{padding:.4286rem .5714rem;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:.7143rem 0 0;padding:0;display:grid;gap:.4286rem;grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
.ask-pick button{appearance:none;font:inherit;width:100%;text-align:left;padding:.6429rem .8571rem;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:max(15px,.8571rem);color:var(--muted)}
.ask-foot{display:flex;gap:1rem;flex-wrap:wrap;margin:.8571rem 0 0;padding-top:.5714rem;border-top:1px solid var(--line);font-size:max(15px,.8571rem);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:.4286rem 0 0;padding-left:1.2857rem;font-size:max(15px,.9286rem);line-height:1.6}
.ask-misses .mono{font-family:var(--num);font-size:max(15px,.8214rem);margin-right:.4286rem}
@media (max-width:820px){
  .ask-key{display:none}
  .ask-card{padding:1rem 1rem .7143rem}
  .ask-num{font-size:2rem}
  .ask-top{padding-right:1.7143rem}
  .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:max(15px,.8571rem);color:var(--ink-2);
  background:var(--surface-2);border:1px solid var(--line);border-radius:999px;
  padding:2px .6429rem;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:.5rem;font-size:max(15px,.75rem);
  text-transform:uppercase;letter-spacing:.04em;font-weight:600;
  color:var(--muted);border:1px solid var(--line);border-radius:4px;
  padding:1px .3571rem;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 .7143rem;font-size:max(15px,.9286rem);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:.5rem;margin:0 0 .8571rem}
.who-choices .who-pick{display:inline-flex;align-items:baseline;gap:.5rem}
.who-choices .dob{font-size:max(15px,.8214rem);color:var(--muted);font-family:var(--num)}

/* ---- 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:.2857rem;margin-left:.4286rem;font-size:max(15px,.8571rem);
  font-weight:500;line-height:1;padding:3px .5714rem;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 .6429rem;font-size:1rem;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:max(15px,.9286rem);line-height:1}
.ptag-x:hover{opacity:1}
.ptags{display:flex;flex-wrap:wrap;gap:.2857rem 0;margin:.4286rem 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:.5714rem;align-items:flex-start;margin:.5714rem 0 .8571rem}
.note-box textarea{flex:1 1 auto;min-height:44px;resize:vertical;font:inherit;font-size:1rem;
  padding:.5714rem .7143rem;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:.2857rem .6429rem;padding:.5rem 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:max(15px,.9643rem);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:1.0357rem;
  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:max(15px,.75rem);letter-spacing:.06em;text-transform:uppercase;
  background:var(--ink);color:var(--paper);border:0;border-radius:99px;padding:2px .5714rem;
  font-weight:600;line-height:1.5}
.step-auto{flex:none;margin:0;font-size:max(15px,.75rem);letter-spacing:.06em;line-height:1.5;
  text-transform:uppercase;color:var(--muted);border:1px dashed var(--line-strong);
  border-radius:99px;padding:1px .5rem}
.step-name{flex:0 1 auto}
.step-note{font-size:max(15px,.8929rem);margin:.7143rem 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:max(15px,.7857rem);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(4.7143rem + 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(5.7143rem + env(safe-area-inset-bottom,0px))}
  body.lead-open .lead-detail:not([hidden]) > td{display:block;padding:.8571rem 1.1429rem 1.7143rem}
  .lead-back{display:inline-flex;margin:.2857rem 0 .7143rem;font-size:1.0714rem}
  body.lead-open .lead-panel{display:block}
  body.lead-open .lead-panel-side{position:sticky;top:0;z-index:1;background:var(--surface);
    padding:.5714rem 0 .7143rem;margin:0 0 .5714rem;border-bottom:1px solid var(--line)}
  body.lead-open .item-actions .btn{min-height:44px;padding:0 1.2857rem;font-size:1.0714rem}
  body.lead-open .item-actions{display:flex;flex-wrap:wrap;gap:.5714rem}
  /* 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:max(15px,.8571rem)}
}

/* ---- 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 .7143rem}
  .strip-nums{display:block;font-size:max(15px,.9286rem);color:var(--muted);margin:0 0 .5714rem;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:.4286rem;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:max(15px,.9286rem);padding:.5rem .8571rem;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:.5714rem}
  .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:.7143rem;row-gap:2px;align-items:center;padding:.7143rem .8571rem .7143rem 1rem;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:1.1429rem;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:.2857rem .5714rem;align-items:center;margin-top:3px;font-size:max(15px,.9286rem)}
  /* 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:max(15px,.9286rem);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,
  .work #list-rows td[data-label="Phone"],.work #list thead th.phone-col{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 1rem;font-size:1rem;border-radius:20px}
  #list-rows tr.lead-detail > td{grid-column:1/-1}
}
/* One line per row on a monitor (7 Oct 2026). The phone number has its own
   column, so the name and its chips share a line, and the insurer sits beside
   what we know about it rather than above it. A phone keeps the stacked card. */
@media (min-width:900px){
  #list-rows .contact-line{display:flex;align-items:center;gap:.2857rem .5714rem;flex-wrap:wrap}
  #list-rows .contact-line .sub-line{margin-top:0}
  #list-rows .contact-line .sub-line .ph{display:none}
  #list-rows td[data-label="Phone"]{white-space:nowrap}
  #list-rows td[data-label="Phone"] .clip{display:inline-block;max-width:15rem;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom}
  #list-rows .ins{flex-direction:row;flex-wrap:wrap;align-items:baseline;column-gap:.4286rem}
}
/* 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 .7143rem}
  .lead-panel-who .name{font-size:1.4286rem;font-weight:600;line-height:1.2}
  .lead-panel-who .sub-line{display:flex;flex-wrap:wrap;gap:.5714rem;align-items:center;margin-top:.2857rem;font-size:max(15px,.9286rem);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: .8571rem; padding: .6429rem 0; border-top: 1px solid var(--line); }
.visit:first-child { border-top: 0; }
.visit-when { font-size: max(15px,.8929rem); 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: .5714rem; align-items: baseline; font-size: max(15px,.9643rem); padding: 1px 0; }
.tx .cdt { font-family: var(--mono); font-size: max(15px,.7857rem); 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: .2857rem .8571rem; margin-top: 3px; }
.visit-money .pay { font-size: max(15px,.8571rem); 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: .2857rem; }
.year-row {
  display: grid; grid-template-columns: 54px 1fr auto; gap: .7143rem; align-items: baseline;
  width: 100%; text-align: left; background: none; border: 0; border-top: 1px solid var(--line);
  padding: .5rem 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: max(15px,.9286rem); }
.year-m { color: var(--muted); font-size: max(15px,.8929rem); font-variant-numeric: tabular-nums; }
.year-row[aria-expanded="true"] .year-n { color: var(--ink); }
.year-body { padding: 2px 0 .5714rem; }

/* Who has actually paid, from the ledger rather than the carrier file. */
.ins-history { border-top: 1px solid var(--line); padding-top: .6429rem; margin-top: .6429rem; }
.ins-title { font-size: max(15px,.7857rem); text-transform: uppercase; letter-spacing: .07em; color: var(--muted); margin-bottom: .3571rem; }
.ins-row { display: grid; grid-template-columns: 1fr auto auto; gap: .7143rem; align-items: baseline; font-size: max(15px,.9286rem); 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: max(15px,.8571rem); 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: 1rem 0 .3571rem;
  font-size: max(15px,.8214rem); text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); font-weight: 600;
}
.note-in {
  display: block; width: 100%; resize: vertical; min-height: 44px;
  padding: .6429rem .7857rem; font: inherit; font-size: 1.0357rem; 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:1.7143rem}
.pd-lock-card{max-width:420px;text-align:center}
.pd-lock-title{font:600 1.8571rem/1.1 var(--ui);letter-spacing:-.02em;margin-bottom:.7143rem}
.pd-lock-sub{color:var(--muted);font-size:1rem;margin:0 0 1rem;line-height:1.55}
.pd-lock-who{color:var(--ink-2);font-size:max(15px,.9286rem);margin:0 0 1.2857rem}
#pd-lock .btn{padding:.7143rem 1.2857rem;font-size:1rem}
.pd-lock-out{display:inline-block;margin-top:1rem;color:var(--muted);font-size:max(15px,.8929rem)}
.pd-lock-out:hover{color:var(--ink)}
@media print{#pd-lock{display:none}}

/* ------------------------------------------- sidebar: fit, don't scroll ---
 *
 * Reported 1 Oct 2026 with a screenshot: a scrollbar down the sidebar and
 * SETTINGS cut off at the bottom. Measured rather than guessed at: the list
 * needs 749px and the window had 741. It missed by EIGHT PIXELS.
 *
 * This had already been tightened once, by hand, to fit a 900px screen (see
 * the block above). That is the problem with fixed pixel values: the next
 * browser window, or one more link, puts it back over the line, and nobody
 * finds out until it is on somebody's screen.
 *
 * So the rows SCALE now. clamp() gives each one a comfortable size when
 * there is room and lets it tighten when there is not, keyed off the height
 * of the window rather than a number somebody measured once. The list stops
 * shrinking at a floor that is still comfortably tappable, which is the
 * point at which scrolling is genuinely the right answer rather than a
 * symptom.
 *
 * Only applies to the real sidebar, not the phone layout, which is a
 * different shape entirely and already scrolls on purpose. */
@media (min-width: 900px) {
  :is(body.has-sidebar, html.pd-sidebar body) .nav a {
    /* 6px of padding at a tall window, 3px at a short one. */
    padding-top: clamp(3px, 0.62vh, .5rem);
    padding-bottom: clamp(3px, 0.62vh, .5rem);
  }
  .side-nav .group { padding: clamp(0px, 0.2vh, 2px) 0 clamp(1px, 0.4vh, .2857rem); }
  .side-nav .group-label {
    margin-top: clamp(2px, 0.5vh, .4286rem);
    margin-bottom: clamp(1px, 0.2vh, 2px);
  }
  /* The spend meter is 76px, the single biggest block in the column after
     the links themselves. It keeps its size where there is room and gives
     back its padding first where there is not: a number nobody is reading
     right now should yield before a navigation row does. */
  :is(body.has-sidebar, html.pd-sidebar body) .side-meters { margin-bottom: clamp(.2857rem, 1vh, .7143rem); }
  .work-box { padding: clamp(2px, 0.4vh, .2857rem) .2857rem; margin-bottom: clamp(.2857rem, 1vh, .7143rem); }
}

/* ---- audit fixes, 2 Oct 2026 ---- */
/* A search box the ask bar has hidden takes its microphone with it. */
.dictate-wrap:has(> [data-ask-hidden]){display:none !important}
/* A table inside a sideways scroller cannot stick to the page: the scroller
   is its sticky container, so the page offset pushed the column headings
   down INTO the rows (Leads list: headings between rows 3 and 4). Inside a
   scroller the headings sit at the top of their own table. */
body .scroll thead th,body .work .scroll th,body .wrap .scroll thead th{top:0}

/* ---- scale rules, 2 Oct 2026 ---- */
/* ONE ROOT SIZE PER WINDOW. Every type size, line height, padding, margin
   and gap in the dashboard is in rem (14px = 1rem, the size it was drawn
   at), so changing the root here scales a whole page, spacing included.
   Percentages rather than px so a browser set to larger text is respected.

     under 760px   16px   a phone is held further away than it is designed for
     760 to 1499   15px   a laptop
     1500 and up   16px   the office screen (1690 wide) and anything bigger

   Raised a step on 7 Oct 2026 night. Keith, on Patient intake in Vaporwave:
   "everything needs to be above a certain point ... I can't read any of
   this stuff". The office screen was at 15px with small text at 14px; it is
   16px with small text at 15px now.

   Type is floored at 15px wherever it is set: max(15px, Xrem). It was 12px
   until 7 Oct 2026, then 14px the same day, when the audit found most screens
   had half their text under 14px; every size under 1rem carries the floor (charts drawn in
   SVG units excepted). A new rule keeps it: never write a bare size under 1rem. */
html{font-size:93.75%}
@media (max-width:759.98px){html{font-size:100%}}
@media (min-width:1500px){html{font-size:100%}}

/* TWO KINDS OF PAGE. A reading page (the default) is a centred column capped
   at 100rem, so it never strands empty space on one side. A data page is a
   table or a board and takes the whole window: columns are what it is for. */
.page[data-layout="data"],:is(body.has-sidebar, html.pd-sidebar body) .page[data-layout="data"]{max-width:none}
/* Running text stops at a readable line whatever the window does. */
.page :is(p,.lede,.sub,.hint,.note-text){max-width:75ch}
.page :is(td,th,.tile,.stat,label,button,a) > p{max-width:none}

/* A row of tabs scrolls sideways; it never squeezes. With 16px type on a
   phone the Billing tabs shrank under their own words and drew over each
   other ("PatientsPayments"). */
.tabs > *,.tabrow > *{flex:0 0 auto;white-space:nowrap}
/* The one headline number big enough to outgrow a phone card. */
@media (max-width:759.98px){.big{font-size:clamp(2.2rem,11vw,3.4rem)}}
/* The 12px floor made the four sidebar headings 2px taller each, which put
   the list 12px over at a 720px window. On a short window the headings give
   the height back in leading, not in type size. */
@media (min-width:900px) and (max-height:780px){.side-nav .group-label{line-height:1.15}}

/* ---- touch targets, 2 Oct 2026 ---- */
/* 4,626 of 5,113 controls measured under 40px on a phone. Asked of the
   pointer, not the width: a small touch laptop needs this and a narrow
   desktop window does not. 44px is the size a fingertip covers.

   IMPORTANT is deliberate. The first version of this block lost to every
   page rule with one more class in it (.item-ask .btn.small set 32px and
   won), which is how the buttons got small in the first place. A floor has
   to hold whatever a page says. */
@media (pointer:coarse){
  .btn,.btn.small,select,summary,.seg button,.tabs a,.tabs button,[role="tab"],.chip,.pill-btn,button.pill,
  .filters button,td button,td select,li button,.row-actions a,.item-contact a,a.name,.nm button,
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="hidden"]):not([type="file"]),
  .side-nav a,.menu a,a.brand,.day-strip-sum{min-height:44px !important}
  .btn,.seg button,.tabs a,.tabs button,[role="tab"],.chip,button.pill,td button{min-width:44px !important}
  .btn.small{padding-inline:.8571rem}
  .btn.icon,.close,.theme-toggle,.side-toggle,.ask-what{min-width:44px !important;min-height:44px !important}
  input[type="checkbox"],input[type="radio"]{width:24px !important;height:24px !important}
  /* A name in a row is the row's link: give it the row's height. */
  td > a:not(.btn),td .name a,li > a:not(.btn),.item-contact a,a.name,a.brand,.day-strip-sum{display:inline-flex;align-items:center;min-height:44px}
  /* The microphone sits inside a field that is now 44px tall, so it can be
     a full target without changing the layout around it. */
  .dictate-btn{width:40px !important;height:40px !important;right:2px}
  .dictate-wrap > textarea + .dictate-btn{top:2px}
  .dictate-wrap > input,.dictate-wrap > textarea{padding-right:3.1rem}
  textarea{min-height:88px}
}

/* ---- phone header, 2 Oct 2026 ---- */
/* ONE BAR ON A PHONE: menu, the page you are on, search, theme. 48px.
   Before this the bar was 56px of "Pride Dental / Front desk" plus Sign out,
   and under it the ask bar took another 60px on every page: a third of the
   first screen was chrome before any content. */
header.top .side-title,header.top .side-search,header.top .side-drawer-foot{display:none}
@media (max-width:899px){
  :is(body.has-sidebar, html.pd-sidebar body) .top{height:48px;padding:0 2px}
  :is(body.has-sidebar, html.pd-sidebar body) .nav{top:48px;display:flex;flex-direction:column}
  .side-scrim{top:48px}
  /* THE DRAWER DID NOT OPEN. "body.nav-open .nav{transform:none}" has been
     outranked since the sidebar was reserved before first paint: that commit
     wrapped the closed state in :is(body.has-sidebar, html.pd-sidebar body),
     which counts as its most specific argument, so the closed rule beat the
     open one and the menu button dimmed the page and showed nothing. */
  html body.nav-open header.top .nav{transform:none}
  :is(body.has-sidebar, html.pd-sidebar body) .side-brand .brand{display:none}
  .side-brand{gap:2px;min-width:0}
  header.top .side-title{display:block;min-width:0;font-weight:650;font-size:1.0625rem;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  header.top .side-search{display:inline-flex;position:relative}
  .side-search svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
  .side-search.on::after{content:"";position:absolute;top:9px;right:9px;width:8px;height:8px;border-radius:50%;background:var(--accent,#2563eb)}
  .side-foot{gap:0}
  .side-foot a[href="/auth/logout"]{display:none}
  header.top .btn.icon{width:44px;height:44px;border-color:transparent;background:transparent}
  header.top .side-drawer-foot{display:flex;align-items:center;gap:.75rem;margin-top:auto;padding:.75rem .5rem 0;border-top:1px solid var(--line)}
  .side-drawer-who{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--muted);font-size:max(15px,.875rem)}
  /* The ask bar is a sheet under the bar, opened by the search button. */
  body:not(.ask-open) .ask{display:none !important}
  body.ask-open .ask,body.ask-open .ask.ask-bare{display:block;position:fixed;top:48px;left:0;right:0;z-index:43;margin:0;padding:.625rem .875rem .75rem;background:var(--paper);border-bottom:1px solid var(--line);box-shadow:0 14px 30px rgba(0,0,0,.22);max-height:calc(100dvh - 48px - 70px);overflow:auto}
  .pd-dup-title{position:absolute !important;width:1px;height:1px;margin:0 !important;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
}
@media (max-width:759.98px){
  /* An intro is one line until it is tapped. */
  .page .lede:not(.open){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;cursor:pointer}
  /* The page's main action rides above the tab bar, under the thumb,
     instead of scrolling away with the top of a 40-screen list. */
  [data-main-action]:not([hidden]):not(:disabled){position:fixed;right:1rem;bottom:calc(64px + env(safe-area-inset-bottom,0px) + .75rem);z-index:40;min-height:48px !important;padding-inline:1.25rem;border-radius:999px;box-shadow:0 8px 24px rgba(0,0,0,.3)}
  .page:has([data-main-action]){padding-bottom:9rem}
}

/* ---- one page frame, 2 Oct 2026 ---- */
/* Figures line up in columns without borrowing the code font. */
body{font-variant-numeric:tabular-nums}
/* A placeholder a script fills in later should not hold a row open. */
.page > div:empty,.page > section:empty{display:none}
/* ONE TILE. Four pages each drew their own (.stat on Voicemails, Messages
   and Registrations; .tile on Solicitations), a different size on each.
   This is the Leads and Recall tile, which the others now share: a big
   figure, a plain label under it. */
.page > .stats,.page > .tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(9.5rem,1fr));gap:.7143rem;margin:0;padding:0}
:where(.page) > .stats > .stat,:where(.page) > .tiles > .tile{min-width:0;padding:1rem 1.1429rem;background:var(--surface);border:1px solid var(--line);border-radius:10px;display:flex;flex-direction:column;gap:2px}
:where(.page) > .stats > .stat > strong,:where(.page) > .tiles > .tile > strong{display:block;font:600 1.8571rem/1.1 var(--ui);letter-spacing:-.03em}
:where(.page) > .stats > .stat > span,:where(.page) > .tiles > .tile > span{font-size:max(15px,.9286rem);color:var(--ink-2)}
@media (max-width:759.98px){.page > .stats,.page > .tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* The older pages' filter rows are the shared one now. */
.page > .bar{align-items:center;flex-wrap:wrap;gap:.6429rem}

/* A row of header buttons wraps; on Claims it ran 44px past a phone. */
.page-head{min-width:0}
.head-side{flex-wrap:wrap;min-width:0}
/* ---- record tables: paging, and cards on a phone, 2 Oct 2026 ---- */
.pd-out{display:none !important}
.pd-more{display:flex;gap:.6rem;justify-content:center;align-items:center;padding:.9rem 0 .2rem}
.pd-more[hidden],.pd-more [hidden]{display:none}
/* A list that is switched off (the Cards view while List is showing) takes its pager with it. */
[hidden] + .pd-more{display:none !important}
.pd-more .btn.quiet{background:transparent;border-color:transparent;color:var(--muted)}
.pd-more .btn.quiet:hover{color:var(--ink)}
/* A TABLE IS NOT A PHONE LAYOUT. Seven columns in 390px meant scrolling
   sideways to find the button that acts on the row. Under 760px each row
   of a record table is a card: the name as its heading, every other value
   under the name of its column, actions across the bottom. */
@media (max-width:759.98px){
  .scroll:has(> table[data-cards]){overflow:visible}
  :is(.wrap,.card,.list,.panel):has(> .scroll > table[data-cards]),:is(.wrap,.card,.list,.panel):has(> table[data-cards]){background:transparent;border:0;box-shadow:none;overflow:visible;padding:0}
  table[data-cards]{display:block;min-width:0 !important;width:100%}
  table[data-cards] thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
  table[data-cards] tbody{display:grid;gap:.625rem}
  table[data-cards] tr{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.55rem 1rem;position:relative;padding:.9rem 1rem;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
  table[data-cards] tr[hidden]{display:none}
  table[data-cards] td{display:block;min-width:0;padding:0 !important;border:0 !important;background:transparent !important;text-align:left !important;white-space:normal;overflow-wrap:anywhere}
  table[data-cards] td[data-label]:not([data-label=""])::before{content:attr(data-label);display:block;margin-bottom:1px;font-size:max(15px,.75rem);font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
  table[data-cards] td.pd-title{grid-column:1 / -1;order:-1;font-size:1.0625rem;font-weight:600}
  table[data-cards] td.pd-title::before{content:none !important}
  /* a cell with no heading is the row's actions; a spanning cell is a detail or an empty state */
  table[data-cards] td[data-label=""],table[data-cards] td[colspan],table[data-cards] td:has(> .row-actions){grid-column:1 / -1}
  table[data-cards] td[data-label=""]{display:flex;flex-wrap:wrap;gap:.5rem;order:9}
  table[data-cards] td:has(> .row-actions){order:9}
  table[data-cards] td:has(> .row-actions)::before{content:none !important}
  table[data-cards] .row-actions{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:flex-start}
  table[data-cards] td:empty{display:none}
  table[data-cards] td .sub,table[data-cards] td .sub-line{white-space:normal}
  /* a long value (a message, a pitch) takes the full width of the card */
  table[data-cards] td.pd-wide{grid-column:1 / -1}
  /* the tick box sits in the corner of its card */
  table[data-cards] td.chk{position:absolute;top:.8rem;right:.9rem;display:block}
  table[data-cards] td.chk::before{content:none !important}
  table[data-cards] tr:has(> td.chk) td.pd-title{padding-right:2.6rem !important}
  /* The coloured stripe that marks an urgent or due row was drawn on the
     first cell, which in a card is a value in the middle. It moves to the
     card's own edge. */
  table[data-cards] td{box-shadow:none !important}
  table[data-cards] tr:is(.urgent,.late,.old,.falling,.st-denied,.bad){border-left:3px solid var(--urgent)}
  table[data-cards] tr.due{border-left:3px solid var(--accent)}
  table[data-cards] tr.warm{border-left:3px solid var(--warn,#b4500e)}
  /* Inside a card the whole card is the target, so a link in it does not
     need to stand 44px tall on its own. */
  table[data-cards] td > a:not(.btn),table[data-cards] td .name a,table[data-cards] a.name{min-height:28px !important}
  .pd-more{flex-direction:column;gap:.25rem}
  .pd-more .btn{width:100%}
}

/* ---- filters as chips, 2 Oct 2026 ---- */
/* .page .bar in the selector: a page whose own .btn rule sets display would otherwise show this on a desktop. */
.page .bar .pd-filter-toggle{display:none}
@media (max-width:759.98px){
  /* The dropdowns come back, as chips. Two older rules hid them outright. */
  .page .bar select{display:inline-flex !important;flex:0 1 auto;min-width:0 !important;width:auto !important;max-width:100%;border-radius:999px;padding-inline:.95rem 2rem;font-size:max(15px,.9375rem)}
  .page .bar .seg:not([aria-label="View"]){display:inline-flex !important}
  .page .bar .seg{max-width:100%;overflow-x:auto;flex-wrap:nowrap !important;scrollbar-width:none;border-radius:12px}
  .page .bar .seg::-webkit-scrollbar{display:none}
  .page .bar .seg > button{flex:0 0 auto;white-space:nowrap}
  .page .bar.pd-filters:not(.open) > .pd-extra{display:none !important}
  .page .bar .pd-filter-toggle{display:inline-flex;border-radius:999px;border-style:dashed}
  .pd-filter-toggle.on{border-style:solid;border-color:var(--accent,#2563eb);color:var(--accent,#2563eb)}
  .page .bar{gap:.5rem;align-items:center}
}

/* ---- list and record side by side, 2 Oct 2026 ---- */
.lead-dock-name{display:none;margin:0 0 .5rem;font-size:1.375rem;font-weight:650;letter-spacing:-.02em}
@media (max-width:899px){body.lead-open .lead-dock-name{display:block}}
/* At 2000px the Leads list was a 1700px-wide table with one line of text
   in each cell, and opening a row pushed every row under it off the
   screen. From 1700px the open record docks on the right and the list
   keeps its place on the left: read the record, act, click the next row. */
@media (min-width:1700px){
  :root{--dock-w:34rem}
  .page:has(#list:not([hidden]) .lead-detail:not([hidden])){padding-right:calc(var(--dock-w) + 3.2rem)}
  #list .lead-detail:not([hidden]){position:fixed;top:1rem;right:1.7143rem;bottom:1rem;width:var(--dock-w);z-index:35;display:block;overflow:auto;background:var(--surface);border:1px solid var(--line-strong);border-radius:14px;box-shadow:0 18px 50px rgba(0,0,0,.25)}
  #list .lead-detail:not([hidden]) > td{display:block;padding:1.1rem 1.3rem 1.6rem;border:0}
  #list .lead-detail .lead-panel{display:block}
  #list .lead-row.open > td{background:var(--surface-2)}
  #list:has(.lead-detail:not([hidden])) table{min-width:0 !important}
  #list .lead-detail .lead-back{display:inline-flex;margin:0 0 .8rem}
  #list .lead-detail .lead-dock-name{display:block}
  /* the dock has the call button; the row's own copy would be cut off by the narrower list */
  #list:has(.lead-detail:not([hidden])) :is(td.row-do,td.row-open,thead th:nth-last-child(-n+2)){display:none}
}

/* ---- section tabs, 2 Oct 2026 ---- */
.pd-section-tabs{display:flex;gap:2px;margin:0;border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.pd-section-tabs::-webkit-scrollbar{display:none}
.pd-section-tabs a{flex:0 0 auto;position:relative;display:inline-flex;align-items:center;gap:.4286rem;padding:.7143rem .8571rem;color:var(--ink-2);text-decoration:none;white-space:nowrap;font-size:max(15px,.9643rem)}
.pd-section-tabs a:hover{color:var(--ink)}
.pd-section-tabs a[aria-current="page"]{color:var(--ink);font-weight:600}
.pd-section-tabs a[aria-current="page"]::after{content:"";position:absolute;left:.8571rem;right:.8571rem;bottom:-1px;height:2px;background:var(--ink)}
.pd-tab-tag{padding:0 .4286rem;border:1px dashed var(--line-strong);border-radius:999px;font-size:max(15px,.7143rem);font-weight:500;color:var(--muted);line-height:1.5}
@media (pointer:coarse){.pd-section-tabs a{min-height:44px}}

/* ---- the feedback bar, 5 Oct 2026 ---- */
.pd-say{position:fixed;left:calc(var(--side-w,0px) + 1.1429rem);bottom:1.1429rem;z-index:70;display:flex;align-items:center;gap:.7143rem;max-width:min(34rem,calc(100vw - 2.2857rem));padding:.7143rem .5rem .7143rem 1rem;border-radius:12px;background:var(--ink);color:var(--paper);font-size:max(15px,.9643rem);line-height:1.35;box-shadow:0 10px 30px rgba(0,0,0,.28)}
:is(body:not(.has-sidebar)) .pd-say{left:1.1429rem}
.pd-say[hidden]{display:none}
.pd-say.bad{background:var(--urgent);color:#fff}
.pd-say-undo,.pd-say-link{flex:none;padding:.3571rem .7143rem;border:1px solid rgba(255,255,255,.35);border-radius:8px;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer;text-decoration:none}
.pd-say-undo:hover,.pd-say-link:hover{background:rgba(255,255,255,.12)}
.pd-say-close{flex:none;width:2rem;height:2rem;border:0;background:transparent;color:inherit;font-size:1.25rem;line-height:1;cursor:pointer;opacity:.9}
.pd-say-close:hover{opacity:1}
@media (max-width:899px){.pd-say{left:.7143rem;right:.7143rem;bottom:calc(64px + env(safe-area-inset-bottom,0px) + .7143rem);max-width:none}}

/* A button that cannot act says why on its face. */
.pd-off,.pd-off:hover,.pd-off:disabled{opacity:.55;cursor:not-allowed;text-decoration:none !important}

/* The keyboard cursor and the key map. */
.pd-cursor{outline:2px solid var(--accent) !important;outline-offset:-2px;border-radius:6px}
tr.pd-cursor > td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
.pd-kbd{position:fixed;right:1.1429rem;bottom:1.1429rem;z-index:71;padding:1rem 1.1429rem;border:1px solid var(--line-strong);border-radius:12px;background:var(--surface);color:var(--ink);box-shadow:0 14px 40px rgba(0,0,0,.25);font-size:max(15px,.9286rem)}
.pd-kbd b{display:block;margin-bottom:.5rem;font-size:max(15px,.8214rem);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.pd-kbd dl{display:grid;grid-template-columns:auto 1fr;gap:.2857rem .8571rem;margin:0}
.pd-kbd dt{font-family:var(--mono);font-weight:600;padding:0 .4286rem;border:1px solid var(--line-strong);border-radius:5px;text-align:center}
.pd-kbd dd{margin:0;color:var(--ink-2)}

/* A line of explanation that stays one line until it is wanted. */
.pd-fold:not(.open){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;cursor:pointer}
.pd-fold:not(.open)::after{content:" more"}

/* A command card in the ask bar: the sentence, then the press. */
.ask-actions{display:flex;flex-wrap:wrap;gap:.5rem;margin:.5714rem 0 .2857rem}
.ask-actions .btn{min-height:2.5714rem;padding-inline:1.0714rem;font-weight:600}

/* The dialogs: one question, one press, no frozen window. */
.pd-dialog-scrim{position:fixed;inset:0;z-index:80;display:flex;align-items:center;justify-content:center;padding:1rem;background:rgba(0,0,0,.45)}
.pd-dialog{width:min(34rem,100%);max-height:calc(100vh - 2rem);overflow:auto;padding:1.2857rem 1.4286rem 1.1429rem;border:1px solid var(--line-strong);border-radius:14px;background:var(--surface);color:var(--ink);box-shadow:0 24px 60px rgba(0,0,0,.35)}
.pd-dialog-text{margin:0 0 .5714rem;font-size:1.1429rem;font-weight:600;line-height:1.35;white-space:pre-line}
.pd-dialog-hint{margin:0 0 .7143rem;color:var(--ink-2);font-size:max(15px,.9286rem);line-height:1.45}
.pd-dialog-field{display:grid;gap:.2857rem;margin:.5714rem 0}
.pd-dialog-field label{font-size:max(15px,.8214rem);letter-spacing:.05em;text-transform:uppercase;color:var(--muted);font-weight:600}
.pd-dialog-field label:empty{display:none}
.pd-dialog-field input,.pd-dialog-field select,.pd-dialog-field textarea{width:100%;padding:.6429rem .7857rem;border:1px solid var(--line-strong);border-radius:8px;background:var(--surface-2);color:var(--ink);font:inherit}
.pd-dialog-field textarea{min-height:6rem;resize:vertical;line-height:1.45}
.pd-dialog-acts{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}
.pd-dialog-acts .btn{min-height:2.7143rem;padding-inline:1.1429rem;font-weight:600}
.pd-dialog.bad .pd-dialog-ok{background:var(--urgent);border-color:var(--urgent);color:#fff}

/* Leads: a phone gets cards and no choice. */
@media (max-width:759.98px){.page .bar .seg.small[aria-label="View"]{display:none !important}}

/* ---- the theme picker ---- */
.pd-theme-pop{position:fixed;z-index:90;min-width:15rem;padding:.5714rem;background:var(--surface);border:1px solid var(--line-strong);border-radius:12px;box-shadow:0 18px 50px rgba(0,0,0,.35)}
.pd-theme-group{padding:.2857rem}
.pd-theme-group + .pd-theme-group{border-top:1px solid var(--line);margin-top:.2857rem;padding-top:.5rem}
.pd-theme-group b{display:block;font-size:max(15px,.7857rem);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);padding:.2857rem .5714rem .3571rem}
.pd-theme-pop button{display:flex;align-items:center;gap:.6429rem;width:100%;min-height:2.5714rem;padding:.4286rem .5714rem;border:0;border-radius:8px;background:transparent;color:var(--ink);font:inherit;text-align:left;cursor:pointer}
.pd-theme-pop button:hover{background:var(--surface-2)}
.pd-theme-pop button[aria-pressed="true"]{background:var(--surface-2);font-weight:600;box-shadow:inset 0 0 0 1px var(--line-strong)}
.pd-theme-pop button[aria-pressed="true"]::after{content:"";margin-left:auto;width:8px;height:8px;border-radius:50%;background:var(--accent, var(--ink))}
.pd-theme-pop .sw{flex:none;width:1.4286rem;height:1.4286rem;border-radius:50%;border:1px solid rgba(0,0,0,.15)}
.pd-theme-pop .sw-light{background:linear-gradient(135deg,#ffffff 55%,#1a3fe6 55%)}
.pd-theme-pop .sw-dark{background:linear-gradient(135deg,#0f1117 55%,#8aa0ff 55%)}
.pd-theme-pop .sw-system{background:linear-gradient(90deg,#ffffff 50%,#0f1117 50%)}
.pd-theme-pop .sw-vaporwave{background:linear-gradient(135deg,#1a0b3a 50%,#ff3fb0 50%)}
.pd-theme-pop .sw-fun{background:linear-gradient(135deg,#fff4d6 50%,#ff7a3d 50%)}
/* The icon row (7 Oct 2026): five themes side by side, one click each. */
.pd-theme-pop.icons{display:flex;gap:.2857rem;min-width:0;padding:.4286rem}
.pd-theme-pop.icons button{flex-direction:column;justify-content:center;gap:.3571rem;width:4.8rem;min-height:4.8rem;padding:.4286rem .2143rem;text-align:center}
.pd-theme-pop.icons .sw{width:2.2857rem;height:2.2857rem}
.pd-theme-pop.icons span{font-size:max(15px,.8571rem);line-height:1.1;white-space:nowrap}
.pd-theme-pop.icons button[aria-pressed="true"]{box-shadow:inset 0 0 0 2px var(--accent, var(--ink))}
.pd-theme-pop.icons button[aria-pressed="true"]::after{content:none}

/* The lead card's insurance row carries its own verb. */
.item-ins{display:flex;align-items:center;gap:.5714rem;flex-wrap:wrap}
.item-ins > .btn{margin-left:auto}

/* An insurance answer reads as an answer (6 Oct 2026). */
.item-ins.ok{border-color:var(--ok, #0f8a60);background:color-mix(in srgb, var(--ok, #0f8a60) 9%, var(--surface-2))}
.item-ins.ok::before{background:var(--ok, #0f8a60)}
.item-ins.ok span{color:var(--ink)}
.item-ins small{margin-left:auto;color:var(--muted);font-size:max(15px,.8214rem);white-space:nowrap}
.item-ins.fresh{animation:insfresh 1.6s ease-out 1}
@keyframes insfresh{0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--ok, #0f8a60) 55%, transparent)}100%{box-shadow:0 0 0 14px transparent}}
.item-name a{color:inherit;text-decoration:underline;text-decoration-color:var(--line-strong);text-underline-offset:3px}
.item-name a:hover{text-decoration-color:currentColor}

/* The name in an open enquiry is a link to the person; it looks like one (6 Oct 2026). */
.lead-panel-who .name .person-link{border-bottom-color:var(--line-strong)}
.lead-panel-who .name .person-link::after{content:" \203A";color:var(--muted);font-weight:400}
.lead-panel-who .name .person-link:hover{border-bottom-color:currentColor}

/* ==== The sidebar by priority: one ranked list, touch-friendly (24 Oct 2026) ====
   Keith: "prioritise what's important ... make it absolutely incredible ... touch friendly".
   One list with quiet headings instead of five boxes; every row a 44px target with 16px text;
   the page you are on lit in the practice colour with a bar at its edge; counts as solid pills.
   Only theme variables, so light, dark, Fun and Vaporwave all keep their own colours. */
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .work-box{border:0;background:none;padding:0;margin:0;box-shadow:none;border-radius:0}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .group{display:grid;gap:2px;padding:.125rem .25rem .875rem}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .group + .group{border-top:0}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .group-label{margin:.375rem .75rem .375rem;font-size:max(15px,.75rem);font-weight:650;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);line-height:1.2}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a:not(.side-mark):not(.side-meter){
  position:relative;display:flex;align-items:center;gap:.75rem;min-height:44px;padding:0 .625rem 0 .75rem;border-radius:12px;
  font-size:max(15px,1.1429rem);font-weight:500;line-height:1.2;color:var(--ink-2,var(--ink));text-decoration:none;transition:background-color .15s ease,color .15s ease}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a:not(.side-mark):not(.side-meter) svg{width:20px;height:20px;opacity:.72;transition:opacity .15s ease}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a:not(.side-mark):not(.side-meter):hover{background:var(--surface-2,rgba(128,128,128,.10));color:var(--ink)}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a:not(.side-mark):not(.side-meter):hover svg{opacity:1}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a:not(.side-mark):not(.side-meter):active{transform:scale(.985)}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a[aria-current="page"]:not(.side-mark):not(.side-meter){
  background:color-mix(in srgb,var(--brand,#0891B2) 15%,transparent);color:var(--ink);font-weight:650}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a[aria-current="page"]:not(.side-mark):not(.side-meter) svg{color:var(--brand,#0891B2);opacity:1}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a[aria-current="page"]:not(.side-mark):not(.side-meter)::before{
  content:"";position:absolute;left:0;top:10px;bottom:10px;width:3px;border-radius:0 3px 3px 0;background:var(--brand,#0891B2)}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a[aria-current="page"]:not(.side-mark):not(.side-meter)::after{display:none}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a .badge{margin-left:auto;min-width:26px;height:24px;display:inline-grid;place-items:center;padding:0 .5rem;
  border-radius:999px;border:0;font-size:max(15px,1.0714rem);font-weight:700;line-height:1;background:var(--brand,#0891B2);color:var(--paper,#fff)}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav a .beta{display:none}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .side-meters{margin:.25rem .5rem .75rem}
@media (prefers-reduced-motion:reduce){:is(body.has-sidebar, html.pd-sidebar body) .side-nav a{transition:none}:is(body.has-sidebar, html.pd-sidebar body) .side-nav a:active{transform:none}}
/* folded groups: the heading is the button */
:is(body.has-sidebar, html.pd-sidebar body) .side-nav button.group-label{display:flex;align-items:center;gap:.5rem;width:calc(100% - 1rem);min-height:44px;margin:.125rem .5rem;padding:0 .5rem 0 .25rem;
  border:0;border-radius:10px;background:none;cursor:pointer;font-family:inherit;text-align:left}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav button.group-label:hover{background:var(--surface-2,rgba(128,128,128,.10));color:var(--ink)}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav button.group-label:focus-visible{outline:2px solid var(--brand,#0891B2);outline-offset:2px}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .side-chev{width:16px;height:16px;margin-left:auto;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transform:rotate(90deg);transition:transform .2s ease}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .group.folded .side-chev{transform:none}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .group.folded > a{display:none}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .group.folded{padding-bottom:0}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .side-dot{display:none;width:8px;height:8px;border-radius:50%;background:var(--brand,#0891B2)}
:is(body.has-sidebar, html.pd-sidebar body) .side-nav .group.folded.has-work .side-dot{display:block}
/* phone tab bar: the same priority, bigger targets */
@media (max-width:899px){.tabbar a{min-height:56px}.tabbar a span{font-size:max(15px,1.0714rem)}}

/* ======================================================================
   LAYOUT PASS, 7 Oct 2026 (master-ec). Keith: "fit on the page, no dead
   space". Review and wireframes in admin/notes/2026-10-06-layout-review.
   The patient record (/person, main#main) keeps its own layout and is left
   out of every rule here on purpose: it is being redesigned separately.
   ====================================================================== */

/* 1. No width cap. Nine pages stopped at 1400px and left a strip on the
      right of a wide screen; the record keeps its own. */
:is(body.has-sidebar, html.pd-sidebar body) .page:not(#main),
:is(body.has-sidebar, html.pd-sidebar body) .page.home{max-width:none}

/* 2. Count tiles are chips on working pages. A row of four 140px cards
      that all said 0 came before any work on most pages. Each tile keeps
      its button, its filter and its words; it is one line now: the
      number, the label, then the detail in grey. Dashboards (Home,
      Analytics, Reports, Spending) keep their KPI cards. */
.page:not(#main):not(#page) > section.strip,
.page > section.stats,
.page > .tiles:not(.period-picker):not(#case-tiles),
.page .tiles4, .page .insr-tiles,
.page > section.peq-strip{display:flex !important;flex-wrap:wrap;gap:.4286rem;margin:0;padding:0;grid-template-columns:none}
.page:not(#main):not(#page) > section.strip > .card,
.page > section.stats > .stat,
.page > .tiles:not(.period-picker):not(#case-tiles) > .tile,
.page .tiles4 > .tile, .page .insr-tiles > .tile,
.page > section.peq-strip > .peq-tile{
  display:inline-flex !important;flex-direction:row !important;align-items:baseline;gap:.4286rem;flex:0 1 auto;
  min-height:0 !important;min-width:0;width:auto;padding:.3571rem .9286rem !important;margin:0;border-radius:999px !important;
  box-shadow:none;text-align:left;max-width:100%}
:is(.page:not(#main):not(#page) > section.strip > .card, .page > section.stats > .stat, .page > .tiles > .tile,
    .page .tiles4 > .tile, .page .insr-tiles > .tile, .page > section.peq-strip > .peq-tile) > *{margin:0 !important;padding:0;white-space:nowrap}
:is(.page:not(#main):not(#page) > section.strip > .card, .page > section.stats > .stat, .page > .tiles > .tile,
    .page .tiles4 > .tile, .page .insr-tiles > .tile, .page > section.peq-strip > .peq-tile)
  > :is(.v, strong, .tile-v, .big){order:0;font-size:1.0714rem !important;line-height:1.3 !important;font-weight:650;letter-spacing:-.01em}
:is(.page:not(#main):not(#page) > section.strip > .card, .page > section.stats > .stat, .page > .tiles > .tile,
    .page .tiles4 > .tile, .page .insr-tiles > .tile, .page > section.peq-strip > .peq-tile)
  > :is(.label, span:not(.tile-v):not(.tile-sub), .tile-l, .l){order:1;font-size:max(15px,.8929rem) !important;color:var(--ink-2);text-transform:none !important;letter-spacing:0 !important;font-weight:500}
:is(.page:not(#main):not(#page) > section.strip > .card, .page > section.stats > .stat, .page > .tiles > .tile,
    .page .tiles4 > .tile, .page .insr-tiles > .tile, .page > section.peq-strip > .peq-tile)
  > :is(.d, .tile-sub, .sub){order:2;font-size:max(15px,.8214rem) !important;color:var(--muted);overflow:hidden;text-overflow:ellipsis;max-width:26ch}
:is(.page:not(#main):not(#page) > section.strip > .card, .page > section.stats > .stat, .page > .tiles > .tile,
    .page .tiles4 > .tile, .page .insr-tiles > .tile, .page > section.peq-strip > .peq-tile)
  > :is(.d, .tile-sub, .sub):empty{display:none}
:is(.page:not(#main):not(#page) > section.strip > .card, .page > section.stats > .stat, .page > .tiles > .tile,
    .page .tiles4 > .tile, .page .insr-tiles > .tile, .page > section.peq-strip > .peq-tile)
  > :is(.caption, .spark, svg, .pipe){display:none !important}

/* 3. The sentence under a page's title said what the page obviously is. */
.page:not(#main) .page-head .lede{display:none}

/* 4. data-fit (see theme.js): the list scrolls inside, its header stays. */
.pd-fit-on{overflow:auto;overscroll-behavior:contain}
/* pdPanes (theme.js): one part of a long page at a time, under a row of tabs. */
.pd-pane-off{display:none !important}
.pd-panes{display:flex;flex-wrap:wrap;gap:0 .2857rem;margin:0 0 1rem;border-bottom:1px solid var(--line)}
.pd-panes [role=tab]{appearance:none;background:none;border:0;border-bottom:2px solid transparent;margin-bottom:-1px;padding:.5714rem .8571rem;font:inherit;font-size:max(15px,.9643rem);color:var(--ink-2);cursor:pointer;white-space:nowrap}
.pd-panes [role=tab]:hover{color:var(--ink)}
.pd-panes [role=tab][aria-selected=true]{color:var(--ink);font-weight:600;border-bottom-color:var(--accent)}
.pd-panes [role=tab]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:6px}
.pd-fit-on thead th{position:sticky;top:0;z-index:2;background:var(--surface);box-shadow:inset 0 -1px 0 var(--line)}

/* 5. A slimmer filter bar: it was 69px of padding around one row of
      drop-downs on most list pages. */
.page:not(#main) > .bar{padding-top:.4286rem;padding-bottom:.4286rem}
.page:not(#main) > .bar :is(input, select){padding:.4286rem .7143rem}

/* 6. Notices are chips, not banners. "Sample data" and "pickup is off"
      took a full-width box above the work on six pages. The whole
      sentence is still there on hover (theme.js copies it to the title). */
.page:not(#main) > .sample,
.page:not(#main) > .off-banner:not([hidden]){display:inline-flex;align-items:center;gap:.4286rem;justify-self:start;width:auto;max-width:min(100%,70ch);
  padding:2px .7857rem;border-radius:999px;font-size:max(15px,.8214rem);line-height:1.6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:help;margin:0}
.page:not(#main) > .off-banner:not([hidden]){border:1px solid var(--urgent);background:var(--urgent-soft);color:var(--urgent)}
.page:not(#main) > .off-banner .how,.page:not(#main) > .sample a{display:none}

/* 7. A warning chip in a page's head (Billing's "Ledger not loaded"),
      instead of a toast over the work. The sentence is its title. */
.pd-chip-warn{display:inline-flex;align-items:center;padding:2px .7857rem;border-radius:999px;border:1px solid var(--urgent);
  background:var(--urgent-soft);color:var(--urgent);font-size:max(15px,.8214rem);font-weight:600;white-space:nowrap;cursor:help}
.pd-chip-warn[hidden]{display:none}

/* 8. More notices as chips: a lede that is not in a page head, Messages'
      "sending is off" line, Solicitations' "AI is off", Digital ads'
      warnings. Their whole sentence is the hover title. */
.page:not(#main) > p.lede{display:none}
.page:not(#main) > p.sending,
.page:not(#main) > #notice > .notice,
.page:not(#main) > .warn-banner:not([hidden]){display:inline-flex;align-items:center;gap:.4286rem;justify-self:start;width:auto;max-width:min(100%,80ch);
  padding:2px .7857rem;margin:0;border-radius:999px;font-size:max(15px,.8214rem);line-height:1.6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:help}
.page:not(#main) > #notice > .notice b{margin-right:.2857rem}
.page:not(#main) > .warn-banner:not([hidden]) > :not(:first-child){display:none}

/* 9. Settings: a sticky section list beside the sections (settings.js). */
@media (min-width:1100px){
  main.page:has(> .set-nav){grid-template-columns:13rem minmax(0,1fr);column-gap:1.7143rem;align-items:start}
  main.page:has(> .set-nav) > *{grid-column:2}
  main.page:has(> .set-nav) > :is(.ask, .pd-section-tabs, .page-head){grid-column:1 / -1}
  main.page:has(> .set-nav) > .set-nav{grid-column:1;position:sticky;top:1rem;align-self:start}
  main.page:has(> .set-nav) > section.cards.two{grid-template-columns:repeat(auto-fit,minmax(22rem,1fr))}
}
.set-nav{display:flex;flex-direction:column;gap:2px;padding:.5714rem;border:1px solid var(--line);border-radius:10px;background:var(--surface)}
.set-nav a{padding:.4286rem .7143rem;border-radius:7px;color:var(--ink-2);text-decoration:none;font-size:max(15px,.9286rem)}
.set-nav a:hover{background:var(--surface-2);color:var(--ink)}
@media (max-width:1099.98px){.set-nav{flex-direction:row;flex-wrap:wrap;margin:0 0 1rem}}
.set-nav [role=tab]{appearance:none;background:none;border:0;text-align:left;padding:.4286rem .7143rem;border-radius:7px;color:var(--ink-2);font:inherit;font-size:max(15px,.9286rem);cursor:pointer}
.set-nav [role=tab]:hover{background:var(--surface-2);color:var(--ink)}
.set-nav [role=tab][aria-selected=true]{background:var(--accent-soft);color:var(--ink);font-weight:600}

/* 10. A chart with nothing to draw is one line, not a full-height panel
       (charts.js emptyNote). Its neighbours in the row keep their size. */
.card.chart:has(> .empty-note){min-height:0 !important;height:auto !important;align-self:start}
.card.chart:has(> .empty-note) > .hint{display:none}
.card.chart > .empty-note{margin:.2857rem 0 0;padding:0;min-height:0;color:var(--muted);font-size:max(15px,.9286rem)}

/* 11. The way back (shell.js, 7 Oct 2026): a page reached from another
       one says where it came from, at its top. */
.pd-back{order:-1;display:flex;align-items:center;margin:0;grid-column:1 / -1}
.pd-back a{display:inline-flex;align-items:center;gap:.4286rem;padding:.2143rem .8571rem .2143rem .5714rem;border-radius:999px;border:1px solid var(--line-strong);
  background:var(--surface);color:var(--ink-2);text-decoration:none;font-size:max(15px,.8929rem);font-weight:500}
.pd-back a:hover{border-color:var(--accent);color:var(--ink)}
.pd-back a span{font-size:1.2857rem;line-height:.8}

/* 12. Filter drop-downs as chips on every screen (theme.js). A filter in
       force is filled in; "Clear" appears beside them when any is. */
.page:not(#main) .bar select{-webkit-appearance:none;appearance:none;width:auto;min-width:0;border-radius:999px;cursor:pointer;
  padding:.3571rem 2rem .3571rem .9286rem;font-size:max(15px,.8929rem);line-height:1.35;
  background:var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238a8378' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right .7857rem center / .6429rem}
.page:not(#main) .bar select.pd-on{background-color:var(--accent-soft);border-color:var(--accent);color:var(--ink);font-weight:600}
.page:not(#main) .bar .pd-clear{border:0;background:none;color:var(--accent);font:inherit;font-size:max(15px,.8929rem);cursor:pointer;padding:.2857rem .4286rem;
  text-decoration:underline;text-underline-offset:3px}
.page:not(#main) .bar .pd-clear[hidden]{display:none}

/* Phone cards show what the desk acts on (7 Oct 2026). Twenty full cards ran
   7 to 16 screens; the row still opens its drawer with everything. Patient
   intake: the gist, then Details (leads.js). Claims, Recall, Billing and
   Referrals keep the columns that decide the next move (their own CSS). */
.queue .item .item-more{display:none}
@media (max-width:759.98px){
  .queue .item .item-more{display:inline-flex}
  .queue .item:not(.pd-open) :is(.item-meta, .item-ask),
  .queue .item:not(.pd-open) .item-body > :not(.item-request):not(.item-snippet){display:none}
  .queue .item:not(.pd-open) .item-snippet{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
  .queue .item .item-actions .pd-off{display:none}
}

/* One mark per insurance company (theme.js pdInsurer, 8 Oct 2026): two
   letters, white on the company's colour, the same on every page. */
.pd-ins{display:inline-grid;place-items:center;box-sizing:border-box;min-width:1.75rem;height:1.375rem;padding:0 .3rem;border-radius:.3rem;background:var(--ins,#4a4f57);color:#fff;
  font-size:max(15px,.8125rem);font-weight:700;font-style:normal;line-height:1;letter-spacing:-.01em;text-transform:none;white-space:nowrap;flex:none;vertical-align:-.28em}
/* With the company's own logo (24 Oct 2026): a white chip in every theme, the
   letters kept inside at size 0 so they return if the image cannot load. */
.pd-ins.has-logo{background:#fff;font-size:0;min-width:1.375rem;padding:0 .14rem;box-shadow:inset 0 0 0 1px rgba(0,0,0,.14)}
.pd-ins.has-logo img{display:block;width:1.12rem;height:1.12rem;object-fit:contain}

/* ---- the bar on every page (8 Oct 2026) ----
   Keith: "put the rotating in the top search bar and get the search bar to
   always work, you can search and you can ask questions." An Ask button on
   every page, the people a typed name could mean listed under the bar, and
   the thought for the day lying in the empty bar (askbar.js). */
.ask{position:relative}
.ask-in{position:relative}
.ask-go{flex:none;height:2.125rem;padding:0 .95rem;border:1px solid var(--ink);border-radius:8px;background:var(--ink);color:var(--paper);font:inherit;font-size:max(15px,.9375rem);font-weight:650;cursor:pointer}
.ask-go:hover{filter:brightness(1.12)}
.ask-go:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* ---- Ask Smile Workbench (24 Oct 2026; the design is
   admin/notes/2026-10-23-ask-smile-station.html). An AI chat box to look
   at: a glowing outline, Smile Workbench's tooth with a dot for whether the AI
   is answering, and a send arrow. The quote still rests inside it. ---- */
:root{--ask-ring:linear-gradient(100deg,var(--accent) 0%,color-mix(in srgb,var(--accent) 45%,#f4a6c0) 55%,#f4a6c0 100%)}
:root[data-theme="fun"]{--ask-ring:linear-gradient(100deg,#0a7ea4 0%,#5fb8d8 45%,#f4a6c0 100%)}
.ask-in{border-color:transparent;background:linear-gradient(var(--surface),var(--surface)) padding-box,var(--ask-ring) border-box}
.ask-in:focus-within{border-color:transparent;box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 16%,transparent),0 10px 26px -16px color-mix(in srgb,#f4a6c0 80%,transparent)}
.ask-avatar{position:relative;flex:none;display:grid;place-items:center;width:30px;height:30px;border-radius:9px;background:linear-gradient(140deg,color-mix(in srgb,var(--accent) 18%,var(--surface)),color-mix(in srgb,#f4a6c0 24%,var(--surface)))}
.ask-avatar .ask-mark,.ask-in:focus-within .ask-avatar .ask-mark{width:21px;height:21px;stroke:none}
.ask-mark .tooth{fill:#fff;stroke:var(--accent);stroke-width:1.4}
.ask-mark .eye{fill:#10384f;stroke:none}
.ask-mark .smile{fill:none;stroke:#10384f;stroke-width:1.2;stroke-linecap:round}
.ask-dot{position:absolute;right:-3px;bottom:-3px;width:10px;height:10px;border-radius:50%;background:var(--muted);border:2px solid var(--surface)}
.ask-in[data-ai="on"] .ask-dot{background:#1fa463}
.ask-in[data-ai="off"] .ask-dot{background:#f0a400}
.ask-who{flex:none;display:flex;flex-direction:column;line-height:1.15;white-space:nowrap}
.ask-who b{font-size:max(15px,.9375rem);color:var(--ink)}
.ask-who small{font-size:max(15px,.8125rem);color:var(--ink-2)}
.ask-go{display:inline-flex;align-items:center;gap:.35rem;border-color:var(--accent);background:var(--accent);color:var(--paper);border-radius:10px}
.ask-go svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
@media (max-width:640px){.ask-go span{display:none}.ask-go{padding:0 .6rem}}
:root[data-theme="vaporwave"] .ask-go{background:var(--v-main);color:var(--v-main-ink);border-color:var(--v-sel-line)}
.ask-found{position:absolute;left:0;right:0;top:calc(46px + .4rem);z-index:60;display:grid;gap:.1rem;padding:.4rem;max-height:min(27rem,70vh);overflow:auto;
  background:var(--surface);border:1px solid var(--line-strong);border-radius:12px;box-shadow:0 18px 40px -18px rgba(0,0,0,.45)}
.ask-found[hidden]{display:none}
.ask-found-h{margin:.25rem .6rem .1rem;font-size:max(15px,.8125rem);font-weight:650;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-2)}
.ask-person{display:grid;grid-template-columns:minmax(9rem,1fr) minmax(0,2.2fr);gap:.1rem 1rem;align-items:baseline;padding:.5rem .6rem;border-radius:8px;color:var(--ink);text-decoration:none}
.ask-person b{font-weight:650;overflow-wrap:anywhere}
.ask-person span{color:var(--ink-2);font-size:max(15px,.9375rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ask-person:hover,.ask-person.on{background:var(--surface-2);box-shadow:inset 0 0 0 1.5px var(--line-strong)}
.ask-found-none{margin:.45rem .6rem;color:var(--ink-2)}
.ask-found-ask{display:flex;align-items:center;gap:.6rem;width:100%;margin-top:.25rem;padding:.55rem .6rem .35rem;border:0;border-top:1px solid var(--line);background:none;
  color:var(--ink-2);font:inherit;font-size:max(15px,.9375rem);text-align:left;cursor:pointer}
.ask-found-ask:hover{color:var(--ink)}
.ask-found-ask kbd{margin-left:auto;padding:0 .4rem;border:1px solid var(--line-strong);border-radius:5px;font:inherit;font-size:max(15px,.8125rem);color:var(--ink-2)}
@media (max-width:640px){.ask-person{grid-template-columns:1fr}.ask-person span{white-space:normal}}
.ask-quote{position:absolute;top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:.8rem;min-width:0;pointer-events:none;color:var(--ink)}
.ask-quote .aq-text{min-width:0;font-size:1rem;font-weight:500;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ask-quote .aq-by{flex:none;font-size:max(15px,.9375rem);color:var(--ink-2);white-space:nowrap}
.ask-quote .aq-by::before{content:"";display:inline-block;width:1.1rem;height:1px;margin-right:.5rem;vertical-align:middle;background:var(--line-strong)}
/* Typed in (askbar.js typeIn, 23 Oct 2026): the rest of the line is there
   but see-through, so nothing moves; a caret of no width leads; the author
   fades in when the words are done. The bar and Home's band alike. */
.pd-untyped{color:transparent}
.pd-typed::after{content:"";display:inline-block;width:2px;height:1em;margin-right:-2px;vertical-align:-.15em;background:var(--accent);animation:pd-caret .9s steps(1) infinite}
@keyframes pd-caret{50%{opacity:0}}
.ask-quote .aq-by,.home-quote figcaption{transition:opacity .45s ease}
.ask-quote.typing .aq-by,.home-quote.typing figcaption{opacity:0}
.ask-in.has-quote input::placeholder{color:transparent}
.ask-in.has-quote:focus-within input::placeholder{color:var(--ink-2)}
.ask-in:focus-within .ask-quote,.ask-in input:not(:placeholder-shown) ~ .ask-quote{display:none}
@media (max-width:759.98px){.ask-quote{display:none}.ask-in.has-quote input::placeholder{color:var(--ink-2)}}
@media (prefers-reduced-motion:reduce){.pd-typed::after{animation:none}}

/* ---- the top row frozen; a page's buttons beside the bar (16 Oct 2026) ----
   Keith: "this stuff in the top can be frozen when you navigate the stuff
   underneath", "save space ... go through all of them". askbar.js joinHead()
   puts a page's one-line header (its buttons; the title and description
   are hidden with the sidebar on) to the right of the bar, and drops a
   header with nothing visible. The row stays at the top while the page
   scrolls; a page's own sticky bar (filters, tabs) sits under it. */
html.pd-sidebar .page:not(.home) > .ask,
html.pd-sidebar .page > .pd-askrow,
html.pd-sidebar #sch-askrow{position:sticky;top:0;z-index:35;background:var(--paper);
  margin-top:-1.1429rem;padding-top:.7143rem;padding-bottom:.5714rem;margin-inline:-1.7143rem;padding-inline:1.7143rem}
html.pd-sidebar .page > .bar{top:var(--ask-h,0px)}
.pd-askrow{display:flex;align-items:center;gap:.5714rem;min-width:0}
.pd-askrow > .ask{flex:1 1 auto;min-width:0;margin:0}
.pd-askrow > .page-head{flex:none;max-width:45%;overflow:hidden;margin:0;flex-wrap:nowrap;align-items:center}
.page-head.pd-head-empty{display:none}
/* ---- one page shape, on every page (18 Oct 2026, the page audit) ----
   askbar.js tidyPage(): tabs under the top row, explanations behind the (i),
   the sample banner as the tab's tag. Here: how those look, page titles
   hidden the same way on every page, and friendly empty pages. */
/* the (i) and what it opens */
.pd-askrow{position:relative}
.pd-about-btn{flex:none;display:inline-grid;place-items:center;width:2.5714rem;height:2.5714rem;border-radius:999px;border:1px solid var(--line-strong);
  background:var(--surface);color:var(--ink-2);cursor:pointer;padding:0}
.pd-about-btn svg{width:1.2857rem;height:1.2857rem;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
.pd-about-btn:hover,.pd-about-btn[aria-expanded="true"]{color:var(--ink);border-color:var(--ink-2)}
.pd-about-pop{position:absolute;right:1.7143rem;top:calc(100% - .2857rem);z-index:60;width:min(34rem,calc(100vw - 2rem));max-height:60vh;overflow:auto;
  padding:.8571rem 1rem;background:var(--surface);color:var(--ink);border:1px solid var(--line-strong);border-radius:14px;box-shadow:0 16px 40px rgba(0,0,0,.18);
  display:grid;gap:.5714rem;font-size:max(15px,.9643rem);line-height:1.5}
.pd-about-pop[hidden]{display:none}
.pd-about-pop p,.pd-about-pop .trend-sub{margin:0;max-width:none;color:var(--ink-2);display:block !important}
@media (max-width:899px){.pd-about-pop{right:.5rem}}
/* the sample banner, now the tab's tag */
.page:not(#main) > .sample.pd-banner-tagged,.page > .sample.pd-banner-tagged{display:none}
.pd-askrow > .pd-page-tag{flex:none;cursor:help}
.pd-section-tabs .pd-tab-tag[title]{cursor:help}
/* page titles hidden the same way everywhere (the sidebar names the page) */
html.pd-sidebar :is(main.page > h1, .trend-head > h1, .lk-head > h1, .cl-head > h1){position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
html.pd-sidebar .cl-head > .cl-sub{display:none}
html.pd-sidebar .trend-head:not(:has(> :not(h1))){display:none}
/* friendly empty pages: the smiling tooth, the words, the button */
:is(#todos > p.empty:not([hidden]), #list > p.empty:not([hidden]), .wrap > #empty.empty:not([hidden]), .cnf-empty:not([hidden]), .peq-empty:not([hidden]), #nobody.card.empty:not([hidden]), #cl-body > p.cl-empty:not([hidden])){display:grid;justify-items:center;text-align:center;gap:.4286rem;padding:2rem 1.1429rem 2.2857rem;color:var(--ink-2);font-size:max(15px,1rem);line-height:1.5}
:is(#todos > p.empty:not([hidden]), #list > p.empty:not([hidden]), .wrap > #empty.empty:not([hidden]), .cnf-empty:not([hidden]), .peq-empty:not([hidden]), #nobody.card.empty:not([hidden]), #cl-body > p.cl-empty:not([hidden]))::before{content:"";width:5.1429rem;height:5.1429rem;border-radius:50%;margin-bottom:.2857rem;
  background:var(--accent-soft) url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2064%2072%22%3E%3Cpath%20d%3D%22M32%204C19%204%208%2010%208%2024c0%2012%204%2016%206%2026%201.6%208%203%2018%207%2018%204.5%200%203.5-16%2011-16s6.5%2016%2011%2016c4%200%205.4-10%207-18%202-10%206-14%206-26C56%2010%2045%204%2032%204Z%22%20fill%3D%22%23fff%22%20stroke%3D%22%239fd0e8%22%20stroke-width%3D%222%22/%3E%3Ccircle%20cx%3D%2224%22%20cy%3D%2228%22%20r%3D%222.8%22%20fill%3D%22%2310384f%22/%3E%3Ccircle%20cx%3D%2240%22%20cy%3D%2228%22%20r%3D%222.8%22%20fill%3D%22%2310384f%22/%3E%3Cpath%20d%3D%22M23%2038c2.6%204%206.6%204%209%204s6.4%200%209-4%22%20fill%3D%22none%22%20stroke%3D%22%2310384f%22%20stroke-width%3D%222.6%22%20stroke-linecap%3D%22round%22/%3E%3C/svg%3E") center 58%/3.2rem no-repeat;animation:pd-empty-bob 3.6s ease-in-out infinite}
:is(#todos > p.empty:not([hidden]), #list > p.empty:not([hidden]), .wrap > #empty.empty:not([hidden]), .cnf-empty:not([hidden]), .peq-empty:not([hidden]), #nobody.card.empty:not([hidden]), #cl-body > p.cl-empty:not([hidden])) b{color:var(--ink);font-size:max(15px,1.0714rem)}
:is(#todos > p.empty:not([hidden]), #list > p.empty:not([hidden]), .wrap > #empty.empty:not([hidden]), .cnf-empty:not([hidden]), .peq-empty:not([hidden]), #nobody.card.empty:not([hidden]), #cl-body > p.cl-empty:not([hidden])) .btn{margin-top:.4286rem}
@keyframes pd-empty-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@media (prefers-reduced-motion:reduce){:is(#todos > p.empty:not([hidden]), #list > p.empty:not([hidden]), .wrap > #empty.empty:not([hidden]), .cnf-empty:not([hidden]), .peq-empty:not([hidden]), #nobody.card.empty:not([hidden]), #cl-body > p.cl-empty:not([hidden]))::before{animation:none}}
/* an empty list does not draw its column headings */
.wrap:has(> #empty:not([hidden])) > .scroll{display:none}
.card-body:has(> .peq-empty:not([hidden])) > table{display:none}
/* chart labels at the 15px floor (Analytics had 33 at 12.6px) */
.chart svg text{font-size:max(15px,.8929rem)}

/* ---- page audit step 2: the look (18 Oct 2026) ----
   One button: one corner, one weight, two heights, whatever page draws it
   (the audit counted 7, 8 and 9px corners, heights from 33 to 41px and
   three weights on the same pages). The theme keeps its colours. Fields 8px,
   cards 14px, chips round: three corners. Section headings one size.
   On a phone a row of counts is ONE row you swipe, not one chip per line
   (four lines on Referrals, Recall, Claims and Pre-estimates). */
main .btn:not(.icon):not(.ask-go):not([hidden]){border-radius:8px;font-weight:600;font-size:max(15px,.9643rem);min-height:2.7143rem;
  line-height:1.2;padding-block:0}
/* No display here: the base .btn is already inline-flex, and a display on
   this strong a rule showed every button a page hides with display:none
   (20 "Texting off" buttons on Referrals and Recall, "More filters"). */
main .btn.small:not(.icon):not([hidden]){min-height:2.2857rem}
@media (pointer:coarse){main .btn:not(.icon):not([hidden]){min-height:44px}}
main :is(input:not([type=checkbox]):not([type=radio]):not([type=range]), select, textarea){border-radius:8px}
main.page:not(.home) :is(.card, section.card, .wrap, .panel){border-radius:14px}
main.page:not(.home) :is(.card-head h2, .card > h2, section.card > h2){font-size:1.2143rem;line-height:1.3}
@media (max-width:720px){
  .page:not(#main):not(#page) > section.strip, .page > section.stats, .page > .tiles:not(.period-picker):not(#case-tiles), .page .tiles4, .page .insr-tiles, .page > section.peq-strip{flex-wrap:nowrap !important;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px !important}
  .page:not(#main):not(#page) > section.strip > .card, .page > section.stats > .stat, .page > .tiles:not(.period-picker):not(#case-tiles) > .tile, .page .tiles4 > .tile, .page .insr-tiles > .tile, .page > section.peq-strip > .peq-tile{flex:none !important}
  :is(.page:not(#main):not(#page) > section.strip > .card, .page > section.stats > .stat, .page > .tiles:not(.period-picker):not(#case-tiles) > .tile, .page .tiles4 > .tile, .page .insr-tiles > .tile, .page > section.peq-strip > .peq-tile) > :is(.d, .tile-sub, .sub){display:none !important}
}

/* ---- page audit step 3: one button a row, the rest in "..." (18 Oct 2026) ----
   <details class="pd-rowmore"> on a list row; askbar.js places the menu on the
   screen when it opens. */
.pd-rowmore{display:inline-block;position:relative}
.pd-rowmore > summary{list-style:none;cursor:pointer;padding-inline:.5714rem}
.pd-rowmore > summary::-webkit-details-marker{display:none}
.pd-rowmore-btn svg{width:1.2857rem;height:1.2857rem;fill:currentColor}
.pd-rowmore[open] > summary{border-color:var(--ink-2);color:var(--ink)}
.pd-rowmore-menu{position:fixed;inset:auto;margin:0;z-index:90;display:grid;min-width:13rem;max-width:min(20rem,calc(100vw - 16px));max-height:min(26rem,70vh);overflow:auto;padding:.2857rem;
  background:var(--surface);color:var(--ink);border:1px solid var(--line-strong);border-radius:14px;box-shadow:0 16px 40px rgba(0,0,0,.2);text-align:left;white-space:normal}
.pd-rowmore-menu > :is(button, a){display:block;width:100%;margin:0;padding:.5714rem .7857rem;border:0;border-radius:8px;background:none;color:var(--ink);font:inherit;
  font-size:max(15px,.9643rem);text-align:left;text-decoration:none;cursor:pointer;line-height:1.3}
.pd-rowmore-menu > :is(button, a):is(:hover, :focus-visible){background:var(--surface-2);outline:none}
.pd-rowmore-menu > :is(button, a)::first-letter{text-transform:uppercase}
.pd-rowmore-h{margin:.4286rem .7857rem .1429rem;font-size:max(15px,.8571rem);font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.pd-rowmore-menu > .pd-rowmore-h:first-child{margin-top:.2857rem}
.pd-rowmore-menu[popover]:not(:popover-open){display:none}
/* Recall: a column that is "?" for everyone takes no room */
table.no-hyg > * > tr > :nth-child(4){display:none}
/* Patient intake: one line a row. "Contacted" and "Waiting" said the same
   thing on every open row; Waiting stays, the exact time of contact is its
   hover. The "found" / "5 on this line" badge sits beside the name. */
@media (min-width:760px){
  #list table[data-cards] > thead th[data-sort="received"], #list-rows > tr > td.contacted{display:none}
  #list-rows td[data-label="Contact"] .name{white-space:nowrap;display:flex;align-items:center}
  /* "5 on this line" is class "from-record ask": the ask bar's margin came with the name */
  #list-rows .from-record.ask{margin-bottom:0}
}

/* ======================================================================
   REVIEW PASS, 12 Nov 2026. Every screen was looked at on a 1920 monitor,
   a 1366 laptop and a 390 phone, in light and dark. Each rule below fixes
   one thing seen on a real screen; nothing here restyles. Only theme
   variables, so every theme keeps its own colours.
   ====================================================================== */

/* Sidebar: "Insurance verifications" ran out of its pill and under the edge. It is "Insurance" now (one
   door, see theme.js), which fits. On a window under 1000px tall the list also tightens a little, so
   Money and the spend meter are not pushed off the bottom. */
@media (min-width:900px) and (max-height:999px){
  :is(body.has-sidebar, html.pd-sidebar body) .side-nav a:not(.side-mark):not(.side-meter){min-height:40px}
  :is(body.has-sidebar, html.pd-sidebar body) .side-nav .group{padding-bottom:.5rem}
}

/* Desktop: a page that fits its list to the window ended 46px lower than the window because of the page's
   own bottom padding, so the whole page scrolled as well as the list (two scrollbars side by side on
   Intake, Recall, Billing, Solicitations, Insurance verifications). 12px is what the fit code leaves. */
@media (min-width:1000px) and (min-height:600px){
  html.pd-sidebar main.page{padding-bottom:12px}
}

/* Patient intake on a laptop: the table was held at 1180px wide inside about 1060px, so "Make appointment"
   was cut in half and the Call button sat off the right edge behind a sideways scrollbar. Between phone
   cards and a wide monitor the table now takes the room it has and wraps inside its cells. */
@media (min-width:760px) and (max-width:1599.98px){
  .work#list table, #list table.work{min-width:0}
  #list table td.row-do, #list table td.row-open{white-space:nowrap}
  /* "How" (Website form, Phone call) is what the tabs above the list already sort by; it is the column
     that gives way first. It is still on the opened row and on a wide monitor. */
  #list table thead th:nth-child(5), #list table td[data-label="How"]{display:none}
  /* A "FAMILY OF ..." tag drops under the name instead of holding the Contact column 340px wide. */
  #list table .contact-line .name{flex-wrap:wrap;row-gap:.125rem;white-space:normal}
  #list table .contact-line .name > a{white-space:nowrap}
}

@media (max-width:899px){
  /* Phone: the (i) "about this page" button sat alone on a row of its own under the title bar, 57px of
     nothing on every page. It now sits in the title bar beside the search button. */
  .pd-askrow > .pd-about-btn{position:fixed;top:3px;right:48px;z-index:41;width:42px;height:42px;border-color:transparent;background:transparent;box-shadow:none}
  .pd-askrow > .pd-about-pop{top:.25rem}
  /* Floor: four tabs were squeezed into the screen until "Planned, not booked" ran into "Unsorted films".
     They keep their own width and the row slides sideways. */
  .cl-tabs{scrollbar-width:none}
  .cl-tabs > button{flex:none;padding-inline:.75rem}
  /* Settings: the section list wrapped into a loose grid of 72px-tall blocks. One row of pills that slides. */
  main.page:has(> .set-nav) > .set-nav{grid-row:auto !important}
  .set-nav{flex-wrap:nowrap;overflow-x:auto;align-items:center;gap:.375rem;scrollbar-width:none;padding:.375rem}
  .set-nav > button{flex:none;min-height:44px;height:auto;white-space:nowrap;padding-inline:.875rem}
}
@media (max-width:759.98px){
  /* Patient record: Call, Book, the insurance line, Check insurance and More were forced onto one line,
     so "Check insurance" printed on top of the insurer's name. They wrap, with the insurance line under. */
  .rec-head .acts{flex-wrap:wrap;overflow:visible}
  .rec-head .acts > :is(a, button, details){flex:none}
  .rec-head .acts > #inx-line{flex:1 1 100%;order:9;min-width:0}
}

/* ---- REVIEW PASS, part two (12 Nov 2026, Keith: "let's make all of these things") ---- */

/* Overview: with nobody in, coming or at checkout, "The office now" is one line, not three empty boxes
   140px tall; on a laptop that is the difference between two tasks on screen and five. It opens by itself
   the moment somebody is due or arrives (office-now.js adds on-quiet). */
.on-wrap.on-quiet > .on-map{display:none}
.on-wrap.on-quiet > .on-head{margin-bottom:0}

/* One page shape: Insurance and Insurers opened with a big title and a paragraph where every other page
   opens with the ask bar and tabs. The paragraph is behind the (i) now (askbar.js); the title stays for
   screen readers; the tab row says where you are. All three wide pages line up with the rest. */
.iv-head > div > h1, .insd-head > h1{position:absolute !important;width:1px;height:1px;margin:0 !important;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.iv > .iv-head{display:none}
.insd-head{margin:0;padding:0;min-height:0}
/* Settings: the ask bar and the tabs sat in the second column, 236px further in than on every other page. */
@media (min-width:1100px){ main.page:has(> .set-nav) > :is(.pd-askrow, .pd-section-tabs){grid-column:1 / -1} }
main.page.insd, main.page.guide, main.page.trends{max-width:100rem}
@media (max-width:759.98px){
  /* Phone: the four "what a verification is" steps filled the whole first screen. Their titles stay, two
     by two; the sentences are one tap away behind the (i). */
  .iv .iv-what{grid-template-columns:1fr 1fr;gap:.375rem}
  .iv .iv-step{padding:.5rem .5rem .5rem 2.5rem;min-height:44px;display:flex;align-items:center}
  .iv .iv-step > span{display:none}
  .iv .iv-step > i{left:.5rem;top:50%;transform:translateY(-50%)}
  .iv .iv-step::after{display:none}
  /* Patient intake: the same three counts showed three times. The tiles stay; they already filter. */
  .strip-nums, .strip-chips{display:none !important}
  /* The page's main button floated over the list and hid "Mark confirmed", "More" and amounts as rows
     went by. It is now a full-width bar sitting on the tab bar, with the page's own colour behind it, so
     rows pass under a solid edge and nothing peeks out beside it. */
  [data-main-action]:not([hidden]):not(:disabled){left:.75rem;right:.75rem;bottom:calc(64px + env(safe-area-inset-bottom,0px) + .5rem);justify-content:center;border-radius:14px;
    box-shadow:0 0 0 100vmax var(--paper) !important;clip-path:inset(-.5rem -100vmax -.875rem -100vmax)}
  .page:has([data-main-action]){padding-bottom:8rem}
}

/* A mouse in an unsteady hand: chips, small buttons, pickers and the Ask button were 34 to 37px tall on a
   desk. 40 is the floor there now (a phone already gets 44). */
@media (min-width:900px){
  .btn, .btn.small, select, .seg button, .chip, .ask button[type="submit"], .ask .ask-go{min-height:40px}
}

/* Digital ads: the setup steps name server settings; the front desk gets one plain sentence instead. */
html:not(.pd-tech) .connect-tech{display:none}
html.pd-tech .connect-plain{display:none}

/* Insurance ends at the window like the list pages do (it gained a tab row). */
@media (min-width:1000px) and (min-height:600px){
  main.page > .iv{height:calc(100vh - 10.75rem)}
}

/* Year-end: the empty "To call" pile carries the button that fills it. */
.ye-start{display:grid;justify-items:center;gap:.5rem;padding:2rem 1rem;text-align:center}
.ye-start > b{font-size:1.25rem;color:var(--ink)}
.ye-start-btn{min-height:52px;padding-inline:1.75rem;font-size:1.125rem;margin-top:.5rem}

/* Claims: "To send" has no list behind it on this release; it reads as coming, not as a dead button. */
.card[data-view="send"]:disabled{opacity:.6;cursor:default}
.card[data-view="send"] .soon{font-size:max(15px,.8rem);font-weight:600;letter-spacing:.04em;text-transform:uppercase;border:1px dashed var(--line-strong);border-radius:999px;padding:0 .4rem;margin-left:.25rem;color:var(--muted)}

/* The Overview keeps the office in one sentence (12 Nov 2026): the map itself is the Floor tab beside it. */
main.home .on-wrap > .on-map{display:none}
main.home > .pd-section-tabs{order:-99;position:static !important;margin-bottom:.25rem}
/* On a wide screen the office sentence shares the row with the Overview and Floor tabs, so it costs no height. */
@media (min-width:1100px){
  main.home > .pd-section-tabs{grid-row:1}
  main.home > #office-now{grid-row:1;grid-column:1 / -1;justify-self:end;align-self:center;z-index:1;max-width:62%}
  main.home > #office-now .on-wrap{border:0;background:none;padding:0;margin:0}
  main.home > #office-now .on-head{margin:0;flex-wrap:nowrap;white-space:nowrap}
  main.home > #office-now .on-say{overflow:hidden;text-overflow:ellipsis}
}
@media (min-width:1100px){
  main.home > #office-now{overflow:hidden;min-width:0}
  main.home > #office-now .on-head{overflow:hidden;min-width:0}
  main.home > #office-now .on-head a{display:none}
  main.home > #office-now .on-say{min-width:0;flex:0 1 auto}
}
@media (min-width:1100px){ main.home > #office-now{z-index:40;position:relative;max-width:70%} main.home > .pd-section-tabs{z-index:auto} }

/* DESIGN-RULES.md, rules 1 to 3 (12 Nov 2026): the ask bar is the first row on every page, full width, with the
   same gap under it before the page's own title row. */
html.pd-sidebar .page > .ask,html.pd-sidebar .page > .pd-askrow{margin-bottom:12px}

/* ---- the account button, 13 Nov 2026 (theme.js makeAccount) ----
   Initials, name and role at the foot of the sidebar; it opens a small menu
   upward with Admin settings (owners and managers) and Sign out. */
.side-foot.has-acct .who,.side-foot.has-acct > a[href="/auth/logout"]{display:none}
.side-acct{position:relative;flex:1 1 auto;min-width:0}
.side-acct-btn{display:flex;align-items:center;gap:.6rem;width:100%;min-height:44px;padding:.35rem .45rem;border:1px solid transparent;border-radius:12px;background:transparent;color:var(--ink);font:inherit;text-align:left;cursor:pointer}
.side-acct-btn:hover,.side-acct-btn[aria-expanded="true"],.side-acct-btn[aria-current="page"]{background:var(--paper);border-color:var(--line)}
.side-acct-av{flex:none;display:grid;place-items:center;width:34px;height:34px;border-radius:50%;background:var(--accent,#2563eb);color:#fff;font-weight:700;font-size:max(15px,.9rem);letter-spacing:.02em}
.side-acct-txt{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;line-height:1.25}
.side-acct-txt b,.side-acct-txt small{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.side-acct-txt b{font-weight:650;font-size:max(15px,.9rem)}
.side-acct-txt small{color:var(--muted);font-size:max(15px,.78rem)}
.side-acct-gear svg,.side-acct-item svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.side-acct-gear{flex:none;display:grid;place-items:center;color:var(--muted)}
.side-acct-menu{position:absolute;left:0;right:0;bottom:calc(100% + 8px);z-index:60;min-width:240px;padding:.4rem;background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:0 14px 40px rgba(0,0,0,.22)}
.side-acct-menu[hidden]{display:none}
.side-acct-id{display:flex;flex-direction:column;padding:.55rem .65rem .65rem;border-bottom:1px solid var(--line);margin-bottom:.3rem;line-height:1.3}
.side-acct-id b{font-weight:650}.side-acct-id small{color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:max(15px,.8rem)}
.side-acct-item{display:flex;align-items:center;gap:.65rem;padding:.6rem .65rem;border-radius:10px;color:var(--ink);text-decoration:none}
.side-acct-item[hidden]{display:none}
.side-acct-item:hover,.side-acct-item:focus-visible{background:var(--paper);outline:none}
.side-acct-item span{display:flex;flex-direction:column;line-height:1.3}
.side-acct-item small{color:var(--muted);font-size:max(15px,.78rem)}
header.top .side-drawer-foot.has-acct{padding:.6rem .1rem 0}
@media (max-width:899px){.side-foot .side-acct{display:none}}
/* The phone drawer ran down behind the tab bar (58px, z-index 50 over the
   drawer's 45), so its foot, Sign out and now the account button, could never
   be scrolled into view. Leave room for the bar (13 Nov 2026). */
@media (max-width:899px){
  :is(body.has-sidebar, html.pd-sidebar body).has-tabbar .nav{padding-bottom:calc(70px + env(safe-area-inset-bottom,0px))}
}
/* v201: the practice's mark switches between the office view and the treatment view */
.pd-views{position:fixed;z-index:200;width:260px;background:var(--surface);border:1px solid var(--line-strong);border-radius:14px;box-shadow:0 18px 50px rgba(0,0,0,.35);padding:6px;display:flex;flex-direction:column;gap:2px}
.pd-view{display:flex;flex-direction:column;padding:8px 10px;border-radius:10px;text-decoration:none;color:var(--ink)}
.pd-view b{font-size:max(15px,1rem)}
.pd-view small{font-size:max(15px,.875rem);color:var(--ink-2)}
.pd-view:hover{background:var(--surface-3)}
.pd-view.on{box-shadow:inset 3px 0 0 var(--ink)}
