/* =====================================================================
   Auto Star — website admin
   Every colour, radius and font lives in :root. To match Auto Star
   Manager's look, change these values only; no component CSS below
   needs touching.
   ===================================================================== */

:root {
    --ink:        #14161a;   /* sidebar + darkest text */
    --ink-2:      #1e2228;
    --ink-3:      #2b3038;
    --gold:       #e8b21a;   /* brand accent */
    --gold-dark:  #b88a0c;

    --bg:         #f5f6f8;   /* app background */
    --surface:    #ffffff;   /* cards, tables */
    --line:       #e3e6ea;
    --text:       #23272e;
    --muted:      #6b7280;

    --ok:         #059669;
    --ok-bg:      #ecfdf5;
    --warn:       #b45309;
    --warn-bg:    #fffbeb;
    --danger:     #b91c1c;
    --danger-bg:  #fef2f2;

    /* ---- Semantic scales -------------------------------------------
       Added during the design-system audit, which found 469 hardcoded
       colours across 129 distinct shades — a third of every colour
       reference in the file bypassing the token layer entirely.

       Each status needs three roles, not one: a solid for text and
       icons, a tint for backgrounds, and a border that sits between
       them. Collapsing those into a single token per status is what
       forces the next person to hardcode again.

       Values are the ones already most used in the file, so adopting
       them changes nothing visible — it just makes the palette
       editable from one place. */

    /* Motion.
       
       ease-out rather than the bare `ease` keyword, which is really
       cubic-bezier(0.25, 0.1, 0.25, 1) — an ease-in-out that starts
       slowly. The slow part lands in the first 80ms, which is exactly
       when somebody is watching to see whether their tap registered.
       
       Tokens rather than literals so the next person changes one value
       instead of thirty-five. */
    --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
    --ease-inout:  cubic-bezier(0.77, 0, 0.175, 1);
    --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);

    /* Durations.
       
       Three, not twelve. .12s, .14s, .15s and .16s were all doing the
       same job — hover feedback on cards and inputs — and 20ms is not a
       difference anybody can see. The point of naming them is that the
       next person adding a component picks one of three instead of
       inventing a thirteenth. */
    --dur-fast: 120ms;   /* hover, focus, press */
    --dur-base: 180ms;   /* menus, panels, icons */
    --dur-slow: 300ms;   /* drawers, sidebar, progress */

    --ok-strong:     #15803d;
    --ok-border:     #bbf7d0;
    --ok-soft:       #f0fdf4;

    --danger-strong: #b42318;
    --danger-border: #fecaca;
    --danger-soft:   #fef2f2;

    --warn-strong:   #92400e;
    --warn-border:   #fde68a;
    --warn-soft:     #fef3c7;

    --info:          #2563eb;
    --info-border:   #dbeafe;
    --info-soft:     #eff6ff;

    /* Neutral ramp. --muted and --line already existed; these fill the
       gaps that were being met with one-off greys. */
    --text-2:        #374151;   /* secondary body text */
    --text-3:        #4b5563;   /* tertiary, captions */
    --muted-2:       #667085;   /* the other grey in heavy use */
    --line-2:        #d7dbe0;   /* stronger divider */
    --surface-2:     #fafbfc;   /* table heads, inset panels */
    --surface-3:     #f3f4f6;   /* chips, quiet fills */

    /* ---- Radii ------------------------------------------------------
       The audit found 22 distinct border-radius values. The redesign
       brief asks for one card radius of 10-12px, so these three are the
       whole vocabulary: a control, a card, and a pill. */
    --radius-pill:   999px;

    /* Interactive accent. Used by every control added since the theme
       system landed — 18 rules referenced it before it existed, which is
       why focus rings, active states and progress bars were invisible.
       Follows --ink so it tracks the chosen theme. */
    --accent:     var(--ink);

    --radius:     8px;
    --radius-sm:  5px;
    --shadow:     0 1px 2px rgba(20,22,26,.05), 0 4px 16px rgba(20,22,26,.05);
    --sidebar-w:  232px;
    --font:       "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --mono:       ui-monospace, "SF Mono", Menlo, monospace;
}

*, *::before, *::after { box-sizing: border-box; }

body.admin { margin: 0; background: var(--bg); color: var(--text); font: 15px/1.6 var(--font); }
a { color: #1d4ed8; }
:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
h1 { font-size: 1.55rem; margin: 0 0 .25rem; }
h2 { font-size: 1.05rem; margin: 0; }
.muted { color: var(--muted); }
.small { font-size: .82rem; }
.nowrap { white-space: nowrap; }
code { font-family: var(--mono); font-size: .84rem; background: #f1f3f5; padding: .1rem .35rem; border-radius: var(--radius-sm); }

/* ---------- Shell ---------- */
.shell { display: flex; min-height: 100vh; }

.sidebar {
    width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
    background: var(--ink); color: #aeb5bf;
    display: flex; flex-direction: column;
    position: sticky; top: 0; height: 100vh;
}
.sidebar__brand { display: flex; gap: .6rem; align-items: center; padding: 1.15rem 1.25rem; border-bottom: 1px solid rgba(255,255,255,.08); }
.sidebar__star { color: var(--gold); font-size: 1.5rem; line-height: 1; }
.sidebar__brand strong { display: block; color: var(--surface); font-size: .95rem; letter-spacing: .06em; }
.sidebar__brand small { display: block; font-size: .72rem; color: #7d858f; }

.sidebar__nav { padding: 1rem .75rem; flex: 1; overflow-y: auto; }
.sidebar__label { margin: 1rem .5rem .4rem; font-size: .68rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); }
.sidebar__label:first-child { margin-top: 0; }
.sidebar__nav a {
    display: flex; align-items: center; gap: .6rem;
    padding: .5rem .6rem; margin-bottom: .1rem; border-radius: var(--radius-sm);
    color: #c3c9d1; text-decoration: none; font-size: .9rem;
}
.sidebar__nav a:hover { background: rgba(255,255,255,.06); color: var(--surface); }
.sidebar__nav a.is-active { background: rgba(232,178,26,.14); color: var(--gold); font-weight: 500; }
.ico { width: 1.1rem; text-align: center; opacity: .85; }

.sidebar__foot { padding: 1rem 1.25rem; border-top: 1px solid rgba(255,255,255,.08); }
.sidebar__view { display: block; color: #c3c9d1; text-decoration: none; font-size: .85rem; margin-bottom: .6rem; }
.sidebar__view:hover { color: var(--gold); }
.sidebar__user { margin: 0 0 .5rem; font-size: .75rem; color: var(--muted); word-break: break-all; }
.sidebar__foot form { margin: 0; }
.sidebar__foot button {
    width: 100%; background: none; border: 1px solid #3a4048; color: #c3c9d1;
    padding: .4rem; border-radius: var(--radius-sm); cursor: pointer; font: inherit; font-size: .82rem;
}
.sidebar__foot button:hover { border-color: var(--gold); color: var(--gold); }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
    display: flex; align-items: center; gap: 1rem;
    background: var(--surface); border-bottom: 1px solid var(--line);
    padding: .7rem 1.5rem; position: sticky; top: 0; z-index: 20;
}
.topbar__menu { display: none; background: none; border: 0; font-size: 1.3rem; cursor: pointer; padding: .2rem .4rem; }
.topbar__search { flex: 1; max-width: 420px; margin: 0; }
.topbar__search input {
    width: 100%; padding: .5rem .8rem; border: 1px solid var(--line);
    border-radius: var(--radius-pill); font: inherit; font-size: .9rem; background: var(--bg);
}
.topbar__new {
    margin-left: auto; background: var(--ink); color: var(--surface); text-decoration: none;
    padding: .45rem 1rem; border-radius: var(--radius-sm); font-size: .85rem; font-weight: 500;
}
.topbar__new:hover { background: var(--ink-3); color: var(--surface); }

.content { padding: 1.75rem 1.5rem 4rem; max-width: 1240px; width: 100%; }
.content--bare { margin: 0 auto; }
body.admin--bare { background: var(--bg); }

/* ---------- Page head ---------- */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.page-head p { margin: 0; }
.page-head__actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.crumb { margin: 0 0 1rem; font-size: .88rem; }

/* ---------- Tiles ---------- */
.tiles { display: grid; gap: .85rem; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); margin-bottom: 1.5rem; }
.tile {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1rem 1.1rem; text-decoration: none; color: inherit; display: block;
    transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.tile:hover { border-color: var(--gold); transform: translateY(-1px); color: inherit; }
.tile__label { display: block; font-size: .74rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.tile strong { display: block; font-size: 1.8rem; line-height: 1.2; }
.tile__sub { font-size: .8rem; color: var(--muted); }
.tile--accent { border-left: 3px solid var(--gold); }

/* ---------- Panels ---------- */
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 1.5rem; overflow: hidden; }
.panel__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .9rem 1.1rem; border-bottom: 1px solid var(--line); }
.panel__body { padding: 1.1rem; margin: 0; }
.two-col { display: grid; gap: 1.25rem; grid-template-columns: 1fr 1fr; align-items: start; }

/* ---------- Filters ---------- */
.filters { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; padding: .85rem 1.1rem; border-bottom: 1px solid var(--line); margin: 0; }
.filters input[type="search"] { flex: 1; min-width: 180px; padding: .45rem .7rem; border: 1px solid var(--line); border-radius: var(--radius-sm); font: inherit; font-size: .88rem; }
.filters select { padding: .45rem .6rem; border: 1px solid var(--line); border-radius: var(--radius-sm); font: inherit; font-size: .88rem; background: var(--surface); }
.filters__count { margin-left: auto; font-size: .82rem; color: var(--muted); }

/* ---------- Bulk bar ---------- */
.bulkbar {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    padding: .7rem 1.1rem; background: var(--ink); color: var(--surface);
    position: sticky; top: 56px; z-index: 15;
}
.bulkbar[hidden] { display: none; }
.bulkbar strong { color: var(--gold); }
.bulkbar .btn-sm { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.2); color: var(--surface); }
.bulkbar .btn-sm:hover { background: rgba(255,255,255,.18); color: var(--surface); }
.bulkbar .btn-sm--danger { background: var(--danger); border-color: var(--danger); }
.bulkbar .btn-sm--quiet { background: none; border-color: transparent; color: #aeb5bf; }

/* ---------- Tables ---------- */
.table { width: 100%; border-collapse: collapse; }
.table th, .table td { text-align: left; padding: .7rem 1.1rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
.table th { background: var(--surface-2); font-size: .72rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); font-weight: 600; }
.table tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: #fcfcfd; }
.table--select .col-check { width: 40px; padding-right: 0; }
.table input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--gold-dark); cursor: pointer; }
.row-title { font-weight: 500; text-decoration: none; color: var(--text); }
.row-title:hover { color: var(--gold-dark); }
.empty-row { text-align: center; color: var(--muted); padding: 2.5rem 1rem; }
.wrap-text { max-width: 320px; }

/* ---------- Badges ---------- */
.pill { display: inline-block; padding: .1rem .55rem; border-radius: var(--radius-pill); font-size: .74rem; font-weight: 600; text-transform: capitalize; }
.pill--published { background: var(--ok-bg); color: #065f46; }
.pill--draft { background: var(--warn-bg); color: var(--warn-strong); }

.kind { display: inline-block; padding: .1rem .5rem; border-radius: var(--radius-sm); font-size: .72rem; font-weight: 500; text-transform: capitalize; background: #eef1f5; color: var(--text-3); }
.kind--service { background: #eef2ff; color: #4338ca; }
.kind--post { background: #f0fdfa; color: #0f766e; }
.kind--media { background: #fdf4ff; color: #a21caf; }

.tag { display: inline-block; margin-left: .4rem; padding: .05rem .4rem; border-radius: var(--radius-sm); background: #eef1f5; color: var(--muted); font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; }

/* ---------- Feed ---------- */
.feed { list-style: none; margin: 0; padding: .4rem 0; }
.feed li { display: flex; gap: .7rem; padding: .55rem 1.1rem; align-items: flex-start; }
.feed li + li { border-top: 1px solid #f2f4f6; }
.feed__dot { width: 7px; height: 7px; border-radius: 50%; background: #cbd5e1; margin-top: .55rem; flex: 0 0 auto; }
.feed__dot--gold { background: var(--gold); }
.feed__meta { display: block; font-size: .78rem; color: var(--muted); }

/* ---------- Buttons ---------- */
.btn-sm {
    display: inline-block; padding: .38rem .8rem; border: 1px solid var(--line);
    background: var(--surface); border-radius: var(--radius-sm); font: inherit; font-size: .85rem;
    font-weight: 500; text-decoration: none; color: var(--text); cursor: pointer; white-space: nowrap;
}
.btn-sm:hover { border-color: var(--gold); color: var(--text); }
.btn-sm--primary { background: var(--ink); color: var(--surface); border-color: var(--ink); }
.btn-sm--primary:hover { background: var(--ink-3); color: var(--surface); }
.btn-sm--quiet { color: var(--muted); }
.btn-sm--danger { background: var(--danger); border-color: var(--danger); color: var(--surface); }
.btn-danger { background: var(--danger) !important; }
.btn-danger:hover { background: #991b1b !important; }
.btn-link-danger { background: none; border: 0; color: var(--danger); font: inherit; font-size: .82rem; cursor: pointer; padding: 0; text-decoration: underline; }

/* ---------- Forms ---------- */
.admin-form { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.6rem; }
.admin-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
label { display: block; font-weight: 600; font-size: .86rem; margin: 1.1rem 0 .3rem; }
input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="url"], input[type="search"], input[type="datetime-local"], select, textarea {
    width: 100%; font: inherit; padding: .6rem .75rem; border: 1px solid var(--line);
    border-radius: var(--radius-sm); background: var(--surface); color: var(--text);
}
textarea.code { font-family: var(--mono); font-size: .87rem; line-height: 1.55; }
input:focus, select:focus, textarea:focus { border-color: var(--gold); outline: none; box-shadow: 0 0 0 3px rgba(232,178,26,.22); }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 0 1.2rem 1.2rem; margin: 1.5rem 0; }
legend { font-weight: 700; font-size: .78rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); padding: 0 .4rem; }
.hint { font-size: .83rem; color: var(--muted); margin: .35rem 0 0; }
button[type="submit"] {
    background: var(--ink); color: var(--surface); border: 0; padding: .7rem 1.4rem;
    border-radius: var(--radius-sm); font: inherit; font-weight: 600; cursor: pointer;
}
button[type="submit"]:hover { background: var(--ink-3); }
.form-actions { margin-top: 1.6rem; }
.danger { margin-top: 1.75rem; background: var(--surface); border: 1px solid var(--danger-border); border-radius: var(--radius); padding: 1.4rem; }
.danger h2 { color: #991b1b; margin-bottom: .4rem; }
.slug-field { display: flex; align-items: center; gap: .3rem; }
.slug-field span { color: var(--muted); font-family: var(--mono); font-size: .88rem; }
.slug-field input { flex: 1; font-family: var(--mono); font-size: .88rem; }
.input-narrow { max-width: 180px; }
.counter { display: block; font-size: .76rem; color: var(--muted); margin-top: .25rem; }
.counter--short { color: var(--warn); }
.counter--good { color: var(--ok); }
.counter--over { color: var(--danger); font-weight: 600; }

.notice { padding: .85rem 1.1rem; border-radius: var(--radius); margin-bottom: 1.25rem; }
.notice--ok { background: var(--ok-bg); border: 1px solid #a7f3d0; color: #065f46; }
.notice--bad { background: var(--danger-bg); border: 1px solid var(--danger-border); color: #991b1b; }

/* ---------- Editor ---------- */
.editor { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.editor__bar { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; padding: .5rem; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.editor__bar button { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .3rem .6rem; font: inherit; font-size: .82rem; cursor: pointer; color: var(--text); }
.editor__bar button:hover { border-color: var(--gold); }
.editor__spacer { flex: 1; }
.editor textarea { border: 0; border-radius: 0; }
.editor textarea:focus { box-shadow: none; }
.editor__preview { padding: 1.25rem; max-height: 520px; overflow: auto; }
.editor__preview img { max-width: 100%; height: auto; }

/* ---------- Image field ---------- */
.image-field { display: flex; gap: 1rem; align-items: flex-start; margin-top: .3rem; }
.image-field__preview { width: 150px; min-height: 96px; flex: 0 0 auto; border: 1px dashed var(--line); border-radius: var(--radius); background: var(--surface-2); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.image-field__preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.image-field__empty { font-size: .76rem; color: var(--muted); padding: .5rem; text-align: center; }
.image-field__controls { flex: 1; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.image-field__controls input { flex: 1 1 100%; font-family: var(--mono); font-size: .84rem; }

/* ---------- Uploader ---------- */
.uploader { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.5rem; margin-bottom: 1.5rem; }
.uploader__drop { border: 2px dashed #cfd5dd; border-radius: var(--radius); padding: 2rem 1rem; text-align: center; transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out); }
.uploader__drop.is-over { border-color: var(--gold); background: var(--warn-bg); }
.uploader__drop input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.uploader__drop label { display: block; margin: 0; cursor: pointer; }
.uploader__drop label strong { display: block; font-size: 1.02rem; }
.uploader__drop label span { font-size: .86rem; color: var(--muted); }
.uploader__list { margin: .8rem 0 0; font-size: .85rem; color: var(--ok); }

/* ---------- Media ---------- */
.media-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
.media-card { margin: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.media-card img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; background: #f1f3f5; }
.media-card figcaption { padding: .8rem; display: grid; gap: .5rem; }
.media-card__path { cursor: pointer; font-size: .72rem; word-break: break-all; }
.media-card__path.is-copied { background: #d1fae5; color: #065f46; }
.media-card__alt { display: flex; gap: .4rem; }
.media-card__alt input { font-size: .8rem; padding: .32rem .5rem; }
.media-card form { margin: 0; }

/* ---------- Picker ---------- */
.picker { position: fixed; inset: 0; z-index: 60; background: rgba(20,22,26,.55); display: flex; align-items: center; justify-content: center; padding: 1.5rem; }
.picker[hidden] { display: none; }
.picker__panel { background: var(--surface); border-radius: var(--radius); width: min(820px, 100%); max-height: 82vh; display: flex; flex-direction: column; overflow: hidden; }
.picker__head { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.25rem; border-bottom: 1px solid var(--line); }
.picker__close { background: none; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .3rem .8rem; cursor: pointer; font: inherit; font-size: .85rem; }
.picker__grid { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); padding: 1.25rem; overflow: auto; }
.picker__item { background: none; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 0; cursor: pointer; overflow: hidden; text-align: left; }
.picker__item:hover { border-color: var(--gold); }
.picker__item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.picker__item span { display: block; padding: .4rem .5rem; font-size: .7rem; color: var(--muted); word-break: break-all; }
.picker__empty { padding: 2rem 1.25rem; color: var(--muted); }

/* ---------- Login ---------- */
.login { max-width: 380px; margin: 12vh auto; background: var(--surface); padding: 2rem; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
.login h1 { margin-bottom: 1rem; }
.login button { width: 100%; margin-top: 1.5rem; }

/* ---------- Responsive ---------- */
@media (max-width: 1000px) { .two-col { grid-template-columns: 1fr; } }

@media (max-width: 820px) {
    .sidebar {
        position: fixed; inset: 0 auto 0 0; z-index: 50;
        transform: translateX(-100%); transition: transform var(--dur-slow) var(--ease-drawer);
    }
    .nav-open .sidebar { transform: translateX(0); }
    .topbar__menu { display: block; }
    .topbar__new { display: none; }
    .admin-form__row { grid-template-columns: 1fr; }
    .image-field { flex-direction: column; }
    .image-field__preview { width: 100%; }
    .content { padding: 1.25rem 1rem 4rem; }
    .table th:nth-child(4), .table td:nth-child(4),
    .table th:nth-child(6), .table td:nth-child(6) { display: none; }
}

/* ---------- Legacy wrapper: the shell now owns page padding, so this
   only constrains form width. Kept so existing views need no edits. ---- */
.admin-wrap { width: 100%; }
.admin-wrap--form { max-width: 880px; }

/* ---------- Per-record history ---------- */
.history { margin-top: 1.5rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.history__head { padding: .85rem 1.1rem; border-bottom: 1px solid var(--line); }
.history__head h2 { font-size: .95rem; }
.history ol { list-style: none; margin: 0; padding: .4rem 0; }
.history li { display: flex; gap: .7rem; padding: .5rem 1.1rem; font-size: .88rem; }
.history li + li { border-top: 1px solid #f2f4f6; }

/* =====================================================================
   Block editor
   ===================================================================== */

.blocks { border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); overflow: hidden; }
.blocks__bar {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: .6rem .9rem; background: var(--surface); border-bottom: 1px solid var(--line);
}
.blocks__hint { font-size: .8rem; color: var(--muted); }

.bpalette {
    display: flex; flex-wrap: wrap; gap: .35rem;
    padding: .75rem .9rem; background: var(--surface); border-bottom: 1px solid var(--line);
}
.bpalette__btn {
    display: inline-flex; align-items: center; gap: .4rem;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
    padding: .35rem .7rem; font: inherit; font-size: .82rem; cursor: pointer; color: var(--text);
}
.bpalette__btn:hover { border-color: var(--gold); background: var(--warn-bg); }
.bpalette__btn span { color: var(--gold-dark); font-weight: 700; width: 1rem; text-align: center; }

.blocks__canvas { padding: .75rem; display: grid; gap: .5rem; min-height: 60px; }
.blocks__empty { margin: 0; padding: 0 .9rem 1.25rem; color: var(--muted); font-size: .9rem; }

.bblock { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.bblock.is-dragging { opacity: .4; }
.bblock.is-target { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(232,178,26,.22); }

.bblock__head { display: flex; align-items: center; gap: .6rem; padding: .6rem .8rem; cursor: pointer; }
.bblock__head:hover { background: var(--surface-2); }
.bblock__grip { cursor: grab; color: #b6bcc5; letter-spacing: -2px; font-size: 1.1rem; }
.bblock__grip:active { cursor: grabbing; }
.bblock__icon { width: 1.3rem; text-align: center; color: var(--gold-dark); font-weight: 700; font-size: .9rem; }
.bblock__type { font-weight: 600; font-size: .87rem; white-space: nowrap; }
.bblock__summary {
    flex: 1; min-width: 0; color: var(--muted); font-size: .84rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bblock__tools { display: flex; gap: .15rem; }
.bblock__tools button {
    background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
    width: 26px; height: 26px; cursor: pointer; color: var(--muted); font-size: .85rem; line-height: 1;
}
.bblock__tools button:hover { border-color: var(--line); background: var(--surface); color: var(--text); }
.bblock__tools button.is-danger:hover { border-color: var(--danger-border); background: var(--danger-bg); color: var(--danger); }

.bblock__body { display: none; padding: .3rem 1rem 1rem; border-top: 1px solid var(--line); }
.bblock.is-open .bblock__body { display: block; }

.bfield { margin-top: .8rem; }
.bfield label { margin: 0 0 .25rem; font-size: .8rem; font-weight: 600; }
.bfield input[type="text"], .bfield textarea, .bfield select { font-size: .9rem; padding: .45rem .6rem; }
.bfield .hint { font-size: .78rem; margin-top: .25rem; }
.bfield__image { display: flex; gap: .5rem; align-items: center; }
.bfield__thumb {
    width: 54px; height: 40px; flex: 0 0 auto; border: 1px solid var(--line);
    border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2); display: flex;
    align-items: center; justify-content: center; font-size: .68rem; color: var(--muted);
}
.bfield__thumb img { width: 100%; height: 100%; object-fit: cover; }

.brepeat { margin-top: 1rem; padding-top: .8rem; border-top: 1px dashed var(--line); }
.brepeat__item { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .6rem .8rem; margin-bottom: .6rem; }
.brepeat__head { display: flex; align-items: center; justify-content: space-between; }
.brepeat__head strong { font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.brepeat__head button {
    background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
    width: 24px; height: 24px; cursor: pointer; color: var(--muted); font-size: .8rem;
}
.brepeat__head button:hover { border-color: var(--line); background: var(--surface); }
.brepeat__head button.is-danger:hover { border-color: var(--danger-border); background: var(--danger-bg); color: var(--danger); }

.legacy-note { margin-top: 1rem; background: var(--warn-bg); border: 1px solid var(--warn-border); border-radius: var(--radius); padding: .8rem 1rem; }
.legacy-note summary { cursor: pointer; font-weight: 600; font-size: .88rem; }
.legacy-note textarea { margin-top: .7rem; background: var(--surface); }

/* ---------- Theme picker ---------- */
.themes { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); margin-bottom: 1.75rem; }
.theme {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    overflow: hidden; margin: 0; transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.theme:hover { border-color: var(--gold); transform: translateY(-2px); box-shadow: var(--shadow); }
.theme.is-active { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(232, 178, 26, .18); }

.theme__preview { display: flex; height: 128px; border-bottom: 1px solid var(--line); }
.theme__rail { flex: 0 0 56px; padding: 10px 8px; display: flex; flex-direction: column; gap: 7px; }
.theme__chip { width: 22px; height: 22px; border-radius: var(--radius-sm); display: block; }
.theme__line { height: 7px; border-radius: var(--radius-sm); background: rgba(255,255,255,.22); display: block; }
.theme__body { flex: 1; padding: 12px; display: grid; grid-template-columns: 1fr 1fr; gap: 7px; align-content: start; }
.theme__tile { height: 30px; border-radius: var(--radius); display: block; }
.theme__tile--muted { opacity: .85; }
.theme__card { height: 22px; border-radius: var(--radius-sm); border: 1px solid rgba(16,24,40,.09); display: block; }

.theme__meta { display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem; padding: .9rem 1rem; }
.theme__meta strong { font-size: .95rem; }
.theme__meta p { margin: .2rem 0 0; }
.theme__meta .pill { margin-left: .4rem; vertical-align: 2px; }

/* ---------- Website theme previews ---------- */
.theme__preview--site { flex-direction: column; height: 150px; padding: 0; }
.theme__nav { display: flex; align-items: center; gap: 5px; padding: 7px 9px; border-bottom: 1px solid; }
.theme__logo { width: 16px; height: 16px; border-radius: var(--radius-sm); flex: 0 0 auto; }
.theme__navline { width: 20px; height: 5px; border-radius: var(--radius-sm); opacity: .55; }
.theme__cta { width: 30px; height: 12px; border-radius: var(--radius-sm); margin-left: auto; }
.theme__hero { flex: 1; padding: 12px; display: flex; flex-direction: column; gap: 6px; justify-content: center; }
.theme__h1 { height: 9px; width: 78%; border-radius: var(--radius-sm); background: rgba(255,255,255,.9); }
.theme__h1--short { width: 52%; background: rgba(255,255,255,.55); }
.theme__btn { width: 42px; height: 13px; border-radius: var(--radius-sm); margin-top: 4px; }
.theme__cards { display: flex; gap: 6px; padding: 9px; }
.theme__cards .theme__c { flex: 1; height: 26px; border-radius: var(--radius-sm); border: 1px solid rgba(16,24,40,.1); }
.theme__best { margin: .4rem 0 0; font-size: .78rem; color: var(--muted); font-style: italic; }

/* ---------- Brand upload panel ---------- */
.brand-form { padding: 1.4rem; }
.brand-grid { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.brand-item label { margin-top: 0; }
.brand-preview {
    height: 92px; margin: .4rem 0 .6rem;
    border: 1px dashed var(--line); border-radius: var(--radius-sm);
    background: var(--surface); display: flex; align-items: center; justify-content: center;
    padding: .6rem; overflow: hidden;
}
.brand-preview--dark { background: var(--ink); border-color: transparent; }
.brand-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
.brand-preview span { font-size: .8rem; color: var(--muted); }
.brand-item input[type="file"] { font-size: .8rem; width: 100%; }
.brand-clear { display: flex; align-items: center; gap: .35rem; margin: .5rem 0 0; font-weight: 400; font-size: .82rem; color: var(--danger); }
.brand-clear input { width: 15px; height: 15px; accent-color: var(--danger); }

/* ---------- Image cropper ---------- */
.crop {
    position: fixed; inset: 0; z-index: 80;
    background: rgba(16, 22, 32, .72);
    display: flex; align-items: center; justify-content: center; padding: 1.5rem;
}
.crop[hidden] { display: none; }
.crop__panel {
    background: var(--surface); border-radius: var(--radius);
    max-width: 900px; width: 100%; overflow: hidden;
    box-shadow: 0 24px 60px rgba(16, 22, 32, .4);
}
.crop__head, .crop__foot {
    display: flex; align-items: center; gap: .6rem;
    padding: .85rem 1.1rem;
}
.crop__head { border-bottom: 1px solid var(--line); }
.crop__foot { border-top: 1px solid var(--line); }
.crop__dims { margin-left: auto; font-size: .8rem; color: var(--muted); font-family: var(--mono); }
.crop__spacer { flex: 1; }

.crop__stage {
    position: relative; display: flex; align-items: center; justify-content: center;
    padding: 1.25rem; overflow: hidden;
    background: repeating-conic-gradient(#eef1f5 0% 25%, var(--surface) 0% 50%) 0 0 / 18px 18px;
    touch-action: none; user-select: none;
}

/* The canvas gets its own zero-padding positioning context. The crop box
   is absolute against this, not against the padded stage, so 0,0 is the
   top-left of the image rather than the top-left of the padding. */
.crop__frame { position: relative; line-height: 0; }
.crop__frame canvas { display: block; }

.crop__box {
    position: absolute; box-sizing: border-box;
    border: 2px solid var(--gold);
    box-shadow: 0 0 0 9var(--radius-pill) rgba(16, 22, 32, .48);
    cursor: move;
}
.crop__h {
    position: absolute; width: 14px; height: 14px;
    background: var(--surface); border: 2px solid var(--gold); border-radius: var(--radius-sm);
}
.crop__h--nw { top: -8px; left: -8px; cursor: nwse-resize; }
.crop__h--ne { top: -8px; right: -8px; cursor: nesw-resize; }
.crop__h--sw { bottom: -8px; left: -8px; cursor: nesw-resize; }
.crop__h--se { bottom: -8px; right: -8px; cursor: nwse-resize; }

.brand-note { color: var(--ok); font-weight: 500; }

@media (max-width: 640px) {
    .crop__panel { max-height: 92vh; overflow-y: auto; }
    .crop__foot { flex-wrap: wrap; }
}

/* Preview the footer logo against the colour it will actually sit on. */
.brand-preview--dark { background: var(--ink); }
.crop__foot .btn-sm { white-space: nowrap; }

/* Library fallback for brand images, used when uploads are unavailable. */
.brand-alt { margin-top: .5rem; display: grid; gap: .35rem; }
.brand-alt .btn-sm { width: 100%; }
.brand-path { font-family: var(--mono); font-size: .72rem; padding: .35rem .5rem; }

.brand-crop {
    display: flex; align-items: center; gap: .4rem;
    margin: .5rem 0 0; font-weight: 400; font-size: .8rem; color: var(--muted);
}
.brand-crop input { width: 15px; height: 15px; accent-color: var(--gold-dark); }

/* Upload feedback: progress reads as neutral, failures as failures. */
.uploader__list { color: var(--muted); }
.uploader__list.is-ok { color: var(--ok); }
.uploader__list.is-bad { color: var(--danger); font-weight: 500; }

/* ---------- Site photo slots ---------- */
.slot-form { padding: 1.4rem; }
.slot-grid { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.slot { border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem; background: var(--surface); }
.slot__head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; margin-bottom: .6rem; }
.slot__head strong { font-size: .95rem; }
.slot__ratio { font-size: .7rem; color: var(--muted); font-family: var(--mono); }
.slot__preview {
    height: 150px; border-radius: var(--radius-sm); overflow: hidden;
    background: repeating-conic-gradient(#f2f4f7 0% 25%, var(--surface) 0% 50%) 0 0 / 16px 16px;
    border: 1px dashed var(--line);
    display: flex; align-items: center; justify-content: center;
}
.slot__preview img { width: 100%; height: 100%; object-fit: cover; }
.slot__empty { font-size: .82rem; color: var(--muted); }
.slot__where { margin: .7rem 0 .25rem; font-size: .78rem; font-weight: 600; color: var(--gold-dark); }
.slot__actions { display: flex; gap: .4rem; margin: .7rem 0 .5rem; flex-wrap: wrap; }
.slot__actions .btn-sm { flex: 1; text-align: center; cursor: pointer; }
.slot__file { position: absolute; width: 1px; height: 1px; opacity: 0; }
.slot__path { font-family: var(--mono); font-size: .72rem; padding: .35rem .5rem; }
.slot__status:empty { display: none; }

/* ---------- Gallery manager ---------- */
.gal-grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); margin-bottom: 1.25rem; }
.gal { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem; }
.gal__thumb { position: relative; border-radius: var(--radius-sm); overflow: hidden; margin-bottom: .5rem; }
.gal__thumb img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.gal__thumb .pill { position: absolute; top: .5rem; left: .5rem; }
.gal label { margin-top: .7rem; font-size: .78rem; }
.gal input[type="text"], .gal input[type="number"], .gal select { font-size: .85rem; padding: .4rem .55rem; }
.gal__consent { display: flex; align-items: flex-start; gap: .4rem; font-weight: 400; font-size: .82rem; margin-top: .9rem; }
.gal__consent input { width: 15px; height: 15px; margin-top: .15rem; accent-color: var(--gold-dark); }
.gal-remove { display: flex; flex-wrap: wrap; gap: 1rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.gal-remove form { margin: 0; }
.setup-steps { margin: 0 0 1rem; padding-left: 1.2rem; }
.setup-steps li { margin-bottom: .5rem; font-size: .92rem; }

/* ---------- Appointments ---------- */
/* Fixed colours for the same reason as .hook-url: a theme is free to set
   --gold and --ink close together, and a count nobody can read is worse
   than no count. */
.nav-badge {
    margin-left: auto; background: #e2445c; color: var(--surface);
    font-size: .7rem; font-weight: 700; border-radius: var(--radius-pill); padding: .05rem .45rem;
    line-height: 1.5;
}
.appt { border-bottom: 1px solid var(--line); padding: 1rem 1.25rem; }
.appt:last-child { border-bottom: 0; }
.appt__main { display: grid; gap: 1rem; grid-template-columns: 180px 1fr 1fr auto; align-items: start; }
.appt__when strong, .appt__who strong, .appt__car strong { display: block; font-size: .95rem; }
.appt__when span, .appt__who span, .appt__car span { font-size: .82rem; color: var(--muted); }
.appt__when code { font-size: .7rem; }
.appt__notes {
    margin: .8rem 0 0; padding: .7rem .9rem; background: var(--bg);
    border-radius: var(--radius-sm); font-size: .88rem;
}
.appt__actions { display: flex; gap: .4rem; margin-top: .8rem; flex-wrap: wrap; }
.appt__actions input[type="text"] { flex: 1; min-width: 160px; font-size: .84rem; padding: .35rem .55rem; }
.appt__actions select { font-size: .84rem; padding: .35rem .5rem; }

.block-form { display: flex; gap: .5rem; flex-wrap: wrap; margin: .8rem 0 1rem; }
.block-form input { font-size: .88rem; padding: .4rem .6rem; }
.blocked-list { list-style: none; margin: 0; padding: 0; }
.blocked-list li { display: flex; align-items: center; gap: .8rem; padding: .5rem 0; border-top: 1px solid var(--line); font-size: .9rem; }
.blocked-list form { margin: 0 0 0 auto; }

@media (max-width: 900px) { .appt__main { grid-template-columns: 1fr; } }

/* ---------- Webhook log ---------- */
/* Copyable URL chip.
   Deliberately does not use --ink and --gold together: the Recon Indigo
   theme sets both to the same colour, which made this invisible. Fixed
   neutral values, so it reads the same in every theme including dark. */
.hook-url {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .55rem .8rem; margin: .25rem 0;
    font-family: var(--mono); font-size: .82rem; line-height: 1.4;
    background: #f1f3f7; color: #1a2233;
    border: 1px dashed #b9c1d1; border-radius: var(--radius-sm);
    cursor: pointer; word-break: break-all; max-width: 100%;
    transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.hook-url::after {
    content: "copy"; flex: 0 0 auto;
    font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
    color: var(--muted); border-left: 1px solid #cfd6e4; padding-left: .5rem;
}
.hook-url:hover { background: #e7ebf3; border-color: #8e9ab4; }
.hook-url.is-copied {
    background: #e8faf1; border-color: #7fd7ab; color: #05603a;
}
.hook-url.is-copied::after { content: "copied"; color: #05603a; border-left-color: #7fd7ab; }

/* A URL inside a numbered step should sit on its own line, not squeeze
   the sentence around it. */
.setup-steps .hook-url { display: flex; margin-top: .4rem; }
.hook { border-bottom: 1px solid var(--line); }
.hook:last-child { border-bottom: 0; }
.hook summary {
    display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
    padding: .8rem 1.25rem; cursor: pointer; font-size: .88rem;
}
.hook summary:hover { background: var(--surface-2); }
.hook__type { font-weight: 600; }
.hook__id { color: var(--muted); }
.hook__time { margin-left: auto; color: var(--muted); font-size: .82rem; }
.hook__size { color: var(--muted); font-size: .78rem; }
.hook__body { padding: 0 1.25rem 1.25rem; }
.hook__body h3 { font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin: 1rem 0 .4rem; }
.hook__body pre {
    background: #0f1115; color: #d7dbe2; padding: 1rem; border-radius: var(--radius-sm);
    overflow: auto; max-height: 420px; font-size: .78rem; line-height: 1.5; margin: 0;
}

/* Same trap as the public stylesheet: an author display rule beats the
   browser's [hidden] { display: none }. */
[hidden] { display: none !important; }

.fieldmap td { font-size: .82rem; padding: .4rem 1.25rem; }
.fieldmap td:first-child { width: 45%; }
.fieldmap code { font-size: .78rem; }

.pause-form { display: flex; gap: .35rem; align-items: center; margin-top: .5rem; }
.pause-form input { font-size: .78rem; padding: .25rem .45rem; max-width: 150px; }

/* ---------- Send-by-hand worklist ---------- */
.send-row { padding: 1rem 1.25rem; border-bottom: 1px solid var(--line); }
.send-row:last-child { border-bottom: 0; }
.send-row__who { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: .5rem; }
.send-row__who strong { font-size: .95rem; }
.send-row__msg { display: block; white-space: pre-wrap; font-family: var(--font); font-size: .86rem; }
.send-row form { margin-top: .6rem; }

/* ---------- Pagination ---------- */
.pager {
    display: flex; gap: .3rem; flex-wrap: wrap; align-items: center;
    padding: 1rem 1.25rem; border-top: 1px solid var(--line);
}
.pager a, .pager span {
    display: inline-block; padding: .35rem .7rem; border-radius: var(--radius-sm);
    font-size: .85rem; text-decoration: none; border: 1px solid var(--line);
    color: var(--text);
}
.pager a:hover { border-color: var(--accent); color: var(--accent); }
.pager .is-current { background: var(--accent); border-color: var(--accent); color: var(--surface); font-weight: 600; }
.filters input[type="search"] { min-width: 240px; font-size: .88rem; padding: .4rem .6rem; }

/* ---------- Campaign templates ---------- */
.tpl-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.tpl {
    display: block; text-decoration: none; padding: 1.1rem;
    border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
    transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.tpl:hover { border-color: var(--accent); transform: translateY(-2px); }
.tpl strong { display: block; font-size: .98rem; margin-bottom: .2rem; }
.tpl__seg { display: inline-block; font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
            color: var(--accent); margin-bottom: .5rem; }
.tpl__when { display: block; font-size: .82rem; color: var(--muted); margin-bottom: .6rem; }
.tpl__body {
    display: block; font-size: .78rem; line-height: 1.5; color: var(--text);
    background: var(--bg); padding: .6rem .7rem; border-radius: var(--radius-sm); white-space: pre-wrap;
}

/* ---------- Counter lookup ---------- */
.lookup-form { display: flex; gap: .5rem; }
.lookup-form input { flex: 1; font-size: 1.05rem; padding: .7rem .9rem; }

.counter-balance {
    display: flex; align-items: baseline; gap: .8rem; flex-wrap: wrap;
    background: var(--ink); color: var(--surface); border-radius: var(--radius);
    padding: 1.25rem 1.5rem; margin-bottom: 1.25rem;
}
.counter-balance__label { font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; opacity: .7; }
.counter-balance strong { font-size: 2.4rem; line-height: 1; color: #ffd66b; }
.counter-balance__pts { opacity: .7; font-size: .88rem; }

.panel--flag { border: 2px solid var(--gold-dark); }
.counter-code {
    display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
    padding: .8rem 0; border-top: 1px solid var(--line);
}
.counter-code code {
    font-size: 1.1rem; letter-spacing: .1em; background: var(--ink); color: #ffd66b;
    padding: .3rem .7rem; border-radius: var(--radius-sm);
}
.counter-code form { margin-left: auto; }

.counter-rewards { display: grid; gap: .6rem; }
.counter-reward {
    display: flex; align-items: center; gap: 1rem;
    padding: .7rem .9rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
    margin: 0;
}
.counter-reward.is-off { opacity: .5; }
.counter-reward__name { font-weight: 600; }
.counter-reward__cost { color: var(--muted); font-size: .85rem; }
.counter-reward button { margin-left: auto; }
.sidebar__role {
    display: inline-block; margin-left: .4rem; padding: .05rem .4rem;
    font-size: .64rem; text-transform: uppercase; letter-spacing: .06em;
    background: var(--line); color: var(--muted); border-radius: var(--radius-sm);
}
.sidebar__staff { display: block; font-size: .8rem; margin-top: .3rem; }
.role-list { margin: 0 0 1rem; padding-left: 1.1rem; }
.role-list li { margin-bottom: .5rem; font-size: .92rem; }
.inline-form { display: flex; gap: .5rem; align-items: center; margin: 0; }
.inline-form select { font-size: .82rem; padding: .25rem .45rem; }
.inline-check { display: flex; align-items: center; gap: .25rem; font-size: .78rem; font-weight: 400; color: var(--muted); }
.inline-check input { width: 14px; height: 14px; }
.pw summary { cursor: pointer; font-size: .82rem; color: var(--accent); }
.pw .block-form { margin-top: .4rem; }

/* ---------- Insights ---------- */
.range { display: flex; gap: .3rem; }
.range a {
    padding: .35rem .75rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
    font-size: .82rem; text-decoration: none; color: var(--text);
}
.range a.is-on { background: var(--accent); border-color: var(--accent); color: var(--surface); }

.spark { display: flex; align-items: flex-end; gap: 2px; height: 110px; }
.spark__bar { flex: 1; background: var(--accent); border-radius: 2px 2px 0 0; min-height: 3px; opacity: .85; }
.spark__bar:hover { opacity: 1; }

.funnel { display: grid; grid-template-columns: 160px 1fr 90px; gap: 1rem; align-items: center; margin-bottom: .7rem; }
.funnel__label { font-size: .88rem; }
.funnel__track { background: var(--line); border-radius: var(--radius-pill); height: 22px; overflow: hidden; }
/* The funnel bars grow from nothing on load.
   
   They used to render at their final width instantly, with a
   `transition: width` that could never fire — the width was written by
   PHP once and nothing ever changed it. Dead code, and a wasted chance:
   a funnel is about the drop between steps, and the eye reads that drop
   far better when it watches the bars arrive at different lengths than
   when it finds them already there.
   
   scaleX rather than width, so the browser composites rather than
   reflowing five bars sixty times a second. transform-origin: left
   because a funnel grows from its start, not its middle. */
.funnel__track span {
    display: block; height: 100%;
    background: var(--accent); border-radius: var(--radius-pill);
    transform: scaleX(calc(var(--pct, 0) / 100));
    transform-origin: left center;
    animation: funnel-grow var(--dur-slow) var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 60ms);
}

@keyframes funnel-grow {
    from { transform: scaleX(0); }
    /* No `to` — the rule above already holds the final value, so the
       keyframe cannot fall out of step with it. */
}
.funnel__n { text-align: right; }
.is-good { color: #05603a; font-weight: 600; }

.insight-cols { display: grid; gap: 1.25rem; grid-template-columns: 1fr 1fr; }
@media (max-width: 800px) {
    .insight-cols { grid-template-columns: 1fr; }
    .funnel { grid-template-columns: 110px 1fr 70px; gap: .6rem; }
}

/* ---------- AI drafting ---------- */
.panel--ai { border: 2px dashed var(--accent); background: var(--surface); }
.panel--ai textarea { width: 100%; font-family: var(--mono); font-size: .88rem; }
.panel--ai input[type="text"] { width: 100%; }
.ai-actions { display: flex; align-items: center; gap: .8rem; margin-top: .8rem; flex-wrap: wrap; }
.ai-status { font-size: .85rem; color: var(--muted); }
.ai-status.is-ok { color: #05603a; }
.ai-status.is-bad { color: var(--danger-strong); }

/* ---------- Connections ---------- */
.conn {
    border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.5rem; margin-bottom: 1.25rem; background: var(--surface);
}
.conn__head { display: flex; align-items: center; gap: .8rem; margin-bottom: .6rem; }
.conn__head h2 { margin: 0; font-size: 1.15rem; }
.conn > p.muted { margin-bottom: 1rem; }
.conn label { margin-top: .9rem; }
.conn__danger { margin-top: 1.25rem; }
.conn__danger summary { cursor: pointer; font-size: .82rem; color: var(--muted); }

.conn-badge {
    font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; font-weight: 700;
    padding: .2rem .55rem; border-radius: var(--radius-pill);
}
.conn-badge--on  { background: #e8faf1; color: #05603a; }
.conn-badge--off { background: #f2f4f7; color: var(--muted-2); }

/* ---------- Assistant ---------- */
.chat-log {
    max-height: 62vh; overflow-y: auto; padding: 1.25rem;
    display: flex; flex-direction: column; gap: .9rem;
}
.chat {
    max-width: 78%; padding: .8rem 1rem; border-radius: var(--radius);
    font-size: .92rem; line-height: 1.6; white-space: pre-wrap; word-break: break-word;
}
.chat--you { align-self: flex-end; background: var(--accent); color: var(--surface); border-bottom-right-radius: 4px; }
.chat--bot { align-self: flex-start; background: var(--bg); border: 1px solid var(--line); border-bottom-left-radius: 4px; }
.chat.is-waiting { opacity: .55; font-style: italic; }
.chat.is-bad { border-color: #fda29b; background: #fff4f3; color: var(--danger-strong); }

.chat-empty { padding: 1rem 0 0; }
.chat-empty p { margin-bottom: .75rem; }
.chat-suggestions { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip-btn {
    background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-pill);
    padding: .45rem .9rem; font-size: .84rem; cursor: pointer; color: var(--text);
    text-align: left;
}
.chip-btn:hover { border-color: var(--accent); color: var(--accent); }

.chat-form {
    display: flex; gap: .6rem; align-items: flex-end;
    padding: 1rem 1.25rem; border-top: 1px solid var(--line);
}
.chat-form textarea { flex: 1; resize: none; font-size: .95rem; line-height: 1.5; max-height: 180px; }

/* ---------- Calendar ---------- */
.cal { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.cal__head, .cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.cal__head span {
    padding: .6rem .5rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .07em;
    color: var(--muted); text-align: center; border-bottom: 1px solid var(--line); background: var(--bg);
}
.cal__day {
    min-height: 116px; padding: .4rem; border-right: 1px solid var(--line);
    border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: .25rem;
    /* The actual fix for a long appointment title breaking the grid.
     *
     * .cal__who already had overflow:hidden and white-space:nowrap —
     * correct, and never the problem. The problem is that a 1fr grid
     * track's minimum width defaults to auto, and auto is pulled up by
     * the nowrap text's full intrinsic width sitting inside this cell.
     * One long Tekmetric description was enough to force this day's
     * whole column wider than its 1/7 share, which is what pushed Friday
     * and Saturday out from under their own headers in the screenshot.
     *
     * min-width: 0 is the standard fix for exactly this shape of bug:
     * it tells the grid item it is allowed to shrink below its content,
     * so the 1fr tracks stay equal and the ellipsis one layer in finally
     * gets to do the job it was already written to do. */
    min-width: 0;
}
.cal__day:nth-child(7n) { border-right: 0; }
.cal__day.is-outside { background: var(--bg); opacity: .5; }
.cal__day.is-today { background: var(--warn-bg); }
.cal__day.is-today .cal__n { background: var(--accent); color: var(--surface); border-radius: var(--radius-pill); }
.cal__day.is-blocked { background: repeating-linear-gradient(45deg, var(--bg), var(--bg) 6px, #eceff4 6px, #eceff4 12px); }
.cal__n { font-size: .78rem; font-weight: 600; color: var(--muted); padding: .1rem .35rem; align-self: flex-start; }
.cal__closed { font-size: .68rem; color: var(--muted); font-style: italic; }

.cal__appt {
    display: block; padding: .25rem .4rem; border-radius: var(--radius-sm); font-size: .72rem;
    line-height: 1.3; text-decoration: none; border-left: 3px solid;
    /* .cal__day is flex, and a flex item's own min-width defaults to auto
       for the same reason a grid item's does — the same nowrap text one
       level further in would otherwise stretch this box past the column
       .cal__day was just fixed to hold to. */
    min-width: 0;
}
.cal__appt--website   { background: #fff8e6; border-color: #d9a521; color: #6b4c00; }
.cal__appt--tekmetric { background: #eef0ff; border-color: #5b5bd6; color: #2f2f8f; }
.cal__appt.is-unconfirmed { border-left-style: dashed; }
.cal__appt:hover { filter: brightness(.96); }
.cal__time { font-weight: 700; display: block; }
.cal__who { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cal-key { display: inline-flex; align-items: center; gap: .3rem; margin-left: .8rem; font-size: .8rem; }
.cal-dot { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.cal-dot--website { background: #d9a521; }
.cal-dot--tekmetric { background: #5b5bd6; }

@media (max-width: 800px) {
    .cal__day { min-height: 78px; padding: .25rem; }
    .cal__who { display: none; }
    .cal__appt { padding: .15rem .3rem; font-size: .66rem; }
}
.panel--ai.is-off { border-style: dashed; opacity: .78; }

/* ---------- Image alt audit ---------- */
.alt-grid { display: grid; gap: 1rem; padding: 1.25rem; }
.alt-item { display: grid; grid-template-columns: 92px 1fr; gap: 1rem; align-items: center; }
.alt-item img { width: 92px; height: 70px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); }
.alt-item input { width: 100%; margin-top: .3rem; }

/* ---------- Repair orders ---------- */
.ro-layout { display: grid; gap: 1.5rem; grid-template-columns: minmax(0,1fr) 340px; align-items: start; }
.ro-concern {
    background: var(--surface); border-left: 4px solid var(--accent);
    padding: 1rem 1.25rem; border-radius: var(--radius); margin-bottom: 1.25rem;
}
.ro-job { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 1rem; }
.ro-job__head { display: flex; justify-content: space-between; gap: 1rem; padding: 1rem 1.25rem; border-bottom: 1px solid var(--line); }
.ro-job__head h2 { font-size: 1.05rem; margin: 0; }
.ro-job__meta { display: flex; align-items: center; gap: .7rem; flex-shrink: 0; }
.ro-lines { width: 100%; border-collapse: collapse; }
.ro-line td { padding: .55rem 1.25rem; border-bottom: 1px solid var(--line); font-size: .88rem; vertical-align: top; }
.ro-line__kind { font-size: .66rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); width: 60px; }
.ro-line--labor { background: #fbfcfe; }
.ro-add { padding: .8rem 1.25rem; }
.ro-add summary { cursor: pointer; font-size: .85rem; color: var(--accent); }
.ro-add__form { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .7rem; }
.ro-add__form input, .ro-add__form select { font-size: .82rem; padding: .35rem .5rem; }
.ro-add__form input[name="description"] { flex: 1 1 180px; }
.ro-add__form input[type="number"] { width: 78px; }
.ro-job__actions { display: flex; gap: .5rem; padding: .8rem 1.25rem; border-top: 1px solid var(--line); flex-wrap: wrap; }

.ro-totals { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.25rem; margin-bottom: 1.25rem; }
.ro-totals > div { display: flex; justify-content: space-between; padding: .35rem 0; font-size: .92rem; }
.ro-totals__grand { border-top: 2px solid var(--line); margin-top: .5rem; padding-top: .7rem !important; font-size: 1.15rem !important; }
.ro-totals__grand strong { color: #05603a; }

@media (max-width: 1000px) { .ro-layout { grid-template-columns: 1fr; } }

/* ---------- Counter type-ahead ---------- */
.typeahead { position: relative; }

/* The panel clips its children so rounded corners work, which cut the
   results list in half. The panel holding a type-ahead has to let it
   escape, and sit above whatever comes next. */
.panel--open { overflow: visible; position: relative; z-index: 10; }

.typeahead input {
    width: 100%;
    font-size: 1.15rem;
    padding: .95rem 1.1rem;
    border-radius: var(--radius);
}
.typeahead input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.typeahead__list {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(16, 24, 40, .16);
    /* Ten rows before scrolling. A list longer than that is slower to
       read than to retype. */
    max-height: 60vh;
    overflow-y: auto;
}
.typeahead__item {
    display: block; width: 100%; text-align: left; background: none; border: 0;
    padding: .85rem 1.1rem; cursor: pointer; border-bottom: 1px solid var(--line);
    line-height: 1.45;
}
.typeahead__item:last-child { border-bottom: 0; }
.typeahead__item strong { display: block; font-size: 1rem; }
.typeahead__item span { display: block; font-size: .86rem; color: var(--muted); margin-top: .1rem; }
.typeahead__item.is-active, .typeahead__item:hover { background: #eef0ff; }
.typeahead__item.is-active { box-shadow: inset 3px 0 0 var(--accent); }
.typeahead__none { padding: 1rem 1.1rem; color: var(--muted); font-size: .9rem; }

.chosen {
    display: flex; justify-content: space-between; align-items: center; gap: 1rem;
    background: #e8faf1; border: 1px solid #7fd7ab; border-radius: var(--radius);
    padding: .8rem 1rem; margin-top: .8rem;
}
.chosen strong { display: block; }

.veh-list { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); margin-bottom: 1rem; }
.veh-opt {
    text-align: left; background: var(--bg); border: 1px solid var(--line);
    border-radius: var(--radius-sm); padding: .6rem .75rem; cursor: pointer;
}
.veh-opt strong { display: block; font-size: .9rem; }
.veh-opt span { font-size: .78rem; color: var(--muted); }
.veh-opt.is-on { border-color: var(--accent); background: #eef0ff; }

@media (max-width: 720px) {
    .typeahead__list {
        position: fixed;
        top: auto; left: .75rem; right: .75rem; bottom: .75rem;
        max-height: 55vh;
    }
    .typeahead input { font-size: 16px; }
}

.ro-empty {
    text-align: center; padding: 4rem 1.5rem;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.ro-empty__icon { font-size: 2.6rem; display: block; margin-bottom: .8rem; opacity: .35; }
.ro-empty h2 { font-size: 1.25rem; margin-bottom: .5rem; }
.ro-empty p { max-width: 420px; margin: 0 auto 1.5rem; }

/* ---------- Job board ----------
   Three columns rather than one per status. The granular status is a chip
   on the card; the board answers the coarser question — waiting on the
   customer, being worked on, or finished. */

.job-search { display: flex; gap: .5rem; margin-bottom: 1rem; }
.job-search input {
    flex: 1; font-size: .95rem; padding: .65rem .9rem;
    border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
}
.job-search input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.job-board {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
}

.job-col {
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
}
.job-col__head {
    padding: .75rem 1rem;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}
.job-col__head h2 { font-size: .88rem; margin: 0; letter-spacing: .01em; }
.job-col__head span { color: var(--muted); font-weight: 400; }

/* A rule per column, so the three groups are distinguishable at a glance. */
.job-col[data-col="estimates"] .job-col__head { box-shadow: inset 0 -3px 0 #94a3b8; }
.job-col[data-col="wip"]       .job-col__head { box-shadow: inset 0 -3px 0 var(--info); }
.job-col[data-col="done"]      .job-col__head { box-shadow: inset 0 -3px 0 #059669; }

.job-col__body { padding: .7rem; display: flex; flex-direction: column; gap: .7rem; min-height: 120px; }
.job-col__empty { color: #aab0ba; font-size: .85rem; text-align: center; padding: 2rem 0; margin: 0; }

.job-card {
    display: block; background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius); padding: .85rem .95rem; text-decoration: none; color: var(--text);
    transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.job-card:hover { border-color: var(--ink); box-shadow: var(--shadow); }

.job-card__top { display: flex; justify-content: space-between; align-items: flex-start; gap: .6rem; margin-bottom: .7rem; }
.job-card__ref { text-align: right; font-size: .8rem; color: var(--accent); font-weight: 600; }
.job-card__ref .muted { display: block; font-weight: 400; }

.job-card__who { font-size: .95rem; margin-bottom: .15rem; }
.job-card__veh { font-size: .88rem; color: var(--muted); margin-bottom: .8rem; }

.job-card__foot {
    display: flex; justify-content: space-between; align-items: center; gap: .5rem;
    padding-top: .7rem; border-top: 1px solid var(--line);
}
.job-card__total { font-size: 1rem; }

.job-badge {
    font-size: .72rem; padding: .25rem .55rem; border-radius: var(--radius-sm);
    background: var(--bg); color: var(--muted); border: 1px solid var(--line);
}
.job-badge--warn { background: var(--warn-bg); color: var(--warn-strong); border-color: #fcd34d; }
.job-badge--ok { background: var(--ok-soft); color: #166534; border-color: var(--ok-border); }

/* Status chips */
.chip { font-size: .72rem; font-weight: 600; padding: .28rem .6rem; border-radius: var(--radius-sm); white-space: nowrap; }
.chip--grey   { background: #f1f3f5; color: #475467; }
.chip--blue   { background: var(--info-soft); color: #1d4ed8; }
.chip--amber  { background: #fff7ed; color: #c2410c; }
.chip--purple { background: #f5f3ff; color: #6d28d9; }
.chip--green  { background: var(--ok-soft); color: var(--ok-strong); }

@media (max-width: 1100px) {
    .job-board { grid-template-columns: 1fr; }
    .job-col__body { max-height: none; }
}

/* ---------- Website hub ---------- */
.hub-heading {
    font-size: .76rem; text-transform: uppercase; letter-spacing: .08em;
    color: var(--muted); margin: 1.75rem 0 .7rem;
}
.hub-heading:first-of-type { margin-top: .5rem; }
.hub-grid { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
.hub-card {
    display: flex; align-items: center; gap: .85rem;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    padding: .9rem 1rem; text-decoration: none; color: var(--text);
    transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.hub-card:hover { border-color: var(--ink); box-shadow: var(--shadow); }
.hub-card__icon {
    width: 34px; height: 34px; flex: 0 0 auto; border-radius: var(--radius-sm);
    background: var(--bg); display: grid; place-items: center; font-size: 1rem; color: var(--muted);
}
.hub-card__body { flex: 1; min-width: 0; }
.hub-card__body strong { display: block; font-size: .94rem; }
.hub-card__hint { display: block; font-size: .8rem; color: var(--muted); line-height: 1.4; }
.hub-card__n {
    flex: 0 0 auto; font-size: .78rem; font-weight: 700; color: var(--muted);
    background: var(--bg); border-radius: var(--radius-pill); padding: .15rem .5rem;
}
.hub-card--warn { border-color: #fcd34d; background: var(--warn-bg); }
.hub-card--warn .hub-card__n { background: #fcd34d; color: #78350f; }

/* ---------- Tabs ---------- */
.tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--line); margin-bottom: 1.25rem; overflow-x: auto; }
.tabs a {
    padding: .6rem .95rem; text-decoration: none; color: var(--muted);
    font-size: .9rem; white-space: nowrap; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs a:hover { color: var(--text); }
.tabs a.is-on { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }

/* ---------- VIN decode ---------- */
.vin-row { display: flex; gap: .5rem; }
.vin-row input { flex: 1; text-transform: uppercase; font-family: var(--mono); }
.vin-status { display: block; font-size: .82rem; color: var(--muted); margin-top: .3rem; min-height: 1.1em; }
.vin-status.is-ok { color: #05603a; }
.vin-status.is-bad { color: var(--danger-strong); }

/* ---------- Canned jobs ---------- */
/* .canned-grid and .canned-pick went with the standalone saved-jobs
   panel. Saved jobs now live inside the add-job form as .saved. */
#canned-items input, #canned-items select { width: 100%; font-size: .82rem; padding: .3rem .4rem; }
#canned-items td { padding: .3rem; }

/* ---------- Concerns and findings ---------- */
.concern-label {
    font-size: .74rem; text-transform: uppercase; letter-spacing: .07em;
    color: var(--muted); margin: 1.1rem 0 .5rem;
}
.concern-label:first-child { margin-top: 0; }
.concern {
    display: grid; grid-template-columns: 1fr 1fr auto; gap: 1rem; align-items: start;
    padding: .7rem 0; border-bottom: 1px solid var(--line); font-size: .9rem;
}
.concern:last-of-type { border-bottom: 0; }
.concern__said { display: flex; gap: .5rem; align-items: baseline; }
.concern__found { color: var(--muted); }
.concern__act { display: flex; gap: .4rem; align-items: center; }

.sev { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; display: inline-block; margin-top: .35rem; }
.sev--urgent    { background: #dc2626; }
.sev--attention { background: #f59e0b; }
.sev--monitor   { background: #3b82f6; }
.sev--none      { background: #cbd5e1; }

/* ---------- Sticky totals bar ---------- */
.ro-bar {
    position: sticky; bottom: 0; z-index: 20;
    display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap;
    background: var(--ink); color: var(--surface);
    padding: .8rem 1.25rem; border-radius: var(--radius);
    margin-top: 1.5rem;
    box-shadow: 0 -4px 20px rgba(20, 22, 26, .18);
}
.ro-bar__label {
    display: block; font-size: .64rem; text-transform: uppercase;
    letter-spacing: .08em; opacity: .6;
}
.ro-bar__cell strong, .ro-bar__gp strong { font-size: 1rem; }
.ro-bar__gp strong { font-size: 1.15rem; }
.ro-bar__gp strong.is-good { color: #4ade80; }
.ro-bar__gp strong.is-low  { color: #fca5a5; }
.ro-bar__sep { width: 1px; align-self: stretch; background: rgba(255,255,255,.18); }
.ro-bar__total { margin-left: auto; text-align: right; }
.ro-bar__total strong { font-size: 1.5rem; }
.ro-bar__go { flex: 0 0 auto; }

@media (max-width: 760px) {
    .ro-bar { gap: .8rem; padding: .7rem .9rem; }
    .ro-bar__total { margin-left: 0; }
    .concern { grid-template-columns: 1fr; gap: .3rem; }
}

/* ---------- Activity feed ---------- */
.feed { list-style: none; margin: 0; padding: 0; }
.feed li {
    display: flex; justify-content: space-between; gap: 1.25rem; align-items: baseline;
    padding: .8rem 1.25rem; border-bottom: 1px solid var(--line);
}
.feed li:last-child { border-bottom: 0; }
.feed__what { font-size: .92rem; }
.feed__detail { display: block; color: var(--muted); font-size: .85rem; margin-top: .1rem; }
.feed__when { color: var(--muted); font-size: .78rem; white-space: nowrap; flex: 0 0 auto; }

/* ---------- Inspection, technician side ----------
   Built for a phone held in one hand under a lift: big tap targets,
   one column, nothing that needs precision. */
.dvi { padding: .5rem; }
.dvi-item { padding: .9rem .75rem; border-bottom: 1px solid var(--line); }
.dvi-item:last-child { border-bottom: 0; }
.dvi-item__name { display: flex; align-items: center; gap: .5rem; margin-bottom: .6rem; }
.dvi-item__name strong { font-size: .96rem; }

.dvi-grade { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; margin-bottom: .6rem; }
.grade { position: relative; }
.grade input { position: absolute; opacity: 0; pointer-events: none; }
.grade span {
    display: block; text-align: center; padding: .7rem .3rem;
    border: 2px solid var(--line); border-radius: var(--radius-sm);
    font-size: .88rem; font-weight: 600; cursor: pointer; background: var(--surface);
}
.grade--good input:checked + span      { background: var(--ok-soft); border-color: #16a34a; color: var(--ok-strong); }
.grade--attention input:checked + span { background: var(--warn-bg); border-color: #f59e0b; color: var(--warn); }
.grade--urgent input:checked + span    { background: var(--danger-bg); border-color: #dc2626; color: var(--danger); }

.dvi-item__detail { display: flex; gap: .4rem; margin-bottom: .6rem; }
.dvi-item__detail input { font-size: .88rem; padding: .5rem .6rem; }
.dvi-measure { max-width: 110px; }
.dvi-item__detail input:last-child { flex: 1; }

.dvi-photos { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.dvi-photos img { width: 62px; height: 62px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); }
.dvi-shoot span {
    display: grid; place-items: center; width: 62px; height: 62px;
    border: 2px dashed var(--line); border-radius: var(--radius-sm);
    font-size: .7rem; color: var(--muted); cursor: pointer; text-align: center; padding: .2rem;
}
.dvi-shoot span:hover { border-color: var(--accent); color: var(--accent); }
.dvi-tojob { margin-top: .6rem; }

.dvi-bar {
    position: sticky; bottom: 0; background: var(--surface);
    border-top: 1px solid var(--line); padding: .8rem 1rem; margin-top: 1rem;
    display: flex; justify-content: flex-end; border-radius: var(--radius);
    box-shadow: 0 -4px 16px rgba(20,22,26,.08);
}

/* =====================================================================
   Workshop density

   The shop screens carry far more on them than a content editor does —
   a repair order is twenty numbers, six statuses and a dozen actions.
   Everything here tightens spacing and sharpens edges so more fits
   without becoming a wall. Colours and typeface are untouched; only the
   density and structure change.
   ===================================================================== */

.shop-ui { font-size: 14px; }

.shop-ui .admin-main { padding: 0; }
.shop-ui .page-head {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: .9rem 1.5rem;
    margin: 0;
    position: sticky; top: 0; z-index: 30;
}
.shop-ui .page-head h1 { font-size: 1.15rem; margin: 0; }
.shop-ui .page-head .muted { font-size: .84rem; margin: .15rem 0 0; }
.shop-ui .crumb { margin: 0 0 .15rem; font-size: .78rem; }

/* Tabs sit directly under the header, as one band. */
.shop-ui .tabs {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: 0 1.5rem;
    margin: 0 0 1.25rem;
    position: sticky; top: 62px; z-index: 29;
    gap: 0;
}
.shop-ui .tabs a { padding: .7rem 1rem; font-size: .86rem; border-bottom-width: 2px; }

/* Everything below the header gets its own gutter. */
.shop-ui .notice,
.shop-ui .ro-layout,
.shop-ui .job-board,
.shop-ui .job-search,
.shop-ui .panel,
.shop-ui .tiles,
.shop-ui .admin-form,
.shop-ui .hint,
.shop-ui .ro-concern,
.shop-ui .ro-bar,
.shop-ui .dvi-bar,
.shop-ui .admin-wrap { margin-left: 1.5rem; margin-right: 1.5rem; }
.shop-ui .admin-wrap--form { margin-left: auto; margin-right: auto; }

/* Cards: crisp, flat, no drop shadow until hover. */
.shop-ui .panel {
    border-radius: var(--radius-sm);
    box-shadow: none;
    margin-bottom: 1rem;
}
.shop-ui .panel__head { padding: .7rem 1rem; }
.shop-ui .panel__head h2 { font-size: .92rem; }
.shop-ui .panel__body { padding: 1rem; }

/* Tables: tighter rows, a header that reads as a header. */
.shop-ui .table thead th {
    background: var(--bg);
    font-size: .7rem; text-transform: uppercase; letter-spacing: .06em;
    color: var(--muted); font-weight: 600;
    padding: .55rem 1rem; border-bottom: 1px solid var(--line);
}
.shop-ui .table td { padding: .6rem 1rem; font-size: .88rem; }
.shop-ui .table tbody tr:hover { background: var(--bg); }

/* Buttons: smaller, squarer, closer together. */
.shop-ui .btn-sm { padding: .4rem .75rem; font-size: .82rem; border-radius: var(--radius-sm); }
.shop-ui .form-actions { gap: .5rem; }

/* Form fields: compact, aligned. */
.shop-ui .admin-form label { font-size: .8rem; margin-bottom: .25rem; margin-top: .9rem; }
.shop-ui .admin-form input,
.shop-ui .admin-form select,
.shop-ui .admin-form textarea { padding: .5rem .65rem; font-size: .88rem; border-radius: var(--radius-sm); }
.shop-ui .admin-form .hint { margin: .3rem 0 0; font-size: .78rem; }
.shop-ui fieldset { padding: .9rem 1rem; border-radius: var(--radius-sm); }
.shop-ui legend { font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; }

/* Jobs on an estimate read as rows of a document, not as cards. */
.shop-ui .ro-job { border-radius: var(--radius-sm); margin-bottom: .75rem; }
.shop-ui .ro-job__head { padding: .75rem 1rem; }
.shop-ui .ro-job__head h2 { font-size: .98rem; }
.shop-ui .ro-line td { padding: .45rem 1rem; font-size: .85rem; }
.shop-ui .ro-add { padding: .6rem 1rem; }
.shop-ui .ro-job__actions { padding: .6rem 1rem; gap: .4rem; }

/* The board: cards a little tighter so more fits above the fold. */
.shop-ui .job-col__head { padding: .6rem .85rem; }
.shop-ui .job-col__body { padding: .6rem; gap: .6rem; }
.shop-ui .job-card { padding: .75rem .85rem; border-radius: var(--radius-sm); }
.shop-ui .job-card__who { font-size: .9rem; }
.shop-ui .job-card__veh { font-size: .84rem; margin-bottom: .6rem; }

/* Totals bar spans the full width, flush to the bottom. */
.shop-ui .ro-bar {
    border-radius: 0;
    margin: 1.5rem 0 0;
    padding: .75rem 1.5rem;
}

.shop-ui .chip { border-radius: var(--radius-sm); }
.shop-ui .tiles { gap: .6rem; }
.shop-ui .tile { padding: .8rem .9rem; border-radius: var(--radius-sm); }
.shop-ui .tile strong { font-size: 1.4rem; }

@media (max-width: 860px) {
    .shop-ui .page-head,
    .shop-ui .tabs { position: static; padding-left: 1rem; padding-right: 1rem; }
    .shop-ui .notice,
    .shop-ui .ro-layout,
    .shop-ui .job-board,
    .shop-ui .job-search,
    .shop-ui .panel,
    .shop-ui .tiles,
    .shop-ui .admin-form,
    .shop-ui .hint,
    .shop-ui .ro-concern,
    .shop-ui .ro-bar,
    .shop-ui .dvi-bar { margin-left: .75rem; margin-right: .75rem; }
}

/* ---------- Repair order header ----------
   ro-head__who, __veh and __odo went with the possessive headline and the
   corner odometer block. The vehicle is the headline now and mileage rides
   in .ro-meta with the rest of the identifiers. */
.shop-ui .page-head h1 .chip { vertical-align: middle; margin-left: .4rem; }

/* ---------- Quick actions ---------- */
.ro-tools {
    display: flex; align-items: center; gap: .25rem; flex-wrap: wrap;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
    padding: .35rem .5rem; margin: 0 1.5rem 1rem;
}
.ro-tools a {
    padding: .4rem .7rem; border-radius: var(--radius-sm); font-size: .82rem;
    text-decoration: none; color: var(--text); white-space: nowrap;
}
.ro-tools a:hover { background: var(--bg); color: var(--accent); }
.ro-tools__spacer { flex: 1; }

@media (max-width: 860px) {
    .ro-tools { margin-left: .75rem; margin-right: .75rem; overflow-x: auto; flex-wrap: nowrap; }
    .ro-jump { overflow-x: auto; flex-wrap: nowrap; }
}

/* ---------- Icons ----------
   Inline SVG inheriting the current colour, so a link's icon dims and
   brightens with its text rather than needing its own state rules. */
.ico-svg { flex: 0 0 auto; vertical-align: -.18em; }
.sidebar a .ico-svg { opacity: .62; transition: opacity var(--dur-fast) var(--ease-out); }
.sidebar a:hover .ico-svg,
.sidebar a.is-on .ico-svg { opacity: 1; }
.ro-tools a { display: inline-flex; align-items: center; gap: .35rem; }
.btn-sm .ico-svg { vertical-align: -.2em; margin-right: .15rem; }
.hub-card__icon .ico-svg { opacity: .7; }
.ro-empty__icon .ico-svg { opacity: 1; }

/* ---------- Labor guide lookup ---------- */
.labor-lookup {
    background: var(--bg); border: 1px solid var(--line);
    border-radius: var(--radius-sm); padding: .8rem .9rem; margin-top: .9rem;
}
.labor-lookup__row { display: flex; gap: .5rem; }
.labor-lookup__row input { flex: 1; }
.labor-results { display: grid; gap: .35rem; margin-top: .6rem; max-height: 260px; overflow-y: auto; }
.labor-hit {
    text-align: left; background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius-sm); padding: .5rem .65rem; cursor: pointer; color: var(--text);
}
.labor-hit:hover { border-color: var(--accent); }
.labor-hit strong { display: block; font-size: .86rem; line-height: 1.3; }
.labor-hit span { font-size: .78rem; color: var(--muted); }
.concern-input { width: 100%; margin-bottom: .4rem; }
.plate-state { flex: 0 0 74px; font-family: var(--mono); text-align: center; }
.vin-row input[data-plate] { text-transform: uppercase; font-family: var(--mono); letter-spacing: .06em; }
.labor-lookup--off { border-style: dashed; opacity: .85; }
.labor-lookup--off strong { display: block; font-size: .9rem; margin-bottom: .3rem; }

/* ---------- Job card ----------
   Labor and parts as separate tables with their own headers. One table
   with a "kind" column forced every row to carry columns that did not
   apply to it, which is what made the old layout hard to scan. */

.jobcard {
    background: var(--surface); border: 1px solid var(--line);
    border-left: 4px solid var(--line); border-radius: var(--radius-sm); margin-bottom: .9rem;
}
.jobcard--approved  { border-left-color: #16a34a; }
.jobcard--complete  { border-left-color: #16a34a; }
.jobcard--declined  { border-left-color: #dc2626; opacity: .72; }
.jobcard--recommended { border-left-color: #f59e0b; }

.jobcard__head {
    display: flex; align-items: center; gap: .75rem;
    padding: .7rem .9rem; border-bottom: 1px solid var(--line);
}
.jobcard__mark {
    width: 22px; height: 22px; border-radius: 50%; flex: 0 0 auto;
    display: grid; place-items: center; font-size: .75rem; font-weight: 700;
    background: var(--bg); color: var(--muted);
}
.jobcard--approved .jobcard__mark,
.jobcard--complete .jobcard__mark { background: #dcfce7; color: var(--ok-strong); }
.jobcard--declined .jobcard__mark { background: #fee2e2; color: var(--danger); }
.jobcard--recommended .jobcard__mark { background: var(--warn-soft); color: var(--warn); }

.jobcard__title { flex: 1; min-width: 0; }
.jobcard__title strong { display: block; font-size: .96rem; line-height: 1.3; }
.jobcard__when { font-size: .76rem; color: var(--muted); }

.jobcard__meta { display: flex; gap: .35rem; margin: 0; flex: 0 0 auto; }
.jobcard__meta select {
    font-size: .74rem; padding: .25rem .4rem; border-radius: var(--radius-sm);
    background: var(--bg); border: 1px solid var(--line); max-width: 130px;
}
.jobcard__total { font-size: 1.05rem; flex: 0 0 auto; min-width: 84px; text-align: right; }

.jobcard__note {
    padding: .55rem .9rem; margin: 0; font-size: .85rem; color: var(--muted);
    border-bottom: 1px solid var(--line); background: var(--bg);
}
.jobcard__empty { padding: 1rem .9rem; margin: 0; color: var(--muted); font-size: .85rem; }

.jobtable { width: 100%; border-collapse: collapse; }
.jobtable thead th {
    background: var(--bg); font-size: .66rem; text-transform: uppercase; letter-spacing: .06em;
    color: var(--muted); font-weight: 600; padding: .35rem .9rem; text-align: left;
    border-bottom: 1px solid var(--line);
}
.jobtable th.num, .jobtable td.num { text-align: right; }
.jobtable td { padding: .45rem .9rem; font-size: .86rem; border-bottom: 1px solid var(--line); }
.jobtable tbody tr:last-child td { border-bottom: 0; }
.jobtable td.num { white-space: nowrap; }

.jobcard__foot {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    padding: .6rem .9rem; border-top: 1px solid var(--line); background: var(--bg);
    border-radius: 0 0 5px 5px;
}
.jobcard__gp { font-size: .8rem; color: var(--muted); }
.jobcard__gp strong { color: var(--text); }
.jobcard__sub { font-size: .8rem; color: var(--muted); }
.jobcard__spacer { flex: 1; }
.jobcard__add summary { cursor: pointer; font-size: .8rem; color: var(--accent); }
.jobcard__add[open] { flex: 1 1 100%; }
.jobcard__foot form { margin: 0; }

@media (max-width: 760px) {
    .jobcard__head { flex-wrap: wrap; }
    .jobcard__meta { order: 3; flex-basis: 100%; }
    .jobtable { font-size: .8rem; }
}

/* ---------- Labor guide diagnostics ---------- */
.labor-debug { padding: .7rem .8rem; font-size: .8rem; }
.labor-debug strong { display: block; margin-bottom: .4rem; }
.labor-debug code { display: block; word-break: break-all; color: var(--muted); margin-bottom: .5rem; font-size: .74rem; }
.labor-debug ul { margin: 0 0 .5rem 1rem; padding: 0; }
.labor-debug li { font-family: var(--mono); font-size: .72rem; color: var(--muted); line-height: 1.6; }
.labor-debug pre { background: var(--bg); padding: .5rem; border-radius: var(--radius-sm); overflow-x: auto; font-size: .7rem; max-height: 220px; }
.labor-debug p { margin: .4rem 0 0; color: var(--muted); }
.labor-caveat { border-top: 1px dashed var(--line); margin-top: .7rem; padding-top: .6rem; }
.labor-part {
    display: flex; align-items: baseline; gap: .5rem;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius-sm); padding: .45rem .6rem; font-size: .82rem;
}
.labor-part span { color: var(--muted); font-size: .76rem; }
.labor-part__price { margin-left: auto; color: var(--text); font-weight: 600; }

/* ---------- Labor guide modal ---------- */
.lg-modal {
    position: fixed; inset: 0; z-index: 200;
    background: rgba(20, 22, 26, .55);
    display: flex; align-items: center; justify-content: center; padding: 1.5rem;
}
.lg-modal[hidden] { display: none; }
.lg-modal__box {
    background: var(--surface); border-radius: var(--radius);
    width: 100%; max-width: 1040px; max-height: 88vh;
    display: flex; flex-direction: column; overflow: hidden;
    box-shadow: 0 24px 60px rgba(20, 22, 26, .4);
}
.lg-modal__head {
    display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem;
    padding: .9rem 1.1rem; background: var(--ink); color: var(--surface);
}
.lg-modal__head h2 { color: var(--surface); margin: 0; font-size: 1.15rem; }
.lg-modal__head p { margin: .1rem 0 0; font-size: .84rem; opacity: .7; }
.lg-modal__x {
    background: none; border: 0; color: var(--surface); font-size: 1.2rem; cursor: pointer; opacity: .7;
}
.lg-modal__x:hover { opacity: 1; }

.lg-modal__body { display: grid; grid-template-columns: minmax(0, 1fr) 320px; overflow: hidden; }
.lg-find { padding: 1rem 1.1rem; overflow-y: auto; }
.lg-find__row { display: flex; gap: .5rem; margin-bottom: .5rem; }
.lg-find__row input { flex: 1; }

.lg-results { margin-top: .8rem; display: grid; gap: .35rem; }
.lg-hit {
    display: flex; align-items: center; gap: .8rem;
    border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .55rem .7rem;
}
.lg-hit div { flex: 1; min-width: 0; }
.lg-hit strong { display: block; font-size: .88rem; }
.lg-hit span { font-size: .74rem; color: var(--muted); }
.lg-hit__h { font-weight: 700; font-variant-numeric: tabular-nums; }
.lg-add {
    width: 28px; height: 28px; flex: 0 0 auto; border-radius: var(--radius-sm);
    border: 1px solid var(--gold-dark); background: var(--gold); color: var(--ink);
    font-weight: 700; cursor: pointer; font-size: 1rem; line-height: 1;
}
.lg-add:disabled { background: #dcfce7; border-color: #86efac; color: var(--ok-strong); cursor: default; }

.lg-browse {
    display: block; width: 100%; text-align: left; cursor: pointer;
    background: var(--bg); border: 1px solid var(--line);
    border-radius: var(--radius-sm); padding: .5rem .7rem;
}
.lg-browse:hover { border-color: var(--gold); }
.lg-browse strong { display: block; font-size: .86rem; }
.lg-browse span { font-size: .74rem; color: var(--muted); }

.lg-cart {
    border-left: 1px solid var(--line); background: var(--bg);
    padding: 1rem; overflow-y: auto; display: flex; flex-direction: column; gap: .8rem;
}
.lg-cart input { width: 100%; }
.lg-cart__section { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); }
.lg-cart__head {
    display: flex; justify-content: space-between;
    padding: .4rem .6rem; border-bottom: 1px solid var(--line);
    font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted);
}
.lg-cart__empty { padding: .6rem; margin: 0; color: var(--muted); font-size: .8rem; text-align: center; }
.lg-line {
    display: flex; align-items: center; gap: .5rem;
    padding: .4rem .6rem; border-bottom: 1px solid var(--line); font-size: .82rem;
}
.lg-line:last-child { border-bottom: 0; }
.lg-line span:first-child { flex: 1; min-width: 0; }
.lg-line span:nth-child(2) { font-variant-numeric: tabular-nums; font-weight: 600; }
.lg-line button { background: none; border: 0; color: var(--danger); cursor: pointer; }
.lg-cart__total {
    display: flex; justify-content: space-between; align-items: baseline;
    padding-top: .5rem; border-top: 2px solid var(--line);
}
.lg-cart__total strong { font-size: 1.3rem; font-variant-numeric: tabular-nums; }
.lg-cart__go { width: 100%; }

@media (max-width: 860px) {
    .lg-modal { padding: 0; }
    .lg-modal__box { max-height: 100vh; border-radius: 0; }
    .lg-modal__body { grid-template-columns: 1fr; }
    .lg-cart { border-left: 0; border-top: 1px solid var(--line); }
}

/* ---------- Labor guide comparison ---------- */
.lg-compare { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); margin-bottom: .6rem; }
.lg-src {
    display: flex; flex-direction: column; gap: .15rem;
    border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .6rem .7rem;
    position: relative;
}
.lg-src__name { font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
.lg-src strong { font-size: 1.5rem; font-variant-numeric: tabular-nums; line-height: 1.1; }
.lg-src__none { font-size: .82rem; color: var(--muted); }
.lg-src .lg-add { position: absolute; top: .5rem; right: .5rem; }
.lg-conf { font-size: .72rem; }
.lg-conf--high { color: var(--ok-strong); }
.lg-conf--medium { color: var(--warn); }
.lg-conf--low { color: var(--danger-strong); }

.lg-basis { font-size: .82rem; color: var(--muted); margin: 0 0 .6rem; line-height: 1.5; }
.lg-gap {
    font-size: .82rem; padding: .45rem .6rem; border-radius: var(--radius-sm);
    background: var(--ok-soft); color: var(--ok-strong); margin: 0 0 .6rem;
}
.lg-gap.is-wide { background: var(--warn-bg); color: var(--warn-strong); }

/* ---------- AI labor estimate ---------- */
.lg-headline {
    display: flex; align-items: center; gap: 1rem; justify-content: space-between;
    border: 1px solid var(--line); border-left: 4px solid var(--muted);
    border-radius: var(--radius-sm); padding: .8rem 1rem; margin-bottom: .6rem;
}
.lg-headline.lg-conf--high { border-left-color: #16a34a; }
.lg-headline.lg-conf--medium { border-left-color: #f59e0b; }
.lg-headline.lg-conf--low { border-left-color: #dc2626; }
.lg-headline strong { display: block; font-size: 2rem; line-height: 1.1; font-variant-numeric: tabular-nums; }
.lg-headline .lg-conf { font-size: .78rem; }
.lg-add--big { width: auto; height: auto; padding: .5rem 1.1rem; font-size: .9rem; }

.lg-section {
    font-size: .68rem; text-transform: uppercase; letter-spacing: .07em;
    color: var(--muted); margin: 1rem 0 .4rem;
}
.lg-second { font-size: .84rem; color: var(--muted); margin: 0 0 .6rem; }
.lg-cmp { font-size: .8rem; display: block; margin-bottom: .4rem; }
.labor-open { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-top: .5rem; }
.labor-open span { color: var(--muted); font-size: .8rem; }
.lg-pinned { display: block; font-size: .74rem; color: var(--muted); margin-top: .25rem; }
.lg-pinned button {
    background: none; border: 0; padding: 0; color: var(--accent);
    cursor: pointer; font-size: .74rem; text-decoration: underline;
}
.lg-quote { background: var(--bg); border-left: 3px solid var(--gold); padding: .6rem .8rem; border-radius: var(--radius-sm); }
.lg-quote button { display: block; margin-top: .5rem; }
.lg-tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--line); margin-bottom: .8rem; }
.lg-tabs button {
    background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
    padding: .5rem .8rem; cursor: pointer; color: var(--muted); font-size: .86rem; font-weight: 600;
}
.lg-tabs button.is-on { color: var(--ink); border-bottom-color: var(--gold); }
#lg-paste { width: 100%; font-family: var(--mono); font-size: .78rem; margin-bottom: .5rem; }

/* ---------- Quick labor entry ---------- */

@media (max-width: 760px) {
}
.btn-link {
    background: none; border: 0; padding: 0; cursor: pointer;
    color: var(--accent); text-decoration: underline; font: inherit;
}
.btn-link:hover { color: var(--ink); }
.pd-note { display: block; font-size: .76rem; color: #05603a; margin-top: .35rem; min-height: 1em; }
.pd-pinned { color: #05603a; }
.pd-pin { margin-top: .6rem; }
.pd-pin summary { cursor: pointer; font-size: .8rem; color: var(--accent); }
.pd-pin input { width: 100%; font-size: .74rem; font-family: var(--mono); margin-top: .4rem; }
.conn-aside { margin: 1rem 1.5rem; }
.lg-parts { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin: .8rem 0; padding-top: .8rem; border-top: 1px solid var(--line); }
.lg-parts .hint { flex: 1; min-width: 200px; margin: 0; }
.pct-field { display: flex; align-items: center; gap: .4rem; }
.pct-field input { max-width: 120px; }
.pct-field span { color: var(--muted); }

/* ---------- Settings, two levels ---------- */
.settings-split { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 1.25rem; align-items: start; }
.settings-side {
    display: flex; flex-direction: column; gap: .1rem;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: .5rem;
}
.settings-side a {
    padding: .5rem .7rem; border-radius: var(--radius-sm); text-decoration: none;
    color: var(--text); font-size: .88rem;
}
.settings-side a:hover { background: var(--bg); }
.settings-side a.is-on { background: var(--gold); color: var(--ink); font-weight: 600; }
.settings-body { min-width: 0; }

/* ---------- Fee table ---------- */
.fee-table { display: grid; gap: .4rem; }
.fee-head, .fee-row {
    display: grid; gap: .4rem; align-items: center;
    grid-template-columns: 110px minmax(120px, 1.4fr) 120px 130px 90px 90px 40px 30px;
}
.fee-head {
    font-size: .66rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted);
    padding: 0 .2rem;
}
.fee-row input, .fee-row select { font-size: .82rem; padding: .35rem .45rem; width: 100%; }
.fee-tax { text-align: center; }

@media (max-width: 900px) {
    .settings-split { grid-template-columns: 1fr; }
    .settings-side { flex-direction: row; overflow-x: auto; }
    .fee-head { display: none; }
    .fee-row { grid-template-columns: 1fr 1fr; padding: .6rem; border: 1px solid var(--line); border-radius: var(--radius-sm); }
}
.pay-list { display: grid; gap: .4rem; max-width: 420px; }
.pay-row { display: flex; gap: .5rem; align-items: center; }
.pay-row input { flex: 1; }
.ro-bar__warn {
    display: block; font-size: .68rem; color: #fca5a5; margin-top: .1rem;
}
.appt-list { display: grid; gap: .4rem; max-width: 560px; }
.appt-row { display: grid; grid-template-columns: 48px minmax(0,1fr) auto auto; gap: .6rem; align-items: center; }
.appt-row input[type="color"] { width: 48px; height: 32px; padding: 2px; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.appt-row .brand-crop { margin: 0; font-size: .8rem; white-space: nowrap; }

/* ---------- Day view ---------- */
.cal-legend { display: flex; flex-wrap: wrap; gap: .8rem; margin: 0 0 1rem; font-size: .78rem; }
.dayview { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.dayview__row { display: grid; grid-template-columns: 72px minmax(0, 1fr); border-bottom: 1px solid var(--line); min-height: 58px; }
.dayview__row:last-child { border-bottom: 0; }
.dayview__row.is-empty { background: var(--bg); }
.dayview__hour {
    padding: .55rem .7rem; border-right: 1px solid var(--line);
    font-size: .74rem; color: var(--muted); font-variant-numeric: tabular-nums;
}
.dayview__slot { padding: .4rem; display: flex; flex-wrap: wrap; gap: .4rem; }

.dayappt {
    --appt: var(--info);
    border-left: 4px solid var(--appt); background: var(--bg);
    border-radius: var(--radius-sm); padding: .5rem .65rem; min-width: 210px; flex: 1 1 210px;
}
.dayappt header { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.dayappt strong { font-size: .88rem; }
.dayappt p { margin: .1rem 0 0; font-size: .78rem; color: var(--muted); }
.dayappt__veh { font-weight: 600; color: var(--text) !important; }
.dayappt__tel { font-size: .78rem; }
.dayappt__type { margin-top: .4rem; }
.dayappt__type select { font-size: .74rem; padding: .2rem .35rem; width: 100%; }

.cal__appt[style*="--appt"] { border-left: 3px solid var(--appt); }
.cal__n { text-decoration: none; color: inherit; }
.cal__n:hover { text-decoration: underline; }

/* ---------- Calendar switcher ---------- */
.cal-switch { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.cal-modes { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.cal-modes a {
    padding: .38rem .8rem; font-size: .82rem; text-decoration: none;
    color: var(--text); border-right: 1px solid var(--line);
}
.cal-modes a:last-child { border-right: 0; }
.cal-modes a:hover { background: var(--bg); }
.cal-modes a.is-on { background: var(--ink); color: var(--surface); }

/* ---------- Week view ----------
   A column per day with blocks positioned inside it, rather than a cell
   per hour. An appointment that runs nine to four has to be able to say
   so, and a cell can only ever show what hour something starts. */
.weekview { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.weekview__head { display: grid; grid-template-columns: 64px repeat(7, minmax(0, 1fr));
                  border-bottom: 2px solid var(--line); background: var(--bg);
                  position: sticky; top: 56px; z-index: 5; }
.weekview__corner { border-right: 1px solid var(--line); }
.weekview__day {
    padding: .5rem .3rem; text-align: center; text-decoration: none; color: var(--text);
    border-right: 1px solid var(--line); display: flex; flex-direction: column; gap: .05rem;
}
.weekview__day:last-child { border-right: 0; }
.weekview__day span { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.weekview__day strong { font-size: 1.05rem; }
.weekview__day em { font-size: .62rem; color: var(--danger); font-style: normal; }
.weekview__day.is-today { background: var(--gold); }
.weekview__day.is-today span, .weekview__day.is-today strong { color: var(--ink); }
.weekview__day.is-closed { opacity: .55; }
.weekview__day:hover { background: var(--line); }

.weekview__body { display: grid; grid-template-columns: 64px repeat(7, minmax(0, 1fr)); }
.weekview__gutter { border-right: 1px solid var(--line); }
.weekview__hour {
    display: block; height: var(--hour-h); padding: .15rem .4rem 0 0; text-align: right;
    font-size: .68rem; color: var(--muted); font-variant-numeric: tabular-nums;
    border-bottom: 1px solid transparent;
}
.weekview__col {
    position: relative; border-right: 1px solid var(--line);
    height: calc(var(--hour-h) * var(--rows)); cursor: cell;
}
.weekview__col:last-child { border-right: 0; }
.weekview__col.is-today { background: rgba(212, 175, 55, .06); }
.weekview__line { display: block; height: var(--hour-h); border-bottom: 1px solid var(--line); }

.weekappt {
    --appt: var(--info);
    position: absolute; background: var(--appt); color: var(--surface); border-radius: var(--radius-sm);
    padding: .2rem .35rem; overflow: hidden; cursor: grab; touch-action: none;
    display: flex; flex-direction: column; gap: 1px; font-size: .7rem; line-height: 1.2;
}
.weekappt:hover { filter: brightness(1.08); z-index: 3; }
.weekappt__time { font-size: .62rem; opacity: .85; font-variant-numeric: tabular-nums; }
.weekappt__who { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.weekappt__what { font-size: .64rem; opacity: .85; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.weekappt.is-unconfirmed { opacity: .78; border: 1px dashed rgba(255,255,255,.65); }
.weekappt.is-dragging { opacity: .65; cursor: grabbing; z-index: 4; }
.weekappt.is-resizing { z-index: 4; }
.weekappt.is-saving { animation: pulse 1s ease-in-out infinite; }

.weekappt__resize {
    position: absolute; left: 0; right: 0; bottom: 0; height: 8px;
    cursor: ns-resize; background: linear-gradient(transparent, rgba(0,0,0,.25));
    border-radius: 0 0 4px 4px;
}
.weekappt__resize::after {
    content: ''; position: absolute; left: 50%; bottom: 2px; transform: translateX(-50%);
    width: 16px; height: 2px; background: rgba(255,255,255,.7); border-radius: 2px;
}
.weekappt__grab { display: none; }

@keyframes pulse { 50% { opacity: .5; } }

@media (max-width: 900px) {
    .weekview { overflow-x: auto; }
    .weekview__head, .weekview__body { grid-template-columns: 52px repeat(7, minmax(104px, 1fr)); min-width: 800px; }
}

/* ---------- Appointment modal ---------- */
.appt-modal { position: fixed; inset: 0; z-index: 200; background: rgba(20,22,26,.55); display: flex; align-items: center; justify-content: center; padding: 1.5rem; }
.appt-modal[hidden] { display: none; }
.appt-modal__box { background: var(--surface); border-radius: var(--radius); width: 100%; max-width: 560px; max-height: 90vh; overflow-y: auto; }
.appt-modal__head { display: flex; justify-content: space-between; align-items: center; padding: .9rem 1.1rem; background: var(--ink); color: var(--surface); }
.appt-modal__head h2 { color: var(--surface); margin: 0; font-size: 1.1rem; }
.appt-modal__x { background: none; border: 0; color: var(--surface); font-size: 1.4rem; cursor: pointer; opacity: .7; }
.appt-modal__x:hover { opacity: 1; }
.appt-modal .admin-form { padding: 1.1rem; margin: 0; }
.appt-modal__bar { background: var(--bg); margin: -1.1rem -1.1rem 1rem; padding: .5rem 1.1rem; font-size: .78rem; color: var(--muted); }
.appt-crumbs b { color: var(--muted); }
.appt-crumbs b.is-on { color: var(--ink); }

.appt-choice { display: flex; gap: .7rem; align-items: flex-start; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .7rem .8rem; margin-bottom: .5rem; cursor: pointer; }
.appt-choice:hover { border-color: var(--gold); }
.appt-choice input { margin-top: .2rem; }
.appt-choice strong { display: block; font-size: .9rem; }
.appt-choice span { font-size: .8rem; color: var(--muted); line-height: 1.45; }

.appt-results { border: 1px solid var(--line); border-radius: var(--radius-sm); margin-top: .3rem; max-height: 200px; overflow-y: auto; }
.appt-hit { display: block; width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--line); padding: .45rem .6rem; cursor: pointer; }
.appt-hit:last-child { border-bottom: 0; }
.appt-hit:hover { background: var(--bg); }
.appt-hit strong { display: block; font-size: .84rem; }
.appt-hit span { font-size: .74rem; color: var(--muted); }

.weekappt { cursor: grab; }
.weekappt em { font-style: normal; opacity: .8; font-size: .62rem; margin-left: .2rem; }
.weekappt.is-dragging { opacity: .4; }
.weekappt.is-saving { animation: pulse 1s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .5; } }

/* ---------- Top bar, on every admin page ---------- */
.admin.has-top .shell { padding-top: 56px; }
.ws-top {
    position: fixed; top: 0; left: 0; right: 0; height: 56px; z-index: 60;
    display: flex; align-items: center; gap: 1rem; padding: 0 1rem;
    background: var(--ink); border-bottom: 2px solid var(--gold);
}
.ws-burger {
    background: none; border: 0; cursor: pointer; padding: .4rem;
    display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto;
}
.ws-burger span { display: block; width: 18px; height: 2px; background: rgba(255,255,255,.8); }
.ws-burger:hover span { background: var(--gold); }

.ws-user { position: relative; }
.ws-who {
    display: flex; align-items: center; gap: .5rem; background: none; border: 0;
    cursor: pointer; color: rgba(255,255,255,.85); font: inherit; font-size: .84rem; padding: .3rem;
}
.ws-avatar {
    width: 30px; height: 30px; border-radius: 50%; background: var(--gold); color: var(--ink);
    display: grid; place-items: center; font-size: .74rem; font-weight: 700; letter-spacing: .02em;
}
.ws-menu {
    position: absolute; right: 0; top: calc(100% + .5rem); min-width: 220px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(20,22,26,.22); padding: .4rem; z-index: 70;
}
.ws-menu[hidden] { display: none; }
.ws-menu__who { display: block; padding: .5rem .6rem; font-size: .74rem; color: var(--muted); border-bottom: 1px solid var(--line); margin-bottom: .3rem; }
.ws-menu__who strong { color: var(--text); font-size: .82rem; }
.ws-menu a { display: block; padding: .45rem .6rem; border-radius: var(--radius-sm); text-decoration: none; color: var(--text); font-size: .85rem; }
.ws-menu a:hover { background: var(--bg); }
.ws-menu__out { border-top: 1px solid var(--line); margin-top: .3rem; padding-top: .55rem !important; color: var(--danger) !important; }

/* ---------- Collapsible sidebar ----------
   The width is set through the variable rather than by overriding
   `width`, because the sidebar also sets `flex: 0 0 var(--sidebar-w)` —
   and a flex-basis beats a width every time. That is why the first
   attempt shrank the labels and left the column the same size. */
.nav-closed { --sidebar-w: 62px; }
.sidebar { transition: width var(--dur-fast) var(--ease-out), flex-basis var(--dur-fast) var(--ease-out); }

.nav-closed .sidebar__brand { justify-content: center; padding-left: 0; padding-right: 0; }
.nav-closed .sidebar__brand > span:not(.sidebar__star) { display: none; }
/* The section headings are <p class="sidebar__label">, not headings.
   Targeting h3 hid nothing, which is why "Workshop" and "Getting
   customers in" were still stacked above the icons. */
.nav-closed .sidebar__label { display: none; }
/* The whole footer block goes: the account name, the role, the staff
   link, the sign-out form and "View site" all live in the top-bar menu
   now, so keeping a squashed copy of them in a 62px column serves
   nobody. */
.nav-closed .sidebar__user,
.nav-closed .sidebar__role,
.nav-closed .sidebar__staff,
.nav-closed .sidebar__view,
.nav-closed .sidebar__foot,
.nav-closed .sidebar form { display: none; }
.nav-closed .sidebar h3 { display: none; }
.nav-closed .sidebar nav { padding-top: .4rem; }
.nav-closed .sidebar nav a,
.nav-closed .sidebar a {
    justify-content: center; padding-left: 0; padding-right: 0;
    gap: 0; position: relative;
}
/* Hide the label text without hiding the icon. */
.nav-closed .sidebar a { font-size: 0; }
.nav-closed .sidebar a > svg,
.nav-closed .sidebar a > .ico-svg { font-size: 1rem; flex: 0 0 auto; }
.nav-closed .sidebar a .chip { display: none; }

.nav-closed .sidebar a::after {
    content: attr(data-label); position: absolute; left: calc(100% + .45rem); top: 50%;
    transform: translateY(-50%); background: var(--ink); color: var(--surface); font-size: .78rem;
    padding: .3rem .55rem; border-radius: var(--radius-sm); white-space: nowrap;
    opacity: 0; pointer-events: none; transition: opacity var(--dur-fast) var(--ease-out); z-index: 80;
    box-shadow: 0 4px 14px rgba(0,0,0,.25);
}
.nav-closed .sidebar a:hover::after { opacity: 1; }

@media (max-width: 900px) {
    .ws-find { display: none; }
    .ws-who__name { display: none; }
    .nav-closed .sidebar { width: 100%; }
    .nav-closed .sidebar a { justify-content: flex-start; font-size: inherit; }
    .nav-closed .sidebar a span:not(.chip) { display: inline; }
    .nav-closed .sidebar h3 { display: block; }
}

@media (max-width: 900px) {
    .sidebar { position: fixed; top: 56px; bottom: 0; left: 0; z-index: 55;
               transform: translateX(-100%); transition: transform var(--dur-slow) var(--ease-drawer); }
    .nav-open .sidebar { transform: translateX(0); }
    .shell { display: block; }
}


/* ---------- Top bar, whichever design is active ----------
   workshop.css also styles .ws-top and loads after this file, so the
   colours here are stated once more at a specificity that survives it.
   Two files describing the same bar is the actual problem; until they
   are merged this keeps it dark rather than transparent. */
body.has-top .ws-top {
    background: var(--ink); color: var(--surface);
    border-bottom: 3px solid var(--gold, #d4af37);
}
body.has-top .ws-brand { color: var(--surface); text-decoration: none; font-weight: 700; letter-spacing: .04em; }
body.has-top .ws-brand span { color: var(--gold, #d4af37); }
body.has-top .ws-find input {
    width: 100%; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14);
    color: var(--surface); border-radius: var(--radius-sm); padding: .45rem .7rem .45rem 2.1rem; font-size: .86rem;
}
body.has-top .ws-find input::placeholder { color: rgba(255,255,255,.45); }
body.has-top .ws-find { position: relative; flex: 1; max-width: 620px; display: flex; align-items: center; }
body.has-top .ws-find .ico-svg { position: absolute; left: .7rem; opacity: .5; pointer-events: none; color: var(--surface); }
body.has-top .ws-top__end { display: flex; align-items: center; gap: .9rem; margin-left: auto; }
/* Gold background, dark text. The previous rule set only the colour and
   inherited the gold background from workshop.css — gold on gold, which
   is how a button becomes invisible. */
body.has-top .ws-new {
    display: inline-flex; align-items: center; gap: .35rem;
    background: var(--gold, #d4af37); color: var(--ink);
    padding: .42rem .8rem; border-radius: var(--radius-sm);
    text-decoration: none; font-weight: 700; font-size: .8rem;
    letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
}
body.has-top .ws-new:hover { background: var(--surface); color: var(--ink); }
body.has-top .ws-new .ico-svg { color: currentColor; }
.auth-menu { position: relative; display: inline-block; }
.auth-menu__list {
    position: absolute; right: 0; bottom: calc(100% + .4rem); min-width: 190px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(20,22,26,.22); padding: .3rem; z-index: 60;
}
.auth-menu__list[hidden] { display: none; }
.auth-menu__list button {
    display: block; width: 100%; text-align: left; background: none; border: 0;
    padding: .5rem .6rem; border-radius: var(--radius-sm); cursor: pointer; font-size: .86rem; color: var(--text);
}
.auth-menu__list button:hover { background: var(--bg); }
.auth-menu__list .is-bad { color: var(--danger); }
.auth-record { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .7rem .8rem;
               margin: .8rem 0; font-size: .84rem; background: var(--ok-soft); }
.auth-record strong { display: block; color: var(--ok-strong); }
.auth-sig { display: block; max-width: 260px; margin-top: .5rem; background: var(--surface);
            border: 1px solid var(--line); border-radius: var(--radius-sm); }

/* ---------- Authorization screen ---------- */
.auth-step { display: flex; gap: .8rem; align-items: flex-start; margin: 1.5rem 0 .8rem; }
.auth-step__n {
    width: 26px; height: 26px; flex: 0 0 auto; border-radius: 50%;
    background: var(--ink); color: var(--surface); display: grid; place-items: center;
    font-size: .8rem; font-weight: 700;
}
.auth-step h2 { margin: 0 0 .15rem; font-size: 1.05rem; }
.auth-step p { margin: 0; }

.auth-all { display: flex; gap: .5rem; margin-bottom: .8rem; flex-wrap: wrap; }

.auth-job { border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: .8rem;
            overflow: hidden; background: var(--surface); }
.auth-job header { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
                   padding: .7rem .9rem; background: var(--bg); border-bottom: 1px solid var(--line); }
.auth-job header h3 { margin: 0; font-size: .96rem; }
.auth-job header strong { white-space: nowrap; }
.auth-job__why { padding: .6rem .9rem 0; margin: 0; font-size: .86rem; color: var(--muted); }
.auth-job--declined { opacity: .62; }
.auth-table { margin: .5rem 0 0; }
.auth-table th, .auth-table td { padding: .35rem .9rem; }

.auth-job__choose { display: flex; align-items: center; gap: .5rem; padding: .7rem .9rem;
                    background: var(--bg); border-top: 1px solid var(--line); }
.auth-job__choose label { display: flex; align-items: center; gap: .4rem; border: 2px solid var(--line);
                          border-radius: var(--radius-sm); padding: .45rem .9rem; cursor: pointer;
                          font-weight: 600; font-size: .86rem; }
.auth-job__choose label:has(input:checked) { border-color: #16a34a; background: var(--ok-soft); color: var(--ok-strong); }
.auth-job__choose label:has(input[value="declined"]:checked) { border-color: #dc2626; background: var(--danger-bg); color: var(--danger); }
.auth-job__total { margin-left: auto; font-size: .82rem; color: var(--muted); }
.auth-job__total strong { color: var(--text); }

.auth-total { display: flex; justify-content: space-between; align-items: baseline;
              padding: .8rem 1rem; background: var(--ink); color: var(--surface);
              border-radius: var(--radius-sm); margin: 1rem 0; }
.auth-total strong { font-size: 1.4rem; }
.back { font-size: .82rem; text-decoration: none; color: var(--muted); }
.back:hover { color: var(--text); }

/* ---------- Sharing an estimate ---------- */
.share__picks { display: grid; gap: .5rem; margin-bottom: .9rem; }
.share__pick {
    display: flex; align-items: flex-start; gap: .6rem; cursor: pointer;
    border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .6rem .75rem;
}
.share__pick:hover { border-color: var(--gold); }
.share__pick:has(input:checked) { border-color: #16a34a; background: var(--ok-soft); }
.share__pick:has(input:disabled) { opacity: .55; cursor: default; }
.share__pick input { margin-top: .15rem; }
.share__pick strong { margin-right: .35rem; }
.share__pick span { font-size: .88rem; }
.share__pick em { color: var(--muted); font-style: normal; font-size: .8rem; }
.share__other { margin: .9rem 0; }
.share__other summary { cursor: pointer; font-size: .84rem; color: var(--accent); }
.panel--danger { border-color: var(--danger-border); }
.panel--danger .panel__head { background: var(--danger-bg); }
.panel--danger .panel__head h2 { color: var(--danger); }
.btn-danger { background: var(--danger); color: var(--surface); border-color: var(--danger); }
.btn-danger:hover { background: #991b1b; }

/* ---------- Dashboard: what needs a person ---------- */
.needs { display: grid; gap: .5rem; margin-bottom: 1.25rem; }
.needs__item {
    display: grid; grid-template-columns: 1fr auto; gap: .2rem .8rem;
    border: 1px solid var(--line); border-left: 4px solid var(--muted);
    border-radius: var(--radius-sm); padding: .7rem .9rem;
    text-decoration: none; color: var(--text); background: var(--surface);
}
.needs__item:hover { border-color: var(--gold); }
.needs__item--amber { border-left-color: #f59e0b; background: var(--warn-bg); }
.needs__item--grey { border-left-color: var(--muted); }
.needs__item strong { font-size: .92rem; }
.needs__worth { font-size: 1.05rem; font-weight: 700; text-align: right; }
.needs__why { grid-column: 1 / -1; font-size: .8rem; color: var(--muted); }

.tile__n { display: block; font-size: 1.75rem; font-weight: 700; line-height: 1.1; }
.tile__label { display: block; font-size: .82rem; font-weight: 600; margin-top: .15rem; }
.tile__sub { display: block; font-size: .74rem; color: var(--muted); margin-top: .1rem; }

/* ---------- Card menus on the board ----------
   The button lives in the top-right corner, which is where people look
   for one — so the card's top row reserves that space rather than having
   the RO number run underneath it. */
.job-slot { position: relative; }
.job-card__top { padding-right: 2.1rem; }

.job-menu { position: absolute; top: .3rem; right: .3rem; z-index: 2; }
.job-menu__dots {
    display: grid; place-items: center;
    width: 28px; height: 28px; padding: 0;
    background: none; border: 0; border-radius: 50%;
    color: var(--muted); cursor: pointer;
    transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.job-menu__dots svg { fill: currentColor; }
.job-menu__dots:hover,
.job-menu__dots[aria-expanded="true"] {
    background: var(--ink); color: var(--surface);
}
.job-menu__dots:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

/* On a touch screen there is no hover, so the button needs to be visible
   on its own — hence the muted colour rather than transparent. */
@media (hover: hover) {
    .job-menu__dots { opacity: .45; }
    .job-slot:hover .job-menu__dots,
    .job-menu__dots[aria-expanded="true"] { opacity: 1; }
}

/* Fixed, not absolute, and positioned by script.
   The column sets overflow:hidden to clip its rounded corners, which also
   clipped this — the first card's menu fitted inside the column and every
   one below it was cut off. Nothing positioned inside a clipping ancestor
   can escape it, so the menu is taken out of the flow entirely. */
.job-menu__list {
    position: fixed; min-width: 214px; max-width: 260px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: 0 14px 34px rgba(20, 22, 26, .26); padding: .3rem; z-index: 200;
}
.job-menu__list[hidden] { display: none; }
.job-menu__list button {
    display: block; width: 100%; text-align: left; background: none; border: 0;
    padding: .5rem .62rem; border-radius: var(--radius-sm); cursor: pointer;
    font-size: .85rem; color: var(--text);
}
.job-menu__list button:hover { background: var(--bg); }
.job-menu__list .is-bad { color: var(--danger); }
.job-menu__list .is-bad:hover { background: var(--danger-bg); }

.job-parked { margin: -.4rem .1rem .6rem; }
.job-parked button {
    width: 100%; background: var(--warn-bg); border: 1px solid #fcd34d; color: var(--warn-strong);
    border-radius: var(--radius-sm); padding: .35rem; font-size: .76rem; cursor: pointer;
}

/* ---------- Work in progress ---------- */
.wip-sum { display: flex; gap: 1.5rem; flex-wrap: wrap; padding: .8rem 1rem; background: var(--bg);
           border-radius: var(--radius-sm); margin-bottom: 1rem; font-size: .86rem; }
.wip-sum strong { font-size: 1.15rem; }
.wip-sum .is-low { color: var(--danger); font-weight: 600; }
.wip-sum .is-good { color: var(--ok-strong); font-weight: 600; }

.wip-job { border: 1px solid var(--line); border-left: 4px solid var(--line);
           border-radius: var(--radius-sm); margin-bottom: .7rem; background: var(--surface); }
.wip-job.is-running { border-left-color: #16a34a; }
.wip-job.is-done { border-left-color: var(--muted); opacity: .72; }
.wip-job header { display: flex; justify-content: space-between; gap: 1rem; padding: .7rem .9rem; }
.wip-job h3 { margin: 0; font-size: .95rem; }
.wip-job p { margin: 0; }
.wip-job__nums { text-align: right; white-space: nowrap; }
.wip-job__nums span { display: block; font-size: .72rem; color: var(--muted); }
.wip-job__nums strong { font-size: 1.1rem; font-variant-numeric: tabular-nums; }
.wip-job__nums .is-low { color: var(--danger); }
.wip-live { color: var(--ok-strong) !important; font-weight: 600; font-variant-numeric: tabular-nums; }

.wip-job__do { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap;
               padding: .6rem .9rem; border-top: 1px solid var(--line); background: var(--bg); }
.wip-on { display: flex; gap: .4rem; align-items: center; }
.wip-on select { font-size: .82rem; padding: .3rem .45rem; }
tr.is-running { background: var(--ok-soft); }

/* ---------- Work in progress, laid out for the bay ---------- */
.wip { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
       margin-bottom: 1rem; overflow: hidden; }
.wip.is-running { border-color: #86efac; box-shadow: 0 0 0 1px #86efac inset; }
.wip.is-done { opacity: .72; }

.wip__head { display: flex; justify-content: space-between; align-items: center; gap: 1rem;
             padding: .7rem .9rem; background: var(--bg); border-bottom: 1px solid var(--line);
             flex-wrap: wrap; }
.wip__head h2 { margin: 0; font-size: 1rem; }
.wip__sold { color: var(--muted); font-weight: 400; font-size: .88rem; }
.wip__tools { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.wip__who { font-size: .84rem; color: var(--muted); }

.wip__start { display: flex; align-items: center; gap: .35rem; }
.wip__start select { font-size: .8rem; padding: .25rem .4rem; max-width: 130px; }
.wip__play {
    display: grid; place-items: center; width: 30px; height: 30px; padding: 0;
    border-radius: 50%; border: 0; cursor: pointer;
    background: #16a34a; color: var(--surface);
}
.wip__play svg { fill: currentColor; }
.wip__play:hover { background: var(--ok-strong); }
.wip__play.is-stop { background: var(--danger); }
.wip__play.is-stop:hover { background: #991b1b; }

.wip__time { display: inline-flex; align-items: center; gap: .3rem; font-variant-numeric: tabular-nums;
             font-weight: 600; font-size: .95rem; }
.wip__time.is-over { color: var(--danger); }

.wip__fix { position: relative; }
.wip__fix summary { cursor: pointer; color: var(--muted); list-style: none; padding: .2rem .35rem; }
.wip__fix summary::-webkit-details-marker { display: none; }
.wip__fix summary:hover { color: var(--text); }
.wip__fix > div { position: absolute; right: 0; top: calc(100% + .3rem); z-index: 30; width: 220px;
                  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
                  box-shadow: 0 12px 30px rgba(20,22,26,.2); padding: .7rem; }
.wip__fix label { display: block; font-size: .78rem; font-weight: 600; margin-bottom: .2rem; }
.wip__fix input { width: 100%; margin-bottom: .4rem; }

.wip__done { background: none; border: 1px solid var(--line); border-radius: var(--radius-sm);
             padding: .35rem .7rem; font-size: .8rem; font-weight: 600; cursor: pointer; color: var(--text); }
.wip__done:hover { background: var(--ink); color: var(--surface); border-color: var(--ink); }

.wip-table { width: 100%; border-collapse: collapse; font-size: .86rem; }
.wip-table th { text-align: left; font-size: .68rem; text-transform: uppercase; letter-spacing: .06em;
                color: var(--muted); padding: .4rem .9rem; background: var(--bg);
                border-bottom: 1px solid var(--line); }
.wip-table td { padding: .45rem .9rem; border-bottom: 1px solid var(--line); }
.wip-table .num { text-align: right; }
.wip-table tr.is-ticked td:first-child { text-decoration: line-through; color: var(--muted); }



.wip__time.is-live { color: var(--ok-strong); font-variant-numeric: tabular-nums; }
.wip__time.is-live.is-over { color: var(--danger); }

.wip-part { font-size: .76rem; padding: .18rem .4rem; border-radius: var(--radius-pill); border: 1px solid; cursor: pointer; }
.wip-part--grey { background: var(--bg); border-color: var(--line); color: var(--muted); }
.wip-part--amber { background: var(--warn-bg); border-color: #fcd34d; color: var(--warn-strong); }
.wip-part--green { background: var(--ok-soft); border-color: #86efac; color: var(--ok-strong); }
.wip-part--red { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger); }

.wip__notes { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem;
              padding: .6rem .9rem; border-top: 1px solid var(--line); font-size: .84rem; flex-wrap: wrap; }
.wip-comments { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; flex: 1; }
.wip-comments li { line-height: 1.45; }
.wip__add summary { cursor: pointer; color: var(--accent); font-size: .82rem; }
.wip__add form { display: flex; gap: .4rem; margin-top: .4rem; }
.wip__add input { min-width: 240px; }

.wip-log summary { cursor: pointer; padding: .7rem .9rem; font-weight: 600; font-size: .9rem; }

/* Was sticky to the bottom of the viewport with negative margins sized
   for a panel that had 1rem of padding. Inside a folding section it stuck
   over whatever came next — the Payment header, usually — and competed
   with .ro-bar, which is the page's actual sticky bar and already carries
   the totals and the primary action. Two things fighting for the bottom
   of the screen; this one is a summary at the end of a section, so it
   sits there. */

@media (max-width: 700px) {
    .wip__head { flex-direction: column; align-items: flex-start; }
}


/* ---------- Shop controls, stated once more under .ws ----------
   workshop.css loads after this file and paints every submit button gold.
   These four carry their own meaning — a stop button and a checkbox in the
   same gold as "Mark completed" tell a technician nothing — so their
   colours are restated at a specificity that survives it. */
.ws .wip__play,
.ws .wip__play[type="submit"] {
    background: #16a34a; color: var(--surface); border: 0; border-radius: 50%;
    width: 30px; height: 30px; padding: 0; text-transform: none; letter-spacing: 0;
}
.ws .wip__play:hover { background: var(--ok-strong); }
.ws .wip__play.is-stop { background: var(--danger); }
.ws .wip__play.is-stop:hover { background: #991b1b; }



.ws .wip__done {
    background: var(--surface); color: var(--text); border: 1px solid var(--line);
    font-size: .8rem; padding: .35rem .7rem; text-transform: none; letter-spacing: 0;
}
.ws .wip__done:hover { background: var(--ink); color: var(--surface); border-color: var(--ink); }

/* ---------- The correction popover must not be clipped ----------
   .wip set overflow:hidden to clip its rounded corners, which also clipped
   this — the same fault as the board menus two versions ago. The radius is
   applied to the first and last children instead. */
.wip { overflow: visible; }
.wip__head { border-radius: var(--radius) var(--radius) 0 0; }
.wip__notes { border-radius: 0 0 var(--radius) var(--radius); }
.wip__fix > div { z-index: 60; }

/* The Done column: header and tick share one class so they cannot drift
   apart. text-align on the cell does not centre a block-level form, which
   is why the tick sat off to one side of its heading. */
.wip-table__tick { width: 70px; text-align: center; }
.wip-table__tick form { display: flex; justify-content: center; margin: 0; }


/* ---------- The done checkbox ----------
   A native input, sized up for a bay. accent-color paints the tick green
   without replacing the control with a div that then has to be kept in
   step with the database — which is exactly what went wrong twice. */
.wip-tick {
    width: 20px; height: 20px; margin: 0;
    accent-color: #16a34a; cursor: pointer;
}
.wip-tick:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---------- Repair order action group ---------- */
/* No float now that it lives in the header's right-hand column. The float
   was compensating for being in the wrong place in the document, which is
   what a negative margin usually means. */
.ro-head__right { display: flex; flex-direction: column; align-items: flex-end; gap: .5rem; }
.ro-acts { display: inline-flex; align-items: center; border: 1px solid var(--line);
           border-radius: var(--radius-sm); background: var(--surface); overflow: visible; }
.ro-act { display: grid; place-items: center; width: 36px; height: 34px; padding: 0;
          background: none; border: 0; border-right: 1px solid var(--line);
          color: var(--muted); cursor: pointer; }
.ro-act:last-child { border-right: 0; }
.ro-act svg { fill: currentColor; }
.ro-act:hover, .ro-act[aria-expanded="true"] { background: var(--ink); color: var(--surface); }
.ro-act__wrap { position: relative; border-right: 1px solid var(--line); }
.ro-act__wrap:last-child { border-right: 0; }
.ro-act__wrap .ro-act { border-right: 0; }
.ro-act__list { position: absolute; right: 0; top: calc(100% + .3rem); min-width: 230px;
                background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
                box-shadow: 0 14px 34px rgba(20,22,26,.24); padding: .3rem; z-index: 70; }
.ro-act__list[hidden] { display: none; }
.ro-act__list a { display: block; padding: .48rem .6rem; border-radius: var(--radius-sm);
                  text-decoration: none; color: var(--text); font-size: .85rem; }
.ro-act__list a:hover { background: var(--bg); }
.ro-act__list hr { border: 0; border-top: 1px solid var(--line); margin: .3rem 0; }
.ro-act__off { display: block; padding: .48rem .6rem; font-size: .85rem; color: var(--muted); }

/* ---------- Modals ---------- */
.modal { position: fixed; inset: 0; z-index: 210; background: rgba(20,22,26,.55);
         display: flex; align-items: center; justify-content: center; padding: 1.5rem; }
.modal[hidden] { display: none; }
.modal__box { background: var(--surface); border-radius: var(--radius); width: 100%;
              max-width: 520px; max-height: 90vh; display: flex; flex-direction: column; overflow: hidden; }
.modal__box--wide { max-width: 940px; }
.modal__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem;
               padding: .9rem 1.1rem; background: var(--ink); color: var(--surface); }
.modal__head h2 { color: var(--surface); margin: 0; font-size: 1.1rem; }
.modal__head p { margin: .1rem 0 0; font-size: .82rem; opacity: .7; }
.modal__x { background: none; border: 0; color: var(--surface); font-size: 1.5rem; line-height: 1;
            cursor: pointer; opacity: .7; }
.modal__x:hover { opacity: 1; }
.modal__body { padding: 1.1rem; overflow-y: auto; }

/* ---------- Profitability ---------- */
.money-ribbon { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
                gap: .5rem; margin-bottom: 1rem; }
.money-ribbon div { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .6rem .7rem; }
.money-ribbon span { display: block; font-size: .68rem; text-transform: uppercase;
                     letter-spacing: .06em; color: var(--muted); }
.money-ribbon strong { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.money-ribbon .is-green { color: var(--ok-strong); }
.money-ribbon .is-amber { color: var(--warn); }
.money-ribbon .is-red { color: var(--danger); }
.money-ribbon .is-grey { color: var(--muted); }

.tabs--inner { margin-bottom: .8rem; }
.tabs--inner button { background: none; border: 0; border-bottom: 2px solid transparent;
                      padding: .45rem .7rem; cursor: pointer; font-size: .84rem;
                      color: var(--muted); font-weight: 600; }
.tabs--inner button.is-on { color: var(--ink); border-bottom-color: var(--gold); }

.money-table { margin-bottom: 1rem; }
.money-table__job th { background: var(--ink); color: var(--surface); }
.money-table__sum td { font-weight: 700; background: var(--bg); }
.money-table__note td { font-size: .78rem; color: var(--muted); background: var(--bg); }
.money-table .is-missing { color: var(--danger); font-size: .76rem; }

/* ---------------------------------------------------------------------
   Payment tab

   A counter flow, top to bottom: the figure, then the one form, then what
   has been taken. Deliberately not a grid of method tiles beside a totals
   panel — the balance is the thing being read aloud, so it leads, and the
   breakdown that explains it folds away.
   --------------------------------------------------------------------- */
.till { display: flex; align-items: flex-start; justify-content: space-between;
        gap: 1rem; padding: 1.2rem 1.3rem; background: var(--ink); color: var(--surface);
        border-radius: var(--radius); }
.till__figure { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.till__label { font-size: .74rem; text-transform: uppercase; letter-spacing: .09em;
               color: rgba(255,255,255,.6); font-weight: 600; }
/* Sized to be read across a counter, not squinted at. */
.till__amount { font-size: 2.6rem; line-height: 1.05; font-weight: 700;
                font-variant-numeric: tabular-nums; color: var(--gold); }
.till__amount--clear { color: var(--surface); }
.till__note { font-size: .82rem; color: rgba(255,255,255,.65); }
.till__side { display: flex; flex-direction: column; align-items: flex-end; gap: .5rem;
              flex: none; }
.till__warn { margin: 0; max-width: 15rem; text-align: right; font-size: .78rem;
              color: var(--gold); }

.till-break { margin: .6rem 0 1.3rem; }
.till-break summary { cursor: pointer; font-size: .84rem; font-weight: 600; padding: .4rem 0;
                      color: var(--muted); }
.till-break__body { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start;
                    padding: .3rem 0 .2rem; }
.till-break dl { display: grid; grid-template-columns: auto auto; gap: .25rem 1.5rem;
                 margin: 0; font-size: .86rem; }
.till-break dt { color: var(--muted); }
.till-break dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.till-break .is-total { font-weight: 700; color: var(--text); padding-top: .3rem;
                        border-top: 1px solid var(--line); }
.till-disc { display: flex; align-items: flex-end; gap: .5rem; }
.till-disc label { font-size: .78rem; color: var(--muted); }
.till-disc input { width: 7rem; }

/* One row: method, amount, button. The ordinary payment never leaves it. */
.take { padding: 1.1rem 1.2rem; background: var(--surface); border: 1px solid var(--line);
        border-radius: var(--radius); margin-bottom: 1.5rem; }
.take__row { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; }
.take__field { flex: 1 1 10rem; min-width: 0; }
.take__field label { display: block; font-size: .78rem; color: var(--muted);
                     margin-bottom: .2rem; }
/* Method gets the room; amount is four digits and a button needs none. */
.take__field--method { flex: 1 1 12rem; }
.take__field--amount { flex: 0 0 9rem; }
.take__field--go { flex: none; }
.take__full { display: flex; align-items: center; gap: .5rem; margin-top: .7rem;
              font-size: .86rem; }
.take__full input { width: 16px; height: 16px; accent-color: var(--gold-dark); }
.take__card { margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.take__card[hidden] { display: none; }
.take__more { margin-top: .9rem; }
.take__more summary { cursor: pointer; font-size: .82rem; color: var(--muted); }
.take__more .take__row { margin-top: .6rem; }

.pay-log { margin-top: 0; }
.pay-log__table form { margin: 0; }
/* Voided rows stay legible — being read is why they are still here. */
.pay-log__table .is-void td { color: var(--muted); text-decoration: line-through; }
.pay-log__table .is-void .chip { text-decoration: none; background: var(--danger-bg);
                                 color: var(--danger); }

@media (max-width: 700px) {
    .till { flex-direction: column; }
    .till__side { align-items: flex-start; }
    .till__warn { text-align: left; }
    .take__field--amount { flex: 1 1 8rem; }
}

/* ---------------------------------------------------------------------
   Likely causes popup

   Ranked list, so the numbering is part of the content rather than
   decoration — "check these in this order" is the whole point.
   --------------------------------------------------------------------- */
.dx-caveat { margin: 0 0 1rem; padding: .7rem .85rem; background: var(--warn-bg);
             color: var(--warn); border-radius: var(--radius-sm); }
.dx-status { font-size: .86rem; color: var(--muted); margin: 0 0 1rem; }
.dx-status[hidden] { display: none; }

.dx-cause { border: 1px solid var(--line); border-radius: var(--radius);
            padding: .85rem 1rem; margin-bottom: .7rem; }
.dx-cause__top { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }
.dx-cause__n { flex: none; width: 22px; height: 22px; border-radius: 50%;
               background: var(--ink); color: var(--surface); font-size: .74rem; font-weight: 700;
               display: inline-flex; align-items: center; justify-content: center; }
.dx-cause__why { margin: .5rem 0 0; font-size: .88rem; }
.dx-cause__check, .dx-cause__parts { margin: .45rem 0 0; font-size: .86rem; }
.dx-cause__check span, .dx-cause__parts span { font-size: .7rem; text-transform: uppercase;
                                               letter-spacing: .06em; color: var(--muted);
                                               font-weight: 600; margin-right: .35rem; }
.dx-cause__check { padding-top: .45rem; border-top: 1px dashed var(--line); }

.dx-tag { margin-left: auto; font-size: .7rem; font-weight: 600; padding: .2rem .5rem;
          border-radius: var(--radius-sm); text-transform: uppercase; letter-spacing: .05em; }
.dx-tag--common { background: var(--ok-bg); color: var(--ok); }
.dx-tag--possible { background: var(--bg); color: var(--muted); }
.dx-tag--less-likely { background: var(--bg); color: var(--muted); opacity: .8; }

.dx-ask { margin-top: 1.1rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.dx-ask h3 { font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
             color: var(--muted); margin: 0 0 .5rem; }
.dx-ask ul { margin: 0; padding-left: 1.1rem; font-size: .88rem; }
.dx-ask li { margin-bottom: .3rem; }
.dx-ask[hidden] { display: none; }

/* ---------------------------------------------------------------------
   Estimate tracking on the board card

   Two small chips rather than a sentence: they are scanned down a column,
   not read. "Sent 2h ago / Not opened" is the one that earns a phone call.
   --------------------------------------------------------------------- */
.job-card__track { display: flex; flex-wrap: wrap; gap: .3rem; margin: .1rem 0 .45rem; }
.track { font-size: .7rem; font-weight: 600; padding: .16rem .45rem; border-radius: var(--radius-sm);
         letter-spacing: .02em; white-space: nowrap; }
.track--none { background: var(--bg); color: var(--muted); }
.track--sent { background: var(--bg); color: var(--text); }
.track--seen { background: var(--ok-bg); color: var(--ok); }
/* Amber, not grey: sent and unopened is the one worth acting on. */
.track--unseen { background: var(--warn-bg); color: var(--warn); }

/* ---------------------------------------------------------------------
   Reports index

   Tiles rather than a list because the set is browsed, not scanned for a
   known name. Blocked ones stay in place, greyed, carrying the reason —
   they are the build list as much as the catalogue.
   --------------------------------------------------------------------- */
.rpt-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.rpt-tile { display: flex; flex-direction: column; gap: .4rem; padding: 1.1rem;
            background: var(--surface); border: 1px solid var(--line);
            border-radius: var(--radius); color: var(--text); text-decoration: none;
            transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out); }
a.rpt-tile:hover { border-color: var(--gold); box-shadow: var(--shadow); }
a.rpt-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rpt-tile__ico { color: var(--muted); line-height: 1; }
a.rpt-tile:hover .rpt-tile__ico { color: var(--ink); }
.rpt-tile__name { font-size: 1rem; }
.rpt-tile__blurb { font-size: .84rem; color: var(--muted); line-height: 1.45; }
.rpt-tile__tag { align-self: flex-start; font-size: .7rem; font-weight: 600;
                 text-transform: uppercase; letter-spacing: .05em; padding: .16rem .45rem;
                 border-radius: var(--radius-sm); background: var(--bg); color: var(--muted); }
.rpt-tile--off { background: var(--bg); }
.rpt-tile--off .rpt-tile__name { color: var(--muted); }
/* The reason sits below a rule so it reads as a note about the tile rather
   than as part of the description. */
.rpt-tile__why { margin-top: .2rem; padding-top: .5rem; border-top: 1px dashed var(--line);
                 font-size: .78rem; line-height: 1.45; color: var(--warn); }

/* ---------------------------------------------------------------------
   Repair order: one page

   Five tabs became five sections. The jump strip moves you down the page
   rather than reloading it, which matters most on the orders this shop
   actually writes — one or two jobs that fit on a screen and a half.
   --------------------------------------------------------------------- */
.ro-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .55rem;
           margin: .3rem 0 0; font-size: .88rem; color: var(--muted); }
.ro-meta > span + span::before { content: "·"; margin-right: .55rem; color: var(--line); }
.ro-meta__ro { font-weight: 600; color: var(--text); }
.ro-meta__odo { font-variant-numeric: tabular-nums; }

/* Sticky so the section you want is always one press away, including
   from the bottom of a long estimate. */
/* Offset below the app's top bar, which is also sticky at top: 0 and is
   56px tall — at top: 0 with the same z-index this slid underneath it and
   left an empty band where the links should be. Other rules in this file
   already offset against the same 56px. */
.ro-jump { position: sticky; top: 56px; z-index: 15; display: flex; flex-wrap: wrap; gap: .2rem;
           margin: 0 0 1.4rem; padding: .35rem 0; background: var(--bg);
           border-bottom: 1px solid var(--line); }
.ro-jump a { padding: .45rem .8rem; font-size: .84rem; font-weight: 600; color: var(--muted);
             text-decoration: none; border-radius: var(--radius-sm); }
.ro-jump a:hover { color: var(--text); background: var(--surface); }
.ro-jump a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Sections stack as rows on a docket rather than floating apart. The
   2.5rem gaps and the heavy rule under every heading were reading as six
   unrelated fragments; a job is one document. */
.ro-sec { margin: 0; }
/* scroll-margin keeps the sticky strip from covering the heading it just
   jumped to. */
/* Clears the top bar and the jump strip together, so a jumped-to heading
   is not hidden behind either. */
.ro-sec[id] { scroll-margin-top: 7.5rem; }
.ro-sec__head { font-size: .74rem; text-transform: uppercase; letter-spacing: .09em;
                color: var(--muted); font-weight: 700; margin: 0; }

/* ---------------------------------------------------------------------
   Deferred work

   A worklist, not a report. Each row carries everything needed to make
   the call without opening anything: what it is, whose car, the number to
   ring, and the price with the date and mileage it was quoted at.
   --------------------------------------------------------------------- */
.def-list { display: flex; flex-direction: column; gap: .7rem; }
.def { display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between;
       padding: 1rem 1.1rem; background: var(--surface); border: 1px solid var(--line);
       border-left: 3px solid var(--line); border-radius: var(--radius); }
/* Overdue earns the only colour on the row, so a list of forty scans in
   one pass. */
.def--due { border-left-color: var(--warn); }
.def__main { min-width: 0; }
.def__title { font-size: 1rem; margin: 0 0 .3rem; display: flex; flex-wrap: wrap;
              align-items: center; gap: .5rem; }
.def__sev { font-size: .68rem; font-weight: 700; text-transform: uppercase;
            letter-spacing: .06em; padding: .14rem .45rem; border-radius: var(--radius-sm); }
.def__sev--urgent { background: var(--danger-bg); color: var(--danger); }
.def__sev--attention { background: var(--warn-bg); color: var(--warn); }
.def__sev--monitor { background: var(--bg); color: var(--muted); }
.def__who { margin: 0 0 .25rem; font-size: .86rem; color: var(--muted); }
.def__quote { margin: 0 0 .2rem; font-size: .88rem; }
.def__detail { margin: 0 0 .2rem; font-size: .84rem; color: var(--muted); }
.def__when { margin: .3rem 0 0; font-size: .8rem; color: var(--muted); }
.def__flag { font-weight: 600; color: var(--warn); }
.def__act { display: flex; flex-direction: column; align-items: stretch; gap: .35rem;
            flex: none; }
.def__act form { margin: 0; }
.def__act .btn-sm { width: 100%; text-align: center; }

@media (max-width: 700px) {
    .def { flex-direction: column; }
    .def__act { flex-direction: row; flex-wrap: wrap; }
}

/* ---------------------------------------------------------------------
   Check-in

   Filled in once at the counter, then read only if something is disputed
   — so it collapses to a single line as soon as it has been recorded
   rather than holding a screen's worth of space for the rest of the job.
   --------------------------------------------------------------------- */
.chk { background: var(--surface); border: 1px solid var(--line);
       border-radius: var(--radius); padding: .8rem 1rem; }
.chk > summary { cursor: pointer; font-size: .9rem; font-weight: 600; }
.chk__flag { margin-left: .4rem; font-size: .7rem; font-weight: 700; text-transform: uppercase;
             letter-spacing: .05em; padding: .14rem .45rem; border-radius: var(--radius-sm);
             background: var(--warn-bg); color: var(--warn); }
.chk__was { display: grid; grid-template-columns: auto 1fr; gap: .3rem 1.2rem;
            margin: .9rem 0 0; font-size: .88rem; }
.chk__was dt { color: var(--muted); }
.chk__was dd { margin: 0; }
.chk__shots { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .8rem; }
.chk__shots img { width: 96px; height: 96px; object-fit: cover; border-radius: var(--radius-sm);
                  border: 1px solid var(--line); display: block; }
.chk__form { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.chk__row { display: flex; flex-wrap: wrap; gap: .75rem; margin-bottom: .75rem; }
.chk__field { flex: 1 1 8rem; min-width: 0; }
.chk__field--wide { flex: 1 1 16rem; }
.chk__field label { display: block; font-size: .78rem; color: var(--muted); margin-bottom: .2rem; }

/* ---------------------------------------------------------------------
   Fuel gauge picker
   --------------------------------------------------------------------- */
.chk__field--fuel { flex: 1 1 100%; }
.fuel { display: flex; flex-wrap: wrap; gap: .3rem; }
.fuel__opt input { position: absolute; opacity: 0; pointer-events: none; }
.fuel__opt span { display: inline-flex; align-items: center; justify-content: center;
                  min-width: 3.2rem; min-height: 2.5rem; padding: .3rem .6rem;
                  border: 1px solid var(--line); border-radius: var(--radius-sm);
                  background: var(--surface); font-size: .86rem; font-weight: 600;
                  cursor: pointer; user-select: none; }
.fuel__opt input:checked + span { background: var(--ink); color: var(--surface); border-color: var(--ink); }
.fuel__opt input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.fuel__opt--none span { font-weight: 400; color: var(--muted); }

/* ---------------------------------------------------------------------
   Tablet

   The shop tablet lives in the bay and gets used with dirty hands, often
   one-handed. Everything that gets tapped grows to the 44px Apple and
   Google both settled on as the smallest reliable target; nothing moves
   position, so the layout a writer learned at the desk is the same one.
   Pointer-based rather than width-based, so a small laptop is unaffected.
   --------------------------------------------------------------------- */
@media (pointer: coarse) {
    .shop-ui input[type="text"], .shop-ui input[type="number"],
    .shop-ui input[type="date"], .shop-ui input[type="time"],
    .shop-ui input[type="tel"], .shop-ui input[type="email"],
    .shop-ui select, .shop-ui textarea {
        min-height: 44px;
        /* 16px stops iOS zooming the page in the moment a field is focused,
           which on a tablet leaves the writer scrolled somewhere else. */
        font-size: 16px;
    }
    .shop-ui .btn-sm, .shop-ui button[type="submit"] { min-height: 44px; padding: .6rem 1rem; }
    .shop-ui .ro-jump a { min-height: 44px; display: flex; align-items: center; }
    .shop-ui .fuel__opt span { min-width: 3.8rem; min-height: 3rem; font-size: .95rem; }
    .shop-ui .chk__shots img { width: 120px; height: 120px; }
    /* A file input styled as a proper target: on a tablet this is the
       camera button, and it is the one control that has to be obvious. */
    .shop-ui input[type="file"] { padding: .8rem; border: 1px dashed var(--line);
                                  border-radius: var(--radius-sm); width: 100%; background: var(--bg); }
}

/* Duplicate sets. Each is a small table because the decision is a
   comparison — visits, spend and last visit side by side are what tell
   you which record is the real one. */
.dup { margin-bottom: 1.2rem; }
.dup .panel__head { display: flex; align-items: baseline; gap: .6rem; }
.dup table form { margin: 0; }
.dup td .small { display: block; }

/* Correcting an invoice. Folded away because it is the exception, and
   kept away from the take-payment form so a way to reduce the bill never
   sits next to the way to collect it. */
.fixit { margin: 0 0 1.5rem; border: 1px solid var(--line); border-radius: var(--radius);
         background: var(--surface); }
.fixit > summary { padding: .7rem 1rem; cursor: pointer; font-size: .86rem; font-weight: 600;
                   color: var(--muted); }
.fixit__body { padding: 0 1rem 1rem; }
.fixit__row { display: flex; flex-wrap: wrap; gap: .75rem; }
.fixit__field { flex: 1 1 14rem; min-width: 0; }
.fixit__field--amt { flex: 0 0 9rem; }
.fixit__field label { display: block; font-size: .78rem; color: var(--muted); margin-bottom: .2rem; }
.fixit__form label { display: block; font-size: .78rem; color: var(--muted);
                     margin: .75rem 0 .2rem; }
.fixit__also { display: flex; align-items: center; gap: .5rem; margin-top: .75rem;
               font-size: .86rem; color: var(--text); }
.fixit__also input { width: 16px; height: 16px; accent-color: var(--gold-dark); }

/* A job jumped to from the labor guide lands under the sticky section
   strip without this — same reason .ro-sec[id] carries it. */
.jobcard[id] { scroll-margin-top: 4rem; }

/* ---------------------------------------------------------------------
   Folding sections

   The order page carries the whole job, but only a slice of it matters at
   any moment. Each section states where it stands on one line and opens
   itself when it is the part in hand — so the page is as long as the work
   in front of you, not as long as everything the order could ever hold.
   --------------------------------------------------------------------- */
.ro-fold { background: var(--surface); border: 1px solid var(--line); border-top: 0; }
/* By id, not :first-of-type — that matches the first <section> among
   siblings, and any section added above these would silently take the
   rounded top with it. */
#sec-checkin .ro-fold { border-top: 1px solid var(--line);
                        border-radius: var(--radius) var(--radius) 0 0; }
#sec-activity .ro-fold { border-radius: 0 0 var(--radius) var(--radius); }

.ro-fold > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap;
                     align-items: baseline; gap: .35rem .8rem;
                     /* A full-width row, so the whole line is the target —
                        on the tablet the label alone is a 90px strip. */
                     padding: .95rem 1.1rem;
                     /* The gold edge marks where you are. Transparent when
                        closed rather than absent, so nothing shifts by a
                        pixel when a section opens. */
                     border-left: 3px solid transparent; margin-left: -1px;
                     transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }
.ro-fold > summary::-webkit-details-marker { display: none; }
/* A caret rather than the browser's triangle, so open and closed read the
   same on every platform the shop uses. */
.ro-fold > summary::after { content: "⌄"; margin-left: auto; color: var(--muted);
                            font-size: 1rem; line-height: 1; align-self: center;
                            transition: transform var(--dur-fast) var(--ease-out); }
.ro-fold[open] > summary::after { transform: rotate(180deg); }
.ro-fold > summary:hover { background: var(--bg); }
.ro-fold > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ro-fold[open] > summary { border-left-color: var(--gold); background: var(--bg); }

/* The state line is information, not a caption — it is the only thing a
   folded section says, so it is set to be read, not squinted at. */
.ro-fold__note { font-size: .84rem; font-weight: 500; letter-spacing: 0;
                 text-transform: none; color: var(--text); }
.ro-fold[open] .ro-fold__note { color: var(--muted); }
.ro-fold__body { padding: .3rem 1.1rem 1.4rem; border-top: 1px solid var(--line);
                 margin-top: -1px; }
.ro-fold[open] > .ro-fold__body { padding-top: 1.2rem; }

@media (pointer: coarse) {
    .ro-fold > summary { padding: 1.1rem; }
}
.chk__by { margin: 0 0 .8rem; font-size: .86rem; color: var(--muted); }

/* ---------------------------------------------------------------------
   The bay

   A technician's queue, read at arm's length on a tablet with the screen
   at an angle. So: one card per job, the job name at heading size, and
   exactly one obvious button. Everything else is context you can ignore.
   --------------------------------------------------------------------- */
.bay-who { display: flex; align-items: center; gap: .5rem; }
.bay-who label { font-size: .78rem; color: var(--muted); }
.bay-on { display: flex; align-items: center; gap: .5rem; margin: 0 0 1rem;
          padding: .7rem .9rem; border-radius: var(--radius);
          background: var(--ok-bg); color: var(--ok); font-size: .9rem; }

.bay-list { display: flex; flex-direction: column; gap: .7rem; }
.bay { display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between;
       padding: 1rem 1.1rem; background: var(--surface); border: 1px solid var(--line);
       border-left: 3px solid var(--line); border-radius: var(--radius); }
/* Gold for the job in hand, amber for one that cannot start, faded for
   one already finished. Three states, three weights of attention. */
.bay--on { border-left-color: var(--gold); background: var(--bg); }
.bay--stuck { border-left-color: var(--warn); }
.bay--done { opacity: .55; }
.bay__main { min-width: 0; }
.bay__job { font-size: 1.05rem; margin: 0 0 .25rem; }
.bay__car { margin: 0 0 .35rem; font-size: .88rem; color: var(--muted); }
.bay__note { margin: 0 0 .4rem; font-size: .86rem; }
.bay__meta { display: flex; flex-wrap: wrap; gap: .2rem .8rem; margin: 0;
             font-size: .78rem; color: var(--muted); }
.bay__free { color: var(--gold-dark); font-weight: 600; }
.bay__stuck { margin: .45rem 0 0; font-size: .82rem; font-weight: 600; color: var(--warn); }
.bay__act { display: flex; flex-direction: column; gap: .4rem; flex: none; min-width: 7rem; }
.bay__act form { margin: 0; }
.bay__act .btn-sm { width: 100%; text-align: center; justify-content: center; }
.bay__tag { display: inline-flex; align-items: center; justify-content: center;
            padding: .5rem .8rem; font-size: .78rem; font-weight: 700; text-transform: uppercase;
            letter-spacing: .05em; color: var(--muted); }

@media (max-width: 700px) {
    .bay { flex-direction: column; }
    .bay__act { flex-direction: row; width: 100%; }
}

/* ---------------------------------------------------------------------
   The floor

   One row per car, and the row's job is to answer "what do I do about
   this" — so the action is a link, set at the same weight as the vehicle
   name, and the status is demoted to the caption under it. A board that
   only shows state makes the reader do the deciding every time.
   --------------------------------------------------------------------- */
.floor-tally { display: grid; gap: .6rem; margin-bottom: 1.1rem;
               grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.tal { padding: .8rem .9rem; background: var(--surface); border: 1px solid var(--line);
       border-radius: var(--radius); border-top: 3px solid var(--line); }
.tal__n { display: block; font-size: 1.7rem; line-height: 1.1; font-variant-numeric: tabular-nums; }
.tal__label { display: block; font-size: .76rem; color: var(--muted); margin-top: .1rem; }
.tal__cash { display: block; margin-top: .35rem; font-size: .8rem; font-weight: 600;
             color: var(--gold-dark); font-variant-numeric: tabular-nums; }
/* Amber top edge where something at that stage has been waiting. The only
   colour on the strip, so it is the only thing that pulls the eye. */
.tal--hot { border-top-color: var(--warn); }
.tal--none { opacity: .5; }
.tal--none .tal__n { color: var(--muted); }

.floor-find { display: flex; gap: .5rem; margin-bottom: 1rem; }
.floor-find input { flex: 1; min-width: 0; }

.floor { display: flex; flex-direction: column; gap: .55rem; }
.car { display: grid; gap: .5rem 1.2rem; align-items: center;
       grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto auto;
       padding: .9rem 1.1rem; background: var(--surface);
       border: 1px solid var(--line); border-left: 3px solid transparent;
       border-radius: var(--radius); }
.car--hot { border-left-color: var(--gold); }
.car__who { min-width: 0; }
.car__veh { font-size: 1rem; font-weight: 700; text-decoration: none; color: var(--text); }
.car__veh:hover { color: var(--accent); }
.car__sub { margin: .15rem 0 0; font-size: .84rem; color: var(--muted); }
.car__sub--dim { font-size: .78rem; }
.car__plate { display: inline-block; padding: .05rem .35rem; margin-right: .35rem;
              border: 1px solid var(--line); border-radius: var(--radius-sm);
              font-size: .74rem; font-weight: 600; letter-spacing: .04em; }
.car__do { min-width: 0; }
/* Same weight as the vehicle name: the two things worth reading on the
   row are which car and what to do about it. */
.car__act { font-size: .95rem; font-weight: 700; text-decoration: none; color: var(--accent); }
.car__act:hover { text-decoration: underline; }
.car__why { display: block; margin-top: .1rem; font-size: .8rem; color: var(--muted); }
/* The row menu. Ahead of the money in the grid so the figure stays hard
   against the right edge where it is scanned down a column. */
.car__menu { position: relative; justify-self: end; }
.car__menu > summary { list-style: none; cursor: pointer; width: 32px; height: 32px;
                       display: flex; align-items: center; justify-content: center;
                       border-radius: var(--radius-sm); color: var(--muted); font-size: 1.1rem; }
.car__menu > summary::-webkit-details-marker { display: none; }
.car__menu > summary:hover { background: var(--bg); color: var(--text); }
.car__menu > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.car__menu-list { position: absolute; right: 0; top: 100%; z-index: 30; min-width: 16rem;
                  padding: .3rem; background: var(--surface); border: 1px solid var(--line);
                  border-radius: var(--radius); box-shadow: var(--shadow); }
.car__menu-list form { margin: 0; }
.car__menu-list a, .car__menu-list button { display: block; width: 100%; text-align: left;
                                            padding: .5rem .6rem; font: inherit; font-size: .86rem;
                                            background: none; border: 0; border-radius: var(--radius-sm);
                                            color: var(--text); text-decoration: none; cursor: pointer; }
.car__menu-list a:hover, .car__menu-list button:hover { background: var(--bg); }
.car__menu-list .is-bad { color: var(--danger); }
@media (pointer: coarse) { .car__menu-list a, .car__menu-list button { min-height: 44px; } }

.car__cash { text-align: right; white-space: nowrap; }
.car__cash strong { display: block; font-size: 1rem; font-variant-numeric: tabular-nums; }
.car__cash span { font-size: .74rem; color: var(--muted); text-transform: uppercase;
                  letter-spacing: .05em; }
.car__none { font-size: .8rem; color: var(--muted); }

@media (max-width: 800px) {
    .car { grid-template-columns: minmax(0, 1fr) auto auto; }
    .car__do { grid-column: 1 / -1; padding-top: .3rem; border-top: 1px solid var(--line); }
}

/* Saved jobs, folded into the add-job form. Chips on one wrapping row
   rather than a grid of cards: the name is the only thing being chosen
   between, and a card per job turned twenty saved jobs into a screenful. */
.saved { margin-top: .5rem; }
.saved > summary { cursor: pointer; font-size: .8rem; color: var(--muted); }
.saved > summary:hover { color: var(--text); }
.saved__row { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .5rem;
              /* Capped so a shop with fifty saved jobs still sees the form
                 underneath rather than scrolling past a list to reach it. */
              max-height: 11rem; overflow-y: auto; }
.saved__one { display: inline-flex; align-items: baseline; gap: .35rem;
              padding: .4rem .65rem; font: inherit; font-size: .84rem;
              background: var(--bg); border: 1px solid var(--line);
              border-radius: var(--radius-sm); cursor: pointer; color: var(--text); }
.saved__one:hover { border-color: var(--gold); background: var(--surface); }
.saved__one:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.saved__one span { font-size: .74rem; color: var(--muted); font-variant-numeric: tabular-nums; }
@media (pointer: coarse) { .saved__one { min-height: 44px; } }

/* ---------------------------------------------------------------------
   Customer lifecycle

   Five stages worked out from visits rather than typed in by anybody, so
   they are true without anyone maintaining them. Drifting and gone quiet
   stay on screen even at zero — a shop wants to see that the number is
   nought, not have the row disappear and leave nothing to compare against.
   --------------------------------------------------------------------- */
.life { display: grid; gap: .5rem; margin-bottom: .9rem;
        grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
.life__cell { display: block; padding: .7rem .8rem; background: var(--surface);
              border: 1px solid var(--line); border-top: 3px solid var(--line);
              border-radius: var(--radius); text-decoration: none; color: var(--text); }
.life__cell:hover { border-color: var(--gold); }
.life__cell.is-on { border-top-color: var(--ink); background: var(--bg); }
.life__cell strong { display: block; font-size: 1.45rem; line-height: 1.1;
                     font-variant-numeric: tabular-nums; }
.life__cell span { display: block; font-size: .74rem; color: var(--muted); margin-top: .1rem; }
.life__cell em { display: block; margin-top: .3rem; font-size: .78rem; font-style: normal;
                 font-weight: 600; color: var(--gold-dark); font-variant-numeric: tabular-nums; }
/* Amber only where the money is walking away. */
.life__cell--warn { border-top-color: var(--warn); }

.lifetag { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
           padding: .16rem .45rem; border-radius: var(--radius-sm); }
.lifetag--active { background: var(--ok-bg); color: var(--ok); }
.lifetag--new { background: var(--bg); color: var(--accent); }
.lifetag--drifting { background: var(--warn-bg); color: var(--warn); }
.lifetag--dormant { background: var(--danger-bg); color: var(--danger); }
.lifetag--never { background: var(--bg); color: var(--muted); }

/* The running total beside the estimate button on the add-job form. Was
   .quick__calc on the panel that has been removed. A misplaced decimal is
   obvious at $1,450 and invisible at 10.0, which is the whole reason it
   is on screen while the number is being typed. */
.labor-calc { font-size: .82rem; color: var(--muted); }
.labor-calc.is-ok { color: var(--ok); font-weight: 600; }
.labor-calc.is-bad { color: var(--danger); }

/* Menu entries that carry a second line explaining what they do. The
   difference between setting aside, cancelling and deleting matters most
   at the moment somebody is choosing between them, which is here. */
.car__menu-list button small { display: block; margin-top: .1rem; font-size: .74rem;
                               font-weight: 400; color: var(--muted); line-height: 1.35; }
.car__menu-list .is-bad small { color: var(--muted); }
.floor-top { display: flex; gap: .5rem; align-items: center; }

/* The complaint, editable where it is read. */
.ro-concern__edit > summary { cursor: pointer; font-size: 1.05rem; line-height: 1.5; }
.ro-concern__edit > summary:hover { color: var(--accent); }
.ro-concern__edit form { margin-top: .6rem; display: flex; flex-direction: column;
                         align-items: flex-start; gap: .5rem; }
.ro-concern__edit textarea { width: 100%; }

/* Occasional actions on a job card, out of the way of the daily ones. */
.job-more { position: relative; margin-left: auto; }
.job-more > summary { list-style: none; cursor: pointer; width: 32px; height: 32px;
                      display: flex; align-items: center; justify-content: center;
                      border-radius: var(--radius-sm); color: var(--muted); font-size: 1.1rem; }
.job-more > summary::-webkit-details-marker { display: none; }
.job-more > summary:hover { background: var(--bg); color: var(--text); }
.job-more > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.job-more__list { position: absolute; right: 0; top: 100%; z-index: 25; min-width: 15rem;
                  padding: .3rem; background: var(--surface); border: 1px solid var(--line);
                  border-radius: var(--radius); box-shadow: var(--shadow); }
.job-more__list form { margin: 0; }
.job-more__list button { display: block; width: 100%; text-align: left; padding: .5rem .6rem;
                         font: inherit; font-size: .86rem; background: none; border: 0;
                         border-radius: var(--radius-sm); color: var(--text); cursor: pointer; }
.job-more__list button:hover { background: var(--bg); }
.job-more__list button small { display: block; margin-top: .1rem; font-size: .74rem;
                               font-weight: 400; color: var(--muted); }
.job-more__list .is-bad { color: var(--danger); }
@media (pointer: coarse) { .job-more__list button { min-height: 44px; } }

/* An answered estimate. The send controls are still there, one press
   behind the thing you actually wanted to know. */
.resend > summary { display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap;
                    padding: .9rem 1.1rem; cursor: pointer; list-style: none; }
.resend > summary::-webkit-details-marker { display: none; }
.resend > summary:hover { background: var(--bg); }
.resend > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.resend__what { font-weight: 600; font-size: .92rem; }
.resend__more { margin-left: auto; font-size: .82rem; color: var(--muted); }
.resend > summary:hover .resend__more { color: var(--accent); }
.resend[open] > summary { border-bottom: 1px solid var(--line); }

/* The details column is placed by .ro-layout's grid, so it needs no
   styling of its own — but min-width:0 stops a long note or a wide table
   inside it pushing the whole grid track past the viewport. Same reason
   .pay-side carries it. */
.ro-side { min-width: 0; }

/* ---------------------------------------------------------------------
   Facts strip

   Replaces the form column that used to run down the right of every
   screen. Almost everything on it is set once at check-in and read from
   then on, so it is set out to be read — one line, scannable, no inputs —
   and the editing sits behind a single fold underneath.
   --------------------------------------------------------------------- */
.facts { display: flex; flex-wrap: wrap; gap: 0; margin: 0 0 .5rem;
         background: var(--surface); border: 1px solid var(--line);
         border-radius: var(--radius); overflow: hidden; }
.facts__one { flex: 1 1 8.5rem; min-width: 0; padding: .7rem .9rem;
              border-right: 1px solid var(--line); }
.facts__one:last-child { border-right: 0; }
.facts__label { display: block; font-size: .68rem; text-transform: uppercase;
                letter-spacing: .08em; color: var(--muted); font-weight: 700; }
.facts__value { display: block; margin-top: .15rem; font-size: .95rem; font-weight: 600;
                font-variant-numeric: tabular-nums; white-space: nowrap;
                overflow: hidden; text-overflow: ellipsis; }

.facts-edit { margin-bottom: 1.4rem; }
.facts-edit > summary { cursor: pointer; font-size: .82rem; color: var(--muted);
                        padding: .2rem 0; }
.facts-edit > summary:hover { color: var(--text); }
.facts-edit__body { padding: .9rem 1rem 1rem; margin-top: .4rem;
                    background: var(--surface); border: 1px solid var(--line);
                    border-radius: var(--radius); }
.facts-edit__note { margin: 0 0 .9rem; padding: .7rem .85rem; font-size: .9rem;
                    background: var(--bg); border-left: 3px solid var(--line);
                    border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }

@media (max-width: 700px) {
    .facts__one { flex: 1 1 45%; border-bottom: 1px solid var(--line); }
}

/* The all/status tiles on the parts page reuse .tal from the floor. This
   is the selected state, which the floor expresses with .is-on. */
.tal--on { border-top-color: var(--ink); background: var(--bg); }
a.tal { text-decoration: none; color: var(--text); }
a.tal:hover { border-color: var(--gold); }
.parts-table form { margin: 0; }
.parts-table td { vertical-align: top; }

/* Look it up. The sources sit under the answer with a rule between them,
   because they are the part that makes the answer worth anything. */
.ask__form { display: flex; gap: .5rem; margin-bottom: .5rem; }
.ask__form input { flex: 1; min-width: 0; }
.ask__status { margin: .6rem 0 0; font-size: .88rem; color: var(--muted); }
.ask__answer { margin-top: .9rem; padding: .9rem 1rem; font-size: .95rem; line-height: 1.55;
               background: var(--bg); border-radius: var(--radius); }
.ask__sources { margin-top: .9rem; padding-top: .8rem; border-top: 1px solid var(--line); }
.ask__sources h3 { font-size: .74rem; text-transform: uppercase; letter-spacing: .08em;
                   color: var(--muted); margin: 0 0 .4rem; }
.ask__sources ul { margin: 0; padding-left: 1.1rem; font-size: .85rem; }
.ask__sources li { margin-bottom: .25rem; }
.ask__nosrc { list-style: none; margin-left: -1.1rem; color: var(--warn); font-weight: 600; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
           overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Job name suggestions under the labor guide box. Where each one came
   from is labelled — a saved job the shop already priced is worth more
   than a name off a list, and the reader should be able to tell. */
.jsug { position: absolute; top: 100%; left: 0; right: 0; z-index: 40; margin: .2rem 0 0;
        padding: .25rem; list-style: none; max-height: 16rem; overflow-y: auto;
        background: var(--surface); border: 1px solid var(--line);
        border-radius: var(--radius); box-shadow: var(--shadow); }
.jsug__hit { display: flex; align-items: baseline; gap: .5rem; padding: .5rem .6rem;
             border-radius: var(--radius-sm); cursor: pointer; font-size: .88rem; }
.jsug__hit:hover, .jsug__hit.is-on { background: var(--bg); }
.jsug__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
              white-space: nowrap; }
.jsug__from { font-size: .7rem; text-transform: uppercase; letter-spacing: .05em;
              color: var(--gold-dark); font-weight: 700; flex: none; }
.jsug__hint { font-size: .76rem; color: var(--muted); flex: none;
              font-variant-numeric: tabular-nums; }
/* The row is the positioning context for the dropdown. */
.lg-find__row { position: relative; }

/* Likely causes, offered rather than asked for. Quieter than the panels
   around it — it is a suggestion, and the technician's own finding, once
   they have one, outranks it. */
.dx-now { margin: 0 0 1.2rem; padding: .9rem 1rem; background: var(--bg);
          border: 1px dashed var(--line); border-radius: var(--radius); }
.dx-now__head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
                margin-bottom: .6rem; }
.dx-now__head h3 { margin: 0; font-size: .78rem; text-transform: uppercase;
                   letter-spacing: .08em; color: var(--muted); }
.dx-now__state { font-size: .74rem; color: var(--muted); }
.dx-now .dx-cause { background: var(--surface); }
.dx-now .dx-ask { margin-top: .8rem; padding-top: .7rem; }

/* ---------------------------------------------------------------------
   Assistant drawer

   Both AI helpers in one panel off the side. Not a column — a column is
   what made this page heavy in the first place — but a drawer that is
   absent until it is wanted and stays where it was put.
   --------------------------------------------------------------------- */
.mate { position: fixed; top: 0; right: 0; bottom: 0; z-index: 60; width: min(24rem, 92vw);
        display: flex; flex-direction: column;
        background: var(--surface); border-left: 1px solid var(--line);
        box-shadow: -12px 0 32px rgba(0, 0, 0, .12); }
.mate[hidden] { display: none; }
.mate__head { display: flex; align-items: center; justify-content: space-between;
              padding: .9rem 1.1rem; border-bottom: 1px solid var(--line);
              background: var(--ink); color: var(--surface); flex: none; }
.mate__head h2 { margin: 0; font-size: .8rem; text-transform: uppercase;
                 letter-spacing: .1em; }
.mate__x { display: inline-flex; align-items: center; gap: .4rem;
           background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.2);
           color: var(--surface); font: inherit; font-size: .78rem; font-weight: 600;
           cursor: pointer; padding: .35rem .7rem; border-radius: var(--radius-sm); }
.mate__x:hover { background: rgba(255,255,255,.22); }
.mate__x:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
@media (pointer: coarse) { .mate__x { min-height: 40px; padding: .5rem .9rem; } }
/* Scrolls on its own so a long answer never moves the order behind it. */
.mate__body { flex: 1; overflow-y: auto; padding: 1rem 1.1rem 2rem; }
.mate__ask { margin-top: 1.2rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
.mate__ask:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.mate__ask h3 { font-size: .78rem; text-transform: uppercase; letter-spacing: .08em;
                color: var(--muted); margin: 0 0 .5rem; }
.mate__toggle { white-space: nowrap; }

/* On a wide screen the page shifts over rather than hiding under the
   drawer — a tech reading a torque figure usually wants the job visible
   at the same time. Narrow screens overlay, because there is no room. */
@media (min-width: 1200px) {
    /* .shop-ui is on <body> itself, not a wrapper — "body.has-mate .shop-ui"
       is a descendant selector that matches nothing. */
    body.shop-ui.has-mate { padding-right: 25rem; }
}

/* The two cells that are controls rather than readings. Sized to sit on
   the same baseline as the values beside them, so the strip still scans
   as one line rather than a form pretending to be one. */
.facts__one--pick form { margin: 0; }
.facts__one--pick select { width: 100%; margin-top: .1rem; padding: .1rem .3rem .1rem 0;
                           font-size: .95rem; font-weight: 600; font-family: inherit;
                           color: var(--text); background: transparent;
                           border: 0; border-bottom: 1px dashed var(--line);
                           border-radius: 0; cursor: pointer; }
.facts__one--pick select:hover { border-bottom-color: var(--gold); }
.facts__one--pick select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (pointer: coarse) { .facts__one--pick select { min-height: 40px; } }

/* The address an approval came from. Quiet until it cannot be relied on. */
.auth-ip { display: block; margin-top: .3rem; font-size: .8rem; color: var(--muted);
           font-variant-numeric: tabular-nums; }
.auth-ip__warn { color: var(--warn); font-weight: 600; font-variant-numeric: normal; }

/* ---------------------------------------------------------------------
   Quality check

   Three buttons a row, sized for a thumb, because this gets filled in
   standing next to the car rather than sitting at the counter.
   --------------------------------------------------------------------- */
.qc-list { list-style: none; margin: 0 0 1rem; padding: 0; }
.qc-item { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
           padding: .6rem 0; border-bottom: 1px solid var(--line); }
.qc-item:last-child { border-bottom: 0; }
.qc-item__name { font-size: .92rem; }
.qc-item__must { margin-left: .4rem; font-size: .66rem; font-weight: 700; text-transform: uppercase;
                 letter-spacing: .05em; color: var(--warn); }
.qc-item__pick { display: flex; gap: .25rem; flex: none; }
.qc-item__pick form { margin: 0; }
.qc-btn { padding: .35rem .7rem; font: inherit; font-size: .82rem; font-weight: 600;
          background: var(--surface); border: 1px solid var(--line);
          border-radius: var(--radius-sm); cursor: pointer; color: var(--muted); }
.qc-btn:hover { border-color: var(--gold); color: var(--text); }
.qc-btn.is-on { color: var(--surface); }
.qc-btn--pass.is-on { background: var(--ok); border-color: var(--ok); }
.qc-btn--fail.is-on { background: var(--danger); border-color: var(--danger); }
.qc-btn--na.is-on { background: var(--muted); border-color: var(--muted); }
.qc-item--ok { opacity: .75; }
.qc-item--bad .qc-item__name { color: var(--danger); font-weight: 600; }
.qc-sign { display: flex; gap: .5rem; margin-top: 1rem; }
.qc-sign input { flex: 1; min-width: 0; }
.qc-sign button[disabled] { opacity: .45; cursor: not-allowed; }
.qc-left { margin: .4rem 0 0; color: var(--warn); }
.qc-failed { margin: .4rem 0 0; font-size: .88rem; color: var(--danger); font-weight: 600; }
@media (pointer: coarse) { .qc-btn { min-height: 44px; min-width: 3.4rem; } }
.qc { margin-bottom: 1.2rem; }

/* .wip-bar* went with the progress bar. Nothing replaced it — the sticky
   totals bar already carried its one real action. */

/* ---------------------------------------------------------------------
   Buying

   Receiving happens with a box open and one hand free, so a line is one
   row with two numbers and a Save. The only colour is on a price that
   came back higher than quoted, because that is the thing worth noticing.
   --------------------------------------------------------------------- */
/* Sits directly under the parts table on a job card, so it reads as
   "these ones still need buying" rather than a form floating at the end
   of the section. */
.po-start { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
            margin: 0; padding: .7rem 1rem;
            background: var(--bg); border-top: 1px solid var(--line); }
.po-start label { font-size: .84rem; color: var(--muted); }
.po-send { margin: 0 0 1.2rem; }
.po-recv { display: flex; gap: .3rem; justify-content: flex-end; margin: 0; }
.po-recv input { width: 5.5rem; text-align: right; }
.po-over { color: var(--danger); font-weight: 600; }
.po-tot { margin-top: 1rem; }
.is-short td:first-child { border-left: 3px solid var(--warn); padding-left: .6rem; }
@media (pointer: coarse) { .po-recv input { min-height: 44px; } }
.po-start--none { font-size: .86rem; color: var(--muted); display: block; }
/* Sign out is a form now, so its button needs to look like the menu links
   around it rather than a button. */
.ws-menu__out { margin: 0; }
.ws-menu__out button { display: block; width: 100%; text-align: left; background: none;
                       border: 0; padding: .55rem .8rem; font: inherit; font-size: .88rem;
                       color: var(--danger); cursor: pointer; }
.ws-menu__out button:hover { background: var(--bg); }
/* Opening hours: a row per day, times aligned so a mistake is visible. */
.hours-table td input[type="time"] { width: 8rem; }
.hours-table td { vertical-align: middle; }

/* Permission grid: two columns of checkboxes with room to read the
   sentence under each, because the sentence is the part that decides
   whether the box should be ticked. */
.perm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 10px 24px; }
.perm-grid .inline-check { align-items: flex-start; gap: 8px; }
.perm-grid .inline-check em { display: block; font-style: normal; font-size: 12px; }

/* =====================================================================
   Loading and feedback primitives  (assets/js/app-loading.js)
   =====================================================================
   Deliberately quiet. This is business software: it should feel fast,
   not animated. Nothing here moves more than it has to, and all of it
   stops moving entirely under prefers-reduced-motion.
   ===================================================================== */

/* The progress bar. Fixed to the top of the viewport rather than the
   content region, because the content region is what gets replaced. */
#app-progress {
    position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 9999;
    background: var(--accent, var(--info));
    transform: scaleX(0); transform-origin: 0 50%;
    transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
    opacity: 0; pointer-events: none;
}
#app-progress.is-on { opacity: 1; }

/* The spinner. One element, used in buttons and beside fields. */
.ldr {
    display: inline-block; width: 13px; height: 13px; flex: none;
    border: 2px solid currentColor; border-right-color: transparent;
    border-radius: 50%; vertical-align: -2px;
    animation: ldr-spin .6s linear infinite;
}
@keyframes ldr-spin { to { transform: rotate(360deg); } }

button[aria-busy="true"] { display: inline-flex; align-items: center; gap: 8px; }
button[aria-busy="true"], button:disabled { cursor: default; opacity: .75; }

.ldr-inline {
    display: inline-flex; align-items: center; gap: 6px; margin-left: 8px;
    font-size: 12px; color: var(--muted, var(--muted-2));
}

/* Toasts. Bottom right, out of the way of the sidebar and of anything
   somebody is reading. */
#app-toasts {
    position: fixed; right: 16px; bottom: 16px; z-index: 9998;
    display: flex; flex-direction: column; gap: 8px; pointer-events: none;
}
.toast {
    pointer-events: auto; max-width: 320px;
    padding: 10px 14px; border-radius: var(--radius);
    background: #1f2937; color: var(--surface); font-size: 13px; line-height: 1.45;
    box-shadow: 0 6px 20px rgba(16, 24, 40, .18);
    opacity: 0; transform: translateY(6px);
    transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.toast.is-in { opacity: 1; transform: none; }
.toast--bad { background: var(--danger-strong); }

/* Skeletons. Grey blocks shaped like the content, with a shimmer slow
   enough not to draw the eye. */
.skel { display: flex; flex-direction: column; gap: 10px; padding: 4px 0; }
.skel__line {
    height: 14px; border-radius: var(--radius-sm);
    background: linear-gradient(90deg, #eceef1 25%, #f4f5f7 37%, #eceef1 63%);
    background-size: 400% 100%;
    animation: skel-shimmer 1.4s ease infinite;
}
@keyframes skel-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

@media (prefers-reduced-motion: reduce) {
    /* The loading primitives, handled individually because each needs a
       different answer: the spinner slows rather than stopping (a frozen
       spinner reads as a hung page), the skeleton loses its shimmer but
       keeps its shape, and the progress bar and toast simply appear. */
    .ldr { animation-duration: 1.4s; }
    .skel__line { animation: none; background: #eceef1; }
    #app-progress { transition: none; }
    .toast { transition: none; transform: none; }

    /* Everything else in the admin.
     *
     * This block covered the loading primitives and nothing else, so a
     * technician who has asked their computer to stop moving things
     * still got twenty-odd transitions all day on the screen they live
     * in. The public site has had a blanket rule for a while; the admin
     * is where somebody actually spends eight hours.
     *
     * Not zero. 0.01ms rather than none, because a transition that never
     * fires never fires transitionend either, and any JavaScript waiting
     * on that would hang. Long enough to complete, short enough that
     * nobody sees it move.
     *
     * The loading rules above still win: they come first and are more
     * specific than the universal selector, so slowing the spinner is
     * not undone here. */
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
        /* Delays too, not just durations.
           
           Collapsing the duration alone leaves a staggered animation
           still staggered: the funnel bars would each wait their turn,
           held at zero width, then snap in one after another. That is a
           flicker sequence — worse than the animation it replaced.
           A delay is motion-adjacent even when nothing moves. */
        animation-delay: 0ms !important;
        transition-delay: 0ms !important;
    }

    /* The spinner is the one thing that should still turn, so it is put
       back after the blanket rule rather than before it. */
    .ldr { animation-duration: 1.4s !important; animation-iteration-count: infinite !important; }
}

/* "Not applicable" — an answer, styled as one, but visibly not a pass.
   Grey rather than green: the technician did their job, the part is not
   on the car. */
.grade--na { color: var(--muted); }
.grade--na input:checked + span,
.grade--na input:checked ~ span { background: #e5e7eb; color: var(--text-2); }

/* Typed inspection checkpoints.
   Grids are numbers a technician taps in on a phone: wide targets,
   decimal keypad, no chrome competing with the value. */
.dvi-hint { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; font-weight: 400; }
.dvi-grid { overflow-x: auto; margin: 8px 0; }
.dvi-grid table { border-collapse: collapse; width: 100%; min-width: 340px; }
.dvi-grid th { font-size: 11px; font-weight: 600; color: var(--muted); text-align: left;
               padding: 2px 6px 4px; white-space: nowrap; }
.dvi-grid tbody th { font-weight: 500; color: var(--text-2); }
.dvi-grid td { padding: 2px; }
.dvi-grid input { width: 100%; min-width: 54px; padding: 8px 6px; text-align: center;
                  font-size: 15px; font-variant-numeric: tabular-nums;
                  border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--surface); }
.dvi-grid input:focus { border-color: var(--accent, var(--info)); outline: 2px solid rgba(37,99,235,.15); }

.dvi-fields { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0; }
.dvi-fields label { display: flex; flex-direction: column; gap: 3px; flex: 1 1 110px; }
.dvi-fields span { font-size: 11px; font-weight: 600; color: var(--muted); }
.dvi-fields input { padding: 8px 10px; font-size: 15px; font-variant-numeric: tabular-nums;
                    border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--surface); }

.dvi-choices { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.dvi-choices label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }

/* Written-answer checkpoints take the full width — a diagnosis does not
   fit on one line and should not be typed into a box that pretends it
   does. */
.dvi-fields__wide { flex: 1 1 100%; }
.dvi-fields textarea { padding: 8px 10px; font-size: 14px; font-family: inherit;
                       border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--surface);
                       resize: vertical; }

/* A photo you can take back.
   The remove button sits on the thumbnail rather than beside it: a row
   of images with a row of crosses underneath makes you work out which
   belongs to which, and getting that wrong deletes the wrong evidence. */
.dvi-shot { position: relative; display: inline-block; line-height: 0; }
.dvi-shot img { display: block; }
.dvi-shot__x {
    position: absolute; top: 3px; right: 3px;
    width: 22px; height: 22px; padding: 0; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    font-size: 15px; border: 0; border-radius: 50%;
    background: rgba(17, 24, 39, .72); color: var(--surface); cursor: pointer;
}
.dvi-shot__x:hover { background: var(--danger-strong); }
.dvi-shot__x:disabled { opacity: .5; cursor: default; }
/* Coarse pointers get a real target — this is used on a phone. */
@media (pointer: coarse) { .dvi-shot__x { width: 30px; height: 30px; font-size: 18px; } }

/* The grade buttons as an actual traffic light.
   The colours were already here but only appeared once a button was
   chosen, so an unanswered checkpoint was four identical grey boxes with
   words on them. A technician scanning a sheet for what is left to do
   should see colour, not read labels — the dot carries it whether the
   button is selected or not. */
.grade span::before {
    content: ''; display: inline-block; vertical-align: -1px;
    width: 10px; height: 10px; margin-right: 6px; border-radius: 50%;
    background: var(--line-2);
}
.grade--good span::before      { background: #16a34a; }
.grade--attention span::before { background: #f59e0b; }
.grade--urgent span::before    { background: #dc2626; }
.grade--na span::before        { background: transparent; border: 2px solid #cbd5e1;
                                 width: 8px; height: 8px; }

/* Unselected keeps a hint of its colour so the row reads as a light;
   selected fills in, as before. */
.grade--good span      { border-color: #cdeed7; }
.grade--attention span { border-color: #f6e3bb; }
.grade--urgent span    { border-color: #f3cdcd; }

/* Narrow phones tighten rather than hide. Dropping the words would leave
   N/A as an unlabelled hollow circle — the one option whose meaning is
   not obvious from a colour — and it would do it on the screen size the
   technicians actually use. */
@media (max-width: 400px) {
    .grade span { font-size: .78rem; padding: .7rem .15rem; }
    .grade span::before { margin-right: 4px; width: 9px; height: 9px; }
}

/* Per-item saving on the inspection sheet.
   The state chip is small and lives beside the button that caused it —
   a toast for every checkpoint on a sixty-three point sheet would be
   sixty-three interruptions. */
.dvi-progress { margin: 0 0 1rem; color: var(--muted, var(--muted-2)); font-size: 14px; }
.dvi-item__foot { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.dvi-next { padding: 9px 14px; font-size: 14px; }
.dvi-state { font-size: 12px; min-height: 1em; }
.dvi-state--pending { color: var(--warn-strong); }
.dvi-state--saving  { color: var(--muted-2); }
.dvi-state--ok      { color: var(--ok-strong); }
.dvi-state--bad     { color: var(--danger-strong); font-weight: 600; }

@media (pointer: coarse) {
    /* Thumb-sized, and full width so it is where a thumb already is. */
    .dvi-item__foot { flex-wrap: wrap; }
    .dvi-next { flex: 1 1 100%; padding: 14px; font-size: 15px; }
}

/* The walk-around silhouette.
   Buttons positioned by percentage over an SVG rather than an absolute
   coordinate system, so the same markup holds up whether it renders at
   phone width or on a full desktop screen. */
/* The drawing sits in its own box so the labels can be positioned as
   percentages of it. Capped in width because a plan-view car stretched
   across a desktop monitor is all whitespace and no information. */
.chk__walk { position: relative; width: 100%; max-width: 300px; margin: .25rem 0 1rem; }
.chk__wheel { fill: #cbd2db; }
.chk__cabin { fill: var(--surface); stroke: #cbd2db; stroke-width: 1.5; }
.chk__walk-label { display: block; font-weight: 600; margin-bottom: .5rem; }
.chk__silhouette { width: 100%; height: auto; display: block; }
.chk__body   { fill: var(--surface-3); stroke: #9ca3af; stroke-width: 2; }
.chk__glass  { fill: var(--info-border); stroke: #93c5fd; stroke-width: 1; }
.chk__mirror { fill: #d1d5db; }

.chk__spot {
    position: absolute; transform: translate(-50%, -50%);
    padding: 5px 9px; font-size: 11px; font-weight: 600; white-space: nowrap;
    border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius-pill);
    background: var(--surface); color: var(--text-2); cursor: pointer;
}
.chk__spot:hover, .chk__spot:focus-visible { border-color: var(--accent, var(--info)); color: #1d4ed8; }
/* Wheels sits behind the body outline, so it needs to be readable on top
   of it without covering the silhouette entirely. */
.chk__spot[data-panel="wheels"] { background: rgba(255,255,255,.92); }

.chk__picker {
    position: absolute; transform: translate(-50%, 8px);
    z-index: 5; min-width: 220px; padding: 10px;
    border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius);
    background: var(--surface); box-shadow: 0 8px 24px rgba(16,24,40,.14);
}
.chk__picker-where { margin: 0 0 6px; font-size: 12px; font-weight: 600; color: var(--muted); }
.chk__picker-kinds { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.chk__picker-close { border: 0; background: transparent; color: var(--muted); font-size: 12px;
                      padding: 4px 0; cursor: pointer; }

.chk__walk-list { list-style: none; margin: .75rem 0 0; padding: 0; display: flex;
                   flex-direction: column; gap: 4px; }
.chk__walk-list li { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.chk__x { border: 0; background: transparent; color: #9ca3af; cursor: pointer;
          font-size: 15px; line-height: 1; padding: 0 4px; }
.chk__x:hover { color: var(--danger-strong); }

.chk__points { margin: .5rem 0; padding-left: 1.1rem; font-size: 13px; color: var(--text-2); }

@media (pointer: coarse) {
    .chk__spot { padding: 8px 12px; font-size: 12px; }
    .chk__picker-kinds .btn-sm { padding: 9px 12px; }
}

/* ---------------------------------------------------------------------
   Photo annotation
   ---------------------------------------------------------------------
   Full-screen, because a technician marking a brake photo needs to see
   the pad, not a postage-stamp preview beside a form. Every control is
   large enough for a thumb — this is drawn with one finger, on a phone,
   usually while the other hand is still holding it or the car.
   --------------------------------------------------------------------- */
.ann {
    position: fixed; inset: 0; z-index: 10000;
    background: rgba(15, 17, 21, .92);
    display: flex; align-items: center; justify-content: center;
}
.ann__panel {
    width: 100%; height: 100%; display: flex; flex-direction: column;
    background: var(--ink); color: var(--surface);
}
.ann__head {
    display: flex; align-items: center; gap: 10px; padding: 10px 12px;
    background: #1c1f26; flex-wrap: wrap;
}
.ann__tools { display: flex; gap: 4px; }
.ann__tool {
    width: 42px; height: 42px; display: flex; align-items: center; justify-content: center;
    border: 1px solid transparent; border-radius: var(--radius);
    background: transparent; color: #d1d5db; font-size: 18px; cursor: pointer;
}
.ann__tool.is-on { background: var(--info); color: var(--surface); }

.ann__colors { display: flex; gap: 6px; margin-left: 4px; }
.ann__color {
    width: 26px; height: 26px; border-radius: 50%;
    border: 2px solid rgba(255,255,255,.35); cursor: pointer;
}
.ann__color.is-on { border-color: var(--surface); }

.ann__undo {
    margin-left: auto; width: 42px; height: 42px; font-size: 18px;
    border: 1px solid rgba(255,255,255,.2); border-radius: var(--radius);
    background: transparent; color: #d1d5db; cursor: pointer;
}
.ann__undo:disabled { opacity: .35; }

.ann__stage {
    flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center;
    padding: 8px; overflow: hidden;
}
.ann__stage canvas {
    max-width: 100%; max-height: 100%; touch-action: none;
    background: #000; border-radius: var(--radius-sm);
}

.ann__caption-bar { padding: 8px 12px; background: #1c1f26; }
.ann__caption-bar input {
    width: 100%; padding: 12px; font-size: 15px; border-radius: var(--radius);
    border: 1px solid rgba(255,255,255,.2); background: #0f1115; color: var(--surface);
}

.ann__foot {
    display: flex; align-items: center; gap: 10px; padding: 10px 12px;
    background: #1c1f26;
}
.ann__hint { font-size: 12px; color: #9ca3af; flex: 1; }
.ann__foot .btn-sm--primary { padding: 12px 22px; font-size: 15px; }
.ann__foot .btn-sm--primary:disabled { opacity: .4; }

/* The mark-up trigger on a thumbnail, beside the existing delete cross. */
.dvi-shot__mark {
    position: absolute; top: 3px; left: 3px;
    width: 22px; height: 22px; padding: 0; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    font-size: 13px; border: 0; border-radius: 50%;
    background: rgba(17, 24, 39, .72); color: var(--surface); cursor: pointer;
}
.dvi-shot__mark:hover { background: var(--info); }

@media (pointer: coarse) {
    .dvi-shot__mark, .dvi-shot__x { width: 30px; height: 30px; font-size: 16px; }
    .ann__tool, .ann__undo { width: 48px; height: 48px; }
}

/* ---------------------------------------------------------------------
   Draft a finding
   ---------------------------------------------------------------------
   Deliberately looks unfinished until "Use this" is pressed — a lighter
   border, a "Draft — not saved yet" label, no styling that could pass at
   a glance for the note field itself. Nothing here should be mistakable
   for a saved, attested finding.
   --------------------------------------------------------------------- */
.dvi-draft-btn {
    flex: none; width: 34px; height: 34px; margin-left: 4px;
    border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius);
    background: var(--surface); font-size: 15px; cursor: pointer;
}
.dvi-item__detail { display: flex; align-items: center; }

.dvi-draft {
    margin: 6px 0 10px; padding: 10px; border: 1px dashed #c7cdd6; border-radius: var(--radius);
    background: #f8f9fb;
}
.dvi-draft__input { display: flex; gap: 6px; }
.dvi-draft__input input {
    flex: 1; padding: 9px 10px; font-size: 14px;
    border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius);
}
.dvi-draft-mic {
    flex: none; width: 38px; border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius);
    background: var(--surface); font-size: 15px; cursor: pointer;
}
.dvi-draft-mic.is-listening { background: #fee2e2; border-color: #f87171; animation: dvi-pulse 1s ease infinite; }
@keyframes dvi-pulse { 50% { opacity: .55; } }

.dvi-draft__actions { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.dvi-draft__status { font-size: 12px; color: var(--muted, var(--muted-2)); }

.dvi-draft__result { margin-top: 10px; padding-top: 10px; border-top: 1px dashed #c7cdd6; }
.dvi-draft__label {
    margin: 0 0 4px; font-size: 10px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: #9298a2;
}
.dvi-draft__result p[data-draft-finding] { margin: 0 0 4px; font-size: 14px; color: #1f2937; }
.dvi-draft__rec { margin: 0 0 8px; font-size: 13px; color: var(--text-3); font-style: italic; }
.dvi-draft__use { display: flex; gap: 8px; }

@media (pointer: coarse) {
    .dvi-draft-btn, .dvi-draft-mic { width: 42px; height: 42px; }
}

/* SEO audit */
.seo-tally { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.25rem; }
.seo-tally__pill { padding: .45rem .85rem; border-radius: var(--radius-pill); font-size: .85rem; background: var(--surface-3); color: var(--text-2); }
.seo-tally__pill strong { font-size: 1rem; }
.seo-tally__pill--bad  { background: #fdeceb; color: #91231a; }
.seo-tally__pill--warn { background: #fdf4e3; color: #8a5a06; }
.seo-tally__pill--ok   { background: #edf7ee; color: #1f6b2c; }

.seo-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; }
.seo-dot--bad  { background: #dc2626; }
.seo-dot--warn { background: #f59e0b; }
.seo-dot--ok   { background: #16a34a; }

.seo-issues { margin: 0; padding-left: 1.1rem; font-size: .85rem; }
.seo-issues--bad  { color: #91231a; }
.seo-issues--warn { color: #8a5a06; }

/* SEO audit — fix-it controls */
.seo-fix { margin-top: .6rem; display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.seo-fix__status { font-size: .78rem; color: var(--muted, var(--muted-2)); }
.seo-fix__draft { flex: 1 1 100%; margin-top: .5rem; padding: .6rem;
                  border: 1px dashed #c7cdd6; border-radius: var(--radius); background: #f8f9fb; }
.seo-fix__label { margin: 0 0 .3rem; font-size: .65rem; font-weight: 700; letter-spacing: .05em;
                  text-transform: uppercase; color: #9298a2; }
.seo-fix__draft textarea { width: 100%; padding: .5rem; font-size: .85rem; font-family: inherit;
                           border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius-sm); resize: vertical; }
.seo-fix__actions { display: flex; align-items: center; gap: .4rem; margin-top: .4rem; }
.seo-fix__count { font-size: .75rem; color: var(--muted, var(--muted-2)); font-variant-numeric: tabular-nums; }
.seo-fix__count.is-over { color: var(--danger-strong); font-weight: 600; }

/* SEO audit — bulk drafting */
.seo-bulk__actions { display: flex; align-items: center; gap: .6rem; margin-top: .6rem; }
.seo-bulk__status { font-size: .82rem; color: var(--muted, var(--muted-2)); }
.seo-bulk__results { margin-top: .9rem; display: flex; flex-direction: column; gap: .5rem; }
.seo-bulk__item { display: grid; grid-template-columns: auto 1fr; gap: .3rem .6rem;
                  align-items: start; padding: .6rem; border: 1px dashed #c7cdd6;
                  border-radius: var(--radius); background: #f8f9fb; }
.seo-bulk__item.is-saved { border-style: solid; border-color: #86c79a; background: #f2f9f4; }
.seo-bulk__where { font-size: .75rem; font-weight: 600; color: var(--muted); }
.seo-bulk__item textarea { grid-column: 2; width: 100%; padding: .45rem; font-size: .85rem;
                           font-family: inherit; border: 1px solid var(--line, var(--line-2));
                           border-radius: var(--radius-sm); resize: vertical; min-width: 0; }
.seo-bulk__save { display: flex; align-items: center; gap: .6rem; margin-top: .9rem;
                  padding-top: .9rem; border-top: 1px solid var(--line, var(--line-2)); }

/* SEO audit — article ideas */
.seo-ideas { margin-top: .9rem; display: flex; flex-direction: column; gap: .5rem; }
.seo-idea { padding: .7rem .8rem; border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius); background: var(--surface); }
.seo-idea strong { display: block; font-size: .95rem; }
.seo-idea__svc { display: inline-block; margin: .25rem 0; padding: .1rem .5rem; border-radius: var(--radius-pill);
                 background: #eef2ff; color: #3730a3; font-size: .7rem; font-weight: 600; }
.seo-idea p { margin: .2rem 0 0; font-size: .85rem; color: var(--text-3); }

/* SEO audit — row actions. Stacked on narrow screens so two buttons
   never squeeze the issue text into a column of single words. */
.seo-actions { display: flex; gap: .35rem; }
@media (max-width: 700px) { .seo-actions { flex-direction: column; } }

/* SEO audit — writing an article from an idea */
.seo-idea__do { display: flex; align-items: center; gap: .5rem; margin-top: .5rem; }
.seo-idea__status { font-size: .78rem; color: var(--muted, var(--muted-2)); }
.seo-idea__done { margin-top: .6rem; padding-top: .6rem; border-top: 1px dashed #c7cdd6; }
.seo-idea__done textarea { width: 100%; padding: .5rem; font-size: .8rem; font-family: inherit;
                           border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius-sm);
                           background: #f8f9fb; resize: vertical; }
.seo-idea__done-do { display: flex; gap: .4rem; margin-top: .4rem; }

/* SEO audit — editing in place.
   Plain-English labels and a visible counter, because the person using
   this owns a garage and should not need to know what a meta tag is. */
.seo-field { margin-top: .75rem; }
.seo-field + .seo-field { padding-top: .75rem; border-top: 1px dashed #e5e7eb; }
.seo-field__label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: .25rem; }
.seo-field textarea { width: 100%; padding: .5rem; font-size: .88rem; font-family: inherit;
                      border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius-sm); resize: vertical; }
.seo-field__help { margin: .3rem 0 .45rem; font-size: .75rem; color: var(--muted, var(--muted-2)); }
.seo-field__count { float: right; font-variant-numeric: tabular-nums; }
.seo-field__count.is-over { color: var(--danger-strong); font-weight: 600; }
.seo-field__do { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.seo-field__status { font-size: .78rem; color: var(--muted, var(--muted-2)); }

/* SEO audit — publishing a draft */
.seo-publish { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
               margin-top: .8rem; padding-top: .8rem; border-top: 1px solid var(--line, var(--line-2)); }

/* An edited-but-unsaved meta box. Amber edge rather than a banner —
   enough to notice, not enough to shout. */
.seo-field.is-unsaved textarea { border-color: #f59e0b; background: #fffdf7; }

/* Article idea — when to publish */
.seo-idea__when, .seo-idea__date {
    padding: .4rem .5rem; font-size: .82rem; font-family: inherit;
    border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius-sm); background: var(--surface);
}
.seo-idea__date[hidden] { display: none; }
.seo-idea__do { flex-wrap: wrap; }

/* Site speed — shrink progress */
[data-speed-row].is-done { background: #f2f9f4; }
[data-speed-row] [data-speed-result] { font-size: .82rem; color: var(--muted, var(--muted-2)); }

/* Search Console panel */
.gsc-steps { margin: .5rem 0 1rem 1.1rem; font-size: .88rem; color: var(--text-2); }
.gsc-steps li { margin-bottom: .4rem; }
.gsc-steps code { display: inline-block; margin-top: .2rem; }
.gsc-site select { max-width: 32rem; }
.gsc-tally { margin-top: 1rem; }

/* Service page scoring */
.svc__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.svc__score { font-size: 1.35rem; font-weight: 700; padding: .15rem .7rem; border-radius: var(--radius-pill); }
.svc__score--ok   { background: #edf7ee; color: #1f6b2c; }
.svc__score--warn { background: #fdf4e3; color: #8a5a06; }
.svc__score--bad  { background: #fdeceb; color: #91231a; }
.svc__checks { display: flex; flex-wrap: wrap; gap: .4rem .9rem; list-style: none; margin: 0 0 .9rem; padding: 0; font-size: .85rem; }
.svc__checks li { display: flex; align-items: center; gap: .35rem; }
.svc__checks .is-ok  { color: #1f6b2c; }
.svc__checks .is-off { color: #91231a; }
.svc__mark { font-weight: 700; }
.svc__todo ol { margin: .3rem 0 .9rem 1.1rem; font-size: .88rem; }
.svc__todo li { margin-bottom: .35rem; }

/* Repair story candidates */
.story-why { margin: .5rem 0 .8rem 1.1rem; font-size: .85rem; color: var(--text-3); }
.story-why li { margin-bottom: .2rem; }

/* Location page filling */
[data-loc-row].is-done { background: #f2f9f4; }
[data-loc-row] [data-loc-result] { font-size: .8rem; color: var(--muted, var(--muted-2)); margin-right: .4rem; }

/* SEO overview */
.seo-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
             gap: .8rem; margin-bottom: 1.25rem; }
.seo-card { padding: 1rem 1.1rem; border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius);
            background: var(--surface); display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.seo-card__label { font-size: .72rem; font-weight: 700; letter-spacing: .05em;
                   text-transform: uppercase; color: #9298a2; }
.seo-card__n { font-size: 2rem; font-weight: 700; line-height: 1.1; }
.seo-card__n--ok   { color: #1f6b2c; }
.seo-card__n--warn { color: #8a5a06; }
.seo-card__n--bad  { color: #91231a; }
.seo-card__sub { font-size: .78rem; color: var(--muted, var(--muted-2)); }

.seo-todo { list-style: none; margin: 0; padding: 0; }
.seo-todo__item { display: flex; align-items: flex-start; justify-content: space-between;
                  gap: 1rem; padding: .9rem 1.1rem; border-top: 1px solid var(--line, var(--line-2)); }
.seo-todo__item:first-child { border-top: 0; }
.seo-todo__item p { margin: .25rem 0 0; font-size: .85rem; color: var(--text-3); }
.seo-todo__level { display: inline-block; margin-right: .4rem; padding: .05rem .45rem;
                   border-radius: var(--radius-pill); font-size: .62rem; font-weight: 700; letter-spacing: .04em;
                   background: var(--surface-3); color: var(--text-3); vertical-align: 2px; }
.seo-todo__item--high .seo-todo__level { background: #fdeceb; color: #91231a; }
.seo-todo__item--medium .seo-todo__level { background: #fdf4e3; color: #8a5a06; }
.seo-links { display: flex; flex-wrap: wrap; gap: .4rem; }

/* Arriving at a specific panel from a link elsewhere.
   An anchor jump on a long page lands silently — you get scrolled to
   something with no sign it is what you clicked for. */
:target.panel {
    scroll-margin-top: 1.5rem;
    border-color: var(--gold, #d6a83c);
    box-shadow: 0 0 0 3px rgba(214, 168, 60, .18);
}

/* FAQs written onto a service page */
.faq-preview { padding: .5rem 0; border-top: 1px dashed #e5e7eb; }
.faq-preview:first-of-type { border-top: 0; }
.faq-preview strong { display: block; font-size: .88rem; }
.faq-preview p { margin: .2rem 0 0; font-size: .85rem; color: var(--text-3); }

/* ---- The drafts / audit rows -------------------------------------
   These rows carry a whole editing form rather than a line of data, so
   the table defaults work against them: cells centre their contents
   vertically, which floats a page name into the middle of a very tall
   row and leaves the first control stranded at the top with a gap under
   it. Everything below is scoped to these two panels only. */

#not-published .table td,
.seo-audit-row td { vertical-align: top; padding-top: 1rem; padding-bottom: 1rem; }

/* The write-the-page step, given a label so it reads as step one rather
   than a button somebody left there. */
.seo-writebody {
    display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
    margin: 0 0 1rem; padding: .7rem .85rem;
    border: 1px solid #e3e6ea; border-left: 3px solid var(--gold, #d6a83c);
    border-radius: var(--radius); background: #fbfaf7;
}
.seo-writebody::before {
    content: 'The page itself';
    width: 100%; font-size: .68rem; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: #9298a2;
}

/* The two meta boxes side by side, with their own quiet heading, so the
   row reads as two steps rather than one long column of controls. */
.seo-fix {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: 1rem 1.5rem; align-items: start;
}
.seo-fix .seo-field { margin-top: 0; }
.seo-fix .seo-field + .seo-field { padding-top: 0; border-top: 0; }

/* Publish sits under both boxes, not beside one of them. */
.seo-publish { grid-column: 1 / -1; margin-top: .2rem; padding-top: .8rem; }

/* The page name column: pinned to the top and narrow, so a long title
   wraps instead of stretching the row. */
#not-published .table td:first-child,
.seo-audit-row td:first-child { width: 16rem; }

@media (max-width: 900px) {
    #not-published .table td:first-child,
    .seo-audit-row td:first-child { width: auto; }
    .seo-fix { grid-template-columns: 1fr; }
}

/* Google profile: copy-ready blocks */
.gp-copy { position: relative; }
.gp-copy textarea { width: 100%; padding: .7rem .85rem; font-family: inherit; font-size: .88rem;
                    line-height: 1.5; border: 1px solid var(--line, var(--line-2)); border-radius: var(--radius);
                    background: #fbfbfc; resize: vertical; }
.gp-copy button { position: absolute; top: .5rem; right: .5rem; }

/* Employee shift clock */
.shift-clock { display: flex; align-items: center; gap: .6rem; }
.shift-clock__on { display: inline-flex; align-items: center; gap: .4rem; padding: .3rem .7rem;
                   border-radius: var(--radius-pill); background: var(--ok-soft);
                   color: var(--ok-strong); font-size: .82rem; font-weight: 600; }
.shift-clock__on::before { content: ''; width: 7px; height: 7px; border-radius: 50%;
                           background: var(--ok-strong); }

/* Tekmetric sync output */
.tek-sync__out { margin: .9rem 0 0; padding: .8rem 1rem; border: 1px solid var(--line);
                 border-radius: var(--radius-sm); background: var(--surface-2); font-size: .85rem; }
.tek-sync__out ul { margin: .3rem 0 .8rem; padding-left: 1.1rem; }
.tek-sync__out code { font-size: .8rem; background: var(--surface-3); padding: .05rem .3rem;
                      border-radius: 3px; }
.tek-sync__label { margin: .6rem 0 .2rem; font-size: .72rem; font-weight: 700;
                   text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }

/* A field the connection test filled in, so it is obvious it changed */
input.is-filled { border-color: var(--ok-strong); background: var(--ok-soft); }

/* Destructive action, set apart from the rest */
.tek-remove { margin-top: 1rem; padding: .7rem .9rem; border: 1px solid var(--danger-border);
              border-radius: var(--radius-sm); background: var(--danger-soft); }
.tek-remove summary { cursor: pointer; font-weight: 600; color: var(--danger-strong); }
.btn-sm--danger { background: var(--danger-strong); border-color: var(--danger-strong); color: #fff; }

/* Message editor */
.msg-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
            margin: .3rem 0 1.2rem; }
.msg-count { font-size: .78rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.msg-count--over { color: var(--danger-strong); font-weight: 600; }
.msg-tags { display: flex; flex-wrap: wrap; gap: .3rem; margin-left: auto; }
.msg-tag { padding: .1rem .45rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
           background: var(--surface-3); font-family: inherit; font-size: .72rem;
           color: var(--text-3); cursor: pointer; }
.msg-tag:hover { border-color: var(--gold, #d6a83c); background: var(--surface); }

/* =====================================================================
   Press feedback
   =====================================================================
   The admin had one :active rule in the whole stylesheet, and it was a
   drag cursor. Every button acknowledged nothing until the page changed.

   On a workshop tablet that is the worst kind of latency: a technician
   taps, sees nothing, and taps again — so the shop gets double
   submissions and the software feels broken when it is merely quiet.

   Three rules, deliberately small:

   - It fires on press, not release. The whole point is that it happens
     while the finger is still down.
   - 1px of travel, not a scale. These are dense rows of controls; a
     button that shrinks by 3% next to six others reads as a wobble.
     Downward movement reads as "pushed" without moving neighbours.
   - .06s, half the hover duration. Feedback that eases in is not
     feedback; it has to be there by the time the eye looks.
   ===================================================================== */

.btn:active,
.btn-sm:active,
.tile:active,
.chip:active,
button[type="submit"]:active,
.rowmenu__panel a:active,
.rowmenu__panel button:active {
    transform: translateY(1px);
    transition: transform .06s ease-out;
}

/* The tile lifts on hover, so its press has to come from the lifted
   position or the button appears to drop two pixels. */
.tile:active { transform: translateY(0); }

/* Anything already disabled should not pretend to respond. */
.btn:disabled:active,
.btn-sm:disabled:active,
button:disabled:active { transform: none; }

@media (prefers-reduced-motion: reduce) {
    /* Motion out, feedback kept.
       
       Reduced motion means no vestibular movement, not no acknowledgement
       — removing the only signal that a tap registered would make the
       app worse for the person who asked for it. A border darkening on
       press does the same job without anything moving. */
    .btn:active,
    .btn-sm:active,
    .tile:active,
    .chip:active,
    button[type="submit"]:active,
    .rowmenu__panel a:active,
    .rowmenu__panel button:active {
        transform: none;
        filter: brightness(.94);
    }
}

/* "Worth making" — generate-with-AI action group (added with the AI
   service-page generator). Keeps the primary button and the quiet
   "See services" link aligned to the right of each row. */
.seo-todo__act { display: flex; flex-direction: column; align-items: flex-end; gap: .35rem; }
.seo-todo__act form { margin: 0; }

/* Field label with an inline "Write with AI" action (service summary). */
.ai-field-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ai-field-head label { margin: 0; }

/* Full-page vehicle-specific labor guide for estimate jobs. */
.rj__guide-status { display: block; flex-basis: 100%; color: var(--muted, #687078); font-size: .82rem; }
.rj__guide-status.is-bad { color: #a33; }
.rj__manual-overlay { position: fixed; z-index: 10000; inset: 0; display: grid; place-items: center; padding: 3vh 3vw; background: rgba(14, 22, 31, .58); }
.rj__manual-overlay[hidden] { display: none !important; }
.rj__manual-dialog { display: flex; flex-direction: column; width: min(1500px, 96vw); height: min(920px, 94vh); overflow: hidden; border-radius: 14px; background: #fff; box-shadow: 0 24px 80px rgba(0,0,0,.28); }
.rj__manual-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1.2rem 1.6rem; background: var(--ink); border-bottom: 3px solid var(--gold); color: #fff; }
.rj__manual-header h2 { margin: 0; font-size: 1.35rem; }
.rj__manual-header p { margin: .25rem 0 0; color: rgba(255,255,255,.88); }
.rj__manual-close { border: 0; padding: 0 .2rem; background: transparent; color: #fff; font-size: 2rem; line-height: 1; cursor: pointer; }
.rj__manual-body { display: grid; grid-template-columns: minmax(0, 1fr) 290px; min-height: 0; flex: 1; }
.rj__manual-results { display: flex; flex-direction: column; gap: .8rem; min-width: 0; min-height: 0; overflow: auto; padding: 1.2rem; }
.rj__manual-summary { padding: 1.25rem; border-left: 1px solid #e3e6e8; background: #f7f8f9; }
.rj__manual-summary h3 { margin: 0 0 .8rem; color: #59636c; font-size: .95rem; }
.rj__manual-summary strong { display: block; font-size: 1.1rem; }
.rj__manual-summary p { color: #687078; line-height: 1.5; }
.rj__manual-search { display: flex; gap: .5rem; }
.rj__manual-search input { flex: 1; min-width: 0; padding: .8rem 1rem; border: 1px solid #d7dce0; border-radius: 9px; font: inherit; font-size: 1.05rem; }
.rj__manual-search button { padding: .7rem 1rem; border: 1px solid var(--gold-dark); border-radius: 8px; background: var(--gold); color: var(--ink); font: inherit; font-weight: 700; cursor: pointer; }
.rj__manual-back { align-self: start; padding: .55rem .8rem; border: 1px solid var(--border, #ddd); border-radius: 8px; background: var(--surface, #fff); color: inherit; cursor: pointer; }
.rj__manual-list { display: grid; align-content: start; gap: .35rem; min-height: 0; overflow: auto; }
.rj__manual-category, .rj__manual-operation { display: flex; align-items: center; justify-content: space-between; gap: .8rem; width: 100%; padding: .75rem .85rem; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); text-align: left; color: inherit; cursor: pointer; }
.rj__manual-category:hover, .rj__manual-operation:hover { border-color: var(--gold-dark); background: var(--warn-bg); }
.rj__manual-category::after { content: '›'; font-size: 1.3rem; }
.rj__manual-operation { display: grid; justify-content: stretch; }
.rj__manual-operation span, .rj__manual-note { margin: 0; color: var(--muted, #687078); font-size: .84rem; }
.rj__manual-choice { display: grid; gap: .2rem; width: 100%; padding: .65rem .8rem; border: 1px solid var(--border, #ddd); border-radius: 8px; background: var(--surface, #fff); text-align: left; color: inherit; }
.rj__manual-choice:not(:disabled) { cursor: pointer; }
.rj__manual-choice:disabled { opacity: .68; }
.rj__manual-choice span { color: var(--muted, #687078); font-size: .82rem; }
.rj__manual-job-name, .rj__manual-tech-search input { box-sizing: border-box; width: 100%; min-width: 0; padding: .65rem .75rem; border: 1px solid var(--line); border-radius: 7px; background: #fff; color: var(--ink); font: inherit; }
.rj__manual-cart { display: grid; gap: .45rem; max-height: 32vh; overflow: auto; }
.rj__manual-cart-item { display: grid; grid-template-columns: minmax(0,1fr) auto auto; align-items: start; gap: .45rem; padding: .55rem 0; border-bottom: 1px solid var(--line); font-size: .88rem; }
.rj__manual-cart-item button { border: 0; background: transparent; color: var(--muted); font-size: 1.2rem; cursor: pointer; }
.rj__manual-total { display: block; margin: .65rem 0; }
.rj__manual-create { width: 100%; padding: .8rem; border: 1px solid var(--gold-dark); border-radius: 8px; background: var(--gold); color: var(--ink); font: inherit; font-weight: 700; cursor: pointer; }
.rj__manual-create:disabled { opacity: .55; cursor: not-allowed; }
.rj__manual-add { justify-self: end; align-self: center; width: 2rem; height: 2rem; border: 0; border-radius: 4px; background: #159447; color: #fff; font-size: 1.4rem; font-weight: 700; cursor: pointer; }
.rj__manual-details { margin-top: .55rem; border: 1px solid var(--line); border-radius: 7px; background: #fff; }
.rj__manual-details summary { padding: .7rem .75rem; color: var(--ink); font-weight: 650; cursor: pointer; }
.rj__manual-details > p { margin: 0; padding: 0 .75rem .75rem; color: var(--muted); line-height: 1.45; }
.rj__manual-diagrams[open] { padding-bottom: .75rem; }
.rj__manual-tech-search { display: flex; gap: .35rem; padding: 0 .65rem; }
.rj__manual-tech-search button { border: 1px solid var(--gold-dark); border-radius: 6px; padding: .5rem; background: var(--ink); color: #fff; font: inherit; cursor: pointer; }
.rj__manual-tech-results { display: grid; gap: .3rem; max-height: 26vh; overflow: auto; padding: .55rem .65rem 0; }
.rj__manual-tech-filter { box-sizing: border-box; width: 100%; min-width: 0; margin: .55rem 0 0; padding: .6rem .7rem; border: 1px solid var(--line); border-radius: 7px; background: #fff; color: var(--ink); font: inherit; }
.rj__manual-tech-list { display: grid; gap: .3rem; max-height: 48vh; overflow: auto; padding-top: .45rem; }
.rj__manual-tech-link { color: var(--ink); text-decoration: none; padding: .5rem; border: 1px solid var(--line); border-radius: 6px; }
.rj__manual-tech-link:hover { border-color: var(--gold-dark); background: var(--warn-bg); }
.ro__labor-guide, .ro__diagrams { display: inline-flex; align-items: center; gap: .45rem; min-height: 42px; padding: .6rem .9rem; border: 1px solid var(--gold-dark); border-radius: 9px; background: var(--gold); color: #fff !important; -webkit-text-fill-color: #fff; font: inherit; font-weight: 700; cursor: pointer; }
.ro__labor-guide:hover, .ro__diagrams:hover { filter: brightness(.96); color: #fff !important; -webkit-text-fill-color: #fff; }
.ro__quick-action { display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; padding: 0; border: 1px solid var(--line); border-radius: 9px; background: var(--surface); color: var(--ink); cursor: pointer; text-decoration: none; }
.ro__quick-action:hover { border-color: var(--gold-dark); background: var(--warn-bg); color: var(--ink); }
.ro__quick-action svg { display: block; }
.ro__print-menu { position: relative; }
.ro__print-menu > summary { list-style: none; }
.ro__print-menu > summary::-webkit-details-marker { display: none; }
.ro__print-options { position: absolute; z-index: 100; top: calc(100% + .5rem); right: 0; display: grid; min-width: 210px; padding: .35rem; border: 1px solid var(--line); border-radius: 9px; background: var(--surface); box-shadow: 0 10px 28px rgba(0,0,0,.16); }
.ro__print-options a { display: block; padding: .7rem .8rem; border-radius: 6px; color: var(--ink); font-size: 1rem; font-weight: 600; text-decoration: none; }
.ro__print-options a:hover { background: var(--warn-bg); color: var(--ink); }
.ro__share-overlay { position: fixed; z-index: 10020; inset: 0; display: grid; place-items: center; padding: 1.25rem; background: rgba(15, 19, 25, .58); }
.ro__share-dialog { display: flex; flex-direction: column; width: min(620px, 94vw); max-height: min(820px, 90vh); overflow: auto; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); box-shadow: 0 24px 70px rgba(0,0,0,.3); }
.ro__share-dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem 1.25rem; border-bottom: 3px solid var(--gold); background: var(--ink); color: #fff; }
.ro__share-dialog-head h2 { margin: 0; color: #fff; font-size: 1.2rem; }
.ro__share-dialog-close { border: 0; padding: 0 .2rem; background: transparent; color: #fff; font-size: 2rem; line-height: 1; cursor: pointer; }
.ro__share-dialog-body { padding: 1.25rem; overflow: auto; }
.ro__share-dialog .ro__send { margin: 0; border: 0; }
.ro__share-dialog .ro__send > summary { display: none; }
.ro__share-dialog .ro__send-body { display: block; padding: 0; }
.ro__vehicle-layout { display: grid; grid-template-columns: minmax(0,1fr) 320px; align-items: start; gap: 1rem; }
.ro__vehicle-main { min-width: 0; }
.ro__vehicle-sidebar { position: sticky; top: 1rem; display: grid; gap: .6rem; padding: .8rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.ro__vehicle-fold { overflow: hidden; border: 1px solid var(--line); border-radius: 8px; background: #fff; }
.ro__vehicle-fold summary { padding: .8rem; color: var(--ink); font-weight: 700; cursor: pointer; }
.ro__vehicle-fold p { margin: 0; padding: .2rem .8rem .7rem; color: var(--muted); line-height: 1.45; }
.ro__vehicle-manual-list { display: grid; gap: .3rem; max-height: 50vh; overflow: auto; padding: 0 .6rem .7rem; }
.ro__vehicle-manual-list .rj__manual-tech-link { display: block; }
.ro__vehicle-group { overflow: hidden; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); box-shadow: 0 2px 8px rgba(22,28,34,.05); }
.ro__vehicle-group > summary { display: flex; align-items: center; gap: .7rem; min-height: 54px; padding: .8rem 1rem; border-left: 5px solid var(--gold); background: var(--ink); color: #fff; font-size: 1.05rem; font-weight: 700; cursor: pointer; list-style: none; }
.ro__vehicle-group > summary::-webkit-details-marker { display: none; }
.ro__vehicle-group > summary::after { content: '⌄'; margin-left: auto; color: #fff; font-size: 1.25rem; transition: transform .15s ease; }
.ro__vehicle-group[open] > summary::after { transform: rotate(180deg); }
.ro__vehicle-group-icon { display: grid; width: 28px; height: 28px; place-items: center; border-radius: 7px; background: var(--gold); color: var(--ink); font-size: 1.1rem; }
.ro__vehicle-group-body { padding: 1rem; }
.ro__vehicle-group-body > :first-child { margin-top: 0; }
.ro__fluid-card { margin: .75rem 0; padding: 1rem; border: 1px solid var(--line); border-left: 4px solid var(--gold); border-radius: 10px; background: var(--surface); }
.ro__fluid-card h3 { margin: 0 0 .45rem; color: var(--ink); font-size: 1.1rem; }
.ro__fluid-application { margin: 0 0 .8rem; color: var(--muted); line-height: 1.5; }
.ro__fluid-details { display: grid; grid-template-columns: minmax(130px, .32fr) minmax(0, 1fr); gap: .4rem .8rem; margin: 0; }
.ro__fluid-details dt { color: var(--muted); font-weight: 600; }
.ro__fluid-details dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
.ro__vehicle-group .ro__spec { margin-bottom: 0; }
.ro__customer-orders { display: grid; gap: .65rem; }
.ro__customer-order { display: grid; gap: .35rem; padding: .85rem 1rem; border: 1px solid var(--line); border-radius: 10px; background: #fff; color: var(--ink); text-decoration: none; transition: border-color .15s ease, background .15s ease; }
.ro__customer-order:hover { border-color: var(--gold); background: var(--gold-soft, #fbf4e3); text-decoration: none; }
.ro__customer-order strong { display: flex; align-items: center; justify-content: space-between; gap: .75rem; }
.ro__customer-order strong span { color: var(--muted); font-size: .85rem; font-weight: 600; }
.ro__customer-order > span { font-weight: 600; }
.ro__customer-order small { color: var(--muted); font-size: .92rem; }
/* Keep labor guide labels readable at the full-page popup's normal zoom. */
body.admin .rj__guide-status { font-size: 1rem !important; line-height: 1.5; }
body.admin .rj__manual-search input { font-size: 1.15rem !important; }
body.admin .rj__manual-search button { font-size: 1.05rem !important; }
body.admin .rj__manual-category { min-height: 58px; padding: .9rem 1rem; font-size: 1.1rem !important; line-height: 1.4; }
body.admin .rj__manual-operation { padding: .9rem 1rem; font-size: 1.05rem !important; line-height: 1.4; }
body.admin .rj__manual-operation span { font-size: .95rem !important; line-height: 1.45; }
body.admin .rj__manual-note { font-size: 1rem !important; line-height: 1.5; }
body.admin .rj__manual-summary h3 { font-size: 1.05rem !important; }
body.admin .rj__manual-summary p { font-size: 1rem !important; }
body.admin .rj__manual-job-name, body.admin .rj__manual-create { font-size: 1rem !important; }
body.admin .rj__manual-cart-item { font-size: .95rem !important; line-height: 1.45; }
body.admin .rj__manual-details summary { font-size: 1rem !important; }
body.admin .rj__manual-tech-filter { font-size: 1rem !important; }
body.admin .rj__manual-tech-link { font-size: 1rem !important; line-height: 1.45; padding: .7rem .75rem; }
@media (max-width: 760px) {
    .rj__manual-overlay { padding: 0; }
    .rj__manual-dialog { width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; }
    .rj__manual-body { grid-template-columns: minmax(0, 1fr); overflow: auto; }
    .rj__manual-results { max-height: 68vh; }
    .rj__manual-summary { border-top: 1px solid #e3e6e8; border-left: 0; }
    .ro__vehicle-layout { grid-template-columns: minmax(0,1fr); }
    .ro__vehicle-sidebar { position: static; }
}
