/* Components — The Dentist Is In
   Requires tokens.css. Class names map 1:1 to ViewComponents. */
*{box-sizing:border-box}
body{margin:0;font-family:var(--font);font-size:var(--text-body);color:var(--ink);
     background:var(--surface-sunken);-webkit-font-smoothing:antialiased;line-height:1.5}
h1,h2,h3,h4{margin:0;font-weight:650;letter-spacing:-.01em}
p{margin:0 0 var(--s3)}
.num,td.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}

/* ============================================================
   COMPONENT · Icon — 16px stroke, inherits currentColor
   ============================================================ */
.icon{width:16px;height:16px;flex:0 0 16px;stroke:currentColor;fill:none;
      stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.icon--lg{width:20px;height:20px;flex-basis:20px}
.icon--xl{width:28px;height:28px;flex-basis:28px;stroke-width:1.5}

/* ============================================================
   COMPONENT · StatusPill — dot + label. Colour from a central map.
   NEVER accepts a colour argument.
   ============================================================ */
.pill{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 10px;
      border-radius:var(--radius-pill);font-size:var(--text-caption);font-weight:600;
      white-space:nowrap;border:1px solid transparent}
.pill::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex:0 0 6px}
.pill--danger {background:var(--danger-subtle); color:var(--danger); border-color:var(--danger-border)}
.pill--success{background:var(--success-subtle);color:var(--success);border-color:var(--success-border)}
.pill--warning{background:var(--warning-subtle);color:var(--warning);border-color:var(--warning-border)}
.pill--neutral{background:var(--neutral-subtle);color:var(--neutral);border-color:var(--neutral-border)}
.pill--accent {background:var(--accent-subtle); color:var(--accent); border-color:var(--accent-border)}
.pill--bare::before{display:none}

/* ============================================================
   COMPONENT · Stepper — the lab case lifecycle, made visible.
   A case moving through 5 stages is inherently visual; a text
   label wastes that. This is the product's signature element.
   ============================================================ */
.stepper{display:flex;align-items:center;gap:0}
.stepper__node{display:flex;flex-direction:column;align-items:center;gap:6px;position:relative}
.stepper__dot{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;
              background:var(--surface);border:2px solid var(--rule-strong);color:var(--ink-muted)}
.stepper__dot .icon{width:11px;height:11px;flex-basis:11px;stroke-width:2.5}
.stepper__label{font-size:var(--text-micro);color:var(--ink-muted);white-space:nowrap}
.stepper__bar{height:2px;width:44px;background:var(--rule-strong);margin:0 2px;margin-bottom:20px}
.stepper__node.is-done .stepper__dot{background:var(--success);border-color:var(--success);color:#fff}
.stepper__node.is-done .stepper__label{color:var(--ink-secondary)}
.stepper__bar.is-done{background:var(--success)}
.stepper__node.is-current .stepper__dot{background:var(--accent);border-color:var(--accent);color:#fff;
     box-shadow:0 0 0 4px var(--accent-subtle)}
.stepper__node.is-current .stepper__label{color:var(--accent);font-weight:600}
.stepper__node.is-late .stepper__dot{background:var(--danger);border-color:var(--danger);color:#fff;
     box-shadow:0 0 0 4px var(--danger-subtle)}
.stepper__node.is-late .stepper__label{color:var(--danger);font-weight:600}

/* Compact — for table rows. Five dots, no labels. */
.stepper--mini{gap:3px}
.stepper--mini .stepper__dot{width:9px;height:9px;border-width:1.5px}
.stepper--mini .stepper__dot .icon{display:none}
.stepper--mini .stepper__bar{width:10px;height:1.5px;margin-bottom:0}
.stepper--mini .stepper__label{display:none}
.stepper--mini .stepper__node{gap:0}

/* ============================================================
   COMPONENT · Avatar — patient initials. Humanises dense tables.
   ============================================================ */
.avatar{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
        background:var(--accent-subtle);color:var(--accent);font-size:var(--text-micro);
        font-weight:700;letter-spacing:.02em;flex:0 0 28px}
.avatar--lg{width:36px;height:36px;flex-basis:36px;font-size:var(--text-dense)}
.avatar--muted{background:var(--neutral-subtle);color:var(--neutral)}
.who{display:flex;align-items:center;gap:10px}
.who__name{font-weight:550;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.who__sub{font-size:var(--text-caption);color:var(--ink-muted)}

/* ============================================================
   COMPONENT · Button
   ============================================================ */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:38px;
     padding:0 14px;border-radius:var(--radius-sm);font-family:inherit;font-size:var(--text-body);
     font-weight:550;border:1px solid transparent;cursor:pointer;white-space:nowrap;
     text-decoration:none;transition:background .12s,border-color .12s,box-shadow .12s}
.btn--primary{background:var(--accent);color:#fff;box-shadow:var(--shadow-sm)}
.btn--primary:hover{background:var(--accent-hover)}
.btn--secondary{background:var(--surface);color:var(--ink);border-color:var(--rule-strong);box-shadow:var(--shadow-sm)}
.btn--secondary:hover{background:var(--surface-hover)}
.btn--destructive{background:var(--surface);color:var(--danger);border-color:var(--danger-border)}
.btn--destructive:hover{background:var(--danger-subtle)}
.btn--ghost{background:transparent;color:var(--ink-secondary)}
.btn--ghost:hover{background:var(--surface-hover);color:var(--ink)}
.btn--chase{background:var(--danger);color:#fff;box-shadow:var(--shadow-sm)}
.btn--chase:hover{background:#A81E1E}
.btn--sm{height:30px;padding:0 10px;font-size:var(--text-dense);gap:5px}
.btn--sm .icon{width:14px;height:14px;flex-basis:14px}
.btn--lab{height:var(--tap-min)}
.btn--clinical{height:var(--tap-clinical);font-size:var(--text-large)}
.btn:disabled{opacity:.4;cursor:not-allowed;box-shadow:none}

/* ============================================================
   COMPONENT · Card
   ============================================================ */
.card{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
      box-shadow:var(--shadow-sm)}
.card__header{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
              padding:var(--s3) var(--s4);border-bottom:1px solid var(--rule);
              font-size:var(--text-section);font-weight:650}
.card__body{padding:var(--s4)}
.card__body--flush{padding:0}

/* ============================================================
   COMPONENT · Stat — headline numbers. Hierarchy, not decoration.
   ============================================================ */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--s3)}

/* Marketing Library — a grid of PhotoPairComponent cards (Phase 4 slice 5) */
.marketing-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(420px,1fr));gap:var(--s4)}
.stat{background:var(--surface);border:1px solid var(--rule);border-left:3px solid var(--rule-strong);
      border-radius:var(--radius);padding:var(--s3) var(--s4);box-shadow:var(--shadow-sm)}
.stat--danger{border-left-color:var(--danger);background:linear-gradient(90deg,var(--danger-subtle) 0%,var(--surface) 60%)}
.stat--warning{border-left-color:var(--warning);background:linear-gradient(90deg,var(--warning-subtle) 0%,var(--surface) 60%)}
.stat--success{border-left-color:var(--success)}
.stat__val{font-size:26px;font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums}
.stat--danger .stat__val{color:var(--danger)}
.stat--warning .stat__val{color:var(--warning)}
.stat__label{display:flex;align-items:center;gap:6px;margin-top:var(--s1);
             font-size:var(--text-caption);color:var(--ink-secondary);font-weight:500}

/* ============================================================
   COMPONENT · FormField
   ============================================================ */
.field{margin-bottom:var(--s4)}
.field__label{display:block;margin-bottom:6px;font-size:var(--text-caption);
              font-weight:600;color:var(--ink-secondary);letter-spacing:.01em}
.field__input,.field__select,.field__textarea{
  width:100%;height:38px;padding:0 var(--s3);font-family:inherit;font-size:var(--text-body);
  color:var(--ink);background:var(--surface);border:1px solid var(--rule-strong);
  border-radius:var(--radius-sm);outline:none;transition:border-color .12s,box-shadow .12s}
.field__textarea{height:auto;padding:10px var(--s3);resize:vertical;line-height:1.55}
.field__input:focus,.field__select:focus,.field__textarea:focus{
  border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-subtle)}
.field__hint{display:flex;gap:5px;margin-top:6px;font-size:var(--text-caption);color:var(--ink-muted)}
.field__error{display:flex;gap:5px;margin-top:6px;font-size:var(--text-caption);color:var(--danger)}
.field--invalid .field__input{border-color:var(--danger)}
.field--clinical .field__input{height:var(--tap-clinical);font-size:var(--text-large)}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--s3)}
.inputgroup{position:relative;display:flex;align-items:center}
.inputgroup .icon{position:absolute;left:11px;color:var(--ink-muted);pointer-events:none}
.inputgroup .field__input{padding-left:34px}

/* ============================================================
   COMPONENT · Table — rows carry their own primary action
   ============================================================ */
.table{width:100%;border-collapse:collapse;font-size:var(--text-dense)}
.table thead th{padding:10px var(--s3);text-align:left;background:var(--surface-sunken);
                font-size:var(--text-micro);font-weight:700;color:var(--ink-secondary);
                text-transform:uppercase;letter-spacing:.05em;
                border-bottom:1px solid var(--rule);white-space:nowrap}
.table tbody td{padding:0 var(--s3);height:52px;border-bottom:1px solid var(--rule);vertical-align:middle}
.table tbody tr{transition:background .1s}
.table tbody tr:hover{background:var(--surface-hover)}
.table tbody tr.is-overdue{box-shadow:inset 3px 0 0 var(--danger)}
.table tbody tr.is-overdue td:first-child{padding-left:15px}
.table .right{text-align:right}
.table .actions{display:flex;gap:6px;justify-content:flex-end;opacity:.35;transition:opacity .12s}
.table tbody tr:hover .actions{opacity:1}
.table tbody tr.is-overdue .actions{opacity:1}
.late{color:var(--danger);font-weight:650}
.due-soon{color:var(--warning);font-weight:600}

/* ============================================================
   COMPONENT · EmptyState — teaches, never a bare panel
   ============================================================ */
.empty{padding:var(--s6) var(--s4);text-align:center}
.empty__icon{display:grid;place-items:center;width:44px;height:44px;margin:0 auto var(--s3);
             border-radius:50%;background:var(--surface-sunken);color:var(--ink-muted)}
.empty__title{font-weight:650;margin-bottom:var(--s1)}
.empty__msg{margin-bottom:var(--s4);color:var(--ink-secondary);font-size:var(--text-dense);
            max-width:36ch;margin-left:auto;margin-right:auto}

/* ============================================================
   COMPONENT · UndoToast — replaces confirmation dialogs
   ============================================================ */
.toast{display:inline-flex;align-items:center;gap:var(--s4);padding:12px var(--s4);
       background:var(--ink);color:#fff;border-radius:var(--radius);font-size:var(--text-dense);
       box-shadow:var(--shadow-lg);position:relative;overflow:hidden}
.toast__action{color:#93C5FD;font-weight:650;background:none;border:0;cursor:pointer;
               font-family:inherit;font-size:var(--text-dense)}
.toast__progress{position:absolute;left:0;bottom:0;height:2px;background:#93C5FD;width:60%}

/* ============================================================
   COMPONENT · Chips / Banner
   ============================================================ */
.chips{display:flex;gap:6px}
.chip{height:32px;padding:0 12px;display:inline-flex;align-items:center;gap:6px;
      background:var(--surface);border:1px solid var(--rule-strong);border-radius:var(--radius-pill);
      font-size:var(--text-dense);font-weight:500;color:var(--ink-secondary);cursor:pointer;
      text-decoration:none}
.chip:hover{background:var(--surface-hover)}
.chip[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
.chip__count{font-size:var(--text-micro);opacity:.7;font-variant-numeric:tabular-nums}

.banner{display:flex;gap:10px;padding:12px var(--s3);border-radius:var(--radius-sm);
        font-size:var(--text-dense);line-height:1.55;align-items:flex-start}
.banner .icon{margin-top:1px}
.banner--warning{background:var(--warning-subtle);color:#8A4A08;border:1px solid var(--warning-border)}
.banner--danger{background:var(--danger-subtle);color:#8F1D1D;border:1px solid var(--danger-border)}
.banner--accent{background:var(--accent-subtle);color:#1B3FA8;border:1px solid var(--accent-border)}

/* ============================================================
   COMPONENT · ToothPicker (FDI)
   ============================================================ */
.teeth{display:inline-block;padding:var(--s3);background:var(--surface-raised);
       border:1px solid var(--rule);border-radius:var(--radius)}
.teeth__arch{display:flex;gap:3px;justify-content:center}
.teeth__arch+.teeth__arch{margin-top:6px}
.teeth__gap{width:14px}
.tooth{width:30px;height:36px;display:grid;place-items:center;background:var(--surface);
       border:1px solid var(--rule-strong);border-radius:5px;font-size:var(--text-micro);
       font-variant-numeric:tabular-nums;color:var(--ink-secondary);cursor:pointer;
       font-family:inherit;transition:all .1s;text-decoration:none}
.tooth:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}
.tooth[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#fff;
       font-weight:700;box-shadow:var(--shadow-sm)}
.teeth__legend{margin-top:10px;font-size:var(--text-micro);color:var(--ink-muted);text-align:center}

/* Clinical tooth chart — states, not selection (Phase 5 slice 2). Same .teeth/.tooth
   markup as the picker above, scoped larger and state-coloured under .chart. */
.chart{padding:var(--s5) var(--s4);background:var(--surface);border:1px solid var(--rule);
       border-radius:var(--radius);display:inline-block}
.chart .teeth__arch{gap:5px}
.chart .teeth__gap{width:22px}
.chart .tooth{width:44px;height:52px;font-size:var(--text-caption);font-weight:600;
              border-width:2px;position:relative}
.tooth--history{background:var(--neutral-subtle);border-color:var(--neutral);color:var(--ink-secondary)}
.tooth--active{background:var(--warning-subtle);border-color:var(--warning);color:var(--warning)}
.tooth--flagged{background:var(--danger-subtle);border-color:var(--danger);color:var(--danger)}
.tooth--flagged::after{content:"";position:absolute;top:3px;right:3px;width:6px;height:6px;
                       border-radius:50%;background:var(--danger)}
.chart__legend{display:flex;gap:var(--s4);justify-content:center;margin-top:var(--s4);flex-wrap:wrap}
.lg{display:flex;align-items:center;gap:7px;font-size:var(--text-caption);color:var(--ink-secondary)}
.lg__sw{width:16px;height:16px;border-radius:4px;border:2px solid}
.chart__arch-label{text-align:center;font-size:var(--text-micro);color:var(--ink-muted);
                   letter-spacing:.06em;text-transform:uppercase;margin:var(--s2) 0}

/* Tooth history drawer (Phase 5 slice 2) */
.drawer{width:420px;max-width:100%;background:var(--surface);border-left:1px solid var(--rule);
        box-shadow:-4px 0 16px rgba(11,18,32,.06);display:flex;flex-direction:column}
.drawer__head{display:flex;align-items:center;justify-content:space-between;padding:var(--s4);
              border-bottom:1px solid var(--rule)}
.drawer__title{font-size:var(--text-title);font-weight:700}
.drawer__sub{font-size:var(--text-caption);color:var(--ink-muted)}
.drawer__body{flex:1;overflow:auto}
.drawer__foot{padding:var(--s3) var(--s4);border-top:1px solid var(--rule);background:var(--surface-sunken)}
.acc{border-bottom:1px solid var(--rule)}
.acc__head{display:flex;align-items:center;gap:10px;padding:var(--s3) var(--s4);cursor:pointer;
           list-style:none}
.acc__head::-webkit-details-marker{display:none}
.acc__head:hover{background:var(--surface-hover)}
.acc__date{font-size:var(--text-caption);color:var(--ink-muted);font-variant-numeric:tabular-nums;
           width:76px;flex:0 0 76px}
.acc__sum{flex:1;font-size:var(--text-dense);font-weight:550}
.acc__body{padding:0 var(--s4) var(--s4) 102px;font-size:var(--text-dense)}
.acc__row{display:grid;grid-template-columns:84px 1fr;gap:var(--s3);padding:5px 0}
.acc__k{color:var(--ink-muted);font-size:var(--text-caption)}
.acc__thumbs{display:flex;gap:6px;margin-top:8px}
.acc__thumb{width:54px;height:54px;border-radius:var(--radius-sm);overflow:hidden;
            background:linear-gradient(135deg,#EDEFF3,#DDE2EA);border:1px solid var(--rule);display:block}
.acc__by{margin-top:10px;font-size:var(--text-micro);color:var(--ink-muted)}

/* Voice capture — one job, everything else hidden (Phase 5 slice 3). Ported verbatim from
   docs/dental-os-handoff/design/dental-os-screens-phase5.html's own .rec block. */
.rec{display:flex;flex-direction:column;align-items:center;justify-content:center;
     padding:var(--s7) var(--s4);gap:var(--s4);min-height:440px}
.rec__ctx{font-size:var(--text-body);color:var(--ink-secondary);text-align:center}
.rec__ctx b{color:var(--ink)}
.rec__btn{width:132px;height:132px;border-radius:50%;border:0;cursor:pointer;
          background:var(--danger);color:#fff;display:grid;place-items:center;
          box-shadow:0 0 0 10px var(--danger-subtle)}
.rec__btn svg{width:48px;height:48px;stroke:currentColor;fill:none;stroke-width:1.75}
.rec__btn[disabled]{opacity:.5;cursor:not-allowed}
.rec__btn--active{animation:rec-pulse 1.6s ease-in-out infinite}
@keyframes rec-pulse{0%,100%{box-shadow:0 0 0 10px var(--danger-subtle)}50%{box-shadow:0 0 0 16px var(--danger-subtle)}}
.rec__time{font-size:30px;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:.02em}
.rec__wave{display:flex;align-items:center;gap:3px;height:38px}
.rec__wave i{display:block;width:4px;border-radius:2px;background:var(--danger);opacity:.75}
.rec__hint{font-size:var(--text-body);color:var(--ink-muted);text-align:center;max-width:34ch}
.rec__actions{display:flex;gap:var(--s3);width:100%;max-width:420px}
.rec__actions .btn{flex:1}
/* [hidden] and .rec__actions{display:flex} are equal-specificity selectors, and this
   stylesheet loads after the UA stylesheet — without this, the plain HTML `hidden`
   attribute this component relies on to hide Discard/Done before recording starts is
   silently overridden and the actions render visible from page load. Found live, not by
   spec (view specs render static markup and never assert computed display). */
.rec__actions[hidden]{display:none}

/* Tooth-select-for-capture mini chart (Phase 5 slice 3, ToothChartComponent :select mode) —
   same .chart/.teeth/.tooth classes as the :chart-mode history chart, just smaller and
   embedded inline on the visit page rather than the full patient profile. */
.chart--compact{padding:var(--s3)}
.chart--compact .tooth{width:34px;height:40px;font-size:var(--text-caption)}

/* AI draft review — split, transcript left, draft right (Phase 5 slice 4). Ported verbatim
   from docs/dental-os-handoff/design/dental-os-screens-phase5.html's own .review block. */
.review{display:grid;grid-template-columns:.85fr 1.15fr;gap:0;
        border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;background:var(--surface)}
.review__left{background:var(--surface-sunken);border-right:1px solid var(--rule);padding:var(--s4)}
.review__right{padding:var(--s4)}
.review__label{font-size:var(--text-micro);text-transform:uppercase;letter-spacing:.06em;
               font-weight:700;color:var(--ink-muted);margin-bottom:var(--s3)}
.transcript{font-size:var(--text-large);line-height:1.7;color:var(--ink);font-style:italic}
.transcript__meta{margin-top:var(--s4);padding-top:var(--s3);border-top:1px solid var(--rule);
                  font-size:var(--text-caption);color:var(--ink-muted)}
.draft-note{display:flex;gap:10px;background:var(--warning-subtle);border:1px solid var(--warning-border);
            border-radius:var(--radius-sm);padding:10px var(--s3);font-size:var(--text-dense);
            color:#8A4A08;margin-bottom:var(--s4)}
@media(max-width:900px){.review{grid-template-columns:1fr}}

/* ============================================================
   COMPONENT · Modal
   ============================================================ */
.modal{width:580px;max-width:100%;background:var(--surface);border:1px solid var(--rule);
       border-radius:var(--radius-lg);box-shadow:var(--shadow-lg)}
.modal--narrow{width:460px}
.modal__header{display:flex;align-items:center;gap:10px;padding:var(--s4);
               border-bottom:1px solid var(--rule);font-size:var(--text-section);font-weight:650}
.modal__body{padding:var(--s4)}
.modal__footer{display:flex;justify-content:flex-end;gap:var(--s2);padding:var(--s3) var(--s4);
               border-top:1px solid var(--rule);background:var(--surface-sunken);
               border-radius:0 0 var(--radius-lg) var(--radius-lg)}

/* ============================================================
   APP SHELL — clinic
   ============================================================ */
.app{display:grid;grid-template-columns:224px 1fr;min-height:560px;border:1px solid var(--rule);
     border-radius:var(--radius-lg);overflow:hidden;background:var(--surface);box-shadow:var(--shadow)}
.app--solo{grid-template-columns:1fr}
.sidebar{background:var(--ink);padding:var(--s4) 0;color:#fff}
.sidebar__brand{display:flex;gap:10px;align-items:center;padding:0 var(--s4) var(--s4);margin-bottom:var(--s2);
                border-bottom:1px solid rgba(255,255,255,.09)}
.sidebar__logo{width:32px;height:32px;border-radius:8px;background:var(--accent);display:grid;
               place-items:center;font-weight:700;font-size:var(--text-dense);flex:0 0 32px}
.sidebar__name{font-size:var(--text-dense);font-weight:650;line-height:1.3}
.sidebar__name small{display:block;font-size:var(--text-micro);font-weight:400;color:rgba(255,255,255,.5)}
/* Also applied to a <button> (the sign-out item, inside button_to's form) — the reset
   properties below are no-ops on the existing <a> items (links have no background/border by
   default) but stop a raw <button> from carrying default browser chrome that doesn't match. */
.sidebar__item{display:flex;align-items:center;gap:10px;padding:9px var(--s4);margin:1px var(--s2);
               border-radius:var(--radius-sm);font-size:var(--text-dense);font-weight:500;
               color:rgba(255,255,255,.68);text-decoration:none;
               background:none;border:0;width:calc(100% - 2 * var(--s2));text-align:left;
               font-family:inherit;cursor:pointer}
.sidebar__item:hover{background:rgba(255,255,255,.07);color:#fff}
.sidebar__item.is-active{background:var(--accent);color:#fff}
.sidebar__badge{margin-left:auto;min-width:18px;height:18px;padding:0 5px;border-radius:var(--radius-pill);
                background:var(--danger);color:#fff;font-size:10px;font-weight:700;display:grid;place-items:center}
/* Not in the original package — needed once real nav existed to add the "Coming soon" state
   CLAUDE.md's UI conventions require for not-yet-built modules. Same modifier-class shape as
   the rest of this file (kcard--overdue, pill--bare, stepper--mini). */
.sidebar__item--disabled{opacity:.4;cursor:default;pointer-events:none}
.topbar{display:flex;align-items:center;justify-content:space-between;gap:var(--s4);height:60px;
        padding:0 var(--s4);border-bottom:1px solid var(--rule);background:var(--surface)}
.topbar__title{font-size:var(--text-title);font-weight:700}
.content{padding:var(--s4);background:var(--surface-sunken);min-height:460px}

/* Lab shell — SUB-BRAND. No clinic navigation anywhere. */
.labshell{border:1px solid var(--rule);border-radius:var(--radius-lg);overflow:hidden;
          background:var(--surface);box-shadow:var(--shadow)}
.labtop{display:flex;align-items:center;justify-content:space-between;gap:var(--s4);height:62px;
        padding:0 var(--s4);border-bottom:1px solid var(--rule)}
.labtop__brand{display:flex;align-items:center;gap:10px;font-size:var(--text-section);font-weight:650}
.labtop__logo{width:30px;height:30px;border-radius:7px;background:var(--ink);color:#fff;
              display:grid;place-items:center;font-size:var(--text-caption);font-weight:700}
.labtop__brand span{color:var(--ink-muted);font-weight:400;font-size:var(--text-dense)}

/* ============================================================
   KANBAN — tap to advance, never drag-only
   ============================================================ */
.kanban{display:flex;gap:var(--s3);padding:var(--s4);background:var(--surface-sunken);overflow-x:auto}
.kcol{flex:0 0 252px;background:var(--surface-raised);border:1px solid var(--rule);border-radius:var(--radius)}
.kcol__head{display:flex;align-items:center;gap:7px;padding:10px var(--s3);
            border-bottom:1px solid var(--rule);font-size:var(--text-dense);font-weight:650}
.kcol__dot{width:7px;height:7px;border-radius:50%;flex:0 0 7px}
.kcol__count{margin-left:auto;font-size:var(--text-micro);color:var(--ink-muted);
             font-variant-numeric:tabular-nums;background:var(--surface-sunken);
             padding:1px 7px;border-radius:var(--radius-pill)}
.kcol__body{padding:var(--s2);display:flex;flex-direction:column;gap:var(--s2);min-height:130px}
.kcard{padding:var(--s3);border:1px solid var(--rule);border-radius:var(--radius-sm);
       background:var(--surface);box-shadow:var(--shadow-sm);cursor:grab}
.kcard:hover{border-color:var(--rule-strong);box-shadow:var(--shadow)}
.kcard--overdue{border-left:3px solid var(--danger)}
.kcard__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s2)}
.kcard__type{font-size:var(--text-body);font-weight:650;line-height:1.35}
.kcard__meta{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:6px;
             font-size:var(--text-micro);color:var(--ink-muted);font-variant-numeric:tabular-nums}
.kcard__clinic{display:flex;align-items:center;gap:7px;margin-top:10px;padding-top:10px;
               border-top:1px solid var(--rule);font-size:var(--text-caption);color:var(--ink-secondary)}
.kcard__advance{width:100%;margin-top:10px}
.newflag{display:inline-flex;align-items:center;gap:4px;font-size:10px;font-weight:700;
         color:var(--accent);text-transform:uppercase;letter-spacing:.05em}

/* ============================================================
   Week calendar (Phase 2 Slice 2) — CalendarWeek
   ============================================================ */
.cal-week{display:flex;background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden}
.cal-week__hours{flex:0 0 52px;border-right:1px solid var(--rule)}
.cal-week__hour{height:56px;font-size:var(--text-micro);color:var(--ink-muted);text-align:right;
                padding-right:6px;transform:translateY(-6px)}
.cal-week__day{flex:1;border-right:1px solid var(--rule);position:relative}
.cal-week__day:last-child{border-right:none}
.cal-week__day.is-today{background:var(--accent-subtle)}
.cal-week__day-head{padding:var(--s2);text-align:center;border-bottom:1px solid var(--rule);
                     font-size:var(--text-caption);color:var(--ink-secondary);position:sticky;top:0;background:inherit}
.cal-week__day-head strong{display:block;font-size:var(--text-body);color:var(--ink)}
.cal-week__grid{position:relative}
.cal-week__now-line{position:absolute;left:0;right:0;height:2px;background:var(--danger);z-index:2}
.cal-week__now-line::before{content:"";position:absolute;left:-4px;top:-3px;width:8px;height:8px;
                             border-radius:50%;background:var(--danger)}
.cal-block{position:absolute;left:2px;right:2px;border-radius:var(--radius-sm);padding:4px 6px;
           font-size:var(--text-micro);overflow:hidden;border:1px solid;text-decoration:none;
           display:block;color:var(--ink)}
.cal-block strong{display:block;font-size:var(--text-caption);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal-block--accent{background:var(--accent-subtle);border-color:var(--accent-border)}
.cal-block--warning{background:var(--warning-subtle);border-color:var(--warning-border)}
.cal-block--success{background:var(--success-subtle);border-color:var(--success-border)}
.cal-block--danger{background:var(--danger-subtle);border-color:var(--danger-border)}
.cal-block--neutral{background:var(--neutral-subtle);border-color:var(--neutral-border)}
.cal-block--double{width:calc(50% - 3px)}
.cal-block--double + .cal-block--double{left:auto;right:2px}
.cal-block__flag{position:absolute;top:2px;right:2px;color:var(--warning)}

/* Book appointment (SlotPicker/SegmentedControl) */
.slots{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:var(--s2)}
.slot{height:40px;border:1px solid var(--rule);border-radius:var(--radius-sm);background:var(--surface);
      font-size:var(--text-dense);font-variant-numeric:tabular-nums;cursor:pointer}
.slot:hover{border-color:var(--accent)}
.slot:has(input:checked){background:var(--accent);border-color:var(--accent);color:#fff}
.slot--busy{color:var(--ink-muted);text-decoration:line-through;background:var(--surface-sunken)}
.slot--busy:has(input:checked){color:#fff;text-decoration:line-through}
.seg{display:inline-flex;border:1px solid var(--rule);border-radius:var(--radius-pill);padding:2px;gap:2px}
.seg__opt{padding:5px 14px;border-radius:var(--radius-pill);font-size:var(--text-caption);
          font-weight:600;color:var(--ink-secondary);cursor:pointer}
.seg__opt.is-active,.seg__opt:has(input:checked){background:var(--ink);color:#fff}

/* Patient picker — live-search dropdown (rebrand/QA fix #1), same shell as a native
   <select>'s popup would occupy: absolutely positioned, anchored to the wrapping field. */
.picker__results{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:20;
                  max-height:240px;overflow-y:auto;background:var(--surface);
                  border:1px solid var(--rule);border-radius:var(--radius-sm);
                  box-shadow:0 8px 24px rgba(0,0,0,.12)}
.picker__option{display:block;width:100%;text-align:left;padding:10px 12px;border:none;
                 background:none;font-size:var(--text-dense);color:var(--ink);cursor:pointer}
.picker__option:hover{background:var(--surface-hover)}
.picker__empty{padding:10px 12px;font-size:var(--text-dense);color:var(--ink-muted)}

/* DeliveryTicks */
.ticks{display:inline-flex;align-items:center;gap:5px;font-size:var(--text-micro);color:var(--ink-muted)}
.ticks__icon{display:inline-flex;position:relative;width:14px}
.ticks__icon .icon{width:14px;height:14px}
.ticks__icon--double .icon:last-child{position:absolute;left:5px}
.ticks--accent{color:var(--accent)}
.ticks--success{color:var(--success)}
.ticks--danger{color:var(--danger)}
.ticks--neutral{color:var(--ink-muted)}

/* PhotoPair — before/after, the forcing function (Phase 4 slice 2) */
.pair{display:grid;grid-template-columns:1fr 1fr;gap:var(--s4)}
.pslot{border-radius:var(--radius);overflow:hidden;border:1px solid var(--rule);background:var(--surface)}
.pslot__head{display:flex;align-items:center;justify-content:space-between;padding:10px var(--s3);
             border-bottom:1px solid var(--rule);font-size:var(--text-dense);font-weight:650}
.pslot__img{height:230px;display:grid;place-items:center;background:linear-gradient(135deg,#EDEFF3,#DDE2EA);
            color:var(--ink-muted);font-size:var(--text-caption)}
.pslot__meta{padding:9px var(--s3);font-size:var(--text-caption);color:var(--ink-muted);
             border-top:1px solid var(--rule)}
.pslot--empty{border:2px dashed var(--rule-strong);background:var(--surface-sunken)}
.pslot--empty .pslot__img{background:none;flex-direction:column;gap:var(--s3);cursor:pointer;
                          min-height:var(--tap-clinical)}
.pslot--empty:hover{border-color:var(--accent)}

/* Consent chip (Phase 4 slice 3) */
.consent{display:inline-flex;align-items:center;gap:6px;font-size:var(--text-caption);
         padding:4px 10px;border-radius:var(--radius-pill);font-weight:600}
.consent .icon{width:13px;height:13px;flex-basis:13px}
.consent--yes{background:var(--success-subtle);color:var(--success);border:1px solid var(--success-border)}
.consent--no{background:var(--neutral-subtle);color:var(--neutral);border:1px solid var(--neutral-border)}

/* BlockNotice — a hard gate, not a reminder (Phase 4 slice 2) */
.block{display:flex;gap:12px;align-items:flex-start;background:var(--danger-subtle);
       border:1px solid var(--danger-border);border-left:4px solid var(--danger);
       border-radius:var(--radius-sm);padding:var(--s3) var(--s4);color:#8F1D1D;font-size:var(--text-dense)}
.block strong{display:block;margin-bottom:2px}

/* Agenda (Today view) */
.agenda-row{display:flex;align-items:center;gap:var(--s3);padding:var(--s3);border-bottom:1px solid var(--rule)}
.agenda-row:last-child{border-bottom:none}
.agenda-row.is-now{box-shadow:inset 3px 0 0 var(--accent);background:var(--accent-subtle)}
.agenda-row.is-past{opacity:.5}
.agenda-row__time{flex:0 0 48px;font-size:var(--text-dense);font-weight:600;font-variant-numeric:tabular-nums}
.agenda-row__who{flex:1;min-width:0}
.agenda-row__meta{font-size:var(--text-caption);color:var(--ink-muted)}
.agenda-row__action{flex:0 0 auto}

/* AttentionList — actions stack below the icon+text row (mockup: "Chase lab" sits on its
   own line under the subtitle), not beside it — a narrow sidebar column has no room for
   icon+text+two buttons all in one row without crushing the text into single-word wraps. */
.att{padding:var(--s3);border-bottom:1px solid var(--rule)}
.att:last-child{border-bottom:none}
.att__top{display:flex;align-items:flex-start;gap:var(--s2)}
.att__icon{flex:0 0 auto;margin-top:2px}
.att--warning .att__icon{color:var(--warning)}
.att--danger .att__icon{color:var(--danger)}
.att__body{flex:1;min-width:0}
.att__title{font-size:var(--text-dense);font-weight:600}
.att__subtitle{font-size:var(--text-caption);color:var(--ink-muted)}
.att__actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;margin-left:26px}

/* Today view layout */
.today-grid{display:grid;grid-template-columns:2fr 1fr 1fr;gap:var(--s4);align-items:start}
/* Grid items default to min-width:auto, so a long patient name's min-content width was
   stretching the 2fr track itself rather than being clipped by .who__name's own ellipsis —
   the actual mechanism behind "agenda row layout breaking on long names" (rebrand/QA fix
   #3). min-width:0 here is what lets that ellipsis rule actually take effect. */
.today-grid > .card{min-width:0}
.today-col__head{display:flex;align-items:center;justify-content:space-between;padding:var(--s3);border-bottom:1px solid var(--rule)}
.today-col__head h2{font-size:var(--text-section);margin:0}
@media (max-width: 1024px){.today-grid{grid-template-columns:1fr}}

/* ---- COMPONENT · PrintDoc — A4, print-safe, no accent colour (dental-os-screens-phase3-4
   mockup, verbatim). ".doc" is a document, not an app screen — it has to survive a cheap
   inkjet and satisfy a CA, so no design-system colour tokens here, just black on white. */
.doc{width:794px;max-width:100%;background:#fff;border:1px solid var(--rule);
     padding:44px 48px;font-size:12px;color:#000;box-shadow:var(--shadow)}
.doc--narrow{width:700px}
.doc__head{display:flex;justify-content:space-between;align-items:flex-start;
           border-bottom:2px solid #000;padding-bottom:14px;margin-bottom:18px}
.doc__clinic{font-size:16px;font-weight:700;margin-bottom:3px}
.doc__meta{text-align:right;font-size:11px;line-height:1.7;font-variant-numeric:tabular-nums}
.doc__label{font-size:15px;font-weight:700;letter-spacing:.08em;margin-bottom:6px}
.doc table{width:100%;border-collapse:collapse;font-size:11px;margin:14px 0}
.doc th{border-bottom:1px solid #000;padding:6px 5px;text-align:left;font-size:10px;
        text-transform:uppercase;letter-spacing:.04em}
.doc td{border-bottom:1px solid #DDD;padding:7px 5px;vertical-align:top}
.doc .r{text-align:right;font-variant-numeric:tabular-nums}
.doc__totals{margin-left:auto;width:290px;font-size:11px}
.doc__totals div{display:flex;justify-content:space-between;padding:4px 0}
.doc__totals .sum{border-top:1.5px solid #000;margin-top:5px;padding-top:8px;font-weight:700;font-size:13px}
.doc__words{margin-top:10px;font-size:11px;font-style:italic}
.doc__foot{margin-top:34px;display:flex;justify-content:space-between;align-items:flex-end;
           font-size:10px;color:#444;line-height:1.6}
.doc__sig{border-top:1px solid #000;padding-top:5px;width:180px;text-align:center}

/* Print: only .doc survives — sidebar, topbar, flash, and anything marked .no-print
   disappear. Test with "Background graphics" unchecked in the browser print dialog (mockup's
   own handoff note) — most people never turn it on, so .doc can't rely on background colours
   to read correctly; it already doesn't use any. */
@media print{
  .sidebar,.topbar,.no-print,.toast{display:none!important}
  .content{padding:0;background:#fff}
  .print-frame{padding:0!important;background:#fff!important;border:none!important;box-shadow:none!important}
  .doc{box-shadow:none;border:none;width:auto}
  .app{display:block}
}

/* Setup checklist (Phase 6 slice 2) — dismissible, resumable, on Today. Ported verbatim from
   docs/dental-os-screens-phase6.html's own .setup/.step block. */
.setup{border:1px solid var(--accent-border);background:var(--accent-subtle);border-radius:var(--radius)}
.setup__head{display:flex;align-items:center;justify-content:space-between;padding:var(--s3) var(--s4);
             border-bottom:1px solid var(--accent-border)}
.setup__title{font-size:var(--text-section);font-weight:650;color:#1B3FA8}
.setup__prog{font-size:var(--text-caption);color:#1B3FA8;font-variant-numeric:tabular-nums}
.setup__body{background:var(--surface);border-radius:0 0 var(--radius) var(--radius)}
.step{display:flex;align-items:center;gap:12px;padding:12px var(--s4);border-bottom:1px solid var(--rule)}
.step:last-child{border-bottom:0}
.step__tick{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;flex:0 0 22px;
            border:2px solid var(--rule-strong);color:transparent}
.step.is-done .step__tick{background:var(--success);border-color:var(--success);color:#fff}
.step.is-next .step__tick{border-color:var(--accent)}
.step__label{flex:1;font-size:var(--text-dense);font-weight:550}
.step.is-done .step__label{color:var(--ink-muted);text-decoration:line-through}
.step__why{font-size:var(--text-caption);color:var(--ink-muted);font-weight:400;display:block;margin-top:1px;text-decoration:none}

/* WhatsApp connection card + Clinic settings rows (Phase 6 slice 3) — both ported verbatim
   from docs/dental-os-screens-phase6.html's own .conn/.setrow/.logodrop blocks. */
.conn{border:1px solid var(--rule);border-radius:var(--radius);background:var(--surface);overflow:hidden}
.conn__head{display:flex;align-items:center;gap:12px;padding:var(--s4);border-bottom:1px solid var(--rule)}
.conn__ico{width:40px;height:40px;border-radius:var(--radius);display:grid;place-items:center;flex:0 0 40px}
.conn__ico--on{background:var(--success-subtle);color:var(--success)}
.conn__ico--off{background:var(--neutral-subtle);color:var(--neutral)}
.conn__ico--warn{background:var(--warning-subtle);color:var(--warning)}
.conn__title{font-size:var(--text-section);font-weight:650}
.conn__sub{font-size:var(--text-caption);color:var(--ink-muted);margin-top:1px}
.conn__body{padding:var(--s4)}
.conn__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:var(--s3);
            padding:var(--s3) var(--s4);background:var(--surface-sunken);border-top:1px solid var(--rule)}
.conn__stat{font-size:var(--text-caption);color:var(--ink-muted)}
.conn__stat b{display:block;font-size:var(--text-large);font-weight:700;color:var(--ink);
              font-variant-numeric:tabular-nums;margin-bottom:1px}

.setrow{display:grid;grid-template-columns:200px 1fr;gap:var(--s4);padding:var(--s4);
        border-bottom:1px solid var(--rule);align-items:start}
.setrow:last-child{border-bottom:0}
.setrow__k{font-size:var(--text-dense);font-weight:600}
.setrow__hint{font-size:var(--text-caption);color:var(--ink-muted);margin-top:2px;font-weight:400}
.logodrop{display:flex;align-items:center;gap:var(--s3)}
.logodrop__prev{width:60px;height:60px;border-radius:var(--radius);border:1px dashed var(--rule-strong);
                display:grid;place-items:center;background:var(--surface-sunken);flex:0 0 60px;overflow:hidden}
.logodrop__prev img{width:100%;height:100%;object-fit:contain}
@media(max-width:800px){.setrow{grid-template-columns:1fr}}

/* Settings sub-nav (Phase 6 slice 3) — not in the mockup itself (Screens 22/23/24 were each
   shown as isolated component demos, only Screen 23 got the full app shell), but three real
   settings pages need something to move between them. Deliberately minimal: reuses .pill's
   own visual language rather than inventing a new tab component for one nav row. */
.subnav{display:flex;gap:8px;margin-bottom:var(--s4);border-bottom:1px solid var(--rule);padding-bottom:var(--s3)}
.subnav__item{display:inline-flex;align-items:center;height:30px;padding:0 14px;border-radius:var(--radius-pill);
              font-size:var(--text-dense);font-weight:600;color:var(--ink-secondary);text-decoration:none}
.subnav__item:hover{background:var(--neutral-subtle)}
.subnav__item.is-active{background:var(--accent-subtle);color:var(--accent)}
.subnav__item.is-disabled{color:var(--ink-muted);cursor:default}
.subnav__item.is-disabled:hover{background:transparent}

/* Plan cards (Phase 6 slice 4) — ported verbatim from docs/dental-os-screens-phase6.html's
   own .plans/.plan block. Deliberately auto-fit, not a hard-coded two-column grid, per the
   mockup's own explicit handoff note — a third plan drops in with zero CSS changes. */
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--s4);align-items:start}
.plan{border:1px solid var(--rule);border-radius:var(--radius);background:var(--surface);overflow:hidden}
.plan.is-current{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-subtle)}
.plan__head{padding:var(--s4);border-bottom:1px solid var(--rule)}
.plan__name{font-size:var(--text-section);font-weight:700}
.plan__price{font-size:30px;font-weight:800;letter-spacing:-.02em;margin-top:6px;font-variant-numeric:tabular-nums}
.plan__price small{font-size:var(--text-dense);font-weight:500;color:var(--ink-muted);letter-spacing:0}
.plan__for{font-size:var(--text-caption);color:var(--ink-muted);margin-top:4px}
.plan__list{padding:var(--s4);display:flex;flex-direction:column;gap:9px;font-size:var(--text-dense)}
.plan__li{display:flex;gap:9px;align-items:flex-start}
.plan__li svg{color:var(--success);margin-top:2px;flex:0 0 15px;width:15px;height:15px}
.plan__foot{padding:0 var(--s4) var(--s4)}

/* Usage meters + plan gates (Phase 6 slice 5) — ported verbatim from
   docs/dental-os-screens-phase6.html's own .meter/.gate blocks. */
.meter{margin-bottom:var(--s4)}
.meter__top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:7px}
.meter__label{font-size:var(--text-dense);font-weight:600}
.meter__val{font-size:var(--text-dense);font-variant-numeric:tabular-nums;color:var(--ink-secondary)}
.meter__bar{height:9px;border-radius:var(--radius-pill);background:var(--neutral-subtle);overflow:hidden;display:flex}
.meter__fill{height:100%}
.meter__fill--ok{background:var(--success)}
.meter__fill--warn{background:var(--warning)}
.meter__fill--full{background:var(--danger)}
.meter__fill--grace{background:repeating-linear-gradient(45deg,var(--warning),var(--warning) 4px,#F5C97A 4px,#F5C97A 8px)}
.meter__note{margin-top:7px;font-size:var(--text-caption);color:var(--ink-muted)}

.gate{border-radius:var(--radius);padding:var(--s5);text-align:center;border:1px solid}
.gate--hard{background:var(--danger-subtle);border-color:var(--danger-border)}
.gate--soft{background:var(--warning-subtle);border-color:var(--warning-border)}
.gate__ico{width:48px;height:48px;border-radius:50%;display:grid;place-items:center;margin:0 auto var(--s3);background:var(--surface)}
.gate__title{font-size:var(--text-section);font-weight:700;margin-bottom:6px}
.gate__body{font-size:var(--text-dense);max-width:44ch;margin:0 auto var(--s4);line-height:1.6}
.gate--hard .gate__title,.gate--hard .gate__body{color:#8F1D1D}
.gate--soft .gate__title,.gate--soft .gate__body{color:#8A4A08}

