/* =====================================================================
   THEME — Workshop

   This theme ships its own layout and its own floor screen, so most of
   what follows styles markup that only exists here (.wsx, .wq). The
   handful of .admin rules exist to match brand.css's specificity on the
   shared components the rest of the app still renders.
   ===================================================================== */

:root {
    --bg:        #f7f8fa;
    --surface:   #ffffff;
    --line:      #e7e9ed;
    --text:      #15171a;
    --muted:     #747b86;

    --ink:       #15171a;
    --ink-2:     #24272c;
    --ink-3:     #515762;

    --gold:      #2563eb;
    --gold-dark: #1d4ed8;
    --accent:    #2563eb;

    --ok:        #177245;  --ok-bg:     #eaf7f0;
    --warn:      #9a6700;  --warn-bg:   #fff7df;
    --danger:    #b42318;  --danger-bg: #fff0ee;

    --radius:    12px;
    --radius-sm: 8px;
    --shadow:    none;
    --font:      "Inter", ui-sans-serif, -apple-system, BlinkMacSystemFont, sans-serif;
    --display:   "Inter", ui-sans-serif, -apple-system, sans-serif;
}

body.ws-app { background: var(--bg); color: var(--text); font-size: 14px; line-height: 1.45; }

/* ---------------------------------------------------------------------
   Shell
   --------------------------------------------------------------------- */
.wsx { display: grid; grid-template-columns: 232px 1fr; min-height: 100vh; }

.wsx__side { background: var(--surface); border-right: 1px solid var(--line);
             padding: 24px 16px; display: flex; flex-direction: column; }
.wsx__brand { display: flex; align-items: center; gap: 10px; padding: 0 8px 26px;
              text-decoration: none; color: var(--text); font-weight: 700; font-size: 16px; }
.wsx__logo { width: 30px; height: 30px; border-radius: 9px; background: var(--ink);
             color: #fff; display: grid; place-items: center; font-size: 14px; flex: none; }
.wsx__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.wsx__nav { display: flex; flex-direction: column; }
.wsx__label { font-size: 10px; letter-spacing: .11em; color: #9aa0aa; font-weight: 700;
              padding: 18px 10px 7px; text-transform: uppercase; }
.wsx__nav a { display: flex; align-items: center; gap: 11px; text-decoration: none;
              color: #515762; padding: 9px 10px; border-radius: 8px; margin: 2px 0; }
.wsx__nav a:hover { background: #f4f6f9; color: var(--text); }
.wsx__nav a.active { background: #f1f4f8; color: var(--text); font-weight: 600; }
.wsx__ico { width: 18px; display: grid; place-items: center; color: #7a818c; flex: none; }
.wsx__nav a.active .wsx__ico { color: var(--accent); }

.wsx__user { margin-top: auto; border-top: 1px solid var(--line); padding: 18px 8px 0;
             display: flex; gap: 10px; align-items: center; }
.wsx__avatar { width: 32px; height: 32px; border-radius: 50%; background: #e9edf3;
               display: grid; place-items: center; font-weight: 700; font-size: 12px; flex: none; }
.wsx__who { min-width: 0; flex: 1; }
.wsx__who strong { display: block; font-size: 13px; overflow: hidden;
                   text-overflow: ellipsis; white-space: nowrap; }
.wsx__who small { color: var(--muted); font-size: 12px; }
.wsx__out { margin: 0; }
.wsx__out button { background: none; border: 0; color: var(--muted); cursor: pointer;
                   font-size: 16px; padding: .3rem; border-radius: 6px; }
.wsx__out button:hover { background: var(--bg); color: var(--danger); }

.wsx__main { min-width: 0; }
.wsx__top { height: 66px; background: var(--surface); border-bottom: 1px solid var(--line);
            display: flex; align-items: center; justify-content: space-between; padding: 0 32px;
            position: sticky; top: 0; z-index: 20; }
.wsx__search { margin: 0; flex: 1; max-width: 360px; }
.wsx__search input { width: 100%; background: var(--bg); border: 1px solid var(--line);
                     border-radius: 9px; padding: 9px 12px; }
.wsx__actions { display: flex; gap: 9px; align-items: center; }
.wsx__new { background: var(--ink); color: #fff; border-radius: 8px; padding: 9px 14px;
            text-decoration: none; font-weight: 600; }
.wsx__new:hover { background: var(--ink-2); color: #fff; }
.wsx__content { padding: 34px 36px 60px; max-width: 1440px; margin: 0 auto; }

/* ---------------------------------------------------------------------
   The work queue
   --------------------------------------------------------------------- */
.wq__head { display: flex; justify-content: space-between; align-items: flex-end;
            margin-bottom: 27px; gap: 1rem; flex-wrap: wrap; }
.wq__head h1 { font-size: 29px; letter-spacing: -.03em; margin: 0 0 5px;
               text-transform: none; font-family: var(--font); }
.wq__sub { color: var(--muted); margin: 0; }
.wq__date { color: var(--muted); }

.wq__metrics { display: grid; gap: 10px; margin-bottom: 26px;
               grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.wq__metric { background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
              padding: 15px 16px; text-decoration: none; color: var(--text); display: block; }
.wq__metric:hover { border-color: #cdd2da; }
/* Selected reads as selected without shouting — a tinted border and a
   barely-there wash, which is all a filter state needs. */
.wq__metric.is-on { border-color: #b7ccff; background: #fbfdff; }
.wq__metric.is-empty { opacity: .55; }
.wq__label { color: var(--muted); font-size: 12px; display: block; }
.wq__n { font-size: 22px; font-weight: 700; margin-top: 5px; display: block;
         font-variant-numeric: tabular-nums; }
.wq__cash { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

.wq { background: var(--surface); border: 1px solid var(--line);
      border-radius: var(--radius); overflow: hidden; }
.wq__bar { display: flex; align-items: center; gap: .6rem; justify-content: space-between;
           padding: 15px 18px; border-bottom: 1px solid var(--line); }
.wq__find { margin: 0; flex: 1; }
.wq__find input { width: 100%; max-width: 420px; }
.wq__empty { padding: 3rem 1.5rem; text-align: center; color: var(--muted); margin: 0; }

.wq__table { width: 100%; border-collapse: collapse; }
.wq__table th { text-align: left; font-size: 11px; letter-spacing: .04em; color: #9298a2;
                font-weight: 700; padding: 12px 18px; border-bottom: 1px solid var(--line);
                background: #fcfcfd; text-transform: uppercase; }
.wq__table td { padding: 15px 18px; border-bottom: 1px solid #eff0f2; vertical-align: middle; }
.wq__table tr:last-child td { border-bottom: 0; }
.wq__table tbody tr:hover { background: #fcfcfd; }
/* A left edge rather than a coloured row: the row stays readable and the
   flag is still visible scanning down twenty of them. */
.wq__table tr.is-urgent td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

.wq__veh { font-weight: 700; display: block; text-decoration: none; color: var(--text); }
.wq__veh:hover { color: var(--accent); }
.wq__meta { font-size: 12px; color: #8b919a; margin-top: 3px; display: block; }
.wq__concern { color: #515762; display: block; max-width: 34ch; }
.wq__next { font-weight: 600; text-decoration: none; color: var(--accent); display: block; }
.wq__next:hover { text-decoration: underline; }
.wq__why { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; }
.wq__tech { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.wq__tech--none { color: var(--muted); }
.wq__dot { width: 28px; height: 28px; border-radius: 50%; background: #edf0f4;
           display: grid; place-items: center; font-size: 11px; font-weight: 700; flex: none; }
.wq__none { color: var(--muted); }
.wq__go { text-align: right; }
.wq__go a { color: #8b919a; text-decoration: none; font-size: 20px; padding: 0 .3rem; }
.wq__go a:hover { color: var(--text); }

/* ---------------------------------------------------------------------
   Status badge — one system, five tones
   --------------------------------------------------------------------- */
.badge { display: inline-flex; padding: 5px 9px; border-radius: 999px; font-size: 11px;
         font-weight: 700; white-space: nowrap; }
.badge--blue  { background: #eef4ff; color: #2458bd; }
.badge--green { background: var(--ok-bg); color: var(--ok); }
.badge--amber { background: var(--warn-bg); color: var(--warn); }
.badge--red   { background: var(--danger-bg); color: var(--danger); }
.badge--grey  { background: #f1f3f6; color: #5b626c; }

/* ---------------------------------------------------------------------
   Shared components, scoped to beat brand.css
   --------------------------------------------------------------------- */
.admin .panel { border: 1px solid var(--line); border-radius: var(--radius); box-shadow: none; }
.admin .panel__head { background: var(--surface); border-bottom: 1px solid var(--line); }
.admin .panel__head h2 { font-size: 15px; font-weight: 600; text-transform: none;
                         letter-spacing: 0; font-family: var(--font); }
.admin .page-head h1 { font-size: 29px; letter-spacing: -.03em; text-transform: none;
                       font-family: var(--font); }
/* Buttons.
 *
 * The trap here is specificity, not colour. `.admin button[type="submit"]`
 * weighs one element more than `.admin .btn-sm--primary`, so a plain
 * submit rule painting the background white beat the primary rule
 * painting it dark — while `color: #fff` survived from elsewhere. The
 * result was white text on a white button, visible only on hover, on
 * every primary submit in the app.
 *
 * Fixed by matching the shape: the primary rules carry the same element
 * and attribute weight as the rule they have to beat, rather than by
 * reaching for !important, which would only move the fight. */
.admin .btn-sm,
.admin button[type="submit"] { border: 1px solid var(--line);
                background: var(--surface); color: var(--text); border-radius: 8px;
                padding: 9px 13px; font-weight: 500; text-transform: none;
                letter-spacing: 0; font-family: var(--font); box-shadow: none; }

.admin .btn-sm--primary,
.admin button[type="submit"].btn-sm--primary,
.admin button[type="submit"].btn--gold { background: var(--ink); color: #fff;
                                          border-color: var(--ink); }
.admin .btn-sm--primary:hover,
.admin button[type="submit"].btn-sm--primary:hover,
.admin button[type="submit"].btn--gold:hover { background: var(--ink-2);
                                                border-color: var(--ink-2); color: #fff; }

/* Same problem for the danger variant. */
.admin .btn-sm--danger,
.admin button[type="submit"].btn-sm--danger { background: var(--danger); color: #fff;
                                               border-color: var(--danger); }

/* A submit that is styled as a link should not inherit the button box. */
.admin button.btn-link-danger { background: none; border: 0; color: var(--danger);
                                padding: 0; font-weight: 500; }

/* A submit with no class of its own.
 *
 * brand.css paints these gold — that is the shop's brand and correct
 * there. This theme's accent is blue, so the same rule has to be answered
 * at the same weight or a bare Save button arrives in someone else's
 * colours. The :not() list mirrors brand.css exactly.
 *
 * rowmenu__item is excluded because a row-actions menu is a list, not a
 * row of buttons. Three :not() clauses give this rule a specificity of
 * (0,4,1), which quietly outranked every attempt to style those items
 * from elsewhere — adding to the exclusion list is the honest fix, where
 * piling on more selectors would only have moved the fight. */
.admin button[type="submit"]:not(.btn-link-danger):not(.btn-sm):not(.rowmenu__item) {
    background: var(--ink); border: 1px solid var(--ink); color: #fff;
}
.admin button[type="submit"]:not(.btn-link-danger):not(.btn-sm):not(.rowmenu__item):hover {
    background: var(--ink-2); border-color: var(--ink-2); color: #fff;
}

/* Anchors styled as buttons inherit link colour from brand.css, which is
   gold. Named here so a dark button gets legible text rather than the
   brand accent on near-black. */
.admin a.wsx__new,
.admin a.btn-sm--primary { color: #fff; }
.admin a.wsx__new:hover,
.admin a.btn-sm--primary:hover { color: #fff; }
.admin .wq__views a { color: var(--muted); }
.admin .wq__views a.is-on { color: var(--text); }
.admin .table th { text-transform: uppercase; font-size: 11px; letter-spacing: .04em;
                   color: #9298a2; }
.admin .chip { border-radius: 999px; font-weight: 700; font-size: 11px; }

@media (max-width: 1000px) {
    .wsx { grid-template-columns: 76px 1fr; }
    .wsx__name, .wsx__nav a span:not(.wsx__ico), .wsx__label, .wsx__who { display: none; }
    .wsx__side { padding: 20px 12px; }
    .wsx__nav a { justify-content: center; }
    .wsx__content { padding: 24px 20px 48px; }
}

@media (max-width: 720px) {
    .wsx { display: block; }
    .wsx__side { display: none; }
    .wsx__top { padding: 0 16px; }
    /* Room at the foot for the bar this breakpoint now shows, plus the
       home-indicator inset on an iPhone with no browser chrome. */
    .wsx__content { padding: 20px 14px calc(72px + env(safe-area-inset-bottom, 0px)); }
    .wq--hide { display: none; }
    .wq { overflow-x: auto; }
    .wq__table { min-width: 620px; }

    .wsx__bottom { display: flex; }
    .wsx__more[hidden] { display: none; }
}

/* ---------------------------------------------------------------------
   Bottom navigation
   ---------------------------------------------------------------------
   Hidden by default and shown only in the 720px block above — sent to
   every screen, on-screen only on the narrow one, which is what keeps
   this from becoming a second thing to keep in step with the sidebar
   it is built from.
   --------------------------------------------------------------------- */
.wsx__bottom {
    display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    align-items: stretch; height: 60px;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: var(--surface); border-top: 1px solid var(--line);
}
.wsx__bottom a, .wsx__bottom-more {
    flex: 1; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 2px; padding: 4px 2px;
    color: var(--muted); text-decoration: none; font-size: 10px; font-weight: 600;
    border: 0; background: transparent;
}
.wsx__bottom a.active { color: var(--accent, #2563eb); }
.wsx__bottom svg { width: 20px; height: 20px; }

/* New sits proud of the bar rather than as a fifth equal tab — the same
   reason it is its own gold button in the sidebar and the top bar. */
.wsx__bottom-new {
    flex: 0 0 52px; display: flex; align-items: center; justify-content: center;
    margin: -14px 4px 0; width: 52px; height: 52px; border-radius: 50%;
    background: var(--gold, #d6a83c); color: #14161a; box-shadow: 0 3px 10px rgba(0,0,0,.2);
}

/* The More sheet */
.wsx__more {
    position: fixed; inset: 0; z-index: 50; display: flex; align-items: flex-end;
    background: rgba(15,17,21,.45);
}
.wsx__more[hidden] { display: none; }
.wsx__more-head {
    /* Rendered by the nav panel below; kept for layout only. */
}
.wsx__more > .wsx__more-head,
.wsx__more nav.wsx__more-nav {
    background: var(--surface);
}
.wsx__more {
    flex-direction: column; justify-content: flex-end;
}
.wsx__more-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 16px; background: var(--surface);
    border-top-left-radius: 14px; border-top-right-radius: 14px;
    border-bottom: 1px solid var(--line);
}
.wsx__more-head button { border: 0; background: transparent; font-size: 20px; color: var(--muted); }
.wsx__more-nav {
    display: flex; flex-direction: column; padding: 8px 8px calc(16px + env(safe-area-inset-bottom, 0px));
    max-height: 70vh; overflow-y: auto; background: var(--surface);
}
.wsx__more-nav a {
    display: flex; align-items: center; gap: 12px; padding: 12px 10px;
    border-radius: 9px; color: var(--text); text-decoration: none; font-size: 15px;
}
.wsx__more-nav a.active { background: var(--bg); color: var(--accent, #2563eb); }
.wsx__more-nav .wsx__label { margin: 10px 10px 2px; font-size: 11px; font-weight: 700;
                              letter-spacing: .04em; text-transform: uppercase; color: #9298a2; }

@media (pointer: coarse) {
    .wsx__bottom a, .wsx__bottom-more { min-height: 44px; }
}

/* ---------------------------------------------------------------------
   Refinements: money on the row, the view toggle, the board
   --------------------------------------------------------------------- */
.wsx__bell { position: relative; display: grid; place-items: center; width: 38px; height: 38px;
             border-radius: 9px; color: var(--muted); text-decoration: none; }
.wsx__bell:hover { background: var(--bg); color: var(--text); }
.wsx__pip { position: absolute; top: 5px; right: 5px; min-width: 16px; height: 16px;
            padding: 0 4px; border-radius: 999px; background: var(--danger); color: #fff;
            font-size: 10px; font-weight: 700; display: grid; place-items: center; }

.wq__views { display: flex; gap: 2px; background: var(--bg); border-radius: 8px; padding: 3px; flex: none; }
.wq__views a { padding: 6px 12px; border-radius: 6px; text-decoration: none; color: var(--muted);
               font-size: 13px; font-weight: 500; }
.wq__views a.is-on { background: var(--surface); color: var(--text); font-weight: 600;
                     box-shadow: 0 1px 2px rgba(21,23,26,.06); }

/* The row is the link, so it has to say so. */
.wq__row { cursor: pointer; }
.wq__num { text-align: right; white-space: nowrap; }
.wq__fig { display: block; font-variant-numeric: tabular-nums; font-weight: 600; }
.wq__cash { display: block; font-size: 12px; margin-top: 2px; }
/* Money that needs doing something about is the only money with colour. */
.wq__cash--due { color: var(--danger); font-weight: 600; }
.wq__cash--ok { color: var(--ok); }
.wq__cash--none { color: var(--muted); }
.wq__next { font-weight: 600; color: var(--accent); display: block; }

/* ---------------------------------------------------------------------
   Board — the same rows, arranged by stage

   Compact cards, because a board earns its place by showing the shape of
   the day at a glance and stops earning it the moment it needs scrolling
   in two directions.
   --------------------------------------------------------------------- */
.wb { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(224px, 1fr);
      gap: 12px; padding: 16px; overflow-x: auto; align-items: start; }
.wb__col { min-width: 0; }
.wb__head { display: flex; align-items: center; justify-content: space-between; gap: .5rem;
            padding: 0 4px 10px; font-size: 12px; font-weight: 700; color: var(--muted); }
.wb__n { background: var(--bg); border-radius: 999px; padding: 1px 7px; font-size: 11px; }
.wb__card { display: block; background: var(--surface); border: 1px solid var(--line);
            border-left: 3px solid var(--line); border-radius: 10px; padding: 11px 12px;
            margin-bottom: 8px; text-decoration: none; color: var(--text); }
.wb__card:hover { border-color: #cdd2da; }
.wb__card.is-urgent { border-left-color: var(--accent); }
.wb__card strong { display: block; font-size: 13px; line-height: 1.3; }
.wb__meta { display: block; font-size: 11px; color: var(--muted); margin-top: 3px; }
.wb__do { display: block; font-size: 12px; font-weight: 600; color: var(--accent); margin-top: 7px; }
.wb__cash { display: block; font-size: 11px; margin-top: 4px; font-variant-numeric: tabular-nums; }
.wb__cash--due { color: var(--danger); font-weight: 600; }
.wb__cash--ok { color: var(--ok); }
.wb__cash--none { color: var(--muted); }
.wb__none { font-size: 12px; color: #b0b5bd; padding: 4px; margin: 0; }

/* ---------------------------------------------------------------------
   Repair order workspace
   --------------------------------------------------------------------- */
.ro__back { margin: 0 0 14px; }
.ro__back a { color: var(--muted); text-decoration: none; font-size: 13px; }
.ro__back a:hover { color: var(--text); }

.ro__head { display: flex; align-items: flex-start; justify-content: space-between;
            gap: 1rem; flex-wrap: wrap; margin-bottom: 18px; }
.ro__head h1 { font-size: 26px; letter-spacing: -.03em; margin: 0 0 4px;
               text-transform: none; font-family: var(--font); }
.ro__who { color: var(--muted); margin: 0; }
.ro__who a { color: var(--muted); }
.ro__status { font-size: 12px; padding: 7px 12px; }

/* The facts an advisor is asked for on the phone, on every tab. */
.ro__facts { display: grid; gap: 0; margin-bottom: 22px; background: var(--surface);
             border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
             grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); }
.ro__facts > div { padding: 13px 15px; border-right: 1px solid var(--line); min-width: 0; }
.ro__facts > div:last-child { border-right: 0; }
.ro__facts span { display: block; font-size: 11px; color: var(--muted); margin-bottom: 3px; }
.ro__facts strong { font-size: 14px; font-variant-numeric: tabular-nums; }
.ro__due { color: var(--danger); }

.ro__tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line);
            margin-bottom: 22px; overflow-x: auto; }
.ro__tabs a { padding: 10px 14px; text-decoration: none; color: var(--muted); font-weight: 500;
              white-space: nowrap; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.ro__tabs a:hover { color: var(--text); }
.ro__tabs a.is-on { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }

.ro__sec { margin-bottom: 30px; }
.ro__sec h2 { font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
              color: var(--muted); font-weight: 700; margin: 0 0 12px; }
.ro__lead { font-size: 15px; line-height: 1.55; margin: 0 0 8px; max-width: 62ch; }
.ro__none { color: var(--muted); margin: 0; }
.ro__why { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; }
.ro__hint { color: var(--muted); font-size: 13px; margin: 14px 0 0; }

.ro__list { list-style: none; margin: 0; padding: 0; }
.ro__list li { padding: 10px 0; border-bottom: 1px solid var(--line); }
.ro__list li:last-child { border-bottom: 0; }
.ro__list .is-void { opacity: .5; text-decoration: line-through; }

.ro__totals { display: grid; grid-template-columns: 1fr auto; gap: 7px 2rem;
              max-width: 340px; margin: 18px 0 0; }
.ro__totals dt { color: var(--muted); }
.ro__totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.ro__totals .is-total { font-weight: 700; border-top: 1px solid var(--line); padding-top: 7px; }

.ro__table { width: 100%; border-collapse: collapse; }
.ro__table th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
                color: #9298a2; font-weight: 700; padding: 10px 12px 10px 0;
                border-bottom: 1px solid var(--line); }
.ro__table td { padding: 12px 12px 12px 0; border-bottom: 1px solid #eff0f2; vertical-align: top; }

.ro__feed { list-style: none; margin: 0; padding: 0; }
.ro__feed li { padding: 11px 0 11px 16px; border-left: 2px solid var(--line); }
.ro__feed strong { font-weight: 600; }
.ro__feed span { display: block; }

/* One place that says what happens next, and it says the same thing the
   workshop row says about this car. */
.ro__step { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
            flex-wrap: wrap; padding: 18px 20px; background: var(--surface);
            border: 1px solid var(--line); border-left: 3px solid var(--accent);
            border-radius: var(--radius); }
.ro__step-label { display: block; font-size: 11px; text-transform: uppercase;
                  letter-spacing: .06em; color: var(--muted); font-weight: 700; margin-bottom: 4px; }
.ro__step strong { font-size: 16px; display: block; }

/* A job — the unit an RO is actually made of. */
.rj { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
      padding: 16px 18px; margin-bottom: 10px; }
.rj__head { display: flex; align-items: center; justify-content: space-between;
            gap: .75rem; margin-bottom: 8px; }
.rj__head h3 { margin: 0; font-size: 15px; font-weight: 600; }
.rj__note { margin: 0 0 8px; max-width: 62ch; }
.rj__why { margin: 0 0 8px; color: var(--muted); max-width: 62ch; }
.rj__money { display: grid; grid-template-columns: 1fr auto; gap: 5px 2rem;
             max-width: 280px; margin: 12px 0 0; font-size: 13px; }
.rj__money dt { color: var(--muted); }
.rj__money dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.rj__money .is-total { font-weight: 700; border-top: 1px solid var(--line); padding-top: 5px; }
.rj__tech { display: flex; align-items: center; gap: 8px; margin: 12px 0 0;
            font-size: 13px; color: var(--muted); }

@media (max-width: 720px) {
    .ro__facts { grid-template-columns: repeat(2, 1fr); }
    .ro__facts > div { border-bottom: 1px solid var(--line); }
}

/* ---------------------------------------------------------------------
   AI, as a surface rather than a personality

   One entry point in the header, one panel where a diagnosis is still
   open, one button where pricing happens. No gradients, no robot, no
   assistant following the cursor around.
   --------------------------------------------------------------------- */
.ro__head-right { display: flex; align-items: center; gap: 10px; }
.ro__ai { display: inline-flex; align-items: center; gap: 6px; background: var(--surface);
          border: 1px solid var(--line); border-radius: 8px; padding: 7px 12px;
          font: inherit; font-size: 13px; font-weight: 500; color: var(--ink-3); cursor: pointer; }
.ro__ai:hover { border-color: var(--accent); color: var(--accent); }
.ro__ai svg { color: var(--accent); }

/* Dashed, because what is inside is a suggestion and the border should
   say so before the text does. */
.ro__ai-panel { border: 1px dashed var(--line); border-radius: var(--radius);
                padding: 14px 16px; background: var(--bg); }
.ro__ai-state { margin: 0; font-size: 12px; color: var(--muted); }
.ro__ai-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 18px 0 0; }
.ro__ai-note { font-size: 12px; color: var(--muted); margin: 0; max-width: 52ch; }

/* The drawer, matching the one the default theme uses. */
.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(21,23,26,.10); }
.mate[hidden] { display: none; }
.mate__head { display: flex; align-items: center; justify-content: space-between;
              padding: 15px 18px; border-bottom: 1px solid var(--line); flex: none; }
.mate__head h2 { margin: 0; font-size: 14px; font-weight: 600; text-transform: none;
                 letter-spacing: 0; }
.mate__x { display: inline-flex; align-items: center; gap: 6px; background: var(--bg);
           border: 1px solid var(--line); color: var(--muted); font: inherit; font-size: 12px;
           font-weight: 600; padding: 6px 11px; border-radius: 7px; cursor: pointer; }
.mate__x:hover { background: #f1f2f4; color: var(--text); }
.mate__body { flex: 1; overflow-y: auto; padding: 18px; }
.mate__ask h3 { font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
                color: var(--muted); font-weight: 700; margin: 0 0 10px; }
.ask__form { display: flex; gap: 8px; margin-bottom: 10px; }
.ask__form input { flex: 1; min-width: 0; }
.ask__status { font-size: 13px; color: var(--muted); margin: 10px 0 0; }
.ask__answer { margin-top: 14px; padding: 14px; background: var(--bg);
               border-radius: var(--radius); font-size: 14px; line-height: 1.55; }
.ask__sources { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.ask__sources ul { margin: 0; padding-left: 1.1rem; font-size: 13px; }
.ask__sources li { margin-bottom: 4px; }
@media (min-width: 1200px) { body.ws-app.has-mate .wsx__main { padding-right: 24rem; } }

/* Editable header cells: a control that looks like the reading beside it
   until it is touched, so the strip still scans as one line. */
.ro__fact--edit { padding: 13px 15px; border-right: 1px solid var(--line); min-width: 0; }
.ro__fact--edit:last-child { border-right: 0; }
.ro__fact--edit span { display: block; font-size: 11px; color: var(--muted); margin-bottom: 3px; }
.ro__fact--edit form { margin: 0; }
.ro__fact--edit select,
.ro__fact--edit input { width: 100%; padding: 0; font: inherit; font-size: 14px; font-weight: 600;
                        color: var(--text); background: transparent; border: 0;
                        border-bottom: 1px dashed var(--line); border-radius: 0; }
.ro__fact--edit select:hover,
.ro__fact--edit input:hover { border-bottom-color: var(--accent); }
.ro__fact--edit input[type="datetime-local"] { font-size: 12.5px; }

/* The diagnosis form and the add-job row. */
.ro__dx { margin-top: 18px; max-width: 46rem; }
.ro__dx label { display: block; font-size: 12px; color: var(--muted); margin: 12px 0 4px; }
.ro__dx input[type="text"], .ro__dx textarea, .ro__dx select { width: 100%; }
.ro__dx-go { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.ro__addjob { display: flex; gap: 8px; margin-bottom: 18px; }
.ro__addjob input { flex: 1; min-width: 0; }
@media (pointer: coarse) { .ro__fact--edit select, .ro__fact--edit input { min-height: 40px; } }
/* A row that cannot be quoted against should say so where it is scanned. */
.wq__veh--none { color: var(--warn); }
.ro__missing { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
               flex-wrap: wrap; padding: 14px 18px; margin-bottom: 18px;
               background: var(--warn-bg); border: 1px solid #f2e2c8;
               border-radius: var(--radius); }
.ro__missing strong { display: block; }
.ro__missing span { font-size: 13px; color: var(--muted); }
.ro__missing form { display: flex; gap: 8px; margin: 0; }

/* Job lines: what the sum is made of. */
.rj__lines { width: 100%; border-collapse: collapse; margin: 12px 0 0; font-size: 13px; }
.rj__lines th { text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
                color: #9298a2; font-weight: 700; padding: 0 0 6px; border-bottom: 1px solid var(--line); }
.rj__lines th.num, .rj__lines td.num { text-align: right; font-variant-numeric: tabular-nums; }
.rj__lines td { padding: 7px 0; border-bottom: 1px solid #f1f2f4; }
.rj__lines tr:last-child td { border-bottom: 0; }
/* Where a number came from, next to the number. */
.rj__src { display: inline-block; margin-left: 6px; font-size: 10px; font-weight: 600;
           text-transform: uppercase; letter-spacing: .04em; color: var(--muted);
           background: var(--bg); border-radius: 4px; padding: 1px 5px; }

/* Capacities and fluids. A reference table, so it reads like one. */
.sp { width: 100%; border-collapse: collapse; }
.sp th { text-align: left; font-size: 12px; font-weight: 500; color: var(--muted);
         padding: 9px 16px 9px 0; border-bottom: 1px solid var(--line); white-space: nowrap;
         vertical-align: top; width: 10rem; }
.sp td { padding: 9px 0; border-bottom: 1px solid var(--line); font-weight: 600; }
.sp tr:last-child th, .sp tr:last-child td { border-bottom: 0; }
.sp__grade { display: block; font-weight: 500; color: var(--ink-3); font-size: 13px; margin-top: 2px; }
.sp__note { display: block; font-weight: 400; color: var(--muted); font-size: 12px; margin-top: 2px; }
/* A blank field is information, so it should look deliberate. */
.sp__none { font-weight: 500; color: var(--muted); font-style: italic; }
.sp__extra { margin: 14px 0 0; font-size: 13px; color: var(--ink-3); }
.sp__warn { margin: 12px 0 0; font-size: 13px; color: var(--warn); font-weight: 600; }
.sp__src { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.sp__src h3 { font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
              color: var(--muted); font-weight: 700; margin: 0 0 6px; }
.sp__src ul { margin: 0; padding-left: 1.1rem; font-size: 13px; }
.sp__again { margin: 14px 0 0; }
.sp__again button { background: none; border: 0; padding: 0; font: inherit; font-size: 13px;
                    color: var(--accent); cursor: pointer; text-decoration: underline; }
.ro__spec { display: grid; grid-template-columns: 9rem 1fr; gap: 8px 1rem; margin: 0; max-width: 40rem; }
.ro__spec dt { color: var(--muted); font-size: 13px; }
.ro__spec dd { margin: 0; font-weight: 500; }

/* ---------------------------------------------------------------------
   Editing a job in place
   ---------------------------------------------------------------------
   These controls shipped before their styles did, so every one of them
   fell through to a browser default or, worse, to the bare-submit rule
   above — which paints any submit without .btn-sm solid black. That is
   how a line-removal cross became a 60px black slab sitting in the
   totals column.

   The shape to aim for: a priced job is a document, and the controls for
   changing it should read as small marks on that document rather than as
   a form bolted underneath it. Nothing here should compete with the
   money for attention.
   --------------------------------------------------------------------- */

/* The hours cell becomes an input without becoming a form.
   Sized to the number it holds — four characters and a step arrow — so
   the column keeps its width and the totals stay lined up. */
.rj__edit { display: inline-block; margin: 0; }
.admin .rj__edit input[type="number"] {
    width: 4.75rem; padding: 4px 6px; margin: 0;
    font-size: 13px; font-variant-numeric: tabular-nums; text-align: right;
    border: 1px solid transparent; border-radius: 6px;
    background: transparent; color: inherit; font-family: var(--font);
}
/* Editable, but only obviously so once you go looking. A field that
   announces itself on every row turns a priced estimate into a form. */
.admin .rj__edit input[type="number"]:hover { border-color: var(--line); background: var(--bg); }
.admin .rj__edit input[type="number"]:focus {
    border-color: var(--accent); background: var(--surface);
    outline: 2px solid rgba(37, 99, 235, .15); outline-offset: 0;
}

/* Removing a line. Quiet until pointed at, and never wider than the
   column it sits in. */
.rj__lines th:last-child, .rj__lines td:last-child { width: 1%; padding-left: 8px; }
.admin .rj__x {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; padding: 0; line-height: 1;
    font-size: 15px; border: 0; border-radius: 6px;
    background: transparent; color: #b9bec7; box-shadow: none;
}
.admin .rj__x:hover { background: var(--danger-bg); color: var(--danger); border: 0; }

/* The foot of a job: add labour on the left, delete on the far right.
   The dashed rule separates editing from the figures above it without
   drawing a second hard box inside the card. */
.rj__actions {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line);
}
.rj__addline { display: flex; flex: 1 1 340px; gap: 6px; margin: 0; min-width: 0; }
.admin .rj__addline input[type="text"],
.admin .rj__addline input[type="number"] {
    margin: 0; padding: 7px 10px; font-size: 13px; font-family: var(--font);
    border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
}
.admin .rj__addline input[type="text"]  { flex: 1 1 auto; min-width: 0; }
.admin .rj__addline input[type="number"] { flex: 0 0 5.5rem; width: 5.5rem; text-align: right;
                                           font-variant-numeric: tabular-nums; }
.admin .rj__addline .btn-sm { flex: 0 0 auto; padding: 7px 12px; font-size: 13px; }

/* Deleting a whole job takes everything priced on it with it. That
   deserves to be reachable and not to look like the primary action, so
   it is a quiet outline that turns red on approach rather than a filled
   slab competing with the job total. */
.rj__del { margin: 0 0 0 auto; flex: 0 0 auto; }
.admin .rj__delbtn {
    padding: 7px 12px; font-size: 13px; font-weight: 500;
    background: transparent; border: 1px solid var(--line); color: var(--muted);
}
.admin .rj__delbtn:hover { background: var(--danger-bg); border-color: var(--danger);
                           color: var(--danger); }

/* A figure somebody overrode. Amber rather than grey: it is the one
   provenance mark that says a human disagreed with the source. */
.rj__src--edited { color: var(--warn); background: var(--warn-bg); }

@media (max-width: 720px) {
    .rj__addline { flex: 1 1 100%; flex-wrap: wrap; }
    .admin .rj__addline input[type="text"] { flex: 1 1 100%; }
    .rj__del { margin-left: 0; }
}

/* Touch: the theme already sets 44px minimums for coarse pointers, and
   these controls are small on purpose for a mouse. Give them the target
   without giving them the visual weight. */
@media (pointer: coarse) {
    .admin .rj__x { width: 44px; height: 44px; }
    .admin .rj__edit input[type="number"] { padding: 10px 8px; border-color: var(--line); }
}

/* The rate, editable in place like the hours beside it.
   The dollar sign sits outside the input so the figure inside stays a
   plain number — a currency symbol typed into a number field is a
   validation error waiting to happen. */
.rj__edit--rate { display: inline-flex; align-items: center; gap: 1px; }
.rj__cur { color: var(--muted); font-size: 13px; }
.admin .rj__edit--rate input[type="number"] { width: 5.25rem; }
@media (pointer: coarse) { .admin .rj__edit--rate input[type="number"] { width: 5.75rem; } }

/* ---------------------------------------------------------------------
   What you do with a finished estimate
   ---------------------------------------------------------------------
   Print, the technician's copy, and sending it for approval. The two
   prints are links because they open a document; sending is a form, and
   it is folded away because it is the one action here with a consequence
   the customer sees. Open by default it would sit under every estimate
   as a permanent block of checkboxes.
   --------------------------------------------------------------------- */
.ro__docs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.admin .ro__docs .btn-sm {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 8px 13px; font-size: 13px; text-decoration: none;
    border: 1px solid var(--line); background: var(--surface); color: var(--text);
}
.admin .ro__docs .btn-sm:hover { border-color: var(--ink-3); color: var(--text); }
.admin .ro__docs .ico-svg { color: var(--muted); }

.ro__send { margin-top: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
            background: var(--surface); }
.ro__send > summary {
    display: flex; align-items: center; gap: 8px; justify-content: space-between;
    padding: 11px 13px; cursor: pointer; font-weight: 600; font-size: 13px;
    list-style: none;
}
.ro__send > summary::-webkit-details-marker { display: none; }
/* A caret that turns, so the row reads as openable without a library. */
.ro__send > summary::after {
    content: ''; width: 7px; height: 7px; margin-left: auto; flex: 0 0 auto;
    border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
    transform: rotate(45deg); transition: transform var(--dur-fast) var(--ease-out);
}
.ro__send[open] > summary::after { transform: rotate(-135deg); }
.ro__send[open] > summary { border-bottom: 1px solid var(--line); }
.ro__send-body { padding: 13px; }
.ro__send-body .share__picks { display: grid; gap: 8px; margin-bottom: 12px; }
.ro__send-body .share__pick { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; }
.ro__send-body .share__other { margin-top: 12px; font-size: 13px; }
.ro__send-body .share__other summary { cursor: pointer; color: var(--muted); }
.admin .ro__send-body input[type="text"],
.admin .ro__send-body input[type="tel"],
.admin .ro__send-body input[type="email"] {
    width: 100%; padding: 8px 10px; font-size: 13px; font-family: var(--font);
    border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
}
.ro__send-body .form-actions { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.ro__send-body .hint { color: var(--muted); font-size: 12px; }

/* A document that cannot be produced yet, shown rather than hidden so the
   rule behind it is learnable. */
.admin .ro__docs .is-off { display: inline-flex; align-items: center; gap: 7px;
    padding: 8px 13px; font-size: 13px; border: 1px dashed var(--line);
    border-radius: 8px; background: transparent; color: #a8adb6; cursor: not-allowed; }
.ro__docs-why { flex: 1 1 100%; margin: 0; color: var(--muted); font-size: 12px; }

/* Sent → opened → signed. Three states, read left to right, with the ones
   that have not happened kept visible rather than hidden — "opened: not
   yet" is the useful fact, and an absent row says nothing. */
.ro__track { display: flex; flex-wrap: wrap; gap: 0; margin: 16px 0 0; padding: 0;
             list-style: none; border: 1px solid var(--line); border-radius: var(--radius-sm);
             overflow: hidden; background: var(--surface); }
.ro__track li { flex: 1 1 33%; min-width: 150px; padding: 10px 13px;
                border-right: 1px solid var(--line); }
.ro__track li:last-child { border-right: 0; }
.ro__track-k { display: block; font-size: 10px; font-weight: 700; letter-spacing: .05em;
               text-transform: uppercase; color: #9298a2; margin-bottom: 3px; }
.ro__track-v { display: block; font-size: 13px; color: var(--muted); }
.ro__track li.is-done .ro__track-k { color: var(--ok); }
.ro__track li.is-done .ro__track-v { color: var(--text); font-weight: 500; }
@media (max-width: 620px) {
    .ro__track li { flex: 1 1 100%; border-right: 0; border-bottom: 1px solid var(--line); }
    .ro__track li:last-child { border-bottom: 0; }
}

/* Inspection list: same table shape as the job lines, with the name
   column carrying a second line for who and when. */
.rj__lines--insp td { vertical-align: top; }
.rj__lines--insp .rj__src { display: block; margin: 3px 0 0; }
.rj__lines--insp a { color: inherit; }

/* The start-an-inspection row. Reuses the add-line form shape so the
   select and its button line up the way every other inline form on this
   screen does. */
.ro__actions-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px;
                   padding-top: 12px; border-top: 1px dashed var(--line); }
.ro__actions-row .rj__addline { flex: 0 1 auto; }
.admin .ro__actions-row select {
    padding: 7px 10px; font-size: 13px; font-family: var(--font);
    border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
}

/* Message tab: channel picker */
.ro-msg__channels { border: 1px solid var(--line); border-radius: var(--radius-sm);
                    padding: .7rem .9rem; margin: .9rem 0; }
.ro-msg__channels legend { padding: 0 .4rem; font-size: .75rem; font-weight: 600;
                           text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.ro-msg__channels label { display: flex; align-items: center; gap: .5rem; padding: .3rem 0;
                          font-size: .9rem; }
.ro-msg__channels input:disabled + * , .ro-msg__channels label:has(input:disabled) { color: var(--muted); }

/* Row actions on the workshop board */
.wq__more { width: 2.5rem; text-align: right; }
.rowmenu { position: relative; display: inline-block; }
.rowmenu summary { list-style: none; cursor: pointer; padding: .2rem .5rem; border-radius: var(--radius-sm);
                   color: var(--muted); font-weight: 700; letter-spacing: .1em; }
.rowmenu summary::-webkit-details-marker { display: none; }
.rowmenu summary:hover { background: var(--surface-3, #f3f4f6); color: var(--ink); }
/* Fixed, not absolute.
   
   The table scrolls horizontally and its wrapper clips overflow, so an
   absolutely positioned panel was cut off at the bottom of the row —
   which is exactly what a menu must never be. Fixed positioning escapes
   both, and the JS places it against the button. */
.rowmenu__panel { position: fixed; z-index: 200; min-width: 17rem; padding: .35rem;
                  border: 1px solid var(--line); border-radius: var(--radius);
                  background: var(--surface); box-shadow: 0 10px 30px rgba(0,0,0,.16);
                  text-align: left; }
/* Written to beat button[type="submit"], which sets a dark background
   globally and outranks a plain element selector. Every menu item was
   rendering as a black block because of it. Matching the attribute here
   puts them on equal specificity, and the class in front wins. */
.rowmenu__panel a,
.rowmenu__panel button,
.rowmenu__panel button[type="submit"] {
    display: block; width: 100%; margin: 0; padding: .55rem .65rem;
    border: 0; border-radius: var(--radius-sm);
    background: transparent; color: var(--ink);
    font: inherit; font-size: .88rem; font-weight: 500;
    text-align: left; text-decoration: none; cursor: pointer;
}

.rowmenu__panel a:hover,
.rowmenu__panel button:hover,
.rowmenu__panel button[type="submit"]:hover { background: var(--surface-2); color: var(--ink); }

.rowmenu__panel small { display: block; margin-top: .1rem; font-size: .75rem;
                        font-weight: 400; color: var(--muted); }

/* A thin rule before the actions that change something, so opening and
   printing are visibly not in the same category as cancelling. */
.rowmenu__panel form:first-of-type { margin-top: .25rem; padding-top: .25rem;
                                     border-top: 1px solid var(--line); }

/* The three actions, coloured by how much they take away.
   
   Green keeps everything, amber keeps the record, red keeps nothing.
   Colour on the text only — the background stays white throughout, so
   the menu reads as a list rather than a row of buttons, and the colour
   is doing one job: telling somebody how far the thing they are about
   to click goes.
   
   Each selector carries [type="submit"] to outrank the global button
   rule in admin.css. */
.rowmenu__panel button.is-keep[type="submit"] { color: var(--ok-strong); }
.rowmenu__panel button.is-warn[type="submit"] { color: var(--warn-strong); }
.rowmenu__panel button.is-bad[type="submit"],
.rowmenu__panel .is-bad                       { color: var(--danger-strong); }

/* Hover tints the row faintly in the same colour rather than filling
   it, which keeps the white background the point of the menu. */
.rowmenu__panel button.is-keep[type="submit"]:hover { background: var(--ok-soft);     color: var(--ok-strong); }
.rowmenu__panel button.is-warn[type="submit"]:hover { background: var(--warn-soft);   color: var(--warn-strong); }
.rowmenu__panel button.is-bad[type="submit"]:hover  { background: var(--danger-soft); color: var(--danger-strong); }

/* The small print under each stays readable rather than taking the
   full colour — three lines of coloured body text would be shouting. */
.rowmenu__panel .is-keep small,
.rowmenu__panel .is-warn small,
.rowmenu__panel .is-bad small { color: inherit; opacity: .7; }

/* On a phone the panel spans the width rather than hugging a button
   that is nearly at the screen edge. */
@media (max-width: 560px) {
    .rowmenu__panel { left: 8px !important; right: 8px !important; min-width: 0; }
}
