/* SmartRecon v4 design system — "Charcoal + Steel Blue" (v2 handoff).
   Authoritative reference: design/design_handoff_smartrecon/README.md +
   SmartRecon v2.dc.html. Class names preserved from v3 so views keep working. */
:root{
  --ink:#191D22;--sub:#5A6879;--faint:#93A0B4;--faint2:#5E6773;
  --accent:#4A7FA7;--accenthover:#3D6A8C;--accentbg:#E3EDF5;--accentbg2:#EFF5FA;
  --green:#3D7A52;--greenbg:#E5F1E8;
  --red:#C0392B;--redbg:#FBEAE5;
  --amber:#856900;--amberbg:#FFF3D8;
  --gold:#C9A227;--goldink:#161207;
  --bg:#F3F4F6;--colbg:#F3F4F6;--card:#FFFFFF;--line:#DEE1E6;--rowline:#EEF1F4;--rowhover:#F8FAFC;
  /* The edge of a box you type into is a user-interface component, and 1.4.11 asks 3:1 of it.
     --line is #DEE1E6, which is 1.31:1 on white: at under a pixel it is effectively invisible,
     and a field with no visible edge stops looking like a field before it stops being
     compliant. This is a form-heavy application used outdoors on a phone. --fieldline is
     3.50:1 on white and 3.09:1 on the canvas, so it clears the bar on both surfaces a field
     can sit on. Cards keep --line: a decorative border is exempt and darkening it would turn
     a calm page into a grid. */
  --fieldline:#828A93;
  --sidebg:#16191E;--sidehover:#1F242B;--sideline:#2A2F37;--sidetext:#9AA3AF;--sidemuted:#5E6773;
  --darkink:#E8EAED;
  /* Legacy aliases — older inline styles in views resolve to v2 tokens. */
  --navy:#16191E;--navy2:#2B2F36;
  --blue:#4A7FA7;--bluebg:#E3EDF5;
  --accent2:#4A7FA7;--amber2:#856900;--chipbg:#EEF1F4;--yellowbg:#FFF3D8
}
*{margin:0;padding:0;box-sizing:border-box;font-family:'Archivo','Segoe UI',system-ui,sans-serif;font-variant-numeric:tabular-nums}
body{background:var(--bg);color:var(--ink);font-size:13px}
a{color:var(--accent)}
.mono,.cd,.key{font-family:ui-monospace,Consolas,monospace}
.muted{color:var(--sub)} .strong{font-weight:700;color:var(--ink)}

/* ------------------------------------------------------------------ */
/* Impersonation banner (sticky, gold)                                 */
/* ------------------------------------------------------------------ */
.impbanner{position:sticky;top:0;z-index:150;background:var(--gold);color:var(--goldink);font-weight:700;font-size:12.5px;padding:8px 16px;display:flex;align-items:center;gap:10px}
.impbanner form{margin-left:auto}
.impbanner button{background:var(--goldink);color:#F5E9C8;border:none;border-radius:2px;padding:5px 12px;font-weight:700;font-size:12px;cursor:pointer;font-family:inherit}

/* ------------------------------------------------------------------ */
/* Shell: dark 240px sidebar + light main                              */
/* ------------------------------------------------------------------ */
.shell{display:flex;min-height:100vh}
.side{width:240px;background:var(--sidebg);border-right:1px solid var(--sideline);padding:20px 10px;flex-shrink:0}
.sideheader{display:flex;align-items:center;justify-content:space-between}
.proj{display:flex;gap:10px;align-items:center;padding:6px 10px 20px}
.proj .ic{width:12px;height:12px;border-radius:2px;background:var(--accent);flex-shrink:0}
.proj b{font-size:14.5px;display:block;color:#fff;font-weight:800}
.proj span{font-size:11.5px;color:var(--sidemuted)}
.hamb{display:none;font-size:20px;color:var(--sidetext);cursor:pointer;padding:4px 10px;border-radius:3px}
.hamb:hover{background:var(--sidehover)}
.sidenav a{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:3px;color:var(--sidetext);text-decoration:none;font-size:13.5px;margin-bottom:1px;border-left:2px solid transparent}
.sidenav a.on{background:var(--sidehover);color:#fff;font-weight:600;border-left:2px solid var(--accent)}
.sidenav a:hover{background:var(--sidehover);color:#fff}
.sidenav a.adminlink.on{border-left-color:var(--gold)}
.sidenav .navlabel{font-size:10px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--sidemuted);padding:6px 10px 4px}
.sidenav .cnt{margin-left:auto;background:#3A2523;color:#F0A9A0;border-radius:99px;font-size:11px;padding:1px 8px;font-weight:700}
.sidenav .hint{margin-left:auto;color:var(--sidemuted);font-size:11.5px}
.sidenav .sep{border-top:1px solid var(--sideline);margin:12px 10px}
.sidenav .who{display:flex;align-items:center;gap:10px;padding:10px;font-size:11.5px;color:var(--sidetext);word-break:break-all}
.main{flex:1;padding:22px 26px;overflow-x:auto;min-width:0;background:var(--bg)}
.crumb{color:var(--sub);font-size:12px;margin-bottom:6px}
h1{font-size:18px;font-weight:700}

@media (max-width:900px){
  .shell{flex-direction:column}
  .side{width:100%;border-right:none;border-bottom:1px solid var(--sideline);padding:8px 10px}
  .proj{padding:6px 10px}
  .hamb{display:block}
  .sidenav{display:none;padding-bottom:8px}
  #navtoggle:checked ~ .sidenav{display:block}
  .main{padding:14px}
}

/* ------------------------------------------------------------------ */
/* Page scaffolding                                                    */
/* ------------------------------------------------------------------ */
.wrap{max-width:1480px}
.wrap.narrow{max-width:1180px}
.pagehead{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;gap:12px;flex-wrap:wrap}
.pagehead h1{font-size:18px;font-weight:700;color:var(--ink);display:flex;align-items:center;gap:10px}
.pagehead .sub{color:var(--sub);font-size:12.5px;margin-top:3px}
.foot{margin-top:26px;padding:14px 0;border-top:1px solid var(--line);color:var(--faint);font-size:11px;text-align:center}
.sec{margin-bottom:20px}
.sec h2{font-size:10.5px;font-weight:700;color:var(--sub);letter-spacing:.09em;text-transform:uppercase;margin-bottom:9px;display:flex;align-items:center;gap:8px}
.sec h2 .cnt{background:#E8EAED;color:var(--ink);border-radius:99px;padding:0 8px;font-size:11px}
.sec h2 .cnt.r{background:var(--redbg);color:var(--red)}
.sec h2 .cnt.a{background:var(--amberbg);color:var(--amber)}

/* Buttons — primary charcoal, accent steel blue, gold for impersonation */
.btn{display:inline-flex;align-items:center;gap:6px;background:#2B2F36;color:#fff;border:none;padding:8px 14px;border-radius:2px;font-weight:600;font-size:12.5px;cursor:pointer;text-decoration:none;font-family:inherit}
.btn:hover{background:#16191E}
.btn.accent{background:var(--accent)} .btn.accent:hover{background:var(--accenthover)}
.btn.gold{background:var(--gold);color:var(--goldink)} .btn.gold:hover{background:#B08D1E}
.btn.ghost{background:#fff;color:var(--ink);border:1px solid var(--line)}
.btn.ghost:hover{background:var(--rowhover)}
.btn.subtle{background:#EEF1F4;color:var(--ink)}
.btn.subtle:hover{background:#E4E6EA}
.btn.amber{background:var(--accent)}
.btn.green{background:var(--green)}.btn.green:hover{background:#2E5C3E}
.btn.red,.btn.danger{background:var(--red)}.btn.red:hover,.btn.danger:hover{background:#A02E22}
.btn.sm{padding:5px 10px;font-size:11.5px}
.btn[disabled],.btn.disabled{opacity:.5;cursor:not-allowed}
.inline-form{display:inline-flex;gap:8px;align-items:center}
.inline-form input[type=text],.inline-form input[type=email]{border:1.5px solid var(--line);border-radius:2px;padding:7px 10px;font-size:12.5px;font-family:inherit}

/* KPI strip */
.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}
.kpi{background:var(--card);border:1px solid var(--line);border-radius:4px;padding:14px 16px}
.kpi .n{font-size:26px;font-weight:800;letter-spacing:-.4px;color:var(--ink)}
.kpi .l{font-size:10.5px;color:var(--sub);font-weight:700;margin-top:2px;text-transform:uppercase;letter-spacing:.09em}
.kpi .s{font-size:11.5px;color:var(--faint);margin-top:4px}
.kpi.warn .n{color:var(--amber)} .kpi.bad .n{color:var(--red)} .kpi.good .n{color:var(--green)}
@media (max-width:900px){.kpis{grid-template-columns:repeat(2,1fr)}}

/* Cards, chips, labels */
.card{background:var(--card);border:1px solid var(--line);border-radius:4px;padding:16px;margin-bottom:14px}
.card.tablecard{padding:0;overflow-x:auto}
.cardtitle{font-size:13.5px;font-weight:700;margin-bottom:10px}
.chip,.lab{display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:2px;font-size:10.5px;font-weight:700}
.chip.stage,.lab.blue{background:#E8EAED;color:#2B2F36}
.chip.red,.lab.red{background:var(--redbg);color:var(--red)}
.chip.green,.lab.green{background:var(--greenbg);color:var(--green)}
.chip.amber,.lab.amber{background:var(--amberbg);color:var(--amber)}
.chip.gray,.lab.gray{background:#EEF1F4;color:var(--sub)}
.chip.pick{border:1.5px solid var(--accent);background:var(--accentbg);color:var(--accent)}

/* Status pill */
.statuspill{display:inline-flex;align-items:center;gap:6px;background:var(--accentbg);color:var(--accent);border-radius:2px;padding:4px 10px;font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.03em}
.statuspill.done{background:var(--greenbg);color:var(--green)}
.statuspill.todo{background:#EEF1F4;color:var(--sub)}
.statuspill.risk{background:var(--redbg);color:var(--red)}

/* Avatars */
.av{width:30px;height:30px;border-radius:50%;border:2px solid #fff;display:inline-flex;align-items:center;justify-content:center;font-size:11.5px;font-weight:700;color:#fff;flex-shrink:0}
.av.sm{width:24px;height:24px;font-size:10px;border:none}
.avatars{display:flex}
.avatars .av{margin-left:-6px}
.avatars .av:first-child{margin-left:0}

/* Tables — dark header row per v2 */
.tbl{width:100%;border-collapse:collapse;font-size:12.5px}
.tbl th{background:var(--sidebg);color:#7A828D;text-align:left;padding:8px 12px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.09em}
.tbl th:first-child{border-radius:4px 0 0 0}.tbl th:last-child{border-radius:0 4px 0 0}
.tbl td{padding:9px 12px;border-bottom:1px solid var(--rowline);vertical-align:middle}
.tbl tr:hover td{background:var(--rowhover)}
.cd{font-weight:700}
.cd.r{color:var(--red)} .cd.a{color:var(--amber)} .cd.g{color:var(--green)}

/* Grids + panels */
.grid2{display:grid;grid-template-columns:2fr 1fr;gap:14px}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
@media (max-width:1100px){.grid4{grid-template-columns:repeat(2,1fr)}}
@media (max-width:900px){.grid2,.grid3{grid-template-columns:1fr}.grid4{grid-template-columns:1fr}}
.panel{padding:16px}
.panel h3{font-size:10.5px;font-weight:700;color:var(--sub);text-transform:uppercase;letter-spacing:.09em;margin-bottom:12px}
.kv{display:flex;justify-content:space-between;gap:10px;padding:7px 0;border-bottom:1px solid var(--rowline);font-size:12.5px}
.kv:last-child{border:none}
.kv .k{color:var(--sub)} .kv .v{font-weight:600;text-align:right}
.kv .v.big{font-size:15px;font-weight:800;color:var(--ink)}

/* Tabs (admin org detail) */
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:14px}
.tabs a{padding:9px 14px;font-size:13px;font-weight:600;color:var(--sub);text-decoration:none;border-bottom:2px solid transparent}
.tabs a.on{color:var(--accent);border-bottom-color:var(--accent)}
.tabs a:hover{color:var(--ink)}

/* Admin forms */
.formgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px 16px}
@media (max-width:1000px){.formgrid{grid-template-columns:1fr}}
.formgrid label{display:flex;flex-direction:column;gap:5px;font-size:10.5px;font-weight:700;color:var(--sub);text-transform:uppercase;letter-spacing:.09em}
.formgrid label.wide{grid-column:1/-1}
.formgrid input,.formgrid select,.formgrid textarea{border:1.5px solid var(--line);border-radius:2px;padding:8px 10px;font-size:13px;font-family:inherit;font-weight:400;text-transform:none;letter-spacing:0;color:var(--ink);background:#fff}
.formgrid input:focus,.formgrid select:focus,.formgrid textarea:focus{outline:2px solid var(--accentbg);border-color:var(--accent)}
.formgrid .sep2{grid-column:1/-1;border-top:1px solid var(--rowline);margin:4px 0}
.formactions{grid-column:1/-1;display:flex;justify-content:flex-end;gap:10px;margin-top:4px}
.card > .formactions{margin-top:12px;display:flex;justify-content:flex-end}

/* Module entitlement toggles */
.modgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
@media (max-width:1000px){.modgrid{grid-template-columns:1fr}}
.modrow{display:flex;align-items:center;gap:10px;padding:10px 12px;border:1px solid var(--line);border-radius:3px;cursor:pointer;font-size:12.5px}
.modrow:hover{background:var(--rowhover)}
.modrow.core{opacity:.75;cursor:default}
.modrow input{width:15px;height:15px;accent-color:var(--accent)}
.modrow .modname{font-weight:700}
.modrow .muted{margin-left:auto;font-size:11px}

/* Upsell denial page */
.upsell{max-width:520px;margin:60px auto;text-align:center;padding:38px 34px}
.upsell .lock{font-size:34px;margin-bottom:10px}
.upsell h1{margin-bottom:8px}
.upsell p{margin-bottom:18px}

/* ------------------------------------------------------------------ */
/* Kanban board                                                        */
/* ------------------------------------------------------------------ */
.filters{display:flex;align-items:center;gap:12px;margin-bottom:18px;flex-wrap:wrap}
.search{border:1.5px solid var(--line);border-radius:3px;padding:7px 12px;font-size:13px;width:200px;color:var(--ink);font-family:inherit}
.search::placeholder{color:var(--faint)}
.fbtn{border:none;background:none;color:var(--sub);font-size:13px;font-weight:500;padding:7px 10px;border-radius:3px;cursor:pointer;text-decoration:none;font-family:inherit}
.fbtn:hover{background:#E8EAED}
.fbtn.on{background:var(--accentbg);color:var(--accent);font-weight:700}
.board{display:flex;gap:12px;align-items:flex-start;padding-bottom:8px}
.col{background:#ECEEF1;border-radius:4px;padding:10px;flex:1 1 0;min-width:170px}
.col .cards,.col .tc{min-width:0}
.tc .sum{overflow-wrap:break-word}
@media (max-width:1360px){
  .board{overflow-x:auto}
  .col{flex:0 0 250px;min-width:250px}
}
.colhead{display:flex;align-items:center;gap:8px;padding:4px 8px 12px;font-size:10.5px;font-weight:700;color:var(--sub);text-transform:uppercase;letter-spacing:.09em}
.colhead .n{background:#DFE1E6;border-radius:99px;padding:0 8px;font-size:11px}
.colhead .sla{margin-left:auto;color:var(--red);text-transform:none;letter-spacing:0;font-weight:700;font-size:11px}
.cards{min-height:24px}
.tc{display:block;background:var(--card);border:1px solid var(--line);border-radius:4px;padding:12px 14px;margin-bottom:10px;cursor:grab;color:var(--ink);text-decoration:none}
.tc:hover{background:var(--rowhover);border-color:#C9CFD6}
.tc.ring{box-shadow:0 0 0 2px var(--red)}
.tc .sum{font-size:13.5px;line-height:1.45;margin-bottom:10px;font-weight:500}
.tc .labels{display:flex;gap:5px;flex-wrap:wrap;margin-bottom:10px}
.tc .foot{display:flex;align-items:center;gap:8px}
.key{font-size:11.5px;color:var(--sub);font-weight:600}
.pri{width:12px;height:12px;border-radius:2px;flex-shrink:0;background:#EF9F27}
.pri.red{background:#C0392B}.pri.orange{background:#D85A30}.pri.yellow{background:#EF9F27}.pri.green{background:#3D7A52}
.due{font-size:11px;font-weight:700;border-radius:2px;padding:2px 7px;margin-left:auto;font-family:ui-monospace,Consolas,monospace}
.due.r{background:var(--redbg);color:var(--red)}
.due.a{background:var(--amberbg);color:var(--amber)}
.tc .foot .av{width:24px;height:24px;font-size:10px;border:none}
.tc .sub2{display:flex;gap:8px;flex-wrap:wrap;color:var(--faint);font-size:11.5px;margin-top:8px;border-top:1px solid var(--rowline);padding-top:8px}
.sortable-ghost{opacity:.4}
.sortable-drag{cursor:grabbing}

/* Parked strip */
.parked{margin-top:16px}
.parked summary{cursor:pointer;font-size:12.5px;font-weight:600;color:var(--sub);padding:8px 10px;border-radius:3px;list-style:none}
.parked summary:hover{background:#E8EAED}
.parked summary::-webkit-details-marker{display:none}
.parkrow{display:flex;gap:10px;flex-wrap:wrap;padding:10px}
.parkcard{display:inline-flex;align-items:center;gap:8px;background:#E8EAED;border-radius:3px;padding:8px 12px;font-size:12px;color:var(--ink);text-decoration:none;font-weight:500}
.parkcard:hover{background:#DFE1E6}
.parkcard .key{font-size:11px}

/* ------------------------------------------------------------------ */
/* Vehicle detail                                                      */
/* ------------------------------------------------------------------ */
.issuekey{color:var(--sub);font-size:12.5px;font-weight:600;margin-bottom:2px;font-family:ui-monospace,Consolas,monospace}
.issue{display:grid;grid-template-columns:1fr 320px;gap:18px;align-items:start}
@media (max-width:1000px){.issue{grid-template-columns:1fr}}
.subtask{display:flex;align-items:center;gap:10px;padding:9px 6px;border-bottom:1px solid var(--rowline);font-size:12.5px}
.subtask:last-child{border-bottom:none}
.subtask:hover{background:var(--rowhover)}
.subtask .stitle{flex:1;font-weight:500;min-width:0}
.subtask .amount{font-weight:700;white-space:nowrap;font-family:ui-monospace,Consolas,monospace}
.sq{width:12px;height:12px;border-radius:2px;flex-shrink:0;background:var(--faint)}
.sq.sev1{background:#3D7A52}.sq.sev2{background:#EF9F27}.sq.sev3{background:#D85A30}.sq.sev4{background:#C0392B}
.feed{list-style:none}
.feed li{display:flex;gap:10px;padding:9px 0;border-bottom:1px solid var(--rowline);font-size:12.5px;align-items:flex-start}
.feed li:last-child{border-bottom:none}
.feed .ftext{flex:1;min-width:0}
.feed .fwho{font-weight:600}
.feed .fwhen{color:var(--faint);font-size:11px;white-space:nowrap}

/* Approvals queue rows */
.qrow{display:flex;align-items:center;gap:14px;padding:14px 16px;border-bottom:1px solid var(--rowline)}
.qrow:last-child{border-bottom:none}
.qrow:hover{background:var(--rowhover)}
.qmain{flex:1;min-width:0}
.qtitle{font-weight:600;font-size:13.5px}
.qsub{font-size:11.5px;color:var(--sub);text-decoration:none;display:inline-block;margin:2px 0 7px}
.qsub:hover{text-decoration:underline;color:var(--accent)}
.qest{text-align:right;min-width:130px}
.qest .big{font-size:16px;font-weight:800;font-family:ui-monospace,Consolas,monospace}
.qest .split{font-size:11px;color:var(--sub)}
.qact{display:flex;flex-direction:column;gap:6px;min-width:110px}

/* Timeline */
/* The recon product's vertical progress timeline. Scoped to ul, because the
   only .timeline in the application is Hobart's ol.timeline audit trail, and
   these rules were landing on it: a 12px grey dot absolutely positioned over
   the first column of every row, plus a 2px left border and an 8px indent the
   Hobart rules did not ask for. Nothing renders ul.timeline today; the rules
   are kept rather than deleted because the recon views they were written for
   still exist. */
ul.timeline{list-style:none}
ul.timeline li{position:relative;padding:0 0 16px 24px;border-left:2px solid var(--line);margin-left:8px;font-size:12.5px}
ul.timeline li:before{content:'';position:absolute;left:-7px;top:1px;width:12px;height:12px;border-radius:50%;background:var(--line);border:2.5px solid #fff}
ul.timeline li.done{border-left-color:var(--green)} ul.timeline li.done:before{background:var(--green)}
ul.timeline li.now:before{background:var(--accent);box-shadow:0 0 0 4px var(--accentbg)}
ul.timeline li .t{font-weight:600} ul.timeline li .d{font-size:11px;color:var(--sub)}

/* Photo placeholders */
.ph{background:linear-gradient(135deg,#E9EBEE,#DEE1E6);border-radius:3px;display:flex;align-items:center;justify-content:center;color:var(--faint);font-weight:700;font-size:11px}
.photobox{aspect-ratio:4/3;border-radius:4px;position:relative;overflow:hidden}
.photobox .tag{position:absolute;bottom:8px;left:8px;font-size:11px;font-weight:700;background:rgba(22,25,30,.85);color:#fff;padding:3px 9px;border-radius:2px}
.photobox.miss{border:2px dashed var(--amber);background:var(--amberbg);display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--amber);font-weight:700;font-size:12px}
.photobox img{width:100%;height:100%;object-fit:cover;display:block}
.photobox.capture{cursor:pointer}
.photobox.capture:hover{border-color:var(--accent);color:var(--accent)}

/* Inspection runner */
.insp{display:grid;grid-template-columns:230px 1fr 300px;gap:14px}
@media (max-width:1000px){.insp{grid-template-columns:1fr}}
.secnav{background:var(--card);border:1px solid var(--line);border-radius:4px;padding:10px;align-self:start}
.secnav a{display:flex;justify-content:space-between;align-items:center;padding:9px 12px;border-radius:3px;text-decoration:none;color:var(--ink);font-weight:500;font-size:12.5px;margin-bottom:2px}
.secnav a.on{background:var(--accentbg);color:var(--accent);font-weight:700}
.secnav a:hover:not(.on){background:var(--rowhover)}
.secnav a .pct{font-size:11px;color:var(--sub)} .secnav a.on .pct{color:var(--accent)}
.check{background:var(--card);border:1px solid var(--line);border-radius:4px;padding:13px 16px;margin-bottom:10px;display:flex;align-items:center;gap:14px}
.check .q{flex:1;font-weight:500;font-size:13.5px}
.check.failed{border-color:var(--red);box-shadow:0 0 0 1px var(--red)}
.seg{display:flex;border:1px solid var(--line);border-radius:2px;overflow:hidden}
.seg button{padding:9px 15px;font-size:12.5px;cursor:pointer;background:#fff;color:var(--sub);border:none;border-right:1px solid var(--line);font-weight:600;font-family:inherit}
.seg button:last-child{border-right:none}
.seg button:hover{background:var(--rowhover)}
.seg button.p{background:var(--greenbg);color:var(--green)} .seg button.f{background:var(--redbg);color:var(--red)} .seg button.na{background:#EEF1F4;color:var(--sub)}
.camchip{width:40px;height:40px;border-radius:3px;border:1.5px dashed var(--line);display:flex;align-items:center;justify-content:center;font-size:16px;color:var(--sub);flex-shrink:0}

/* Forms */
.input, select.input, textarea.input{border:1.5px solid var(--line);border-radius:2px;padding:8px 12px;font-size:12.5px;font-family:inherit;background:#fff;color:var(--ink);width:100%}
.input:focus{outline:2px solid var(--accentbg);border-color:var(--accent)}
textarea.input{min-height:70px;resize:vertical}
.field{margin-bottom:12px}
.field label{display:block;font-size:10.5px;color:var(--sub);margin-bottom:5px;font-weight:700;text-transform:uppercase;letter-spacing:.09em}
.searchbox{border:1.5px solid var(--line);border-radius:3px;padding:8px 12px;font-size:12.5px;width:220px;font-family:inherit}

/* Decision gate option cards */
.opt{padding:16px;border:2px solid var(--line);cursor:pointer;display:block;border-radius:4px}
.opt input[type=radio]{position:absolute;opacity:0}
.opt .head{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.opt .radio{width:24px;height:24px;border-radius:50%;border:2px solid var(--line);display:flex;align-items:center;justify-content:center;font-size:12px;flex-shrink:0}
.opt .desc{font-size:12px;color:var(--sub);margin-left:34px}
.opt:has(input:checked){border-color:var(--accent);background:var(--accentbg2)}
.opt:has(input:checked) .radio{border-color:var(--accent)}
.opt:has(input:checked) .radio:after{content:'●';color:var(--accent)}

/* Notifications */
.notif{display:flex;gap:12px;align-items:flex-start;padding:14px 16px;border-bottom:1px solid var(--rowline)}
.notif.unread{background:var(--accentbg2)}
.notif .sevdot{width:9px;height:9px;border-radius:50%;margin-top:5px;flex-shrink:0;background:var(--faint)}
.notif .sevdot.warn{background:#D85A30} .notif .sevdot.crit{background:#C0392B}

/* Toast */
.toast{position:fixed;bottom:24px;left:24px;z-index:200;background:#16191E;color:#fff;padding:12px 18px;border-radius:3px;font-weight:500;font-size:12.5px;box-shadow:0 8px 16px rgba(9,20,30,.3);max-width:420px;border-left:3px solid var(--faint)}
.toast.ok{border-left-color:#3D7A52}
.toast.err,.toast.bad{border-left-color:#C0392B}

/* Login */
.login-shell{min-height:100vh;display:flex;align-items:center;justify-content:center;background:var(--sidebg)}
/* max-width, not width: at 380px fixed the sign-in card was wider than a 360px phone
   and the page scrolled sideways before anybody had typed anything. */
.login-card{background:var(--card);border:1px solid var(--line);border-radius:4px;padding:34px 36px;width:100%;max-width:380px}
.login-card .logo{display:flex;align-items:center;gap:8px;color:var(--ink);font-size:20px;font-weight:800;margin-bottom:4px}
.login-card .logo .dot{width:10px;height:10px;border-radius:2px;background:var(--accent);display:inline-block}
.login-card .sub{color:var(--sub);font-size:12.5px;margin-bottom:22px}
.valerr{color:var(--red);font-size:12px;margin-top:4px;font-weight:600}

/* Sign out control in the sidebar footer. Sidebar is dark, so this uses the
   --side* tokens rather than body ink, which rendered invisible. */
.signout { padding: 4px 14px 16px; }
.signout button {
    width: 100%;
    background: var(--sidehover);
    color: var(--sidetext);
    border: 1px solid var(--sideline);
    border-radius: 6px;
    padding: 8px 10px;
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.signout button:hover { color: var(--darkink); border-color: var(--sidetext); }

/* ==========================================================================
   Hobart "Our cars" + one-car page.
   Tokens taken from the locked v3 wireframes: Archivo, #EFF1F4 canvas,
   #1B2028 ink, #4A7FA7 accent, 8px cards, 0 2px 12px rgba(20,25,32,.06).
   ========================================================================== */

.carspage, .carpage { max-width: 1320px; }

.carshead { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 18px; }
.carstitle { font-size: 26px; font-weight: 800; letter-spacing: -.4px; margin: 0; color: var(--ink); }
.carssub { font-size: 13px; color: var(--sub); margin-top: 4px; }

.carsearch { display: flex; gap: 8px; }
.carsearch input {
    width: 380px; max-width: 100%; padding: 9px 12px; font: inherit; font-size: 13px;
    border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--ink);
}
.carsearch input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.carsearch button {
    padding: 9px 16px; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
    background: var(--navy); color: #fff; border: 1px solid var(--navy); border-radius: 6px;
}
.carsearch button:hover { background: var(--navy2); }

.visually-hidden {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/*
    ------------------------------------------------------------------------------------
    Everything below that restyles a SHARED class is scoped to .hobart.

    This stylesheet serves two products out of one file: the recon application (dealer
    one's live software) and this tenant. The Hobart rules were written as bare class
    selectors at top level, so they did not add a tenant style — they REPLACED the recon
    product's. Measured before scoping: .chip is used 28 times across 13 recon views and
    .panel 27 times across 12, and both were silently redefined.

      * .chip went from a 2px-radius 10.5px tag to a 999px pill at 12.5px with a card
        background and a border. Line 112 styles `.chip,.lab` as a PAIR; only .chip was
        pulled away, so anywhere the two sit together they stopped matching. Nobody
        designs that on purpose, which is what makes it an accident rather than a
        unification.
      * .panel went from `padding:16px` — no background at all — to a white card with a
        border, an 8px radius and a drop shadow. Every panel in the recon product.
      * .muted changed colour and picked up `font-size:13px`, which is also what made a
        parenthetical inside an 11px form label render LARGER than the label.
      * .warn newly matched `class="kpi warn"` on the arbitration dashboard, turning that
        tile's label red while its number stayed amber — two different severities on one
        tile.

    Caught before it shipped: dealer one's service last deployed on 2026-07-31, from
    before this branch, so the regression was latent rather than live.

    body already carries class="hobart", so the hook existed and simply was not used —
    the print block below even overrides `body.hobart` by name, so it was known about.
    ------------------------------------------------------------------------------------
*/

/* Colour chips */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.hobart .chip {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 7px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
    background: var(--card); border: 1px solid var(--line); color: var(--sub); text-decoration: none;
}
.hobart .chip:hover { border-color: var(--faint); color: var(--ink); }
.hobart .chip.on { background: var(--navy); border-color: var(--navy); color: #fff; }
.hobart .chip b { font-weight: 800; }
/* The inset ring is what makes the white "Ready for sale" swatch visible at all. Any new
   place that shows a stage colour as a dot must be in this list, or the dot renders as a
   zero-size nothing - which is how the board lost its colours. */
.hobart .chip .dot, .moveopt .dot, .boardcolhead .dot {
    width: 10px; height: 10px; border-radius: 50%; display: inline-block;
    box-shadow: inset 0 0 0 1px rgba(20,25,32,.18);
}

/* Car table */
table.cars { width: 100%; border-collapse: collapse; background: var(--card);
    border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
    box-shadow: 0 2px 12px rgba(20,25,32,.06); }
table.cars th {
    text-align: left; font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--faint2); padding: 11px 14px;
    background: var(--rowline); border-bottom: 1px solid var(--line);
}
table.cars td { padding: 12px 14px; border-bottom: 1px solid var(--rowline); font-size: 13.5px; vertical-align: middle; }
table.cars tr:last-child td { border-bottom: 0; }
table.cars tbody tr:hover { background: var(--rowhover); }

.pill {
    display: inline-block; padding: 4px 11px; border-radius: 999px;
    font-size: 11.5px; font-weight: 700; letter-spacing: .01em; white-space: nowrap;
}
.carlink { font-weight: 600; color: var(--ink); text-decoration: none; }
.carlink:hover { color: var(--accent); text-decoration: underline; }
.note { display: block; font-size: 12px; color: var(--faint2); margin-top: 2px; }
.dash { color: var(--faint); }
/* Scoped: bare .warn newly matched `class="kpi warn"` in the recon product. */
.hobart .warn { color: var(--red); font-weight: 600; }
.mono { font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.num { text-align: right; font-variant-numeric: tabular-nums; }

.emptystate {
    background: var(--card); border: 1px solid var(--line); border-radius: 8px;
    padding: 40px; text-align: center; display: flex; flex-direction: column; gap: 8px;
}
.emptystate b { font-size: 15px; }
.emptystate span { color: var(--sub); font-size: 13px; }

/* ---------- one-car page ---------- */
.backlink { display: inline-block; font-size: 13px; color: var(--accent); text-decoration: none; margin-bottom: 12px; }
.backlink:hover { text-decoration: underline; }

.notice {
    background: var(--amberbg); border: 1px solid #E5D9A8; color: var(--amber);
    border-radius: 6px; padding: 10px 14px; font-size: 13px; margin-bottom: 14px;
}

.carhero {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 24px;
    padding-bottom: 16px; border-bottom: 2px solid var(--ink); margin-bottom: 20px;
}
.carhero h1 { font-size: 24px; font-weight: 800; letter-spacing: -.4px; margin: 0; color: var(--ink); }
.carids { font-size: 12.5px; color: var(--sub); margin-top: 5px; }
.stagebox { display: flex; align-items: center; gap: 10px; }

.movebox { position: relative; }
.movebox summary {
    cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--sub);
    border: 1px solid var(--line); background: var(--card); border-radius: 6px; padding: 6px 12px;
    list-style: none;
}
.movebox summary::-webkit-details-marker { display: none; }
.movebox summary:hover { color: var(--ink); border-color: var(--faint); }
.movelist {
    position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; min-width: 240px;
    background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 8px;
    box-shadow: 0 8px 28px rgba(20,25,32,.14);
}
.movehead { font-size: 11px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .06em; color: var(--faint2); padding: 4px 8px 8px; }
.moveopt {
    display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
    background: none; border: 0; border-radius: 6px; padding: 8px; font: inherit;
    font-size: 13px; color: var(--ink); cursor: pointer;
}
.moveopt:hover { background: var(--rowhover); }
.moveopt em { margin-left: auto; font-style: normal; font-size: 11px; color: var(--faint2); }

.cargrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; margin-bottom: 16px; }
.hobart .panel {
    background: var(--card); border: 1px solid var(--line); border-radius: 8px;
    padding: 18px 20px; box-shadow: 0 2px 12px rgba(20,25,32,.06);
}
.hobart .panel.wide { margin-bottom: 16px; }
.hobart .panel h2 { font-size: 14px; font-weight: 800; margin: 0 0 14px; color: var(--ink); }
.panelhead { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.panelhead h2 { margin-bottom: 14px; }
.total { font-size: 13px; color: var(--sub); }
.total b { color: var(--ink); font-variant-numeric: tabular-nums; }
/* flex-direction is not optional here. Without it the panel is a ROW: the upload form
   becomes a 290px column beside the picture, squeezing a 1312px photo to 1021px, and its
   own wrapped flex lines get spread down 326px of stretched height — which is what put a
   large gap above "Upload". The panel has always been a vertical stack; it just never
   said so. */
/* .hobart-scoped so it still outranks `.hobart .panel`'s padding shorthand. As a bare
   .photopanel this became (0,1,0) against (0,2,0) and lost, which put the card's 18/20
   padding back around a photo that is meant to bleed to the edge. */
.hobart .photopanel { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
/* Direct child only. As a descendant selector this also hit every thumbnail in
   .photostrip, and at (0,2,1) it beat .photostrip img at (0,1,1) — so a car with two
   photos rendered its "thumbnails" 340px tall. The hero image is the panel's own child;
   say so, and the strip keeps its own rules. */
/* The hero image now lives inside .photostage (see below); the old direct-child rules that
   COVER-cropped it into a fixed band are gone rather than left as zombies matching nothing. */

dl.facts { display: grid; grid-template-columns: auto 1fr; gap: 9px 18px; margin: 0; font-size: 13px; }
dl.facts.two { grid-template-columns: auto 1fr auto 1fr; }
dl.facts dt { color: var(--faint2); }
dl.facts dd { margin: 0; color: var(--ink); font-weight: 500; }

/*
    A loss has to LOOK like a loss.
    
    `dl.facts dd` is (0,1,2) and `.warn` is (0,1,0), so every dd.warn in the
    application was rendering in ordinary ink at ordinary weight — a car priced
    below what it cost showed "-$805" in exactly the same treatment as a profit.
    The minus sign was the only signal, and the eye goes to the number, not its
    punctuation.
    
    Found by pricing a car underwater in a browser and looking at it. Nothing
    measurable was wrong: the class was applied, the value was correct, the
    warning sentence underneath it rendered. The one thing that failed was the
    part only looking can check.
*/
dl.facts dd.warn { color: var(--red); font-weight: 700; }

.yesno { display: flex; gap: 8px; }
.yesno span {
    flex: 1; text-align: center; padding: 12px 0; border-radius: 6px;
    font-size: 15px; font-weight: 800; letter-spacing: .04em;
    border: 1px solid var(--line); background: var(--rowline); color: var(--faint);
}
.yesno .yes.on { background: var(--greenbg); border-color: #A8CDB4; color: var(--green); }
.yesno .no.on { background: var(--redbg); border-color: #E3B4AC; color: var(--red); }
.stamp { font-size: 12px; color: var(--faint2); margin-top: 10px; }
.stamp.warn { color: var(--red); font-weight: 600; }

table.rows { width: 100%; border-collapse: collapse; }
table.rows th {
    text-align: left; font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--faint2); padding: 8px 10px;
    border-bottom: 1px solid var(--line);
}
/* `table.rows th` is more specific than `.num`, so a numeric column header stayed
   left-aligned while its values were right-aligned — the "PRICE" label floated a long way
   from the prices under it. Affects every numeric table in the app, not just the reports. */
table.rows th.num { text-align: right; }
table.rows td { padding: 10px; border-bottom: 1px solid var(--rowline); font-size: 13px; }
table.rows tr:last-child td { border-bottom: 0; }

.openbadge {
    display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 999px;
    font-size: 10.5px; font-weight: 700; background: var(--amberbg); color: var(--amber);
}
.warrantybadge {
    display: inline-block; padding: 3px 9px; border-radius: 999px;
    font-size: 11px; font-weight: 700; background: var(--accentbg); color: var(--deepaccent, #31597A);
}
.clip { font-size: 12.5px; color: var(--accent); }
/* Scoped: this is the second definition of .muted. The first, at the top of the file, sets
   colour only; this one adds an absolute font-size that reaches every .muted in both
   products. */
.hobart .muted { color: var(--faint2); font-size: 13px; margin: 0; }

.auditlink { display: inline-block; font-size: 13px; font-weight: 600; color: var(--accent); text-decoration: none; }
.auditlink:hover { text-decoration: underline; }

@media (max-width: 720px) {
    .carshead { flex-direction: column; align-items: stretch; }
    .carsearch input { width: 100%; max-width: none; }
    table.cars th:nth-child(3), table.cars td:nth-child(3) { display: none; }
    dl.facts.two { grid-template-columns: auto 1fr; }
}

/* Contrast fix: --faint (#93A0B4) on white is ~2.6:1 and failed AA for the
   "not attached" / placeholder text on the car page. */
.carpage .dash, .carspage .dash { color: var(--faint2); }

/* ==========================================================================
   Hobart chrome: light top bar with tabs, per the approved v3 wireframes.
   The dark SmartRecon rail belongs to the recon product, not this tenant.
   ========================================================================== */
body.hobart { background: #EFF1F4; color: #1B2028; font-family: Archivo, "Segoe UI", system-ui, sans-serif; }

.skiplink {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: #1B2028; color: #fff; padding: 10px 16px; border-radius: 0 0 6px 0;
}
.skiplink:focus { left: 0; }

.hbar { background: #fff; border-bottom: 1px solid #DDE1E6; box-shadow: 0 1px 3px rgba(20,25,32,.04); }
.hbar-in {
    max-width: 1360px; margin: 0 auto; padding: 0 24px;
    display: flex; align-items: center; gap: 28px; min-height: 62px; flex-wrap: wrap;
}
.hbrand-name { font-size: 18px; font-weight: 800; letter-spacing: -.3px; color: #1B2028; }

/* Tab labels are short phrases, not single words. Without nowrap a fourth tab makes
   flexbox break "Warranty service search" across three lines and the whole bar grows
   to three rows. The row scrolls on narrow screens instead (see the 820px block). */
.htabs { display: flex; gap: 4px; margin-right: auto; flex-shrink: 0; }
.htabs a {
    padding: 9px 14px; border-radius: 6px; font-size: 13.5px; font-weight: 600;
    color: #3A4350; text-decoration: none; white-space: nowrap;
}
.htabs a:hover { background: #F1F3F6; color: #1B2028; }
.htabs a.on { background: #1B2028; color: #fff; }
.htabs a:focus-visible, .hbtn:focus-visible, .hsignout button:focus-visible {
    outline: 2px solid #4A7FA7; outline-offset: 2px;
}

.hactions { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
.hactions .hbtn { white-space: nowrap; }
.hsignout button { white-space: nowrap; }
.hbtn {
    display: inline-block; padding: 9px 15px; border-radius: 6px; border: 1px solid #1B2028;
    background: #1B2028; color: #fff; font: inherit; font-size: 13px; font-weight: 600;
    text-decoration: none; cursor: pointer;
}
.hbtn:hover { background: #2B2F36; color: #fff; }
.hbtn.ghost { background: transparent; color: #3A4350; border-color: #C9D0D9; }
.hbtn.ghost:hover { background: #F1F3F6; color: #1B2028; }

.hwho { display: flex; align-items: center; gap: 8px; }
.hav {
    width: 28px; height: 28px; border-radius: 50%; background: #4A7FA7; color: #fff;
    display: grid; place-items: center; font-size: 11px; font-weight: 700;
}
.hname { font-size: 13px; color: #3A4350; white-space: nowrap; }
.hsignout button {
    background: none; border: 0; padding: 6px 2px; font: inherit; font-size: 12.5px;
    color: #5A6470; cursor: pointer; text-decoration: underline;
}
.hsignout button:hover { color: #1B2028; }

.hmain { max-width: 1360px; margin: 0 auto; padding: 28px 24px 64px; }
.carpage.narrow { max-width: 780px; }

/* Stage pill doubling as the move control, per the wireframe. */
summary.pillbtn { cursor: pointer; list-style: none; user-select: none; }
summary.pillbtn::-webkit-details-marker { display: none; }
summary.pillbtn:focus-visible { outline: 2px solid #1B2028; outline-offset: 2px; }

/* Title YES/NO as real buttons. */
.yesno button {
    flex: 1; padding: 14px 0; border-radius: 6px; font: inherit;
    font-size: 15px; font-weight: 800; letter-spacing: .04em; cursor: pointer;
    border: 1px solid var(--line); background: var(--rowline); color: var(--faint2);
}
.yesno button:hover { border-color: var(--faint); color: var(--ink); }
.yesno button:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }
.yesno.readonly { display: flex; gap: 8px; }
.titlepanel .yesno { max-width: 380px; }

/* Inline add forms. */
.addbox { margin-top: 16px; border-top: 1px solid var(--rowline); padding-top: 14px; }
.addbox summary {
    cursor: pointer; font-size: 13px; font-weight: 600; color: #4A7FA7; list-style: none;
}
.addbox summary::-webkit-details-marker { display: none; }
.addbox summary:hover { text-decoration: underline; }
.addform { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-top: 14px; }
.addform.stacked { align-items: flex-end; }
.addform .field { display: flex; flex-direction: column; gap: 5px; }
.addform .field.grow { flex: 1 1 260px; }
.addform .field.checks { flex-direction: row; gap: 14px; align-items: center; padding-bottom: 8px; }
.addform label { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--faint2); }
.addform .field.checks label { text-transform: none; letter-spacing: 0; font-size: 13px; font-weight: 500; color: var(--ink); }
/* A parenthetical inside a field label has to read as an aside, and .muted made it the opposite.
   .muted is declared twice — once as colour only, and again further down with `font-size: 13px`,
   which wins. Inside an 11px uppercase 700-weight label that bumps the aside UP to 13px while it
   keeps the label's own weight and capitals, so "ASKING PRICE (IF YOU KNOW IT YET)" shouted the
   qualifier louder than the thing it qualifies. Sentence case at the label's own size, lighter,
   is what an aside looks like. */
.addform label .muted,
.field label .muted {
    font-size: inherit; font-weight: 500; letter-spacing: inherit; text-transform: none;
}
.addform input, .addform select {
    padding: 8px 10px; font: inherit; font-size: 13px; border: 1px solid var(--line);
    border-radius: 6px; background: #fff; color: var(--ink); min-width: 130px;
}
.addform input:focus-visible, .addform select:focus-visible {
    outline: 2px solid #4A7FA7; outline-offset: 1px; border-color: #4A7FA7;
}
/* Scoped: recon's own .formactions sits in a grid and uses margin-top:4px with no width.
   Unscoped this changed both, on four recon screens, for the sake of two pixels here. */
.hobart .formactions { display: flex; gap: 10px; width: 100%; margin-top: 6px; }
.footnote { margin-top: 12px; font-size: 12px; }
.notice.ok { background: var(--greenbg); border-color: #A8CDB4; color: var(--green); }
.notice ul { margin: 6px 0 0 18px; }

/* Who changed this? */
ol.timeline { list-style: none; margin: 0; padding: 0; }
ol.timeline li {
    display: grid; grid-template-columns: 150px 1fr auto; gap: 14px;
    padding: 12px 0; border-bottom: 1px solid var(--rowline); font-size: 13.5px;
}
ol.timeline li:last-child { border-bottom: 0; }
.tl-who { font-weight: 700; color: var(--ink); }
.tl-what { color: var(--sub); }
.tl-delta { display: block; font-size: 12.5px; color: var(--ink); font-variant-numeric: tabular-nums; }
.tl-reason { display: block; font-size: 12.5px; color: var(--faint2); font-style: italic; }
.tl-when { font-size: 12.5px; color: var(--faint2); white-space: nowrap; }

/* Warranty search */
.custhead { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; margin-bottom: 4px; }
.custhead h2 { margin: 0; font-size: 16px; }
.custmeta { display: flex; gap: 14px; font-size: 12.5px; color: var(--faint2); }
.warrantycar { margin-top: 18px; }
.warrantycarhead { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; font-size: 13.5px; }

/* A customer with two cars gets two tables stacked inside one card, and auto layout sized each
   one to its own content — measured 48px of disagreement on the "Type" column between two
   tables sitting directly under one another. Fixed layout plus the colgroup makes the pair read
   as one list, which is what it is. min-width keeps the columns legible instead of crushing
   them on a phone; .tablewrap already scrolls. */
.warrantycar table.rows { table-layout: fixed; min-width: 860px; }
.warrantycar col.w-in,
.warrantycar col.w-out { width: 12%; }
.warrantycar col.w-what { width: 25%; }
.warrantycar col.w-type { width: 13%; }
.warrantycar col.w-tech { width: 14%; }
.warrantycar col.w-charged { width: 10%; }
.warrantycar col.w-invoice { width: 14%; }
/* Fixed layout will not grow a cell, so long work descriptions have to wrap rather than spill. */
.warrantycar table.rows td { overflow-wrap: anywhere; }

@media (max-width: 820px) {
    .hbar-in { min-height: 0; padding: 10px 16px; gap: 12px; }
    .htabs { order: 3; width: 100%; overflow-x: auto; }
    .hmain { padding: 18px 16px 48px; }
    ol.timeline li { grid-template-columns: 1fr; gap: 4px; }
    .tl-when { text-align: left; }
}

/*
   The photo stage. The old hero was `object-fit: cover` into a 340px band, which cropped
   roughly a third off the top and bottom of every 4:3 listing shot — roofs and wheels gone
   on the one page whose job is looking at the car. CONTAIN on a neutral surface shows the
   whole photo at whatever shape it was taken; the surface absorbs the difference between
   aspect ratios instead of the photo paying for it.

   The height cap still matters for the same reason as before: full-width in a single
   column, an uncapped portrait phone shot would fill the viewport and push every fact
   below the fold.
*/
.hobart .photostage {
    position: relative; display: grid; place-items: center;
    background: #F4F6F8; min-height: 200px;
}
.hobart .photostage .stagehero {
    display: block; max-width: 100%; max-height: 440px; width: auto; height: auto;
}
@media (max-width: 820px) { .hobart .photostage .stagehero { max-height: 260px; } }

/* Prev/next. Links, not buttons: the no-JS gallery is ?photo= navigation, and gallery.js
   upgrades the same elements. 44px+ targets — this is thumbed on a lot. */
.stagenav {
    position: absolute; top: 50%; transform: translateY(-50%);
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 56px; font-size: 30px; line-height: 1;
    color: #1B2028; background: rgba(255,255,255,.82);
    border: 1px solid var(--line); border-radius: 6px;
    text-decoration: none; user-select: none;
}
.stagenav:hover { background: #fff; }
.stagenav:focus-visible { outline: 2px solid #3D6A8C; outline-offset: 2px; }
.stagenav.prev { left: 10px; }
.stagenav.next { right: 10px; }

.stagecount {
    position: absolute; right: 10px; bottom: 10px; margin: 0;
    padding: 3px 10px; border-radius: 999px;
    background: rgba(27,32,40,.78); color: #fff;
    font-size: 11.5px; font-variant-numeric: tabular-nums;
}
.stagecount b { font-weight: 700; }

/* Inline invoice attach control inside a table cell. */
.attachform { display: flex; align-items: center; gap: 8px; }
.attachlabel { position: relative; display: inline-flex; }
.attachlabel input[type=file] {
    position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer;
}
.attachlabel span {
    font-size: 12.5px; color: #4A7FA7; text-decoration: underline; cursor: pointer; white-space: nowrap;
}
.attachlabel input[type=file]:focus-visible + span { outline: 2px solid #4A7FA7; outline-offset: 2px; }
.attachform button {
    font: inherit; font-size: 12px; padding: 4px 10px; border-radius: 5px;
    border: 1px solid var(--line); background: #fff; color: var(--sub); cursor: pointer;
}
.attachform button:hover { border-color: var(--faint); color: var(--ink); }
a.clip { text-decoration: none; }
a.clip:hover { text-decoration: underline; }

/* ------------------------------------------------------------------ */
/* Reports: charts                                                     */
/*                                                                     */
/* Geometry lives in the Razor views (SVG needs real numbers); this is  */
/* only the paint. Two rules run through all of it:                    */
/*   * marks carry the series colour, TEXT never does — values, labels  */
/*     and legends stay in ink/muted so identity is a swatch beside the */
/*     words, not the words themselves.                                */
/*   * grid and axes are recessive: 1px, near-canvas, never competing   */
/*     with the data.                                                  */
/* The series colours (#2E6DB4 / #E8720B) were run through the palette  */
/* validator: OKLab ΔE 33.2 normal vision, 24.4 protanopia — pass. The  */
/* UI accent #4A7FA7 FAILED the chroma floor, which is why charts do    */
/* not reuse the link colour.                                          */
/* ------------------------------------------------------------------ */
/* Same reason as .photopanel: it overrides part of `.hobart .panel`'s padding shorthand. */
.hobart .chartpanel { padding-bottom: 18px; }

.charthead {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 20px; flex-wrap: wrap; margin-bottom: 14px;
}
.charthead h2 { margin: 0; font-size: 15.5px; font-weight: 700; color: #1B2028; }
.chartsub { margin: 3px 0 0; font-size: 12.5px; color: var(--faint2); }

/* Legend — always present for two or more series. */
.legend { list-style: none; margin: 0; padding: 0; display: flex; gap: 16px; flex-wrap: wrap; }
.legend li { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--sub); }
.swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }

/* A second measure in a different unit becomes a stat tile, never a second axis. */
.stat { display: flex; flex-direction: column; gap: 2px; text-align: right; }
.statlabel {
    font-size: 10.5px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--faint2);
}
.statvalue { font-size: 18px; font-weight: 800; color: #1B2028; font-variant-numeric: tabular-nums; }

/* The plot. The viewBox fixes the aspect ratio, so the height must be allowed to follow
   the width — capping it makes the browser letterbox the drawing and the plot shrinks into
   the middle of a wide empty box. The panel already sits inside a 1360px shell, so the tall
   end of this is about 340px. */
.chart { display: block; width: 100%; height: auto; overflow: visible; }
.chart g { cursor: default; }
.chart g:hover rect, .chart g:hover circle { filter: brightness(.92); }

.chart .grid { stroke: #E4E8EC; stroke-width: 1; }
.chart .axisline { stroke: #C9D0D9; stroke-width: 1; }
.chart .axis { font-size: 10.5px; fill: #6B7684; }
.chart text.num { text-anchor: end; dominant-baseline: middle; }
.chart text.mid { text-anchor: middle; }
/* Best-to-worst range behind the line: the dealership's own band, not a benchmark. */
.chart .band { fill: #2E6DB4; opacity: .07; }
/* A month with no average gets a tick on the baseline instead of a point at zero. */
.chart .nodata { stroke: #B6BEC8; stroke-width: 2; }
.chart .series1line { fill: none; stroke: #2E6DB4; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }

/* Ordered age bins. One hue carries magnitude; the oldest bin is a STATE, so it
   takes the serious status colour and also says so in words. */
.buckets {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px;
    align-items: end; padding-top: 6px;
}
.bucket { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.bucketvalue { font-size: 20px; font-weight: 800; color: #1B2028; font-variant-numeric: tabular-nums; }
.bucketvalue.concern { color: #B02A21; }
.bucketbar {
    width: 100%; max-width: 84px; height: 130px; display: flex; align-items: flex-end;
    background: #F4F6F8; border-radius: 4px; overflow: hidden;
}
.bucketfill { width: 100%; min-height: 4px; background: #2E6DB4; border-radius: 4px 4px 0 0; }
.bucketfill.concern { background: #D32F2F; }
.bucketlabel {
    font-size: 12px; color: var(--sub); text-align: center; display: flex;
    flex-direction: column; align-items: center; gap: 4px;
}
.concerntag {
    font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: #B02A21; background: #FBEAE5; border: 1px solid #EFC4BC;
    border-radius: 3px; padding: 2px 6px; white-space: nowrap;
}

/* Horizontal bars: identity on the reading axis, value direct-labelled.
   
   Named "rank" rather than "hbar" because .hbar is ALREADY the Hobart top bar,
   fifty lines up. Two top-level rules, same specificity, so the later one won:
   every page's top bar was being laid out as a 160px/1fr/40px grid, which is
   what pushed 261px of horizontal scroll onto every single screen at phone
   width and stacked the brand, the tabs and the actions into three rows. In
   the other direction, every row of "cars sold per person" picked up the top
   bar's white background, bottom rule and drop shadow.
   
   Confirmed by asking a browser for the computed style of .hbar on nine
   rendered pages, not by reading the cascade — I had read it and got it
   backwards first. */
.rankbars { display: flex; flex-direction: column; gap: 10px; }
.rankbar { display: grid; grid-template-columns: 160px 1fr 40px; gap: 12px; align-items: center; }
.rankbarname {
    font-size: 13px; color: #1B2028; font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rankbartrack { height: 16px; background: #F4F6F8; border-radius: 4px; overflow: hidden; }
.rankbarfill { height: 100%; min-width: 3px; background: #2E6DB4; border-radius: 0 4px 4px 0; }
.rankbarvalue { font-size: 13px; font-weight: 700; color: #1B2028; text-align: right; font-variant-numeric: tabular-nums; }

/*
   Three widths, as a bounded ladder rather than overlapping max-widths.

   Written as a range on purpose: the middle rule used to live in a later
   max-width: 820px block, which meant that at 390px it re-declared three
   columns while the phone rule's grid-template-areas still described two — so
   the bar landed in the 110px name column and rendered at 110px instead of
   250px. It looked plausible enough to miss and was only obvious side by side
   with the desktop render.
*/
@media (min-width: 561px) and (max-width: 820px) {
    .rankbar { grid-template-columns: 110px 1fr 32px; gap: 8px; }
}

/* On a phone the name column leaves nothing for the bar, so the name moves
   above its own row and the bar gets the full width. */
@media (max-width: 560px) {
    .rankbar { grid-template-columns: 1fr 40px; grid-template-areas: "name name" "track value"; row-gap: 4px; }
    .rankbarname { grid-area: name; white-space: normal; }
    .rankbartrack { grid-area: track; }
    .rankbarvalue { grid-area: value; }
}

/* Every chart ships a table view. */
.tableview { margin-top: 14px; border-top: 1px solid var(--rowline); padding-top: 10px; }
.tableview summary {
    cursor: pointer; font-size: 12.5px; font-weight: 600; color: #4A7FA7; list-style: none;
}
.tableview summary::-webkit-details-marker { display: none; }
.tableview summary:hover { text-decoration: underline; }
.tableview summary:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }
.tableview table { margin-top: 10px; }

.chartnote { margin-top: 12px; font-size: 12.5px; color: var(--faint2); }

/* ------------------------------------------------------------------ */
/* Reports: customer statement (built to be printed and handed over)   */
/* ------------------------------------------------------------------ */
.statement h3 {
    margin: 22px 0 10px; font-size: 13px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--faint2);
}
.statement h3:first-of-type { margin-top: 8px; }
.stmthead {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 20px; flex-wrap: wrap; padding-bottom: 16px; border-bottom: 2px solid #1B2028;
}
.stmthead h2 { margin: 0; font-size: 20px; font-weight: 800; }
.stmtmeta { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 5px; font-size: 12.5px; color: var(--faint2); }
.stmtperiod { display: flex; flex-direction: column; gap: 2px; text-align: right; }
.stmtperiod .statvalue { font-size: 14px; }

.stmttotals {
    margin-top: 24px; padding-top: 16px; border-top: 2px solid #1B2028;
    display: flex; justify-content: flex-end; gap: 32px; flex-wrap: wrap;
}
.stmttotals > div { display: flex; flex-direction: column; gap: 2px; text-align: right; }
.stmttotals .grand .statvalue { font-size: 22px; }
.stmttotals .grand .statlabel { color: #1B2028; }

.printrow { margin-top: 18px; display: flex; justify-content: flex-end; }

/* The letterhead exists only on paper. */
.printonly { display: none; }
.stmtletterhead { justify-content: space-between; align-items: baseline; padding-bottom: 14px; }
.stmtdealer { font-size: 17px; font-weight: 800; color: #1B2028; }
.stmtprinted { font-size: 11px; color: #5A6470; }

/* Don't rely on the browser's default print margin — headless printers use none at all,
   which runs the totals off the edge of the paper. */
@page { margin: 14mm; }

@media print {
    .noprint, .hbar, .hbar-in, .htabs, .hactions, .skiplink { display: none !important; }
    /* body.hobart sets the canvas grey and is more specific than a bare `body`, so it has
       to be overridden by name or the printer lays down a full page of ink. */
    body, body.hobart { background: #fff; font-size: 12px; }
    .printonly { display: flex; }
    .hmain { padding: 0; max-width: none; }
    .hobart .panel, .hobart .statement { border: 0; box-shadow: none; padding: 0; background: #fff; }
    .statement h3 { margin-top: 18px; }
    table.rows { page-break-inside: avoid; }
    a { color: #1B2028; text-decoration: none; }
    /* Letter paper is ~816 CSS px, which is under the 820px phone breakpoint — without
       these the printed page inherits the stacked mobile layout. */
    .stmthead { flex-direction: row; }
    .stmtperiod { text-align: right; align-items: flex-end; }
    .stmttotals { justify-content: flex-end; }

    /*
        Browsers strip background colours when printing, to save ink. On these
        pages the background colour IS the information: the Monday title-chase
        list printed with its colour column blank, and the aging chart printed
        as four numbers above four empty boxes. Both are the reason somebody
        printed the page.
        
        Asked for only on the marks that carry meaning, not document-wide —
        the point of the default is to not lay down a page of ink.
    */
    .pill, .dot, .rankbarfill, .bucketbar, .bucketfill,
    .chartbar, .chartfill, .legendswatch, .warrantybadge, .concerntag {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    /* An outline survives even where colour does not, so a printed pill is
       still a distinct shape rather than a floating word. */
    .pill { border: 1px solid #6B7480 !important; }

    /* Every chart ships a table view; on paper it is the more useful of the two,
       so it prints open regardless of whether it was expanded on screen. */
    .tableview[open] table, .tableview table { display: table !important; }
    .tableview summary { display: none; }
}

/* Scoped to `screen`: Letter paper measures under 820px, so an unscoped max-width block
   also applies while printing and would stack the statement as if it were a phone. */
@media screen and (max-width: 820px) {
    .buckets { gap: 10px; }
    .bucketbar { height: 96px; }
    .charthead, .stmthead { flex-direction: column; }
    .stat, .stmtperiod { text-align: left; align-items: flex-start; }
    .stmttotals { justify-content: flex-start; }
}

/* ------------------------------------------------------------------ */
/* List | Pictures | Board                                             */
/* ------------------------------------------------------------------ */
.viewswitch {
    display: inline-flex; gap: 2px; padding: 3px; margin-bottom: 16px;
    background: #E4E8EC; border-radius: 8px;
}
.viewswitch a {
    padding: 6px 14px; border-radius: 6px; font-size: 13px; font-weight: 600;
    color: #4A5563; text-decoration: none; white-space: nowrap;
}
.viewswitch a:hover { color: #1B2028; }
.viewswitch a.on { background: #fff; color: #1B2028; box-shadow: 0 1px 2px rgba(20,25,32,.10); }
.viewswitch a:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }

/* ------------------------------------------------------------------ */
/* Photo grid: "our cars as pictures"                                  */
/* ------------------------------------------------------------------ */
/* The photo grid's own Person/Make/Year row is gone: all three views share
   _FilterBar now, so the product has one filter row rather than three that
   could drift apart. */
.clearall { font-size: 13px; color: #4A7FA7; align-self: center; }

.photogrid {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 18px;
}
.photocard {
    background: #fff; border: 1px solid #DDE1E6; border-radius: 8px; overflow: hidden;
    box-shadow: 0 2px 12px rgba(20,25,32,.06); display: flex; flex-direction: column;
}
.photolink { display: block; line-height: 0; }
.photocard img { width: 100%; height: 168px; object-fit: cover; object-position: center; }
/* A car with no photo says so, rather than showing a broken image or an empty box. */
.nophoto {
    display: grid; place-items: center; height: 168px; background: #F4F6F8;
    font-size: 12.5px; color: var(--faint); line-height: 1.4;
}
.photobody { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.photobody .carlink { font-size: 14px; font-weight: 700; }
.photometa { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; font-size: 12.5px; color: var(--faint2); }
.soldto { color: var(--ink); }

/* ------------------------------------------------------------------ */
/* Board: every colour is a column                                     */
/* ------------------------------------------------------------------ */
/* Columns share the width rather than scrolling sideways: a dealer with six colours should
   see all six at once, which is the whole reason to look at a board. */
.boardcols { display: flex; gap: 10px; align-items: flex-start; }
.boardcol {
    flex: 1 1 0; min-width: 0;
    background: #E9ECF0; border-radius: 8px; padding: 10px;
}
.boardcolhead { display: flex; align-items: baseline; gap: 7px; padding: 2px 3px 10px; }
/* Wrap rather than ellipsis: "Ready for sale" and "Arbitration" are the two longest column
   names Hobart uses, and truncating them to "READY ..." tells the reader nothing. */
.boardcolname {
    flex: 1 1 auto; min-width: 0;
    font-size: 11px; font-weight: 800; letter-spacing: .03em; text-transform: uppercase;
    color: #3A4350; line-height: 1.3;
}
.boardcolhead .dot { flex: 0 0 auto; position: relative; top: -1px; }
.boardcount {
    margin-left: auto; font-size: 11.5px; font-weight: 700; color: #5A6470;
    background: #fff; border-radius: 10px; padding: 1px 8px;
}

.boardlist {
    list-style: none; margin: 0; padding: 0; min-width: 0;
    display: flex; flex-direction: column; gap: 8px; min-height: 60px;
}
.boardcard {
    background: #fff; border: 1px solid #DDE1E6; border-radius: 6px; padding: 9px 10px;
    box-shadow: 0 1px 2px rgba(20,25,32,.06); cursor: grab; min-width: 0;
}
/* A long name like "2018 Chevrolet Silverado 1500 LT" has to be allowed to wrap, or its
   min-content width stops the column shrinking and the whole board scrolls sideways. */
.boardcard .carlink {
    font-size: 12.5px; font-weight: 700; display: block; line-height: 1.35;
    overflow-wrap: anywhere;
}
.boardmeta { margin-top: 3px; font-size: 11.5px; color: var(--faint2); }
.boardnote { margin-top: 5px; font-size: 11.5px; color: var(--sub); overflow-wrap: anywhere; }
.boardcard.isdragging { opacity: .45; }
/* "Drop here" only lights up on a column this person may actually move the car to. */
.boardlist.dropok { outline: 2px dashed #4A7FA7; outline-offset: 3px; border-radius: 6px; }
.boardempty { font-size: 12px; color: var(--faint); padding: 8px 4px; }

.movebox.small { margin-top: 8px; }
.movebox.small .movetrigger {
    cursor: pointer; list-style: none; font-size: 12px; font-weight: 600; color: #4A7FA7;
}
.movebox.small .movetrigger::-webkit-details-marker { display: none; }
.movebox.small .movetrigger:hover { text-decoration: underline; }
.movebox.small .movetrigger:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }

@media (max-width: 1100px) {
    /* Below this the columns are too narrow to read a car's name, so let the board scroll
       sideways rather than squeezing every title into a vertical stack of single words. */
    .boardcols { overflow-x: auto; padding-bottom: 10px; }
    .boardcol { flex: 0 0 200px; }
}

/* ------------------------------------------------------------------ */
/* People and roles                                                    */
/* ------------------------------------------------------------------ */
.personemail { display: block; font-size: 12px; color: var(--faint2); margin-top: 2px; }
.youtag {
    display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 3px;
    background: var(--accentbg); color: var(--accent);
    font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
}
.roleform { display: flex; gap: 8px; align-items: center; }
.roleform select {
    padding: 6px 9px; font: inherit; font-size: 13px; border: 1px solid var(--line);
    border-radius: 6px; background: #fff; color: var(--ink); min-width: 150px;
}
.roleform select:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 1px; }
.roleform .hbtn { padding: 6px 12px; font-size: 12.5px; }
.roledesc, .lockednote { display: block; margin-top: 5px; font-size: 12px; color: var(--faint2); }
.lockednote { font-style: italic; }

/* A switched-off person stays on the list — their name is on the work they did — but reads
   as inactive rather than being silently dropped. */
tr.offrow > td { opacity: .55; }
tr.offrow b { text-decoration: line-through; }

.linkbtn {
    background: none; border: 0; padding: 0; font: inherit; font-size: 12.5px;
    color: #4A7FA7; cursor: pointer; text-decoration: underline;
}
.linkbtn:hover { color: #1B2028; }
.linkbtn:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }

/* The one-time setup link. Shown once and never stored, so it has to be easy to select. */
.setuplink { margin-top: 10px; }
.setuplink code {
    display: block; padding: 10px 12px; background: #fff; border: 1px solid #A8CDB4;
    border-radius: 6px; font-size: 12.5px; word-break: break-all; user-select: all;
    color: var(--ink);
}
.setupnote { display: block; margin-top: 6px; font-size: 12px; color: var(--green); }

/* ------------------------------------------------------------------ */
/* Neutral pages: access denied, no role yet, error, 404               */
/*                                                                     */
/* No dealership name and no navigation on purpose. The old Access-    */
/* denied page inherited the reconditioning product's dark chrome, so  */
/* a dealership user who hit it saw another product's branding and a   */
/* breadcrumb reading "Reconditioning".                                */
/* ------------------------------------------------------------------ */
.plainshell {
    min-height: 100vh; display: grid; place-items: center;
    padding: 24px; background: #EFF1F4;
}
.plaincard {
    width: 100%; max-width: 460px; background: #fff; border: 1px solid #DDE1E6;
    border-radius: 10px; padding: 32px 28px; box-shadow: 0 2px 16px rgba(20,25,32,.07);
    font-family: Archivo, "Segoe UI", system-ui, sans-serif; color: #1B2028;
}
.plaintitle { margin: 0 0 12px; font-size: 20px; font-weight: 800; line-height: 1.3; }
.plainbody { margin: 0 0 14px; font-size: 14px; line-height: 1.6; color: #3A4350; }
.plainmeta { margin: 0 0 18px; font-size: 12.5px; color: #5A6470; line-height: 1.6; }
.plainmeta code, .tracecode {
    display: inline-block; padding: 4px 8px; background: #F4F6F8; border: 1px solid #E4E8EC;
    border-radius: 4px; font-size: 12px; word-break: break-all; user-select: all;
}
.plainfoot { margin: 18px 0 0; font-size: 12.5px; color: #5A6470; line-height: 1.6; }
.plainform { margin-top: 8px; }
.plaincard .hbtn { display: inline-block; }

/* ------------------------------------------------------------------ */
/* Car photos                                                          */
/* ------------------------------------------------------------------ */
.nophoto.tall {
    height: 200px; gap: 4px; padding: 20px; text-align: center;
    /* --faint failed contrast on near-white; this is the same fix applied elsewhere. */
    color: var(--faint2);
}
.nophoto.tall b { font-size: 14px; color: var(--ink); }

/* The panel is padding:0 so the photo can bleed to the card edge, which means everything
   below it supplies its own gutter — 20px to line up with .panel's own padding. */
.photoform {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 14px 20px 18px; margin-top: 0; border-top: 1px solid var(--rowline);
}
/* The file input is visually replaced by the label's button, but stays focusable and
   keyboard-operable — it is not display:none. */
.photolabel { position: relative; display: inline-flex; }
.photolabel input[type="file"] {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; cursor: pointer;
}
.photolabel input[type="file"]:focus-visible + span { outline: 2px solid #4A7FA7; outline-offset: 2px; }
.photoprimary { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--sub); }
/* 44px minimum: this is thumbed on a lot, outdoors, one-handed. */
.photoprimary input { width: 20px; height: 20px; }

.photostrip {
    list-style: none; margin: 14px 0 18px; padding: 0 20px;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 10px;
}
.photostrip li {
    position: relative; border: 1px solid #DDE1E6; border-radius: 6px; overflow: hidden;
    background: #F4F6F8;
}
.photostrip li.isprimary { border-color: #4A7FA7; box-shadow: 0 0 0 1px #4A7FA7; }
/* The photo currently ON the stage. Distinct from .isprimary on purpose: "this is the main
   picture" and "this is the one you are looking at" are different facts, and both need to
   be visible at once. */
.photostrip li.isshown { border-color: #1B2028; box-shadow: 0 0 0 2px #1B2028; }
.photostrip .thumblink { display: block; }
.photostrip .thumblink:focus-visible { outline: 2px solid #3D6A8C; outline-offset: 2px; }
.photostrip img { display: block; width: 100%; height: 84px; object-fit: cover; }
.primarytag {
    position: absolute; top: 6px; left: 6px; padding: 2px 7px; border-radius: 3px;
    background: rgba(27,32,40,.82); color: #fff;
    font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.photoremove {
    display: block; width: 100%; padding: 9px 6px; border: 0; border-top: 1px solid #DDE1E6;
    background: #fff; color: #B02A21; font: inherit; font-size: 12px; font-weight: 600;
    cursor: pointer; min-height: 36px;
}
.photoremove:hover { background: #FBEAE5; }
.photoremove:focus-visible { outline: 2px solid #B02A21; outline-offset: -2px; }

/* ------------------------------------------------------------------ */
/* Form helpers shared by the new screens                              */
/* ------------------------------------------------------------------ */
.backlink { display: inline-block; margin-bottom: 12px; font-size: 13px; color: #4A7FA7; }
.formlead { margin: 0 0 18px; font-size: 13.5px; line-height: 1.6; color: var(--sub); }
.fieldhint { display: block; margin-top: 5px; font-size: 12px; color: var(--faint2); }
.optional {
    font-size: 10px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
    color: var(--faint2);
}
.noticelist { margin: 0; padding-left: 18px; }
.noticelist li + li { margin-top: 4px; }

/* ------------------------------------------------------------------ */
/* Corrections                                                         */
/*                                                                     */
/* Fixing a typo has to be reachable from the typo, but it must not     */
/* compete with the data for attention — a table where every row shouts */
/* "EDIT" stops reading as a table. So the correction row is quiet, and */
/* recessive until opened.                                             */
/* ------------------------------------------------------------------ */
/*
    A correction row must read as belonging to the job ABOVE it.

    Found by looking at it in a browser, which is the only way it could have been
    found: measured, everything was correct — the row existed, its colspan was
    right, its controls worked. But the job row and the correction row each had an
    identical bottom border, so the grey band sat exactly equidistant between two
    jobs with no cue tying it to either. On a three-job car it was genuinely
    ambiguous which job "Fix this job" would edit, and clicking the wrong one
    edits the wrong cost.

    Two changes make the pair read as one block: the border between a job and its
    own correction row is removed, and the correction row carries a left accent
    bar. The border after the correction row stays, so the boundary falls between
    jobs rather than inside one.
*/
table.rows tr:has(+ tr.fixrow) > td {
    border-bottom: 0;
}

.fixrow > td {
    padding: 2px 12px 10px;
    border-bottom: 1px solid var(--rowline);
    background: #F4F7FA;
    box-shadow: inset 3px 0 0 #D3DDE7;
}
.fixbox { margin-top: 8px; }
.fixbox > summary {
    display: inline-block; cursor: pointer; font-size: 12px; font-weight: 600;
    color: #4A7FA7; padding: 4px 0; list-style: none;
}
.fixbox > summary::-webkit-details-marker { display: none; }
.fixbox > summary::before { content: "✎ "; }
.fixbox > summary:hover { text-decoration: underline; }
.fixbox > summary:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }
.fixbox[open] > summary { margin-bottom: 10px; }

.inlineform { display: inline-flex; align-items: center; gap: 10px; margin: 8px 12px 0 0; }

/*
    Parts under a job. The parts row belongs to the job above it the same way the
    correction row does, so it joins the same visual block: no border between a job
    and its parts, none between the parts and the correction row, and the same left
    accent so the whole stack reads as one job.
*/
table.rows tr:has(+ tr.partsrow) > td {
    border-bottom: 0;
}
tr.partsrow:has(+ tr.fixrow) > td {
    border-bottom: 0;
}
.partsrow > td {
    padding: 0 12px 8px;
    border-bottom: 1px solid var(--rowline);
    background: #F4F7FA;
    box-shadow: inset 3px 0 0 #D3DDE7;
}
.partlist {
    list-style: none; margin: 6px 0 0; padding: 0;
    font-size: 12.5px;
}
.partlist li {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
    padding: 3px 0;
}
.partqty { font-weight: 600; }
.partswarn {
    margin: 6px 0 0; font-size: 12.5px; color: #856900;
    background: #FFF3D8; border: 1px solid #EAD9A6; border-radius: 5px;
    padding: 6px 10px; display: inline-block;
}
/* A text-sized action inside a dense list — still a real button, still 44px on touch. */
.linklike {
    background: none; border: 0; padding: 2px 4px; font-size: 12px; cursor: pointer;
    color: #4A7FA7; text-decoration: underline; text-underline-offset: 2px;
}
.linklike.danger { color: #B02A21; }
.linklike:hover { color: #1B2028; }
.linklike:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }
@media (pointer: coarse) {
    .linklike { padding: 12px 10px; min-height: 44px; }
}
.partremove { margin: 0; }

/* A shelf part that has sat too long. The number itself turns loud — the row is the
   report, and 60 days is when "waiting" becomes "stranded". */
.shelfold { color: #B02A21; }

/* A 32px-high button is fine for a mouse and wrong for a thumb, so the
   small variant keeps a 44px touch target via padding on coarse pointers. */
.hbtn.small { padding: 6px 12px; font-size: 12px; }
@media (pointer: coarse) {
    .hbtn.small { padding: 12px 16px; min-height: 44px; }
}

/* Destructive actions read as destructive, and sit apart from the save
   button so the two are never adjacent under a thumb. */
.hbtn.ghost.danger { color: #B02A21; border-color: #E3B7B1; }
.hbtn.ghost.danger:hover { background: #FBEAE5; color: #8E1F18; }
.removeform {
    margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--rowline);
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
}

/* The asking-price panel. The number is the point, so it gets the same
   weight as the "Spent so far" total it sits above. */
.pricepanel .total { font-size: 15px; }


/* ------------------------------------------------------------------ */
/* Phones                                                              */
/*                                                                     */
/* The technician in the shop and the salesperson on the lot are phone  */
/* users. Everything in this block is a measured defect, not a guess —  */
/* nine rendered pages were measured at 390px in a real browser.        */
/* ------------------------------------------------------------------ */

/*
    Safari zooms the whole page when a focused input's text is under 16px, and
    never zooms back out. Every input in this application was 13px, so tapping
    the search box left the lot's staff at ~140% with the top bar off-screen.

    Applied on coarse pointers rather than by width, because the trigger is the
    on-screen keyboard, not the viewport: a small window on a desktop does not
    need it, and a large tablet does.
*/
@media (pointer: coarse) {
    input:not([type=checkbox]):not([type=radio]):not([type=hidden]),
    select, textarea,
    /* Named explicitly because each of these is more specific than a bare
       element selector and quietly won. Measured, not assumed: after the first
       attempt every text input reported 16px and every <select> still reported
       13px, on the car page, the People screen and the photo grid. */
    .addform input, .addform select,
    .roleform select,
    /* The shared filter row is the same story: .hobart .carfilters input is two
       classes deep and beat the bare element selector, so tapping the search box
       on a phone zoomed the whole board. */
    .hobart .carfilters input, .hobart .carfilters select,
    .formgrid input, .formgrid select, .formgrid textarea,
    .input, select.input, textarea.input {
        font-size: 16px;
    }
}

/*
    Tables wider than the phone. Without a wrapper the TABLE pushes the
    DOCUMENT wide, so the whole page scrolls sideways and the sticky header
    slides off with it — the recon side of the app has had this fix all along
    and it was never applied to these screens. With the wrapper only the table
    scrolls, and the page stays put.
*/
.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tablewrap > table { min-width: 100%; }

/* A scrollable region has to be reachable by keyboard, or its contents are
   unreachable without a mouse or a finger. */
.tablewrap:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }

@media (pointer: coarse) {
    /* 44px is the smallest reliable touch target. Measured before this: the
       nav tabs 34px, the board's move control ~14px, "Turn off" on the People
       screen ~15px. Only the title YES/NO buttons already cleared it. */
    .htabs a, .hactions .hbtn, .hsignout button,
    /* .chip is scoped: a 44px floor on the recon product's small inline tags would distort
       13 of its screens on any touch device, and none of those chips are tap targets. */
    .viewswitch a, .hobart .chip, .moveopt, .pillbtn, .rowaction {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
    }

    /* Inline text buttons in table rows get their height from padding rather
       than a min-height, so the row does not grow by 30px per cell. */
    .rowaction { padding: 12px 10px; }
}

/*
    One long note must not destroy the board. The card note is the work item's
    whole description, and that field allows a thousand characters, with nothing
    clamping it — one chatty technician turned a 178px card into a column the
    height of the screen and pushed every other column out of view.
*/
.boardnote {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ------------------------------------------------------------------ */
/* Confirming something irreversible                                   */
/*                                                                     */
/* A <details> rather than a JS confirm(): it needs no script, cannot   */
/* be defeated by a misfired tap, and degrades to a plain visible       */
/* button if anything about it fails. Opening is one deliberate action  */
/* and confirming is a second.                                         */
/* ------------------------------------------------------------------ */
.confirmbox > summary {
    cursor: pointer; list-style: none; font-size: 12.5px; font-weight: 600;
    color: #B02A21; padding: 8px 10px; border-radius: 4px; display: inline-flex;
    align-items: center;
}
.confirmbox > summary::-webkit-details-marker { display: none; }
.confirmbox > summary:hover { background: #FBEAE5; text-decoration: underline; }
.confirmbox > summary:focus-visible { outline: 2px solid #B02A21; outline-offset: 1px; }
.confirmbody {
    margin-top: 8px; padding: 10px 12px; background: #FBEAE5;
    border: 1px solid #EFC4BC; border-radius: 4px; max-width: 320px;
}
.confirmbody .muted { margin: 0 0 10px; font-size: 12.5px; }

/* Inline row controls need a real target without stretching the row. */
.rowaction { min-height: 36px; display: inline-flex; align-items: center; white-space: nowrap; }
/* The people list lives in a .narrow 780px column, which left 91px for "Signed in" and 81px for
   "Access" — so "Aug 12, 2026" and "Turn off" each broke across two lines on every row. Both are
   short, indivisible labels; refusing to wrap them costs "What they can do" eight pixels it has
   to spare and stops a destructive control reading as two words stacked in a corner. */
td.peoplewhen { white-space: nowrap; }


/* ------------------------------------------------------------------ */
/* Panels inside a form                                                */
/*                                                                     */
/* .addform is display:flex/wrap, so a <section class="panel"> placed   */
/* directly inside one becomes a FLEX ITEM and sizes itself to its own  */
/* content. On the settings screen that produced four panels of three   */
/* different widths — 780, 722, 780, 780 — stepping in and out by sixty */
/* pixels down the page. Every individual panel was correct; only the   */
/* set of them was wrong, which is why it took looking at the page      */
/* rather than checking any one thing.                                  */
/* ------------------------------------------------------------------ */
.addform > .panel {
    flex: 0 0 100%;
    width: 100%;
}

/* Fields stacked inside a panel are plain blocks, not flex children, so they
   inherit none of the form's gap and the first label crowds the paragraph above
   it. */
.addform > .panel .field + .field,
.addform > .panel p + .field {
    margin-top: 14px;
}

/* ------------------------------------------------------------------
   Checking a car in, from a phone.

   Sized for a thumb and one hand: every control is at least 48px tall, the
   mileage box is deliberately oversized because it is the one number with a
   workflow gate behind it, and the whole column is capped so the screen is
   still sane on the office laptop.

   All new selector names, so none of this can reach the recon product.
   ------------------------------------------------------------------ */
.hobart .intake {
    max-width: 560px; margin: 0 auto; padding: 4px 14px 40px;
}
.hobart .intaketitle {
    font-size: 22px; font-weight: 700; margin: 10px 0 2px; letter-spacing: -0.01em;
}
.hobart .intakesub {
    font-size: 13px; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.04em; color: #5A6472; margin: 22px 0 8px;
}
.hobart .intakehead { margin-bottom: 6px; }
.hobart .intakemeta { font-size: 12.5px; color: #5A6472; display: block; }
.hobart .intakenote { font-size: 12.5px; color: #856900; display: block; margin-top: 2px; }
.hobart .intakedone { font-size: 12px; color: #2E7D46; display: block; margin-top: 2px; }

.hobart .intakelist { list-style: none; margin: 0; padding: 0; }
.hobart .intakelist li { margin-bottom: 8px; }
.hobart .intakelist a {
    display: block; padding: 14px 16px; min-height: 48px;
    background: #fff; border: 1px solid var(--rowline); border-radius: 8px;
    text-decoration: none; color: inherit;
}
.hobart .intakelist a:active { background: #F4F7FA; }
.hobart .intakelist a:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; }
.hobart .intakecar { display: block; font-weight: 600; font-size: 15.5px; }

.hobart .intakesearch { display: flex; gap: 8px; }
.hobart .intakesearch input {
    flex: 1; min-height: 48px; font-size: 16px; padding: 10px 12px;
    border: 1px solid var(--rowline); border-radius: 8px;
}
.hobart .intakesearch .hbtn { min-height: 48px; }

.hobart .intakeform { margin-top: 18px; }
.hobart .intakefield { margin-bottom: 18px; }
.hobart .intakefield label { display: block; font-weight: 600; font-size: 14px; margin-bottom: 6px; }
.hobart .intakefield input {
    width: 100%; min-height: 48px; padding: 10px 12px;
    border: 1px solid var(--rowline); border-radius: 8px;
    /* 16px minimum, or iOS zooms the page on focus and the layout jumps. */
    font-size: 16px;
}
.hobart .intakehint { display: block; font-size: 12.5px; color: #5A6472; margin-top: 5px; }

/* The number the mileage gate depends on. Big enough to check at arm's length. */
.hobart .intakenumber { font-size: 30px !important; font-weight: 700; letter-spacing: 0.01em; }

.hobart .intakeshots {
    border: 1px solid var(--rowline); border-radius: 8px; padding: 12px;
    margin-bottom: 18px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
}
.hobart .intakeshots legend { font-weight: 600; font-size: 14px; padding: 0 6px; }
.hobart .intakeshot {
    display: flex; align-items: center; justify-content: center; text-align: center;
    min-height: 64px; padding: 10px; cursor: pointer;
    background: #F4F7FA; border: 1px dashed #C6D2DE; border-radius: 8px;
    font-size: 14px; font-weight: 600; color: #3D6A8C;
}
/* The input is the tap target's mechanism, not its appearance. */
.hobart .intakeshot input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.hobart .intakeshot:active { background: #E8EEF4; }
.hobart .intakeshot:focus-within { outline: 2px solid #4A7FA7; outline-offset: 2px; }
.hobart .intakeshot::before { content: "📷"; margin-right: 8px; font-size: 17px; }

.hobart .intakesubmit {
    width: 100%; min-height: 56px; font-size: 17px; font-weight: 700; margin-top: 4px;
}

/* The one filter row, on all three views of the cars. */
.hobart .carfilters {
    display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
    margin: 12px 0 6px;
}
.hobart .carfilters .field { display: flex; flex-direction: column; gap: 4px; }
.hobart .carfilters .field.grow { flex: 1 1 260px; }
.hobart .carfilters label {
    font-size: 11px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: #5A6472;
}
.hobart .carfilters input,
.hobart .carfilters select {
    min-height: 38px; padding: 7px 10px; font-size: 14px;
    border: 1px solid var(--rowline); border-radius: 6px; background: #fff;
}
.hobart .filteractions { display: flex; align-items: center; gap: 12px; }
.hobart .filtercount { font-size: 13px; color: #5A6472; margin: 2px 0 10px; }
.hobart .filtercount b { color: #1B2028; }

/* Photos on the board. Sized so a column still shows several cards at once — the board's
   job is the whole lot at a glance, and a wall of large pictures is a different screen
   (that screen is Pictures). */
.hobart .boardshot {
    display: block; margin: -2px -2px 8px; border-radius: 6px; overflow: hidden;
    background: #EFF1F4; aspect-ratio: 4 / 3;
}
.hobart .boardshot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hobart .boardnoshot {
    display: flex; align-items: center; justify-content: center; height: 100%;
    font-size: 11.5px; color: #8A94A2;
}

/* The photos checkbox sits with the filters, not with the view tabs: choosing a view and
   choosing how that view looks are different kinds of decision. */
.hobart .photocheck {
    display: flex; align-items: center; gap: 7px;
    font-size: 14px; font-weight: 600; cursor: pointer;
    padding: 0 2px; min-height: 38px; white-space: nowrap;
}
.hobart .photocheck input { width: 17px; height: 17px; margin: 0; cursor: pointer; }
.hobart .photocheck:focus-within { outline: 2px solid #4A7FA7; outline-offset: 3px; border-radius: 4px; }

/* Sign-in: the forgot-password link sits on the password label's row, per the v3 wireframe.
   Not scoped to .hobart on purpose - the sign-in screen is shared by both products and both
   want the link. It adds two classes rather than redefining anything either product uses. */
.fieldrow { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.forgotlink { font-size: 12px; color: #4A7FA7; text-decoration: none; }
.forgotlink:hover { text-decoration: underline; }
.forgotlink:focus-visible { outline: 2px solid #4A7FA7; outline-offset: 2px; border-radius: 3px; }
.forgotlead { font-size: 14px; line-height: 1.55; margin: 4px 0 14px; }

/* ==========================================================================
   Accessibility and consistency fixes from the design audit
   (design/claude-design/hobart/AUDIT.md).

   Every rule below is scoped to .hobart, and that is not timidity. The shared-stylesheet
   guard refused the first version of this block, correctly: an unscoped `input` or `a`
   rule at the end of this file silently restyles twenty-five of dealer one's live screens,
   which is how .chip and .panel were changed across that product once already. The audit
   was of THIS tenant, the findings were measured on THIS tenant's screens, and a shared
   accessibility change to a live product is a decision to take with its own review rather
   than a side effect of a demo. The tokens above are the exception and are deliberate:
   --amber was failing 4.5:1 for both products and the fix is the same colour to the eye.
   ========================================================================== */

/*
    1.4.11 Non-text Contrast -- the edge of a control, at 3:1.

    --line is #DEE1E6, 1.31:1 on white, rendered under a pixel. The audit put this first even
    ignoring compliance, and it is right to: this is a form-heavy application used on a lot,
    outdoors, in daylight, on a phone, and the boundary of the box you are typing into was
    effectively invisible. A field with no visible edge stops looking like a field before it
    stops being compliant.

    Keyed on the CONTROL rather than on a list of the places a field happens to appear -- that
    list is exactly the mistake the touch rule made and had to be corrected for.
*/
.hobart input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=file]),
.hobart select,
.hobart textarea {
    border-color: var(--fieldline);
}

/*
    1.4.3 Contrast -- accent-coloured TEXT moves to the darker step already in the palette.

    #4A7FA7 is 4.30:1 on white against a 4.5 requirement, and it carries text on all eleven
    screens: every link, "Show the numbers", "Who changed this?", "+ Add another job", the
    avatar initials. #3D6A8C is 5.77:1 on white, 5.10 on the canvas and 4.86 on the accent
    tint, so it clears the bar on every surface it lands on.

    Fills keep #4A7FA7. The approved brand colour stays wherever it reads as brand and is not
    carrying text -- the active chip, the stage dots, the brand furniture. The avatar is the
    one fill that has to darken with its text, because white on #4A7FA7 is the same 4.30:1
    failure and the initials have nowhere else to go.
*/
.hobart a,
.hobart .clip, .hobart .auditlink, .hobart .backlink,
.hobart .linklike, .hobart .tableview summary {
    color: var(--accenthover);
}
.hobart .hav { background: var(--accenthover); }

/* ...and the ones that were never accent: a warning is red on every screen it appears on. */
.hobart a.warn, .hobart .boardwarn, .hobart .shelfold { color: #B02A21; }

/*
    The settings checkboxes were visibly broken, and three faults compounded to do it: a 130px
    min-width written for text fields that also applied to the checkbox, giving it a 130x13
    layout box; a block label inside a row-direction field, so control and text were inline
    content in what was left; and .fieldhint becoming a flex sibling rather than sitting under
    the field. "We carry our own paper" wrapped so that "own paper" landed on the next line to
    the LEFT of its own checkbox.

    The correct exclusion already existed in this stylesheet six hundred lines away, in the
    touch rule. It simply was not applied here.
*/
.hobart .addform input[type=checkbox],
.hobart .addform input[type=radio] { min-width: 0; width: 16px; height: 16px; }
.hobart .addform .field.checks { flex-direction: column; align-items: flex-start; gap: 4px; }
.hobart .addform .field.checks label { display: flex; align-items: center; gap: 10px; line-height: 1.35; }
.hobart .addform .field.checks .fieldhint { margin-top: 0; padding-left: 26px; }

/*
    Field width says what goes in the box. Nine settings inputs were all 739px wide: the
    sales-tax percentage ("7"), the day counts ("31"), and a two-hundred-character warranty
    company name. Width is the cheapest affordance there is and it was carrying none.
*/
.hobart .addform .field.tiny input { width: 7ch; min-width: 0; }
.hobart .addform .field.short input { width: 12ch; min-width: 0; }
.hobart .fieldunit { display: flex; align-items: center; gap: 8px; }
.hobart .fieldunit .unit { font-size: 12.5px; font-weight: 600; color: var(--faint2); }

/*
    Target size. The application adopted 44px as its own standard, with a comment saying why,
    and then applied it to a hand-written list of the places somebody had measured. Everything
    that COMMITS something -- "Save these settings", "Save the car", "Upload", "Apply" -- was
    left at desktop size on a phone, as was .carlink, which is the primary way to open a car
    from every table in the product. Keyed on the component this time.
*/
@media (pointer: coarse) {
    .hobart .hbtn, .hobart a.carlink, .hobart .clearall,
    .hobart .auditlink, .hobart .backlink, .hobart a.warn, .hobart .boardwarn,
    /* .backlink is the PARAGRAPH, not the link inside it, so the rule above lifted a block
       that was already tall enough and left the 17px anchor exactly as it was. Measured, not
       assumed -- which is the only reason this was noticed. */
    .hobart .backlink a,
    /* The one screen whose entire point is tapping these: the card is opened because the phone
       rang, and the number and the address were 15px targets. */
    .hobart .custcontact a,
    /* A <summary> is a control, not a caption: "Show the numbers" and "+ Put a part on the
       shelf" are the way into a whole panel and both measured 14px tall on a phone. */
    .hobart summary {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
    }
    /* In a table cell height comes from padding, or the row grows by 30px per cell. */
    .hobart td a.carlink, .hobart td a.warn { min-height: 0; padding: 11px 0; }

    /* Explicitly excluded from the sibling 16px rule and absent from the touch rule, so the
       two controls you tap with a thumb were the smallest things on the screen.

       Repeated at .addform depth on purpose. The first version set 22px on
       `.hobart input[type=checkbox]` and measured 16px on the settings screen anyway, because
       `.hobart .addform input[type=checkbox]` two rules above is one class more specific and
       won inside the media query. A touch rule that loses to the rule it is correcting is not
       a touch rule. */
    .hobart input[type=checkbox], .hobart input[type=radio],
    .hobart .addform input[type=checkbox], .hobart .addform input[type=radio] {
        width: 24px; height: 24px;
    }
}

/*
    The board under-weighted the one fact it exists to surface. A car waiting on its title
    renders red, semibold and linked to the chase list on /Cars; red and sorted first on
    /Cars/Titles; and on /Cars/Board it was --sub grey at 11.5px, plain text, no link --
    styled identically to "Sold to Dana Okafor", so a neutral status and a compliance warning
    looked the same. The board is the screen the shop works from all day.
*/
.hobart .boardwarn {
    display: inline-block; margin-top: 5px; font-size: 11.5px; font-weight: 600;
    text-decoration: none;
}
.hobart .boardwarn:hover { text-decoration: underline; }

/*
    The board's columns had no container, so a lane was inferred from alignment alone and the
    empty space under a short column read as the end of the board rather than an empty lane.
    Faint enough to stay out of the way of the cards.
*/
.hobart .boardcol { background: rgba(27, 32, 40, .022); border-radius: 8px; padding: 6px; }

/* A picture that is not of this car says so, in the amber the product already uses for
   "true, and you should know it" rather than the red it uses for "something is wrong". */
.hobart .stockshot {
    margin: 10px 0 0; padding: 9px 12px; font-size: 12.5px; line-height: 1.45;
    background: var(--amberbg); color: var(--amber);
    border-left: 3px solid var(--amber); border-radius: 0 4px 4px 0;
}
.hobart .stockshot b { font-weight: 700; }

/*
    The customer card's identity block.

    The three contact details used to run together in one grey line separated by the same dot
    -- "(219) 555-1411 · 3569 Wisconsin Avenue, Griffith, IN · twojcik@example.com" -- which on
    a phone wrapped into a paragraph with a dangling dot at the end of a line. They are three
    different kinds of thing and one of them is the reason the screen exists.
*/
.hobart .custid { display: flex; align-items: flex-start; gap: 14px; }
.hobart .custav {
    flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%;
    background: var(--accenthover); color: #fff;
    display: grid; place-items: center;
    font-size: 15px; font-weight: 700; letter-spacing: .02em;
    margin-top: 2px;
}
.hobart .custcontact {
    list-style: none; margin: 6px 0 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: 4px 22px;
    font-size: 13.5px; color: var(--sub);
}
.hobart .custcontact li { display: flex; align-items: baseline; gap: 7px; }
.hobart .custcontact .lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--faint2);
}
.hobart .custcontact a { text-decoration: none; }
.hobart .custcontact a:hover { text-decoration: underline; }

@media (max-width: 620px) {
    /* Stacked on a phone: at this width the three details cannot share a row without one of
       them wrapping mid-address. */
    .hobart .custcontact { flex-direction: column; gap: 3px; }
}

/* The service contract column on the customer card. A contract that still stands reads as an
   ordinary fact; one that has run out is not an error and is not red, it is simply over. */
.hobart .coverruns { display: block; color: var(--ink); }
.hobart .coverwhich {
    display: block; margin-top: 1px;
    font-size: 11.5px; color: var(--faint2);
}
.hobart .coverended { color: var(--sub); }
