/* ============================================================
   REVMA SHELL — the one design system (Mission: final frontend)
   Visual direction: preview.revma.com.au (Inter, #E63946, soft ink)
   Every rv-* class the app uses is defined here, once.
   ============================================================ */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');

:root{
  /* THE OFFICIAL BRAND COLOURS, off the REVMA brand kit — Red #C1122E
     (Pantone 200 C) and Grey #8B9B91 (Pantone 443 C). The app had been running
     #E63946, a brighter, pinker red that is NOT the brand: printed signage,
     invoices and the website would never have matched the screen. These are the
     real values, and the logo artwork uses exactly the same two. */
  --rv-red:#C1122E; --rv-red-dark:#9c0f25; --rv-red-soft:#fbe9ec;
  --rv-grey:#8B9B91; --rv-grey-soft:#eef1ef;
  --rv-ink:#111827; --rv-ink-2:#1a1d23; --rv-navy:#0f172a;
  --rv-bg:#f6f7f9; --rv-card:#ffffff; --rv-line:#e5e7eb; --rv-soft:#f3f4f6;
  --rv-muted:#6b7280; --rv-green:#16a34a; --rv-orange:#f59e0b; --rv-blue:#2563eb;

  /* THE ACTION COLOUR — separate from the brand colour, on purpose.
     RED IS REVMA'S IDENTITY. It is not a good colour for the button you press
     forty times a day: red is the colour of stop, error and danger, so a screen
     whose every primary action is red reads as a screen full of alarms. Peter's
     words: "Red's angry."
     Blue is not an arbitrary substitute — it is the colour of the CONTINUE card
     on the Live Job screen, the one surface he has repeatedly said he likes. So
     pressing forward is blue everywhere, and red goes back to meaning REVMA
     (logo, nav, workspace badge) and genuine alarm (errors, overdue counts).
     Change --rv-action here and every forward action in the app follows. */
  --rv-action:#1f6feb; --rv-action-dark:#1a5fd0; --rv-action-soft:#eaf2fe;

  --rv-r-sm:10px; --rv-r:14px; --rv-r-lg:18px;
  --rv-shadow:0 1px 2px rgba(17,24,39,.05),0 8px 24px rgba(17,24,39,.06);
  --rv-shadow-lg:0 18px 50px rgba(17,24,39,.16);
  --rv-side-w:248px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body.rv-admin{font-family:'Inter',system-ui,-apple-system,sans-serif;background:var(--rv-bg);color:var(--rv-ink);font-size:15px;line-height:1.5;-webkit-font-smoothing:antialiased}
a{color:var(--rv-red);}
h1,h2,h3,h4{color:var(--rv-ink);letter-spacing:-.01em}

/* ---------- Shell layout ---------- */
.rv-shell{display:flex;min-height:100vh}
.rv-main{flex:1;min-width:0;display:flex;flex-direction:column}
.rv-content{padding:20px 22px;flex:1}
@media(max-width:820px){.rv-content{padding:14px 12px}}

/* ---------- Sidebar ---------- */
.rv-side{width:var(--rv-side-w);flex:none;background:var(--rv-card);border-right:1px solid var(--rv-line);display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow-y:auto}
.rv-side-brand{display:flex;align-items:center;gap:10px;padding:18px 16px 14px;border-bottom:1px solid var(--rv-line)}
.rv-side-brand img,.rv-logo img{height:34px}
.rv-logo{font-weight:800;font-size:1.15rem;color:var(--rv-ink);text-decoration:none;
  /* The logo is the way HOME from every screen, and it was a 34px target next
     to a 38px account button. Both are on every page he opens; both are now
     46px (Bible 96 section 3). The type size does not change -- only the
     area his thumb has to hit. */
  display:inline-flex;align-items:center;min-height:var(--rv-tap,46px)}
.rv-logo b,.rv-side-brand b{color:var(--rv-red)}
.rv-nav{padding:10px 8px;flex:1}
/* 46px MINIMUM. Bible 96 section 3: "He is standing at a counter holding a
   receipt." These were 42px and the sub-links 38px, so the whole menu was
   under the size his own rule sets. Not negotiable, and the same on the phone,
   the tablet and the desk -- one look. */
.rv-nav a{display:flex;align-items:center;gap:11px;padding:11px 12px;margin:1px 4px;border-radius:var(--rv-r-sm);color:var(--rv-ink);text-decoration:none;font-weight:600;font-size:.92rem;min-height:46px}
.rv-nav a svg{width:18px;height:18px;flex:none;color:var(--rv-muted)}
.rv-nav a:hover{background:var(--rv-soft);color:var(--rv-ink)}
.rv-nav a.active{background:var(--rv-red-soft);color:var(--rv-red);}
.rv-nav a.active svg{color:var(--rv-red)}
.rv-nav-group{margin:2px 4px;border:0;background:none}
.rv-nav-group summary{display:flex;align-items:center;gap:11px;padding:11px 12px;border-radius:var(--rv-r-sm);color:var(--rv-ink);font-weight:600;font-size:.92rem;cursor:pointer;list-style:none;min-height:46px}
.rv-nav-group summary::-webkit-details-marker{display:none}
.rv-nav-group summary:hover{background:var(--rv-soft)}
.rv-nav-group summary svg{width:18px;height:18px;color:var(--rv-muted)}
.rv-nav-group[open] summary{color:var(--rv-ink)}
.rv-nav-group-links{padding:2px 0 6px}
.rv-nav-group-links a{padding:11px 12px 11px 22px;min-height:46px;font-weight:500;font-size:.88rem}
.rv-nav-dot{width:8px;height:8px;border-radius:999px;background:var(--rv-red);flex:none}
.rv-nav-subdot{width:6px;height:6px;border-radius:999px;background:#cbd5e1;flex:none}
.rv-side-foot{border-top:1px solid var(--rv-line);padding:14px 16px}
.rv-who{font-weight:700;font-size:.92rem}
.rv-role{color:var(--rv-muted);font-size:.8rem;margin:2px 0 8px;text-transform:capitalize}
.rv-side-foot button{background:none;border:1px solid var(--rv-line);border-radius:999px;padding:7px 14px;font:inherit;font-size:.85rem;font-weight:600;color:var(--rv-ink);cursor:pointer}
.rv-side-foot button:hover{border-color:var(--rv-red);color:var(--rv-red)}
html.rv-nav-collapsed .rv-side{display:none}

/* ---------- Topbar ---------- */
.rv-topbar{background:var(--rv-card);position:sticky;top:0;z-index:60;display:flex;align-items:center;gap:14px;padding:10px 18px;background:rgba(255,255,255,.92);backdrop-filter:blur(8px);border-bottom:1px solid var(--rv-line)}
.rv-topbar h1{font-size:1.05rem;margin:0;font-weight:800}
.rv-flex{display:flex;align-items:center;gap:10px}
.rv-flex-between{display:flex;align-items:center;justify-content:space-between;gap:10px}
.rv-burger{background:none;border:0;cursor:pointer;color:var(--rv-ink);display:grid;place-items:center;width:38px;height:38px;border-radius:10px}
.rv-burger:hover{background:var(--rv-soft)}
.rv-top-search{min-width:260px;max-width:520px;flex:1}
.rv-top-search form,.rv-gsearch{display:flex;align-items:center;gap:8px;background:var(--rv-soft);border:1px solid var(--rv-line);border-radius:999px;padding:6px 8px}
.rv-top-search input,.rv-gsearch input{border:0;background:transparent;outline:0;width:100%;font:inherit;font-size:.9rem;color:var(--rv-ink);padding:2px 6px}
.rv-top-search button{border:0;background:var(--rv-action);color:#fff;border-radius:999px;padding:7px 14px;font-weight:700;font-size:.85rem;cursor:pointer}
.rv-top-search button:hover{background:var(--rv-action-dark)}
.rv-top-actions{margin-left:auto;display:flex;align-items:center;gap:8px}
/* 46px. Bible 96 section 3 -- and the token already exists, so use it. */
.rv-icon-btn{position:relative;display:grid;place-items:center;width:var(--rv-tap,46px);height:var(--rv-tap,46px);border-radius:999px;border:1px solid var(--rv-line);background:var(--rv-card);color:var(--rv-ink);text-decoration:none;cursor:pointer}
.rv-icon-btn:hover{border-color:#c7ccd6;background:var(--rv-soft)}
.rv-icon-btn .rv-notif-count{position:absolute;top:-4px;right:-4px;background:var(--rv-red);color:#fff;font-size:.68rem;font-weight:800;min-width:18px;height:18px;border-radius:999px;display:grid;place-items:center;padding:0 4px}
.rv-avatar{width:var(--rv-tap,46px);height:var(--rv-tap,46px);border-radius:999px;background:var(--rv-ink);color:#fff;display:grid;place-items:center;font-weight:800;font-size:.9rem;text-decoration:none}
.rv-quick-actions{position:relative}
.rv-quick-actions summary{width:42px;height:42px;border-radius:999px;background:var(--rv-action);color:#fff;display:grid;place-items:center;font-size:24px;font-weight:800;line-height:1;cursor:pointer;list-style:none;box-shadow:0 10px 24px rgba(31,111,235,.28)}
.rv-quick-actions summary::-webkit-details-marker{display:none}
.rv-quick-menu{position:absolute;right:0;top:calc(100% + 8px);z-index:80;min-width:240px;background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r);box-shadow:var(--rv-shadow-lg);padding:8px}
.rv-quick-menu a{display:block;padding:11px 12px;border-radius:var(--rv-r-sm);color:var(--rv-ink);text-decoration:none;font-weight:700;font-size:.9rem}
.rv-quick-menu small{display:block;color:var(--rv-muted);font-weight:500;margin-top:2px;font-size:.78rem}
.rv-quick-menu a:hover{background:var(--rv-soft)}
.rv-preview-pill{background:var(--rv-red-soft);color:var(--rv-red);font-size:.68rem;font-weight:800;letter-spacing:.06em;padding:4px 10px;border-radius:999px;flex:none}

/* ---------- Cards & stats ---------- */
.rv-card{background:var(--rv-card);border:1px solid var(--rv-line);border-radius:var(--rv-r);padding:16px 18px;box-shadow:var(--rv-shadow)}
.rv-card h2,.rv-card h3{margin-top:0;font-size:1rem}
.rv-stat{background:var(--rv-card);border:1px solid var(--rv-line);border-radius:var(--rv-r);padding:16px}
.rv-stat-num{font-size:1.7rem;font-weight:800;letter-spacing:-.02em}
.rv-stat-lbl{color:var(--rv-muted);font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em}
.rv-stat-alert .rv-stat-num{color:var(--rv-red)}
.rv-stat-row{display:flex;justify-content:space-between;gap:10px;padding:7px 0;border-bottom:1px solid var(--rv-soft);font-size:.92rem}
.rv-action-card{display:block;background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r);padding:14px;text-decoration:none;color:var(--rv-ink)}
.rv-action-card b{font-size:.9rem}.rv-action-card span{font-size:.8rem;color:var(--rv-muted);display:block;margin-top:3px;line-height:1.35}
.rv-action-card:hover{border-color:#c8d0dd;box-shadow:var(--rv-shadow-lg)}
.rv-action-row,.rv-actions-row{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* ---------- Grids ---------- */
.rv-grid{display:grid;gap:14px}
.rv-grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.rv-grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.rv-grid-4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media(max-width:1080px){.rv-grid-4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:820px){.rv-grid-2,.rv-grid-3,.rv-grid-4{grid-template-columns:1fr}}

/* ---------- Buttons ---------- */
.rv-btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;border-radius:999px;border:1px solid transparent;
  padding:10px 18px;font:inherit;font-size:.9rem;font-weight:700;cursor:pointer;text-decoration:none;min-height:40px;line-height:1.2}
.rv-btn-primary{background:var(--rv-action);color:#fff}
.rv-btn-primary:hover{background:var(--rv-action-dark)}
.rv-btn-secondary{background:var(--rv-soft);color:var(--rv-ink);border-color:var(--rv-line)}
.rv-btn-secondary:hover{background:#e9ebef}
.rv-btn-navy{background:var(--rv-action-soft);color:var(--rv-action-dark);border-color:rgba(31,111,235,.28)}
.rv-btn-navy:hover{background:#dbe8fd}
.rv-btn-ghost{background:var(--rv-card);color:var(--rv-ink);border-color:var(--rv-line)}
.rv-btn-ghost:hover{border-color:#c7ccd6;background:var(--rv-soft)}
.rv-btn-sm{padding:7px 13px;font-size:.83rem;min-height:34px}
.rv-btn[disabled]{opacity:.5;cursor:not-allowed}
/* 46, not 44 -- the phone is the one place the rule matters most. */
@media(max-width:820px){.rv-btn{min-height:var(--rv-tap,46px)}.rv-btn-sm{min-height:38px}}

/* ---------- Inline links inside forms ----------
   Measured on production 19 Aug 2026: "open a full customer file" was 15px and
   the project "Back" was 21px. Bible 96 is 46px on anything he taps, and an
   inline link in a form is a thing he taps. */
.rv-field small a, .rv-muted a, a.rv-muted, a.rv-backlink{
  display:inline-flex;align-items:center;min-height:var(--rv-tap,46px);
  padding:0 4px;text-decoration:underline;text-underline-offset:3px}

/* ---------- Customer picker ----------
   One box on every doorway. Rows are 46px+ because he picks a client standing
   in a plant room with one thumb. */
.cp-q{width:100%}
.cp-results{margin-top:8px;display:flex;flex-direction:column;gap:6px}
.cp-row{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;
  min-height:var(--rv-tap,46px);padding:9px 13px;text-align:left;cursor:pointer;
  border:1px solid var(--rv-line);border-radius:var(--rv-r-sm);background:var(--rv-card,#fff)}
.cp-row:hover,.cp-row:focus{border-color:var(--rv-red);outline:none}
.cp-row-name{font-weight:700;font-size:.95rem;line-height:1.25}
.cp-row-meta{font-size:.82rem;opacity:.75;line-height:1.25}
.cp-picked{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.cp-chip{flex:1 1 auto;min-height:var(--rv-tap,46px);display:flex;flex-direction:column;
  justify-content:center;padding:7px 14px;border-radius:var(--rv-r-sm);
  border:1px solid var(--rv-green,#1c7c3c);background:rgba(28,124,60,.08)}
.cp-chip-name{font-weight:750}
.cp-chip-meta{font-size:.82rem;opacity:.75}

/* ---------- Pagination ----------
   The REVMA paginator view (resources/views/vendor/pagination/revma.blade.php)
   replaced Laravel's Tailwind one and gave its buttons .rv-pager-btn -- but the
   rule was never written, so "Older ->" rendered as bare inline text: 19px at
   BOTH 412 and 1920, measured on production 19 Aug 2026. Bible 96 section 3 is
   46px on anything he taps, and the pager sits at the bottom of a 3,092-row list. */
.rv-pager{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-top:4px}
.rv-pager-btn{display:inline-flex;align-items:center;justify-content:center;
  min-height:var(--rv-tap,46px);padding:0 16px;border:1px solid var(--rv-line);
  border-radius:var(--rv-r-sm);background:var(--rv-card,#fff);color:var(--rv-ink);
  font-weight:650;font-size:.9rem;text-decoration:none}
.rv-pager-btn.is-off{opacity:.45;cursor:not-allowed}
.rv-pager-count{font-size:.88rem;opacity:.75}
@media(max-width:520px){
  /* One thumb: both buttons stay full-size and the count drops under them
     rather than squeezing three things onto a 412px line. */
  .rv-pager-btn{flex:1 1 auto}
  .rv-pager-count{flex:1 0 100%;order:3;text-align:center}
}

/* ---------- Forms ---------- */
.rv-input,select.rv-input,textarea.rv-input,.ct-input,.ct-select,.ct-textarea{width:auto;padding:10px 13px;border:1px solid var(--rv-line);border-radius:var(--rv-r-sm);
  font:inherit;font-size:.92rem;color:var(--rv-ink);background:#fff;outline:0}
.rv-input:focus,.ct-input:focus,.ct-select:focus,.ct-textarea:focus{border-color:var(--rv-action);box-shadow:0 0 0 3px rgba(31,111,235,.14)}
.rv-input-sm{padding:7px 10px;font-size:.85rem}
.rv-field{margin-bottom:14px}
.rv-field label,.rv-lbl,.rv-label{display:block;font-weight:700;font-size:.86rem;margin-bottom:5px;color:var(--rv-ink)}
.rv-hint,.rv-tip{color:var(--rv-muted);font-size:.8rem}
.rv-err{color:var(--rv-red);font-size:.83rem}
.rv-ok{color:var(--rv-green)}
.rv-req{color:var(--rv-red)}
.rv-mb0{margin-bottom:0}

/* ---------- Tables ---------- */
.rv-table{width:100%;border-collapse:collapse;font-size:.9rem}
.rv-table th{background:var(--rv-soft);color:var(--rv-ink);text-align:left;padding:10px 12px;font-size:.76rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--rv-line)}
.rv-table td{padding:11px 12px;border-bottom:1px solid var(--rv-soft);vertical-align:top}
.rv-table tr:hover td{background:#fafbfc}
.rv-right{text-align:right}
.rv-ref{font-weight:800;color:var(--rv-red);text-decoration:none}

/* ---------- Badges & alerts ---------- */
/* BADGE TRIO — background + text + MATCHING BORDER, not a tinted pill floating
   on white. The border is what makes a status readable at a glance rather than
   read-then-understood: the eye catches an outlined shape before it reads the
   word. The colours stay REVMA's existing ones — they are already within a hair
   of the reference palette — so only the border is new. Nothing that uses these
   classes today changes meaning, and inline-flex + gap lets a dot or icon sit
   inside the badge without the caller adding spacing hacks. */
.rv-badge{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:999px;font-size:.74rem;font-weight:700;background:var(--rv-soft);color:var(--rv-ink);border:1px solid var(--rv-line)}
.rv-badge-green{background:#e5f6ec;color:#137a3e;border-color:#c3e9d3}
.rv-badge-grey{background:var(--rv-soft);color:var(--rv-muted);border-color:var(--rv-line)}
.rv-badge-amber{background:#fef3e2;color:#b45309;border-color:#f7ddb4}
.rv-badge-red{background:var(--rv-red-soft);color:var(--rv-red);border-color:rgba(230,57,70,.32)}
.rv-badge-blue{background:#e8effd;color:#1d4ed8;border-color:#c9d8fb}
.rv-alert{padding:12px 15px;border-radius:var(--rv-r-sm);font-size:.9rem;font-weight:600;border:1px solid transparent}
.rv-alert-green{background:#e5f6ec;border-color:#bfe8cf;color:#137a3e}
.rv-alert-red{background:var(--rv-red-soft);border-color:#f6c6cb;color:#a4232f}

/* ---------- Text colours ---------- */
.rv-muted{color:var(--rv-muted)}
.rv-ink{color:var(--rv-ink)}.rv-red{color:var(--rv-red)}.rv-green{color:var(--rv-green)}
.rv-orange{color:var(--rv-orange)}.rv-blue{color:var(--rv-blue)}.rv-navy{color:var(--rv-navy)}
.rv-soft{color:var(--rv-muted)}
.rv-sub{color:var(--rv-muted);font-size:.85rem}
.rv-line{border-top:1px solid var(--rv-line);margin:12px 0}

/* ---------- Command bar & steps ---------- */
/* Soft command bar — light shell on the page, not a dark navy slab.
   Same layout/spacing; only the skin changed. Titles/actions read dark. */
.rv-command-bar{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;background:#f8fafc;color:var(--rv-ink);border:1px solid var(--rv-line);border-radius:var(--rv-r-lg);padding:18px 20px;box-shadow:var(--rv-shadow)}
.rv-command-bar h1,.rv-command-bar h2,.rv-command-title{color:var(--rv-ink);margin:0;font-size:1.15rem;font-weight:800}
.rv-command-sub{color:var(--rv-muted);font-size:.88rem;margin-top:4px}
/* NIGHT MODE: the command panel was white text on a white panel.
   .rv-command-bar hardcodes background:#f8fafc while its colour comes from
   var(--rv-ink), which flips to near-white under .rv-theme-dark -- so the
   background stayed light and the text went pale with it, leaving the
   introduction unreadable. The background must follow the theme too.
   Fixed in the shared stylesheet rather than on one page: this partial is
   included by six screens and all six had it. */
body.rv-theme-dark .rv-command-bar{background:#171b22;border-color:#232a35;color:#e5e7eb}
body.rv-theme-dark .rv-command-sub{color:#9aa1ab}
.rv-command-bar .rv-btn-ghost{background:#fff;border-color:var(--rv-line);color:var(--rv-ink)}
.rv-command-bar .rv-btn-ghost:hover{background:var(--rv-soft);border-color:#c7ccd6}
.rv-workflow-steps{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}
.rv-step{border:1px solid var(--rv-line);border-radius:var(--rv-r-sm);background:#fff;padding:11px 12px}
.rv-step strong{display:block;font-size:.82rem}
.rv-step span{display:block;color:var(--rv-muted);font-size:.75rem;margin-top:3px;line-height:1.25}
.rv-step.is-next{border-color:rgba(31,111,235,.4);box-shadow:inset 3px 0 0 var(--rv-action)}
.rv-steprow{display:flex;gap:10px;align-items:center}

/* ---------- Timeline / health / misc ---------- */
.rv-timeline{display:flex;flex-direction:column;gap:10px}
.rv-timeline-row{display:grid;grid-template-columns:18px minmax(0,1fr) auto;gap:10px;align-items:start;padding:12px;border:1px solid var(--rv-line);border-radius:var(--rv-r-sm);background:#fff}
.rv-timeline-dot{width:10px;height:10px;border-radius:50%;background:var(--rv-blue);margin-top:5px}
.rv-timeline-row.urgent .rv-timeline-dot{background:var(--rv-red)}
.rv-timeline-row.done .rv-timeline-dot{background:var(--rv-green)}
.rv-timeline-row.warn .rv-timeline-dot{background:var(--rv-orange)}
.rv-health-strip{display:flex;gap:8px;flex-wrap:wrap}
.rv-health-top{display:flex;justify-content:space-between;align-items:center;gap:10px}
.rv-health-item{display:flex;align-items:center;gap:8px;background:#fff;border:1px solid var(--rv-line);border-radius:999px;padding:7px 12px;font-size:.85rem;font-weight:600}
.rv-dot{display:inline-block;width:9px;height:9px;border-radius:999px;background:#9ca3af}
.rv-photo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:10px}
.rv-photo-grid img{width:100%;border-radius:var(--rv-r-sm);border:1px solid var(--rv-line)}
.rv-cal-wrap{background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r);padding:10px}
.rv-control-shell{max-width:1280px;margin:0 auto}
.rv-sig-canvas{border:2px dashed var(--rv-line);border-radius:var(--rv-r-sm);background:#fff;touch-action:none}
.rv-back{color:var(--rv-muted);text-decoration:none;font-size:.88rem;
  /* BACK WAS 16px TALL. It is on the top of nearly every screen he uses and it
     was the smallest thing on the page -- Bible 96 section 3, 46px minimum on
     anything he taps, and this is the control he reaches for one-handed when a
     screen turns out to be the wrong one. Inline-flex so the text stays where
     it was and only the TARGET grows. */
  display:inline-flex;align-items:center;min-height:var(--rv-tap,46px);padding:4px 2px}
.rv-acts{display:flex;gap:8px;flex-wrap:wrap}
.rv-resend{font-size:.85rem}
.rv-remember{display:flex;align-items:center;gap:8px;font-size:.9rem}

/* ---------- Login ---------- */
.rv-login{max-width:400px;margin:8vh auto;background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r-lg);padding:26px;box-shadow:var(--rv-shadow-lg)}
.rv-login-head{text-align:center;margin-bottom:18px}

/* ---------- Project tabs / tables reuse ---------- */
.project-table{width:100%;border-collapse:collapse;font-size:.9rem}
.project-table th{background:var(--rv-soft);text-align:left;padding:9px 11px;font-size:.75rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--rv-line)}
.project-table td{padding:10px 11px;border-bottom:1px solid var(--rv-soft)}
.project-link{color:var(--rv-red);font-weight:700;text-decoration:none}
.muted-small{color:var(--rv-muted);font-size:.8rem}

/* ---------- Mobile ---------- */
@media(max-width:820px){
  .rv-side{position:fixed;left:0;top:0;bottom:0;z-index:100;transform:translateX(-105%);transition:transform .2s;box-shadow:var(--rv-shadow-lg);height:100dvh}
  .rv-side.open{transform:translateX(0)}
  .rv-topbar{background:var(--rv-card);padding:8px 10px}
  .rv-top-search{display:none}
  .rv-quick-actions{position:fixed;right:16px;bottom:16px;z-index:90}
  .rv-quick-actions summary{width:54px;height:54px;font-size:28px}
  .rv-quick-menu{position:fixed;top:auto;bottom:80px;right:16px;left:16px;min-width:0}
  .rv-command-bar{grid-template-columns:1fr}
  .rv-workflow-steps{grid-template-columns:1fr 1fr}
  .rv-table{font-size:.85rem}
  .rv-content h1{font-size:1.1rem}
}

/* ---------- Dark theme hook (kept minimal) ---------- */
body.rv-theme-dark{background:#101318;color:#e5e7eb}
body.rv-theme-dark .rv-card,body.rv-theme-dark .rv-stat{background:#171b22;border-color:#232a35}
body.rv-theme-dark .rv-side,body.rv-theme-dark .rv-topbar{background:var(--rv-card);background:#12161d;border-color:#232a35}
body.rv-theme-dark .rv-nav a{color:#c6cbd4}

/* ============================================================
   RVX — the NEW EXPERIENCE layer (Mission 014)
   Card-based module pages in the preview.revma.com.au language:
   stat tiles, filter pills, rich entity cards with row actions.
   Reused by every module list page — one design system.
   ============================================================ */
.rvx-wrap{max-width:1180px;margin:0 auto}
.rvx-head{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:14px;margin-bottom:20px}
.rvx-head h1{font-size:1.7rem;font-weight:800;margin:0;letter-spacing:-.02em}
.rvx-head p{color:var(--rv-muted);margin:4px 0 0;font-size:.92rem;max-width:640px}
.rvx-head-actions{display:flex;gap:8px;flex-wrap:wrap}

.rvx-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:20px}
.rvx-tile{background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r);padding:15px 16px;box-shadow:var(--rv-shadow)}
.rvx-tile .lbl{font-size:.8rem;color:var(--rv-muted);font-weight:600}
.rvx-tile .num{font-size:1.6rem;font-weight:800;margin-top:3px;letter-spacing:-.02em;color:var(--rv-ink)}
.rvx-tile.is-red .num{color:var(--rv-red)}
.rvx-tile.is-green .num{color:var(--rv-green)}
.rvx-tile.is-blue .num{color:var(--rv-blue)}
.rvx-tile.is-amber .num{color:var(--rv-orange)}

.rvx-toolbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:16px}
.rvx-search{flex:1;min-width:240px;display:flex;align-items:center;gap:8px;background:#fff;border:1px solid var(--rv-line);border-radius:999px;padding:9px 14px}
.rvx-search input{border:0;outline:0;background:transparent;font:inherit;font-size:.92rem;width:100%;color:var(--rv-ink)}
/* IT WRAPS. Bible 96 section 3, in his own words: "No horizontal scrollers on
   anything he has to choose from. A menu that hides its own contents off the
   right edge is a guessing game." These pills are the filter and the sort --
   the two things he chooses from most on a list -- and at 412 the last one sat
   off the edge of the screen. Every pill is now visible without flicking. */
.rvx-pills{display:flex;flex-wrap:wrap;gap:8px;padding-bottom:2px}
/* 46px: these are things he taps standing up. Bible 96 section 3. */
.rvx-pill{display:inline-flex;align-items:center;min-height:46px;border:1px solid var(--rv-line);background:#fff;color:var(--rv-muted);border-radius:999px;padding:8px 16px;font:inherit;font-size:.86rem;font-weight:700;white-space:nowrap;cursor:pointer;text-decoration:none}
.rvx-pill:hover{background:var(--rv-soft)}
.rvx-pill.is-active{background:var(--rv-action-soft);border-color:rgba(31,111,235,.35);color:var(--rv-action-dark)}

.rvx-cards{display:flex;flex-direction:column;gap:14px}
.rvx-card{background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r);box-shadow:var(--rv-shadow);overflow:hidden;cursor:pointer;transition:box-shadow .15s,border-color .15s}
.rvx-card:hover{box-shadow:var(--rv-shadow-lg);border-color:#d6dbe4}
.rvx-card-body{padding:18px 20px}
.rvx-card-top{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:16px}
.rvx-card-lead{flex:1;min-width:200px}
.rvx-badges{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.rvx-status{display:inline-flex;align-items:center;gap:5px;padding:3px 11px;border-radius:999px;font-size:.74rem;font-weight:700;color:#fff}
.rvx-s-draft{background:#6b7280}.rvx-s-sent{background:var(--rv-blue)}.rvx-s-partial{background:var(--rv-orange)}
.rvx-s-paid{background:var(--rv-green)}.rvx-s-overdue{background:var(--rv-red)}.rvx-s-void{background:#374151}
.rvx-s-open{background:#6b7280}.rvx-s-accepted{background:var(--rv-green)}.rvx-s-declined{background:#374151}
.rvx-num{font-size:.82rem;color:var(--rv-muted);font-weight:600}
.rvx-card-name{font-size:1.15rem;font-weight:800;color:var(--rv-ink);margin:0 0 4px}
.rvx-meta{display:flex;flex-wrap:wrap;gap:14px;color:var(--rv-muted);font-size:.85rem}
.rvx-meta span{display:inline-flex;align-items:center;gap:5px}
.rvx-figures{display:grid;grid-template-columns:repeat(3,auto);gap:18px;text-align:left}
.rvx-figures .k{color:var(--rv-muted);font-size:.78rem;font-weight:600}
.rvx-figures .v{font-weight:700;color:var(--rv-ink);font-size:.92rem;margin-top:2px}
.rvx-figures .v.big{font-size:1.3rem;font-weight:800;color:var(--rv-red)}
.rvx-card-actions{margin-top:16px;padding-top:14px;border-top:1px solid var(--rv-soft);display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}
.rvx-empty{background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r);padding:48px 24px;text-align:center;box-shadow:var(--rv-shadow)}
.rvx-empty .ico{font-size:2.4rem;margin-bottom:10px}
.rvx-empty h3{margin:0 0 6px;font-size:1.2rem}
.rvx-empty p{color:var(--rv-muted);margin:0 0 18px}
.rvx-none{display:none;text-align:center;color:var(--rv-muted);padding:30px}
@media(max-width:820px){
  .rvx-head h1{font-size:1.35rem}
  .rvx-card-top{flex-direction:column}
  .rvx-figures{grid-template-columns:1fr 1fr;gap:12px}
  .rvx-card-actions{justify-content:stretch}
  .rvx-card-actions .rv-btn{flex:1}
}

/* ============================================================
   RVX PROJECT FOLDER — the digital job folder experience (Mission 014)
   Projects are the centre; this makes opening one feel like opening
   a complete job folder: status front and centre, money as tiles,
   traffic lights, and a first-class timeline.
   ============================================================ */
.rvx-folder{background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r-lg);box-shadow:var(--rv-shadow);overflow:hidden;margin-bottom:16px}
.rvx-folder-top{display:flex;flex-wrap:wrap;gap:16px;justify-content:space-between;padding:20px 22px}
.rvx-folder-kicker{font-size:.74rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--rv-muted)}
.rvx-folder-title{font-size:1.7rem;font-weight:800;letter-spacing:-.02em;margin:4px 0 8px;color:var(--rv-ink)}
.rvx-folder-meta{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.rvx-chip{display:inline-flex;align-items:center;gap:6px;background:var(--rv-soft);border-radius:999px;padding:5px 12px;font-size:.82rem;font-weight:700;color:var(--rv-ink)}
/* A CHIP HE CAN TAP IS A BUTTON. On the job report the customer, the site
   address and Documents are chips that navigate, and they were 30px tall --
   Bible 96 section 3. A chip that is only a label keeps its size; only the
   ones that are links grow. */
a.rvx-chip{min-height:var(--rv-tap,46px)}
.rvx-folder-actions{display:flex;flex-wrap:wrap;gap:8px;align-content:flex-start}
.rvx-status-banner{display:flex;align-items:center;gap:10px;padding:13px 22px;font-weight:700;font-size:.95rem;border-top:1px solid var(--rv-line)}
.rvx-status-banner .lt{width:12px;height:12px;border-radius:999px;flex:none}
.rvx-status-banner .nx{color:var(--rv-muted);font-weight:600}
.rvx-sb-green{background:#f0fdf4}.rvx-sb-green .lt{background:var(--rv-green)}
.rvx-sb-yellow{background:#fffbeb}.rvx-sb-yellow .lt{background:var(--rv-orange)}
.rvx-sb-red{background:var(--rv-red-soft)}.rvx-sb-red .lt{background:var(--rv-red)}
.rvx-sb-grey{background:var(--rv-soft)}.rvx-sb-grey .lt{background:#9ca3af}

.rvx-split{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:16px;margin-bottom:16px}
@media(max-width:1000px){.rvx-split{grid-template-columns:1fr}}
.rvx-traffic{display:flex;flex-direction:column;gap:8px}
.rvx-traffic-row{display:grid;grid-template-columns:14px 1fr;gap:10px;align-items:start;background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r-sm);padding:11px 13px}
.rvx-traffic-row .lt{width:11px;height:11px;border-radius:999px;margin-top:4px}
.rvx-traffic-row strong{display:block;font-size:.9rem;color:var(--rv-ink)}
.rvx-traffic-row span{display:block;font-size:.82rem;color:var(--rv-muted);margin-top:1px}
.lt-green{background:var(--rv-green)}.lt-yellow{background:var(--rv-orange)}.lt-red{background:var(--rv-red)}.lt-grey{background:#9ca3af}

/* pill tabs (keep .project-tab / .project-panel class names + existing JS) */
.project-tabs{display:flex;gap:8px;overflow-x:auto;margin:4px 0 18px;padding-bottom:4px;border-bottom:0}
.project-tab{border:1px solid var(--rv-line);background:#fff;border-radius:999px;padding:9px 16px;font-weight:700;font-size:.86rem;color:var(--rv-muted);white-space:nowrap;cursor:pointer;transition:all .12s}
.project-tab:hover{background:var(--rv-soft)}
.project-tab.on{background:var(--rv-action-soft);border-color:rgba(31,111,235,.35);color:var(--rv-action-dark)}

/* first-class timeline */
.rvx-tl{position:relative;padding-left:8px}
.rvx-tl-row{position:relative;display:grid;grid-template-columns:16px 1fr;gap:14px;padding:0 0 16px}
.rvx-tl-row:not(:last-child)::before{content:"";position:absolute;left:7px;top:16px;bottom:0;width:2px;background:var(--rv-line)}
.rvx-tl-dot{width:14px;height:14px;border-radius:999px;margin-top:3px;border:3px solid #fff;box-shadow:0 0 0 1px var(--rv-line)}
.rvx-tl-card{background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r-sm);padding:11px 14px}
.rvx-tl-when{font-size:.78rem;color:var(--rv-muted);font-weight:600}
.rvx-tl-title{font-weight:700;color:var(--rv-ink);text-decoration:none;display:inline-block;margin:2px 0}
.rvx-tl-title:hover{color:var(--rv-red)}
.rvx-tl-detail{font-size:.84rem;color:var(--rv-muted)}

/* ---- RVX editor: Edit | Preview | Send experience (quotes, invoices) ---- */
.rvx-ehead{background:#fff;border:1px solid var(--rv-line);border-radius:var(--rv-r-lg);box-shadow:var(--rv-shadow);padding:16px 18px;margin-bottom:16px}
.rvx-ehead-top{display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;align-items:flex-start}
.rvx-ehead h1{font-size:1.35rem;font-weight:800;margin:6px 0 6px;letter-spacing:-.02em}
.rvx-tabs2{display:flex;gap:8px;margin-top:14px;overflow-x:auto}
.rvx-etab{border:1px solid var(--rv-line);background:#fff;border-radius:999px;padding:9px 22px;font:inherit;font-weight:700;font-size:.9rem;color:var(--rv-muted);cursor:pointer;white-space:nowrap}
.rvx-etab:hover{background:var(--rv-soft)}
.rvx-etab.on{background:var(--rv-action-soft);border-color:rgba(31,111,235,.35);color:var(--rv-action-dark)}
.rvx-epanel{display:none}
.rvx-epanel.on{display:block}
.rvx-sendcard{max-width:640px}

/* ============================================================
   RV-FLOW — the directional chevron strip.
   ------------------------------------------------------------
   Peter's rule made visible: "no stoppages, no thinking, keep
   flowing." Pills tell you WHERE you are; arrows tell you which
   way the work goes. That is the whole difference, and it is why
   this exists alongside the existing pill strips rather than
   replacing them — a progress strip you can scrub is navigation,
   this is direction.

   Deliberately NOT a new colour system: done/current/todo map
   onto the same green / blue-accent / grey the traffic lights
   already use, so a chevron and a badge for the same step can
   never disagree. Horizontal scroll on small screens instead of
   wrapping, because a broken zig-zag reads as two rows of steps
   rather than one path.
   ============================================================ */
.rv-flow{display:flex;align-items:center;gap:6px;overflow-x:auto;padding:2px 0 6px;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.rv-flow::-webkit-scrollbar{display:none}
.rv-flow-step{display:inline-flex;align-items:center;gap:7px;flex:0 0 auto;white-space:nowrap;
  padding:9px 14px;min-height:40px;border-radius:var(--rv-r-sm);border:1px solid var(--rv-line);
  background:var(--rv-soft);color:var(--rv-muted);font-size:.84rem;font-weight:700;text-decoration:none}
.rv-flow-step:hover{background:#e9ebef}
/* DONE — green, and it carries a tick so the state survives being
   photographed, printed, or looked at by someone colour-blind. */
.rv-flow-step.is-done{background:#e5f6ec;border-color:#c3e9d3;color:#137a3e}
/* CURRENT — the one place to look. Ring, not fill: a solid block here
   competes with the Next Step card, which must stay the loudest thing. */
.rv-flow-step.is-current{background:#fff;border-color:var(--rv-blue);color:#1d4ed8;box-shadow:0 0 0 3px rgba(37,99,235,.14)}
/* ATTENTION — amber never blocks. It is a step dealt with but not
   completed, and it must read as "keep going", not as a wall. */
.rv-flow-step.is-attention{background:#fef3e2;border-color:#f7ddb4;color:#b45309}
.rv-flow-arrow{flex:0 0 auto;color:#c3c8d0;font-weight:800;font-size:1rem;line-height:1;user-select:none}
.rv-flow-step .rv-flow-n{opacity:.6;font-weight:800}
@media(max-width:820px){
  .rv-flow-step{min-height:44px;padding:10px 14px}   /* thumb target on a phone */
}

/* ============================================================
   DAY BRIGHTNESS — the light-mode half of the contrast control.
   ------------------------------------------------------------
   Night already had three levels (soft / standard / high). Day had
   exactly one, and it was the brightest one: a near-white page on a
   bright screen, which is what Peter means by "the day is a bit
   bright". These give day the same three levels night has.

   Only the SURFACES move — page, cards, lines, and how hard the
   shadows land. Text stays at full strength: dimming the page and
   dimming the words are different things, and the second one makes
   a screen harder to read, not easier.
   ============================================================ */
/* DIM — the page recedes, cards stay white so they still lift off it. */
body.rv-admin:not(.rv-theme-dark)[data-rv-day="dim"]{
  --rv-bg:#e9ecf1; --rv-card:#fdfdfe; --rv-line:#d8dde5; --rv-soft:#eceff4;
  --rv-shadow:0 1px 2px rgba(17,24,39,.06),0 8px 24px rgba(17,24,39,.08);
}
body.rv-admin:not(.rv-theme-dark)[data-rv-day="dim"] .rv-side,
body.rv-admin:not(.rv-theme-dark)[data-rv-day="dim"] .rv-topbar{background:var(--rv-card);background:#fbfcfd}
body.rv-admin:not(.rv-theme-dark)[data-rv-day="dim"] .rv-command-bar{background:#eef1f6}

/* SOFT — dimmer again, and the cards come off pure white too. This is
   the one for a bright office or a screen turned up. */
body.rv-admin:not(.rv-theme-dark)[data-rv-day="soft"]{
  --rv-bg:#dee3ea; --rv-card:#f7f9fb; --rv-line:#ccd3dd; --rv-soft:#e6eaf0;
  --rv-shadow:0 1px 2px rgba(17,24,39,.07),0 8px 24px rgba(17,24,39,.09);
}
body.rv-admin:not(.rv-theme-dark)[data-rv-day="soft"] .rv-side,
body.rv-admin:not(.rv-theme-dark)[data-rv-day="soft"] .rv-topbar{background:var(--rv-card);background:#f2f5f8}
body.rv-admin:not(.rv-theme-dark)[data-rv-day="soft"] .rv-command-bar{background:#e8edf3}
body.rv-admin:not(.rv-theme-dark)[data-rv-day="soft"] .rv-card,
body.rv-admin:not(.rv-theme-dark)[data-rv-day="soft"] .rv-stat,
body.rv-admin:not(.rv-theme-dark)[data-rv-day="soft"] .rvx-card,
body.rv-admin:not(.rv-theme-dark)[data-rv-day="soft"] .rvx-tile{background:var(--rv-card)}

/* NIGHT, LIFTED — his words: "the night's very, very dark." The existing
   soft/standard/high tokens are workspace-driven and stay as they are;
   this raises the FLOOR so the darkest setting is still a screen you can
   see shapes on, rather than a black rectangle with text on it. */
body.rv-admin.rv-theme-dark{--rv-line:#2a323d}
body.rv-admin.rv-theme-dark .rv-card,
body.rv-admin.rv-theme-dark .rv-stat,
body.rv-admin.rv-theme-dark .rvx-card,
body.rv-admin.rv-theme-dark .rvx-tile{box-shadow:0 1px 2px rgba(0,0,0,.28)}

/* ============================================================
   THE LOGO IN THE CORNER.
   ------------------------------------------------------------
   The whole logo — mark AND wordmark — not the initial-in-a-circle
   it was showing. Sized by HEIGHT with width:auto so the artwork's
   own proportions decide the rest; a fixed width would squash it
   the first time the sidebar changes size.
   ============================================================ */
.rv-side-brand--logo{display:block;padding:16px 14px 12px}
.rv-logo-img{height:38px;width:auto;max-width:100%;display:block}
/* Day/night pair. Both are in the markup and CSS picks one, so the
   swap is instant on theme toggle with no second network request
   and no flash of the wrong artwork. */
.rv-logo-night{display:none}
body.rv-theme-dark .rv-logo-day{display:none}
body.rv-theme-dark .rv-logo-night{display:block}
.rv-logo-text{color:var(--rv-ink);font-weight:800;font-size:1.15rem;letter-spacing:1px}
body.rv-theme-dark .rv-logo-text{color:#e5e7eb}
/* The collapsed rail and the phone drawer both keep the full logo —
   it is a 248px sidebar, there is room. Only the height comes down. */
@media(max-width:820px){.rv-logo-img{height:34px}}

/* ============================================================
   SOFT SKIN — the approved "one look", 2026-08-16
   Peter: "a bit harsh on the eyes... I want it soft in the eyes.
   Nothing too harsh. Traffic lights, arrows just very easy going,
   and everything easy to see, not one big huge jargon."
   COLOUR AND SHAPE ONLY. No layout, no behaviour.
   DELETE THIS WHOLE BLOCK TO REVERT THE ENTIRE APP.
   ============================================================ */
:root{
  /* ink lifted off near-black — near-black is what makes a screen feel hard */
  --rv-ink:#2b3440; --rv-ink-2:#2b3440; --rv-muted:#7a8798;
  --rv-bg:#f7f9fb; --rv-line:#e9edf2; --rv-soft:#f2f5f8;

  /* the action colour is now a SOFT WASH, not a solid slab */
  --rv-action:#1967d2; --rv-action-dark:#14539f;
  --rv-action-soft:#e8f0fe; --rv-action-line:#d2e3fc; --rv-action-hi:#d9e7fd;

  /* traffic lights, desaturated. Still obvious across a yard, no longer shouting. */
  --rv-green:#1e7a42;  --rv-green-bg:#e9f5ec; --rv-green-line:#d4e9db; --rv-green-dot:#4caf6d;
  --rv-orange:#a1690b; --rv-amber-bg:#fdf4e0; --rv-amber-line:#f6e6c0; --rv-amber-dot:#e5a83b;
  --rv-warn:#b3423f;   --rv-warn-bg:#fceceb;  --rv-warn-line:#f5d6d4;  --rv-warn-dot:#e0736f;

  --rv-r-sm:12px; --rv-r:14px; --rv-r-lg:18px;
  --rv-tap:46px;
}
body.rv-theme-dark{
  --rv-ink:#e4e9f0; --rv-ink-2:#e4e9f0; --rv-muted:#8e9bab;
  --rv-bg:#151b24; --rv-card:#1d242f; --rv-line:#2b3441; --rv-soft:#222b37;
  --rv-action:#9cc4f8; --rv-action-dark:#b9d5fb;
  --rv-action-soft:#1e3350; --rv-action-line:#2f4d73; --rv-action-hi:#264062;
  --rv-green:#7fd3a1;  --rv-green-bg:#17332a; --rv-green-line:#255742;
  --rv-orange:#e8c274; --rv-amber-bg:#3a2c14; --rv-amber-line:#5c4520;
  --rv-warn:#e79a97;   --rv-warn-bg:#3a2020;  --rv-warn-line:#5c3230;
}

/* THE BUTTON. Was a solid slab you could not look at forty times a day. */
.rv-btn{min-height:var(--rv-tap);padding:11px 18px;font-weight:680}
.rv-btn-primary{background:var(--rv-action-soft);color:var(--rv-action);border-color:var(--rv-action-line)}
.rv-btn-primary:hover{background:var(--rv-action-hi);color:var(--rv-action-dark)}
.rv-btn-navy{background:var(--rv-action-soft);color:var(--rv-action);border-color:var(--rv-action-line)}
.rv-btn-secondary,.rv-btn-ghost{background:var(--rv-card);color:var(--rv-muted);border-color:var(--rv-line)}
.rv-btn-secondary:hover,.rv-btn-ghost:hover{background:var(--rv-soft);color:var(--rv-ink)}
.rv-btn-sm{min-height:38px;padding:8px 14px}
/* 46px ON THE SCREENS THIS MISSION OWNS. .rv-btn-sm is 38px app-wide, which is
   under the rule everywhere -- but raising it globally mid-mission would move
   every screen in the application, including ones nobody has walked. Bible 92
   rule 5. So the job report list rows and the job report itself, which is what
   he is holding on a site, meet the rule now, and the app-wide gap is written
   into the handover instead of half-fixed. */
.rvx-card-actions .rv-btn, .rvx-card-actions .rv-btn-sm,
.rvx-wrap .rv-btn, .rvx-wrap .rv-btn-sm,
.jrx .rv-btn, .jrx .rv-btn-sm { min-height: var(--rv-tap, 46px); }
/* The workflow step pills scrolled sideways AND were 38px. Bible 96 section 3
   forbids both. They wrap now. */
.jrx #jrStepsCard > div { flex-wrap: wrap !important; overflow-x: visible !important; }
.jrx #jrStepsCard .rv-btn { min-height: var(--rv-tap, 46px); }
/* The rest of the job report's controls, which are not buttons: the fold-away
   summaries and the tick-box labels for Quote / Return visit / Follow-up. A
   21px label is a miss waiting to happen, and it is the LABEL a thumb lands
   on, not the 16px box inside it. */
.jrx summary { min-height: var(--rv-tap, 46px); display: flex; align-items: center; }
.jrx label:has(> input[type="checkbox"]), .jrx label:has(> input[type="radio"]) {
  min-height: var(--rv-tap, 46px); display: inline-flex; align-items: center; gap: 8px; }
/* The + in the top bar is a control on every screen in the admin. */
.rv-quick-actions > summary { min-height: var(--rv-tap, 46px); min-width: var(--rv-tap, 46px);
  display: inline-flex; align-items: center; justify-content: center; }
@media(max-width:820px){.rv-btn{min-height:var(--rv-tap)}}
:focus-visible{outline:3px solid var(--rv-action);outline-offset:2px}

/* ---- the one look: stats, flow, tabs, traffic-light pills ---- */
.one-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
.one-stat{background:var(--rv-bg);border:1px solid var(--rv-line);border-radius:var(--rv-r-sm);padding:14px 16px}
.one-stat .n{display:block;font-size:28px;font-weight:780;line-height:1.1}
.one-stat .l{display:block;font-size:12.5px;color:var(--rv-muted);font-weight:600;margin-top:2px}
.one-stat.g{border-left:4px solid var(--rv-green-dot)} .one-stat.g .n{color:var(--rv-green)}
.one-stat.a{border-left:4px solid var(--rv-amber-dot)} .one-stat.a .n{color:var(--rv-orange)}
.one-stat.r{border-left:4px solid var(--rv-warn-dot)}  .one-stat.r .n{color:var(--rv-warn)}

/* THE WHOLE FLOW ON ONE SCREEN. Peter: "the one with the arrows, that's still...
   it should be on the one screen and arrowed around." It was a sideways
   scroller, so on a phone he saw "Arrived 49 -> It's a bill 27 ->" and the rest
   fell off the right edge. Bible 96: no horizontal scrollers on anything he has
   to read. It wraps now -- every step and every arrow visible at 412px. */
.one-flow{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding-bottom:2px}
.one-node{display:flex;align-items:center;gap:8px;min-height:var(--rv-tap);padding:9px 16px;border-radius:22px;
  font-size:14px;font-weight:650;white-space:nowrap;border:1px solid var(--rv-line);background:var(--rv-bg);color:var(--rv-muted)}
.one-node b{font-weight:780}
.one-node.g{background:var(--rv-green-bg);color:var(--rv-green);border-color:var(--rv-green-line)}
.one-node.a{background:var(--rv-amber-bg);color:var(--rv-orange);border-color:var(--rv-amber-line)}
.one-node.r{background:var(--rv-warn-bg);color:var(--rv-warn);border-color:var(--rv-warn-line)}
.one-arw{color:var(--rv-muted);opacity:.45;font-size:15px;flex:0 0 auto}

.one-dot{width:8px;height:8px;border-radius:50%;display:inline-block;flex:0 0 auto;background:currentColor}
.one-dot.g{background:var(--rv-green-dot)} .one-dot.a{background:var(--rv-amber-dot)} .one-dot.r{background:var(--rv-warn-dot)}

.one-tabs{display:flex;gap:8px;overflow-x:auto;padding-bottom:2px;align-items:center;flex-wrap:wrap}
.one-tab{display:inline-flex;align-items:center;gap:7px;min-height:var(--rv-tap);padding:9px 16px;border-radius:22px;
  background:var(--rv-bg);border:1px solid var(--rv-line);color:var(--rv-muted);
  font-size:14px;font-weight:650;text-decoration:none;white-space:nowrap}
.one-tab:hover{background:var(--rv-soft);color:var(--rv-ink)}
.one-tab.on{background:var(--rv-action-soft);color:var(--rv-action);border-color:var(--rv-action-line)}
.one-tab .c{font-weight:780}

/* THE CUSTOMER RECORD, IN TABS.
   Ten panels on one scroll meant the thing he came for was always below the
   fold. One panel is shown at a time; the tab bar itself is .one-tabs, which
   already carries the 46px rung, so nothing new is invented for the look. */
.cu-panel{display:none}
.cu-panel.is-on{display:block}

/* The three-dot menu. Duplicate and Delete sat on the bare row next to the
   things he presses daily; they live behind one 46px control now. */
.cu-more{position:relative;display:inline-flex}
.cu-more-btn{min-width:var(--rv-tap,46px);font-size:1.15rem;line-height:1}
.cu-more-menu{position:absolute;right:0;top:calc(100% + 6px);z-index:40;min-width:232px;
  background:var(--rv-card);border:1px solid var(--rv-line);border-radius:var(--rv-r,14px);
  box-shadow:0 12px 28px rgba(0,0,0,.14);padding:6px;display:flex;flex-direction:column;gap:2px}
.cu-more-menu[hidden]{display:none}
.cu-more-menu form{margin:0}
.cu-more-item{display:flex;align-items:center;width:100%;min-height:var(--rv-tap,46px);
  padding:9px 13px;border:0;border-radius:var(--rv-r-sm,10px);background:none;cursor:pointer;
  font:inherit;font-weight:650;color:var(--rv-ink);text-align:left}
.cu-more-item:hover{background:var(--rv-soft)}
/* Red is a traffic light, so it says the state — it is not a button colour.
   The item stays an ordinary action and only its words are red. */
.cu-more-danger{color:var(--rv-red)}

.one-pill{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:22px;
  font-size:12.5px;font-weight:620;border:1px solid var(--rv-line);background:var(--rv-bg);color:var(--rv-muted);white-space:nowrap}
.one-pill.g{background:var(--rv-green-bg);color:var(--rv-green);border-color:var(--rv-green-line)}
.one-pill.a{background:var(--rv-amber-bg);color:var(--rv-orange);border-color:var(--rv-amber-line)}
.one-pill.r{background:var(--rv-warn-bg);color:var(--rv-warn);border-color:var(--rv-warn-line)}

.one-key{display:flex;gap:16px;flex-wrap:wrap;margin-top:14px;padding-top:12px;border-top:1px solid var(--rv-line)}
.one-key span{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:var(--rv-muted);font-weight:600}
.one-h2{font-size:12.5px;font-weight:700;color:var(--rv-muted);margin:0 0 8px;letter-spacing:.02em}

/* the old hand-rolled dark slabs on this page */
#rvBulkBar{background:var(--rv-action-soft)!important;color:var(--rv-action)!important;border:1px solid var(--rv-action-line)}
#rvBulkBar button{background:var(--rv-action)!important;color:#fff!important;border-radius:22px!important;min-height:40px}

/* Nothing you have to aim at. 157 of 192 controls on Expenses were under 44px.
   AND THEN THIS RULE SET 44, WHICH IS TWO SHORT. Bible 96 section 3 says 46 and
   says it is not negotiable. Because this selector is specific -- body + form +
   :not() beats a plain class -- it was quietly holding every workspace chip,
   every Sign out button, the dictation button and every text, search, date,
   email and number input in the admin at 44px, overriding the 46px on the
   button classes themselves. One number, in one place, across the app.
   The token exists; it is used here now so the next change cannot drift. */
body.rv-admin input[type=text],body.rv-admin input[type=search],body.rv-admin input[type=date],
body.rv-admin input[type=email],body.rv-admin input[type=number],body.rv-admin select,
body.rv-admin input[name=search]{min-height:var(--rv-tap,46px);border-radius:12px;border:1px solid var(--rv-line);
  background:var(--rv-card);color:var(--rv-ink);padding:10px 12px}
body.rv-admin label{font-size:12.5px;font-weight:650;color:var(--rv-muted)}
body.rv-admin form button:not(.rv-btn){min-height:var(--rv-tap,46px);border-radius:22px;padding:11px 18px;
  background:var(--rv-action-soft);color:var(--rv-action);border:1px solid var(--rv-action-line);font-weight:680;cursor:pointer}

/* ============================================================
   NIGHT THAT YOU CAN ACTUALLY READ — 2026-08-16
   Peter, on the How it works page at night: "when you get the
   night, it is too dark. They got the red in there, and that's
   just not user friendly."
   He was right twice. Two separate faults:
     1. Night was near-black. Lifted below.
     2. 123 views paint their own colours INLINE (2,393 hardcoded
        hexes). Inline light-mode ink survives into night mode, so
        #333 body text and #7c2d12 red headings land on a near-black
        card and vanish. Until those views are cleaned out one by
        one, the block below catches the common ones so no screen
        is unreadable at night.
   ============================================================ */
body.rv-theme-dark{
  /* lifted off black — a screen at night should be dim, not switched off */
  --rv-bg:#1a212b; --rv-card:#232b37; --rv-line:#333d4b; --rv-soft:#2a3340;
  --rv-ink:#e6ebf2; --rv-ink-2:#e6ebf2; --rv-muted:#98a5b5;
}
body.rv-theme-dark .rvx-card,body.rv-theme-dark .rvx-tile,
body.rv-theme-dark .rvx-toolbar,body.rv-theme-dark .rvx-pill,
body.rv-theme-dark .rv-side,body.rv-theme-dark .rv-topbar{
  background:var(--rv-card)!important;border-color:var(--rv-line)!important;color:var(--rv-ink)!important}
body.rv-theme-dark .one-stat{background:var(--rv-soft);border-color:var(--rv-line)}

/* --- the safety net for inline light-mode ink, night only --- */
body.rv-theme-dark [style*="background:#fff"],
body.rv-theme-dark [style*="background: #fff"],
body.rv-theme-dark [style*="background:#ffffff"]{background:var(--rv-card)!important}
body.rv-theme-dark [style*="border:1px solid #eee"],
body.rv-theme-dark [style*="border:1px solid #ddd"]{border-color:var(--rv-line)!important}

body.rv-theme-dark [style*="color:#333"],body.rv-theme-dark [style*="color: #333"],
body.rv-theme-dark [style*="color:#1a1a2e"],body.rv-theme-dark [style*="color: #1a1a2e"],
body.rv-theme-dark [style*="color:#111"],body.rv-theme-dark [style*="color:#000"]{color:var(--rv-ink)!important}

body.rv-theme-dark [style*="color:#666"],body.rv-theme-dark [style*="color: #666"],
body.rv-theme-dark [style*="color:#777"],body.rv-theme-dark [style*="color:#888"],
body.rv-theme-dark [style*="color: #888"],body.rv-theme-dark [style*="color:#999"],
body.rv-theme-dark [style*="color:#6b7280"],body.rv-theme-dark [style*="color:#6b727e"],
body.rv-theme-dark [style*="color:#64748b"]{color:var(--rv-muted)!important}

/* RED IS NOT A TEXT COLOUR AT NIGHT. It is REVMA's identity and a genuine
   alarm — dark red on a dark card is neither, it is just unreadable. */
body.rv-theme-dark [style*="color:#7c2d12"],body.rv-theme-dark [style*="color:#c2410c"],
body.rv-theme-dark [style*="color:#cc2229"],body.rv-theme-dark [style*="color:#C1122E"],
body.rv-theme-dark [style*="color:#b91c1c"],body.rv-theme-dark [style*="color:#991b1b"]{color:var(--rv-warn)!important}
body.rv-theme-dark [style*="color:#14562f"],body.rv-theme-dark [style*="color:#2e7d32"],
body.rv-theme-dark [style*="color:#166534"],body.rv-theme-dark [style*="color:#137333"]{color:var(--rv-green)!important}
body.rv-theme-dark [style*="background:#fffaf5"],body.rv-theme-dark [style*="background:#fffbf5"],
body.rv-theme-dark [style*="background:#fef7e0"],body.rv-theme-dark [style*="background:#eef3ff"]{
  background:var(--rv-soft)!important;border-color:var(--rv-line)!important}
body.rv-theme-dark a{color:var(--rv-action)}

/* The floating REVMA button was sitting on top of the words. */
.rv-content{padding-bottom:104px}

/* Night, part two. The workspace Appearance settings inject their own colours
   with !important from the layout, so these need the same weight to survive. */
body.rv-theme-dark .rv-exp-table tr,body.rv-theme-dark table,
body.rv-theme-dark tbody,body.rv-theme-dark tr{background:var(--rv-card)!important}
body.rv-theme-dark thead th{background:var(--rv-soft)!important;color:var(--rv-muted)!important}
body.rv-theme-dark .rv-btn-primary{background:var(--rv-action-soft)!important;
  color:var(--rv-action)!important;border-color:var(--rv-action-line)!important}
body.rv-theme-dark [style*="background:var(--rv-ink)"]{
  background:var(--rv-action-soft)!important;color:var(--rv-action)!important}
body.rv-theme-dark input,body.rv-theme-dark select,body.rv-theme-dark textarea{
  background:var(--rv-soft)!important;color:var(--rv-ink)!important;border-color:var(--rv-line)!important}

/* Night, part three — the last measured failures on /admin/expenses. */
body.rv-theme-dark [style*="color:#9a3412"],body.rv-theme-dark [style*="color:#444"],
body.rv-theme-dark [style*="color: #444"],body.rv-theme-dark [style*="color:#555"],
body.rv-theme-dark [style*="color:#422006"],body.rv-theme-dark [style*="color:#78350f"]{color:var(--rv-orange)!important}
body.rv-theme-dark .rv-avatar{background:var(--rv-action-soft)!important;color:var(--rv-action)!important}
/* the workspace badge: REVMA red is unreadable on its own dark tint at night */
body.rv-theme-dark .rv-ws-btn,body.rv-theme-dark .rvx-ws,body.rv-theme-dark [class*="ws-badge"]{color:#f3a3ae!important}
/* white on the gold accent never passed — gold wants dark ink on it */
.rv-gold,[style*="background:#e0b256"],[style*="background:var(--rv-gold)"]{color:#2b3440!important}

/* Light tint backgrounds written inline survive into night and strand the text
   on them. Catch the whole family. */
body.rv-theme-dark [style*="background:#fff7ed"],body.rv-theme-dark [style*="background:#ffedd5"],
body.rv-theme-dark [style*="background:#fef3c7"],body.rv-theme-dark [style*="background:#fefce8"]{
  background:var(--rv-amber-bg)!important;border-color:var(--rv-amber-line)!important}
body.rv-theme-dark [style*="background:#fee2e2"],body.rv-theme-dark [style*="background:#fef2f2"]{
  background:var(--rv-warn-bg)!important;border-color:var(--rv-warn-line)!important}
body.rv-theme-dark [style*="background:#f0fdf4"],body.rv-theme-dark [style*="background:#ecfdf5"]{
  background:var(--rv-green-bg)!important;border-color:var(--rv-green-line)!important}
body.rv-theme-dark [style*="background:#eff6ff"]{background:var(--rv-action-soft)!important}
body.rv-theme-dark .rv-ws-btn,body.rv-theme-dark .rvx-ws{color:#fff!important}
body.rv-theme-dark .rv-btn:not(.rv-btn-primary){background:var(--rv-soft)!important;
  color:var(--rv-ink)!important;border-color:var(--rv-line)!important}

/* ============================================================
   NIGHT SWEEP — the rest of the app, 2026-08-16.
   Measured across 14 screens at 412px in night mode. Dashboard was the
   worst in the app (61 of 143 text elements unreadable), then Service
   jobs (56) and Cashflow (24). Three distinct causes, all here.
   ============================================================ */

/* 1. Dashboard components kept a hard white background at night while the
      ink turned light — white on white. These are class-based, so the
      inline-style safety net above could never have caught them. */
body.rv-theme-dark .rv-quick-menu,body.rv-theme-dark .rv-icon-btn,
body.rv-theme-dark .rv-health-item,body.rv-theme-dark .rv-timeline-row,
body.rv-theme-dark .rv-action-card,body.rv-theme-dark .rv-stat,
body.rv-theme-dark .rv-card,body.rv-theme-dark .rv-panel,body.rv-theme-dark .rv-box{
  background:var(--rv-card)!important;border-color:var(--rv-line)!important;color:var(--rv-ink)!important}
body.rv-theme-dark .rv-timeline-row.done{background:var(--rv-green-bg)!important;border-color:var(--rv-green-line)!important}
body.rv-theme-dark .rv-timeline-row.warn{background:var(--rv-amber-bg)!important;border-color:var(--rv-amber-line)!important}
body.rv-theme-dark .rv-icon-btn{color:var(--rv-ink)!important}

/* 2. Service jobs: mid-greys (#374151, #4b5563) written straight onto dark
      cards. 53 of that screen's 56 failures were these two values. */
body.rv-theme-dark [style*="color:#374151"],body.rv-theme-dark [style*="color: #374151"],
body.rv-theme-dark [style*="color:#4b5563"],body.rv-theme-dark [style*="color: #4b5563"],
body.rv-theme-dark [style*="color:#475569"],body.rv-theme-dark [style*="color:#334155"],
body.rv-theme-dark [style*="color:#1f2937"],body.rv-theme-dark [style*="color:#111827"],
body.rv-theme-dark [style*="color:#0f172a"],body.rv-theme-dark [style*="color:#212529"]{color:var(--rv-ink)!important}

/* 3. Cashflow: REVMA red used as body text. Red is the brand and a real
      alarm — as small text on a dark card it is neither, just unreadable. */
body.rv-theme-dark [style*="color:var(--rv-red)"],
body.rv-theme-dark [style*="color:#e63946"],body.rv-theme-dark [style*="color:#E63946"]{color:#f3a3ae!important}
/* NOT --rv-red globally: it is also a BACKGROUND for white-text badges,
   and repainting it pink broke those. Text-only above. */
body.rv-theme-dark .rv-logo b,body.rv-theme-dark .rv-side-brand b{color:#f3a3ae}

/* Light slate/grey backgrounds also survive into night. If the ink is lifted
   but the chip behind it stays light, that is a fault I caused, not one I found. */
body.rv-theme-dark [style*="background:#e2e8f0"],body.rv-theme-dark [style*="background:#f1f5f9"],
body.rv-theme-dark [style*="background:#f8fafc"],body.rv-theme-dark [style*="background:#f3f4f6"],
body.rv-theme-dark [style*="background:#f9fafb"],body.rv-theme-dark [style*="background:#eee"],
body.rv-theme-dark [style*="background:#f5f5f5"],body.rv-theme-dark [style*="background:#fafafa"],
body.rv-theme-dark [style*="background:#f6f7f9"]{
  background:var(--rv-soft)!important;border-color:var(--rv-line)!important;color:var(--rv-ink)!important}

/* ══ C3 — PRINT. ═════════════════════════════════════════════════════════════
   Ctrl+P on any admin screen used to print the menu, the workspace chips, the
   search box, the tick boxes, the Delete button and the floating Feedback pill,
   with the actual record squeezed into the right-hand two thirds. It was not a
   printable page, it was a screenshot of an app.

   Print-only. Not one rule here applies on screen, so nothing that already
   works can move. The rule is simple: paper gets the RECORD and nothing you
   could tap. Controls do not exist on paper.

   This is the screen printed clean. The PDF (Download PDF) is still the
   document the CUSTOMER receives -- one truth each, and they are not the same
   job. */
@media print {
  /* Chrome drops backgrounds by default; ink on white is what a printer does
     best and what a filed report should look like. */
  html, body { background: #fff !important; color: #000 !important; }

  /* Everything you could press, and everything that frames the app. */
  .rv-side, .rv-topbar, .rv-burger, .rv-quick-actions, .rv-quick-menu,
  .fbw-btn, .fbw-overlay, .penny-fab, .penny-sheet, .penny-scrim,
  .rvx-toolbar, .rvx-pills, .rvx-search, .rvx-head-actions,
  .rvx-card-actions, .rv-nav, .rv-side-foot, .jr-no-print,
  input[type="checkbox"], .rv-btn, button, form#jr-copy { display: none !important; }

  /* The page is the paper now. */
  .rv-shell, .rv-main, .rv-content { display: block !important; margin: 0 !important;
    padding: 0 !important; width: auto !important; max-width: none !important; }
  .rv-content > * { max-width: none !important; }

  /* Cards become sections on a page, not floating tiles. */
  .rv-card, .rvx-card, .rvx-panel, .rv-panel, .rvx-tile {
    box-shadow: none !important; border: 1px solid #ccc !important;
    margin-bottom: 10px !important; }
  /* A ROW of a printed list must never split across two sheets -- half a job
     report at the bottom of page one is unreadable. A whole CARD is allowed to
     flow, because forbidding that left the first sheet three quarters empty
     while the visit details waited for page two. */
  .rvx-card { break-inside: avoid; page-break-inside: avoid; }

  /* A row of a printed list must not be split across two sheets. */
  .rvx-cards { display: block !important; }
  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }

  /* NO URLs ON THE PAPER. The usual print trick is to append every link's
     href after it. On a job report that means "(http://127.0.0.1:8000/admin/
     customers/4)" printed beside the customer's name, three times a page. That
     is machine output, and Bible 96 section 4 is explicit: never make him read
     it. Links print as plain black text.
     (This rule was written the other way first, and the printed proof is what
     showed how bad it looked.) */
  a { color: #000 !important; text-decoration: none !important; }

  /* FORM FIELDS ARE VALUES ON PAPER, NOT BOXES.
     A printed input drawn with its border and its fixed height reads as a
     BLANK FORM someone forgot to fill in -- and worse, a textarea keeps its
     on-screen height, so a long write-up printed with everything past line two
     silently missing. A report that drops the work description is not a
     report. Height goes to auto and the chrome comes off. */
  /* .jrx scopes its own field styling in admin.css, and a class selector beats
     a bare element one even when both shout, so the boxes survived the first
     attempt. Named here so paper wins. */
  input, textarea, select, .rv-input, .rv-input-sm,
  .jrx input, .jrx textarea, .jrx select, .jrx .rv-input {
    border: 0 !important; background: transparent !important; box-shadow: none !important;
    padding: 0 !important; height: auto !important; min-height: 0 !important;
    max-height: none !important; overflow: visible !important; resize: none !important;
    color: #000 !important; font-size: 1rem !important; -webkit-appearance: none; appearance: none; }
  textarea { display: block !important; white-space: pre-wrap !important; }

  /* A placeholder is a hint, not an answer. Printed, it reads as the answer --
     "Follow-up required: What's still to do, or what to come back for" is a
     sentence he never wrote. */
  ::placeholder { color: transparent !important; opacity: 0 !important; }

  /* Progress bars, step counters and "0/1 steps done" are about using the
     screen. Paper is the finished thing. */
  #jrStepsCard, .rv-workflow-steps, .rv-steprow, .jrx-go, .rvx-traffic-row { display: none !important; }

  @page { margin: 14mm; }
}

/* ------------------------------------------------------------------
   .rv-tap — THE CLASS THAT DID NOTHING.

   Blades across the CRM put class="rv-tap" on a link to mean "this is
   something he taps, give it a thumb-sized target". There was no rule
   for it anywhere in this stylesheet or in admin.css. Every one of them
   rendered as bare 19px text — 50 of them on one customer record.
   Same shape as the .rv-pager-btn bug.

   inline-flex so the text stays exactly where it was and only the
   TARGET grows (Bible 96 section 3, and the pattern already used by
   .rv-logo and .rv-back above).
   ------------------------------------------------------------------ */
.rv-tap{display:inline-flex;align-items:center;min-height:var(--rv-tap,46px)}
.rv-tap.rv-ref{font-variant-numeric:tabular-nums}

/* Workspace chips and theme buttons were 46 tall but 40 wide. A tap
   target is an area, not a height. */
.rv-ws-btn{min-width:var(--rv-tap,46px)}

/* Short labels ("Matt", "bgis") were 46 tall and 31 wide. The text stays
   left; only the box he can hit extends. */
.rv-tap{min-width:var(--rv-tap,46px);justify-content:flex-start}

/* Every text box he types into is a target too. */
.rv-input,.rv-select,input[type=search].rv-search{min-height:var(--rv-tap,46px)}

/* The one search box that sits on EVERY screen was 28px tall and had no
   class at all, so nothing had ever reached it. */
.rv-top-search input,.rv-top-search button{min-height:var(--rv-tap,46px)}

/* ------------------------------------------------------------------
   DUPLICATE CONTACTS — the screen that cleans 1,473 groups.
   It was 1,468 controls under 46px: raw 13px radios and checkboxes,
   and 40px name links. Unusable one-handed, which is the only way it
   ever gets used. The boxes themselves grow; nothing moves.
   ------------------------------------------------------------------ */
.rv-dupes input[type=radio],
.rv-dupes input[type=checkbox]{width:24px;height:24px;cursor:pointer}
.rv-dupes td:has(> input[type=radio]),
.rv-dupes td:has(> input[type=checkbox]){padding:8px 6px}
.rv-dupes .ct-name{display:flex;align-items:center;gap:10px;min-height:var(--rv-tap,46px);padding:4px 0}
.rv-dupes .js-group-include{width:26px;height:26px}
.rv-dupes label:has(> .js-group-include){min-height:var(--rv-tap,46px)}
.rv-dupes #selectAllGroups{width:26px;height:26px}
.rv-dupes .ct-head label{min-height:var(--rv-tap,46px)}
.rv-dupes #bulkBar label{min-height:var(--rv-tap,46px)}
.rv-dupes .rv-btn-sm{min-height:var(--rv-tap,46px)}
/* The Keep radio and the include tick sat bare in a <td> at 24px with no
   wrapper, so there was nothing bigger to aim at. The whole cell is now
   the target. */
.rv-cellpick{display:flex;align-items:center;justify-content:center;
  min-width:var(--rv-tap,46px);min-height:var(--rv-tap,46px);cursor:pointer;margin:0 auto}

/* BIBLE 91 §19 — THE FIVE TOOLS, on the phone he is actually holding.
   Five buttons in a wrapping row at 412px broke their own words in half
   ("Ma / ter / ial"). A five-column grid gives each one a 46px+ square, the
   icon above the word, and nothing wraps. Scoped to the working screen so no
   other row of buttons in the application moves. */
.jw-tools{display:grid;grid-template-columns:repeat(5,1fr);gap:8px}
.jw-tools .rv-btn{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  min-height:64px;padding:8px 4px;font-size:.76rem;line-height:1.1;text-align:center;white-space:normal}
.jw-tools .rv-btn > span{font-size:1.15rem;line-height:1}

/* BIBLE 96 — THE JOB SCREENS ON A PHONE (.jbx: start, hub, work, review,
   exceptions). Three buttons side by side inside a 412px card broke their own
   words in half ("Create custom / er now"). On a phone each way on gets the
   full width of the card, in the order it should be read; from 560px up they
   go back to a row. Scoped to these screens so no other button row moves. */
@media (max-width:559px){
  .jbx .rvx-card-actions{display:grid;grid-template-columns:1fr;gap:9px}
  .jbx .rvx-card-actions > .rv-btn,
  .jbx .rvx-card-actions > button,
  .jbx .rvx-card-actions > a{width:100%;justify-content:center;white-space:normal}
  /* A one-button form in an action row is one of the ways on, so it gets the
     same full width; a pause reason and its button stay side by side. */
  .jbx .rvx-card-actions > form{display:flex;gap:8px;width:100%;margin:0}
  .jbx .rvx-card-actions > form > .rv-btn{flex:1;white-space:normal}
  /* The five tools stay a grid of squares — they are icons, not sentences.
     Three across on a phone, because five across broke "Material" in half. */
  .jbx .jw-tools{grid-template-columns:repeat(3,1fr)}
  .jbx .jw-tools > .rv-btn{width:auto}
}

/* ── CUSTOMERS AS A TABLE (2026-08-20) ────────────────────────────────────────
   His words: the Job table is easier on the eye; the cards were oversized, wasted
   vertical space and repeated five buttons on every record — four customers on a
   screen. Same table as Service Jobs, rows a touch taller, cards only on a phone. */
.cu-table td { padding-top:12px; padding-bottom:12px; }
.cu-row { cursor:pointer; }
.cu-row:nth-child(even) { background:var(--rv-row-alt, rgba(0,0,0,.02)); }
.cu-row:hover { background:var(--rv-act-bg, #e8f0fe); }
.cu-name { font-weight:650; color:var(--rv-ink); }
.cu-tablewrap { overflow-x:auto; }

/* The three-dot menu — one control, everything secondary behind it. */
.cu-more { position:relative; display:inline-block; }
.cu-more > summary {
  list-style:none; cursor:pointer; min-width:46px; min-height:46px;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--rv-r); font-size:20px; line-height:1; color:var(--rv-muted);
}
.cu-more > summary::-webkit-details-marker { display:none; }
.cu-more > summary:hover { background:var(--rv-act-bg, #e8f0fe); color:var(--rv-act-ink, #1967d2); }
.cu-more-menu {
  position:absolute; right:0; z-index:40; min-width:170px; padding:6px;
  background:var(--rv-card, #fff); border:1px solid var(--rv-line, #e3e7ec);
  border-radius:var(--rv-r); box-shadow:0 8px 24px rgba(0,0,0,.12);
}
.cu-more-menu a, .cu-more-menu button {
  display:block; width:100%; text-align:left; padding:11px 12px; min-height:46px;
  background:none; border:0; border-radius:var(--rv-r-s, 6px); cursor:pointer;
  font:inherit; color:var(--rv-ink); text-decoration:none;
}
.cu-more-menu a:hover, .cu-more-menu button:hover { background:var(--rv-act-bg, #e8f0fe); }
.cu-more-menu .danger { color:var(--rv-red); }

/* PHONE — dedicated card markup (.cu-mobile). The desktop table is hidden
   outright rather than folded up: every previous attempt to convert table cells
   into a card put two fields in the same box. */
.cu-mobile{ display:none; }
@media (max-width: 820px) {
  .cu-tablewrap{ display:none !important; }
  .cu-mobile{ display:block; }

  .cum-card{
    background:var(--rv-card,#fff); border:1px solid var(--rv-line,#e3e7ec);
    border-radius:var(--rv-r,10px); padding:12px; margin-bottom:10px;
  }
  .cum-top{ display:flex; align-items:flex-start; gap:8px; }
  .cum-tick{
    flex:0 0 46px; min-width:46px; min-height:46px;
    display:flex; align-items:center; justify-content:center; cursor:pointer;
  }
  .cum-tick input{ width:22px; height:22px; }
  .cum-name{
    flex:1 1 auto; min-width:0; min-height:46px;
    display:flex; align-items:center;
    font-size:1.02rem; font-weight:640; line-height:1.3;
    color:var(--rv-ink,#2b3440); text-decoration:none; word-break:break-word;
  }
  .cum-more{ flex:0 0 46px; position:relative; }
  .cum-more summary{
    list-style:none; min-width:46px; min-height:46px;
    display:flex; align-items:center; justify-content:center; cursor:pointer;
    color:var(--rv-muted,#6b7684);
  }
  .cum-more summary::-webkit-details-marker{ display:none; }
  .cum-menu{
    position:absolute; right:0; top:46px; z-index:20; min-width:150px;
    background:var(--rv-card,#fff); border:1px solid var(--rv-line,#e3e7ec);
    border-radius:8px; box-shadow:0 6px 18px rgba(0,0,0,.12); overflow:hidden;
  }
  .cum-menu a{ display:flex; align-items:center; min-height:46px; padding:0 14px;
    color:var(--rv-ink,#2b3440); text-decoration:none; }
  .cum-menu a+a{ border-top:1px solid var(--rv-line,#e3e7ec); }

  .cum-row{ display:flex; gap:10px; align-items:baseline; padding:4px 0 4px 54px; }
  .cum-lbl{ flex:0 0 96px; font-size:.74rem; text-transform:uppercase; letter-spacing:.05em;
    color:var(--rv-muted,#6b7684); }
  .cum-val{ flex:1 1 auto; min-width:0; font-size:.9rem; color:var(--rv-ink,#2b3440); }
  .cum-break{ word-break:break-all; }
  .cum-val a{ display:inline-flex; align-items:center; min-height:46px; }

  .cum-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px; padding:4px 0 4px 54px; }
  .cum-grid>div{ display:flex; flex-direction:column; gap:2px; min-width:0; }
  .cum-grid .cum-lbl{ flex:none; }
}

/* The phone and email are tap targets on a phone, not just text. */
.cu-table td a[href^="tel:"], .cu-table td a[href^="mailto:"] {
  display:inline-flex; align-items:center; min-height:46px;
}
@media (min-width: 821px) {
  /* Desktop rows sit at his 56–64px, not 72. */
  .cu-table td { padding-top:8px; padding-bottom:8px; }
  .cu-table td a[href^="tel:"], .cu-table td a[href^="mailto:"] { min-height:0; }
}

/* ---- CUSTOMER RECORD: the daily strip and the folded sections ------------ */
.cu-daily{ margin-bottom:14px; }
.cu-primary{ display:flex; flex-wrap:wrap; align-items:baseline; gap:8px; }
.cu-plabel{ font-size:.74rem; text-transform:uppercase; letter-spacing:.05em; color:var(--rv-muted,#6b7684); }
.cu-pname{ font-size:1.05rem; font-weight:650; }
.cu-pname.cu-none{ color:var(--rv-muted,#6b7684); font-weight:600; }
.cu-hint{ font-size:.86rem; color:var(--rv-muted,#6b7684); margin:8px 0 0; }
.cu-acts{ display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
.cu-act{ min-height:46px; display:inline-flex; align-items:center; justify-content:center; padding:0 14px; }
.cu-act.is-off{ opacity:.5; cursor:default; }
.cu-sub{ display:flex; flex-wrap:wrap; gap:8px; margin:-6px 0 16px; }
.cu-subbtn{ min-height:46px; }
.cu-subbtn.on{ background:var(--rv-blue-bg,#e8f0fe); border-color:var(--rv-blue-line,#d2e3fc); color:var(--rv-blue,#1967d2); }
.cu-fold{ border:1px solid var(--rv-line,#e3e7ec); border-radius:var(--rv-r,10px); background:var(--rv-card,#fff); margin-bottom:10px; }
.cu-fold>summary{ list-style:none; cursor:pointer; min-height:46px; display:flex; align-items:center; padding:0 13px; font-weight:640; }
.cu-fold>summary::-webkit-details-marker{ display:none; }
.cu-fold.cu-danger>summary{ color:var(--rv-red,#b3423f); }
.cu-foldbody{ padding:0 13px 13px; }
@media (max-width:820px){
  .cu-act{ flex:1 1 46%; }
  .cu-sub{ overflow-x:auto; }
}
.cu-primbanner{ display:flex; gap:12px; align-items:center; justify-content:space-between;
  flex-wrap:wrap; margin-bottom:12px; border-left:4px solid var(--rv-orange,#a1690b); }
.cu-choose{ margin-top:8px; width:100%; }
@media (min-width:821px){ .cu-choose{ width:auto; } }
