:root{
  --bg:#f4f6fb; --card:#ffffff; --ink:#0f1729; --ink-soft:#48566e; --ink-faint:#7a879e;
  --line:#e6ebf3; --line-soft:#eef2f8;
  --brand:#2f6bff; --brand-2:#1e4fd6; --brand-ink:#0b2a7a;
  --brand-tintbg:#eef3ff; --good:#12b76a; --good-bg:#e7f8ef;
  --amber:#f59e0b; --radius:16px; --shadow:0 1px 2px rgba(16,26,48,.04),0 8px 24px rgba(16,26,48,.06);
  --shadow-lg:0 12px 40px rgba(16,26,48,.12);
}
*{box-sizing:border-box}
/* 🔴🔴 HIDDEN MEANS HIDDEN, EVERYWHERE (Kevin, 2026-09-09 — he hit this twice in ten minutes).
   A page marks something hidden and it draws anyway, because almost every block on this CRM is
   given a display of its own — .qpick is a flex row, .stl .s is a flex row — and a plain "hidden"
   loses to any display rule. So the Quote updated row showed on a customer who never had one, and
   the whole Send row stayed on Tom Lee's card after he had paid: *"the change is not taking
   affect"*. Both were correctly MARKED hidden the whole time.

   One rule for the entire control panel, so this cannot come back a third time on some other
   block nobody thought of. → memory hq-one-rule-not-two-copies · success-before-the-write-defect */
[hidden]{display:none!important}
html,body{margin:0;padding:0}
/* 🔴 THE PAGE'S OWN COLOUR IS BACK TO NOTHING — TAKEN OUT AGAIN 18 Sept, minutes after it went in.
   Painting the page dark to kill the white flash between customers made the MESSAGES screens jump:
   Kevin, straight away — "the whole screen is shooting to the top... that's worse than before."
   The messages screens hold the page pinned at the top and snap back anything that scrolls, so a
   change that touches how every page is painted is not safe to make there in the middle of a
   testing day. The white flash goes back on the parked list; the keypad keeps its own fix, which
   only touches the keypad. → memory flash-between-customers-parked */
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,Helvetica,Arial,sans-serif;
  background:
    radial-gradient(1150px 520px at 90% -80px, rgba(123,108,255,.13), transparent 60%),
    radial-gradient(950px 480px at -5% 4%, rgba(45,140,255,.10), transparent 55%),
    linear-gradient(180deg,#e7ecf7 0%,#e1e7f3 46%,#e8ecf6 100%);
  background-attachment:fixed;
  color:var(--ink);-webkit-font-smoothing:antialiased;font-size:15px;line-height:1.5}

/* ── EVERY CONTROL USES OUR FONT ──────────────────────────────────────────────
   Kevin, 2026-08-24, pointing at a pair of Yes/No buttons: *"this isn't our font. It doesn't
   look like our page at all... I've seen this a few other places."* He had found a whole class
   of fault, not one button.

   A <button>, <input>, <select> or <textarea> does NOT inherit the page font — every browser
   drops it to its own default (Arial here) unless told otherwise. So any control that was
   styled for colour and size but never for FONT quietly rendered in the wrong typeface, and it
   only jumped out on the ones that had no other styling either.

   This is the root fix, and it is deliberately at the top: one line, and every control on every
   HQ screen speaks in the page's own voice — including the ones neither of us has spotted. */
button, input, select, textarea, optgroup{ font-family:inherit; }
/* 🔴 NO TRANSITION ON THE COLUMN. Kevin, 2026-08-24: "when I open the sidebar it's behind the
   leads board." Animating grid-template-columns is slow and, worse, the sidebar itself snaps to
   its full 264px instantly while the COLUMN crawls from 70px over .18s — so for that fifth of a
   second the nav is wider than the space it has been given and the page content sits on top of
   it. Measured mid-animation: nav 264px wide, column still 70px. The width change is now
   instant, which is also how it reads: a sidebar is either open or it is not. */
.app{display:grid;grid-template-columns:264px 1fr;min-height:100vh}

/* ---------- LEFT NAV ---------- */
.nav{overflow-x:hidden;background:#0f1729;color:#c7d0e0;display:flex;flex-direction:column;padding:18px 14px;gap:2px;position:sticky;top:0;height:100vh;overflow:auto}
.brand{display:flex;align-items:center;gap:10px;padding:6px 8px 16px}
.brand .mark{width:34px;height:34px;border-radius:9px;background:linear-gradient(135deg,#3d78ff,#1e4fd6);
  display:grid;place-items:center;color:#fff;font-weight:800;font-size:13px;letter-spacing:.3px;box-shadow:0 4px 14px rgba(47,107,255,.5)}
.brand b{color:#fff;font-size:15px;font-weight:700;letter-spacing:.2px;display:block;line-height:1.15}
.brand span{color:#8695b3;font-size:11.5px}
.client{margin:4px 4px 12px;padding:10px 12px;background:#182238;border:1px solid #232f49;border-radius:11px;
  display:flex;align-items:center;gap:10px;cursor:pointer}
.client .dot{width:30px;height:30px;border-radius:8px;background:#fff;color:#1e4fd6;display:grid;place-items:center;font-weight:800;font-size:12px;overflow:hidden;flex:none;border:1px solid rgba(0,0,0,.06)}
.client .dot img{width:100%;height:100%;object-fit:contain;padding:2px}
.client .who{flex:1;min-width:0}
.client .who b{color:#fff;font-size:13px;display:block}
.client .who span{color:#8695b3;font-size:11px}
/* The chevron is gone (nothing ever listened to it); this rule stays harmless if any
   page still carries the old markup from cache. The client tile is now the sidebar's
   header, so it sits tight under the Home link and no longer looks clickable. */
.client .chev{display:none}
.client{cursor:default;margin-top:0}
.client .navcollapse{margin-left:auto}
/* Sidebar section headings. Jeannine, via Kevin 2026-08-22: she wants to SEE them, in a gold
   that is "nothing too bright, but really nice looking". Two changes, and the size is half of it —
   they were 11px, the smallest type in the product, in a pale blue-grey that sat almost flat on the
   navy. Now 12.5px in a muted antique gold.
   The grey pill is gone. A filled box around a label competes with the nav items below it, which
   are the things she actually clicks; a hairline under the word separates the groups just as well
   and puts the weight back on the items. Kevin picked this over a gold pill and a gold left-bar. */
.navgroup{font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;color:#dcbe7c;font-weight:800;
  margin:18px 6px 8px;padding:0 2px 7px;background:none;border-bottom:1px solid rgba(220,190,124,.22);border-radius:0}
.navsec:first-of-type .navgroup{margin-top:4px}

/* The collapsed rail's labels (nav.js positions it; see the note there for why it is not a ::after).
   Same navy and the same gold hairline as the section headings, so it reads as part of the sidebar
   rather than a browser thing. pointer-events:none — the bubble must never sit between her cursor
   and the icon she is about to click. */
.navtip{position:fixed;z-index:120;pointer-events:none;
  background:#16203a;color:#f2f6ff;font-size:13px;font-weight:650;letter-spacing:.01em;
  border:1px solid rgba(220,190,124,.28);border-radius:9px;padding:7px 12px;white-space:nowrap;
  box-shadow:0 10px 26px -10px rgba(0,0,0,.7);
  opacity:0;transform:translateX(-4px);transition:opacity .11s ease,transform .11s ease}
.navtip.on{opacity:1;transform:translateX(0)}
/* the little wedge pointing back at the icon */
.navtip::before{content:'';position:absolute;left:-5px;top:50%;margin-top:-4px;width:8px;height:8px;
  background:#16203a;border-left:1px solid rgba(220,190,124,.28);border-bottom:1px solid rgba(220,190,124,.28);
  transform:rotate(45deg);border-radius:1px}
.navitem{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:9px;color:#c1ccdf;font-size:13.5px;
  text-decoration:none;cursor:pointer;font-weight:500;transition:background .12s,color .12s}
.navitem svg{width:17px;height:17px;opacity:.8;flex:none}
.navitem:hover{background:#182238;color:#fff}
/* ── GREEN TICK ON A CONNECTIONS ROW (Kevin, 2026-09-07: "green tick on the ones that are done").
   Sits at the far right of the row so the account name is never crowded. nav.js only ever adds
   this after a live answer comes back saying yes — there is no hardcoded tick anywhere.
   The `.navitem svg` rule above would paint the tick at 17px and 80% opacity like a row icon;
   a tick is an answer, not decoration, so it is smaller, fully opaque and green. */
.navitem .navtick{margin-left:auto;display:grid;place-items:center;width:17px;height:17px;flex:none;color:#3ddc8a}
.navitem .navtick svg{width:14px;height:14px;opacity:1}
/* WHERE YOU ARE. Kevin, 2026-08-29, with the menu open on his phone: "Is there a way of seeing
   what I'm currently on? Like, it's highlighted." The tint below already existed — it was never
   reaching the page, because the live site drops the .html from the address and nav.js was
   comparing against a name that still had it. Fixed in nav.js.
   The bar down the left edge is new: a tint alone is easy to miss on a phone in daylight, and
   this row is the answer to "where am I", which should never need a second look. Blue, the same
   blue every other action in HQ uses — gold means HIE and red means waiting on us, and neither
   is what a menu row is saying. -> memory hq-leads-board-design-rules */
.navitem.active{background:linear-gradient(90deg,rgba(47,107,255,.30),rgba(47,107,255,.07));color:#fff;
  font-weight:800;box-shadow:inset 3px 0 0 #4d84ff}
.navitem.active svg{opacity:1;color:#8fb2ff}
.nav .spacer{flex:1}
.usage{margin:8px 6px 4px;padding:11px 12px;background:#141d31;border:1px solid #222d46;border-radius:11px}
/* Our name, on HER screen — quiet, not shouting. It sits under the usage bar, the last thing in
   the sidebar. It is deliberately small and dim: this is a credit, not an advert, and the moment
   it competes with her own business name on her own control panel it has gone too far. */
.navby{margin:10px 8px 12px;font-size:11px;line-height:1.4;color:#6b7793;letter-spacing:.01em}
.navby b{color:#95a3c0;font-weight:700}
.app.navrail .navby{display:none}
.usage .row{display:flex;justify-content:space-between;font-size:11.5px;color:#9aa8c6;margin-bottom:7px}
.usage .bar{height:6px;background:#232f49;border-radius:99px;overflow:hidden}
.usage .bar i{display:block;height:100%;width:34%;background:linear-gradient(90deg,#3d78ff,#12b76a);border-radius:99px}

/* Sidebar "Back to your home" exit — slim breadcrumb at the very top */
.navhome{display:flex;align-items:center;gap:7px;margin:0 6px 12px;padding:6px 6px 12px;border-bottom:1px solid rgba(255,255,255,.07);
  text-decoration:none;color:#8695b3;font-size:12px;font-weight:700;letter-spacing:.01em;transition:color .14s}
.navhome:hover{color:#fff}
.navhome:hover svg{transform:translateX(-2px)}
.navhome svg{width:15px;height:15px;flex:none;transition:transform .14s}
.app.navrail .navhome{display:none}

/* Sidebar "Message us" — in-nav support entry (replaces the old floating chip) */
.navmsg{display:flex;align-items:center;gap:10px;margin:2px 4px 12px;padding:10px 12px;border-radius:11px;cursor:pointer;text-decoration:none;
  background:linear-gradient(135deg,rgba(61,120,255,.16),rgba(30,79,214,.07));border:1px solid rgba(61,120,255,.3);transition:background .14s,border-color .14s}
.navmsg:hover{background:linear-gradient(135deg,rgba(61,120,255,.26),rgba(30,79,214,.13));border-color:rgba(61,120,255,.5)}
.navmsg .navmsg-ic{width:30px;height:30px;border-radius:8px;background:linear-gradient(135deg,#3d78ff,#1e4fd6);display:grid;place-items:center;flex:none}
.navmsg .navmsg-ic svg{width:16px;height:16px;color:#fff}
.navmsg .navmsg-tx{min-width:0}
.navmsg .navmsg-tx b{color:#fff;font-size:13px;font-weight:700;display:block;line-height:1.2}
.navmsg .navmsg-tx span{color:#9db4e6;font-size:11px;display:block;line-height:1.25;margin-top:1px}
/* Message panel (modal) */
.msgpanel{position:fixed;inset:0;z-index:120;display:none;align-items:center;justify-content:center;padding:20px;
  background:rgba(10,14,26,.5);opacity:0;transition:opacity .16s}
.msgpanel.show{display:flex;opacity:1}
.msgcard{width:100%;max-width:420px;background:var(--card);border:1px solid var(--line);border-radius:16px;box-shadow:0 24px 60px rgba(10,14,26,.4);
  padding:20px;transform:translateY(8px);transition:transform .16s}
.msgpanel.show .msgcard{transform:translateY(0)}
.msghd{display:flex;align-items:center;gap:10px}
.msghd b{font-size:16px;color:var(--ink);font-weight:800}
.msghd .msgx{margin-left:auto;border:0;background:#eef2f8;color:var(--ink-soft);width:30px;height:30px;border-radius:8px;font-size:18px;line-height:1;cursor:pointer}
.msghd .msgx:hover{background:#e2e8f2;color:var(--ink)}
.msgsub{font-size:13px;color:var(--ink-faint);margin:6px 0 13px;line-height:1.5}
.msgcard textarea{width:100%;min-height:104px;font-family:inherit;font-size:14px;color:var(--ink);background:#fbfcfe;
  border:1px solid var(--line);border-radius:11px;padding:11px 13px;outline:none;resize:vertical;transition:border .12s,box-shadow .12s}
.msgcard textarea:focus{border-color:var(--brand);box-shadow:0 0 0 3px rgba(47,107,255,.12);background:#fff}
.msgcard .msgsend{width:100%;justify-content:center;margin-top:12px}
.msgcard .msgnote{font-size:11.5px;color:var(--ink-faint);text-align:center;margin-top:9px}
/* 🔴 z-index 130 put every message BEHIND the Review & send window (250), so pressing
   Approve & send and being refused looked exactly like the button doing nothing.
   Kevin, 2026-08-23: "I hit approve and send, and nothing happened." The message a
   send gives back must sit above everything, or it is not a message. */
.msgtoast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(12px);opacity:0;z-index:400;
  background:var(--ink);color:#fff;font-size:14px;font-weight:600;padding:11px 18px;border-radius:11px;
  box-shadow:0 10px 30px rgba(15,23,41,.28);pointer-events:none;transition:opacity .2s,transform .2s;
  /* 🔴 A MESSAGE HAS TO FIT ON A PHONE. Jeannine works on one, and a single unbroken line ran off
     both edges of a 375px screen — so the end of the sentence, which is where the reason lives,
     was the part nobody could see. → memory verify-on-mobile-jeannine-works-on-a-phone */
  max-width:min(560px, calc(100vw - 28px));line-height:1.45}
.msgtoast.show{opacity:1;transform:translateX(-50%) translateY(0);pointer-events:auto}
/* 🔴 A MESSAGE THAT STAYS IS WAITING ON US, SO IT IS RED (Kevin's three colours, 2026-08-25).
   Navy is the ordinary "here is what happened"; red is the one that needs somebody to do
   something, and staying on screen is exactly what that means. → memory hq-leads-board-design-rules */
.msgtoast.stay{background:#d1392f;cursor:pointer}   /* the same red the Quotes card already uses */
/* 🔴 THE 40-SECOND UNDO BAR, AND ONLY THAT BAR (Kevin, 2026-09-10: "the pop up just look very
   simple. I just thought we can make it look nicer").
   It carries its own class so the ordinary "Saved" message is untouched — a save that suddenly
   looked different everywhere is not what was asked for. This one is a letter on its way out and
   it holds the screen for forty seconds, so it earns a bit more presence: a navy-into-blue
   gradient, a little more room, and a hairline edge to lift it off the page. */
.msgtoast.hqhold{
  background:linear-gradient(135deg,#101d42 0%,#1e3a8f 55%,#3d54d8 100%);
  padding:13px 16px;border-radius:14px;border:1px solid rgba(255,255,255,.14);
  box-shadow:0 14px 38px rgba(10,20,60,.42)}

/* 🔴 UNDO AT THE TOP WHILE SHE TYPES (Kevin, 21 Sept 5:40pm, looking at his own iPhone: "can we just have the pop up
   show… at the top of the screen under the name… a little smaller but visible"). After she sends, the keyboard stays up
   like iPhone Messages, and it covered the Undo bar at the bottom. While she is typing the name bar steps aside, so the
   Undo bar takes that spot instead — a little smaller — where no keyboard can reach it. Keyboard down: unchanged.
   The spot is chosen once, when the pop-up appears (nav.js adds .hqtop), so it cannot jump while she reaches for Undo. */
@media (max-width:860px){
  .msgtoast.hqhold.hqtop{top:calc(var(--hqTopY,0px) + env(safe-area-inset-top) + 8px);bottom:auto;
    transform:translateX(-50%) translateY(-12px);min-width:0!important;width:calc(100vw - 24px);padding:8px 10px!important}
  .msgtoast.hqhold.hqtop.show{transform:translateX(-50%) translateY(0)}
  .msgtoast.hqtop .hqh-ring,.msgtoast.hqtop .hqh-ring svg{width:32px;height:32px}
  .msgtoast.hqtop .hqh-ring b{font-size:13px}
  .msgtoast.hqtop .hqh-txt b{font-size:14px}
  .msgtoast.hqtop .hqh button{padding:7px 12px;font-size:14px}
}

/* THE UNDO POP-UP WEARS THE TYPING AREA'S BLUE (Kevin, 21 Sept 5:50pm, from his iPhone: "the blue gradient… use that
   for the container that says sending… undo or send now"). Same navy fade, same soft glow, same thin blue line on top,
   so the pop-up reads as part of the box she just typed in. Phone only — the desk layout is untouched. */
@media (max-width:860px){
  html .msgtoast.hqhold{background:
    linear-gradient(90deg,rgba(47,107,255,0),#2f6bff 20%,#5b8cff 50%,#2f6bff 80%,rgba(47,107,255,0)) top / 100% 2px no-repeat,
    radial-gradient(320px 110px at 50% 0%,rgba(79,134,255,.45) 0%,rgba(47,107,255,.14) 50%,rgba(0,0,0,0) 100%),
    linear-gradient(165deg,#1d2757 0%,#141a3e 55%,#0d1130 100%)!important}
}

/* THE SAME TWO BUTTONS AS THE PHONE STRIP (Kevin, 21 Sept: "the send now button should be that gold… the steel look using
   the same colors"). Send now wears the gold of Transfer and Pick up — gold means a person does something here. Undo
   wears the steel blue of Hold. Same shape, edge and shadow as the 18 Sept pair, so they read as one family. */
@media (max-width:860px){
  html #hqHoldNow{color:#2a1d00;background:linear-gradient(180deg,#f7d477,#d9a52c);border:1px solid rgba(255,238,198,.75);
    box-shadow:0 6px 16px -8px rgba(120,84,10,.85),inset 0 1px 0 rgba(255,255,255,.55)}
  html #hqHoldUndo{color:#fff;background:linear-gradient(180deg,#5b7bd6,#2c4694);border:1px solid rgba(190,212,255,.5);
    box-shadow:0 6px 16px -8px rgba(20,40,110,.9),inset 0 1px 0 rgba(255,255,255,.35)}
}

/* Sidebar collapse toggle + icon-rail (desktop) */
.navcollapse{margin-left:auto;flex:none;width:30px;height:30px;border-radius:8px;border:1px solid #232f49;background:#182238;color:#9db0d0;display:grid;place-items:center;cursor:pointer;padding:0;transition:background .14s,color .14s}
.navcollapse:hover{background:#22304d;color:#fff}
.navcollapse svg{width:17px;height:17px}
.navlabel{white-space:nowrap;overflow:hidden}
@media(min-width:761px){
  /* Painted from the very first frame — see the inline snippet in each page's head. Without
     this the collapsed rail arrived a frame late and the whole page visibly jumped. */
  html.rail-boot .app{grid-template-columns:70px 1fr}
  .app.navrail{grid-template-columns:70px 1fr}
  .app.navrail .nav{padding:16px 11px}
  /* collapse to icons only */
  .app.navrail .navlabel,
  .app.navrail .navtick,
  .app.navrail .brandtx,
  .app.navrail .client .who,
  .app.navrail .client .chev,
  .app.navrail .navmsg .navmsg-tx,
  .app.navrail .usage{display:none}
  /* Collapsed rail: the heading text goes, and so must its rule — a 0-height box still paints its
     border, which would have left a stray gold line floating in the rail. */
  .app.navrail .navgroup{height:0;padding:8px 0 0;overflow:hidden;border-bottom:0}
  .app.navrail .brand{justify-content:center;gap:0;padding:6px 0 14px}
  .app.navrail .brand .mark{display:none}
  .app.navrail .navcollapse{margin:0 auto}
  /* The collapse button now lives inside the client tile, so in the 70px rail the emblem
     and the button would sit shoulder to shoulder in a space that fits neither. Stack them:
     emblem on top, the button under it — she still needs that button to open the sidebar
     back up, so it must never be the thing that gets squeezed out. */
  .app.navrail .client{flex-direction:column;justify-content:center;gap:8px;padding:8px 4px;margin:4px 0 10px}
  .app.navrail .client .navcollapse{margin:0}
  .app.navrail .navmsg{justify-content:center;padding:10px 0;margin:2px 0 10px}
  .app.navrail .navitem{justify-content:center;padding:10px 0}
  .app.navrail .navmsg .navmsg-ic{margin:0}
}
@media(max-width:760px){ .navcollapse{display:none} }

/* ---------- MAIN ---------- */
.main{display:flex;flex-direction:column;min-width:0}
.topbar{height:64px;background:rgba(255,255,255,.85);backdrop-filter:saturate(1.4) blur(8px);
  border-bottom:1px solid var(--line);display:flex;align-items:center;gap:14px;padding:0 26px;position:sticky;top:0;z-index:5}
.topbar .crumb{color:var(--ink-faint);font-size:13px}
.topbar h1{font-size:17px;margin:0;font-weight:700;letter-spacing:-.01em}
.topbar .grow{flex:1}
.btn{border:0;cursor:pointer;font-weight:650;font-size:13.5px;border-radius:10px;padding:9px 15px;display:inline-flex;align-items:center;gap:8px;font-family:inherit;text-decoration:none}
.btn svg{width:16px;height:16px}
.btn-ghost{background:#fff;border:1px solid var(--line);color:var(--ink-soft)}
.btn-ghost:hover{border-color:#cfd8e6;color:var(--ink)}
.btn-primary{color:#fff;background:linear-gradient(135deg,#3d78ff,#1e4fd6);box-shadow:0 6px 16px rgba(47,107,255,.32)}
.btn-primary:hover{filter:brightness(1.05);box-shadow:0 8px 22px rgba(47,107,255,.42)}
.btn-test{color:#0b6b43;background:var(--good-bg);border:1px solid #bfeed4}
.btn-test:hover{background:#dcf6e8}

.content{padding:26px;max-width:1500px;width:100%}
.stephint{display:flex;align-items:center;gap:10px;color:var(--ink-soft);font-size:13.5px;margin:2px 2px 18px}
.stephint .b{background:var(--brand-tintbg);color:var(--brand-2);font-weight:700;border-radius:8px;padding:2px 9px;font-size:12px}

.split{display:grid;grid-template-columns:1fr 460px;gap:22px;align-items:start}
/* minmax(0,1fr), not 1fr: a plain `1fr` column can never shrink below its content's
   min-content width, so one wide child (a textarea, a long nowrap row) pushed the whole
   PAGE wider than the phone and everything slid sideways. (Elon 2026-08-15) */
@media(max-width:1180px){.split{grid-template-columns:minmax(0,1fr)}}

.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
.card+.card{margin-top:18px}
.card .hd{padding:18px 20px 4px}
.card .hd h2{margin:0;font-size:15.5px;font-weight:700;letter-spacing:-.01em}
.card .hd p{margin:4px 0 0;color:var(--ink-faint);font-size:13px}
.card .bd{padding:16px 20px 20px}

.field{margin-bottom:18px}
.field:last-child{margin-bottom:0}
.label{display:flex;align-items:center;justify-content:space-between;font-size:12.5px;font-weight:700;color:var(--ink-soft);margin-bottom:7px;letter-spacing:.01em}
.label .hint{font-weight:500;color:var(--ink-faint);font-size:11.5px}
textarea,input[type=text],select{width:100%;font-family:inherit;font-size:14px;color:var(--ink);background:#fbfcfe;
  border:1px solid var(--line);border-radius:11px;padding:11px 13px;outline:none;transition:border .12s,box-shadow .12s}
textarea:focus,input:focus,select:focus{border-color:var(--brand);box-shadow:0 0 0 3px rgba(47,107,255,.12);background:#fff}
/* PLACEHOLDERS WERE THE BROWSER'S OWN GREY and nothing overrode it. Kevin, 2026-08-24, looking
   at the agent card: *"you can't read the writing. It's deselected."* He had taken the greyed
   example name for a real entry that was somehow switched off — which is the whole failure of
   faint text: it does not read as a hint, it reads as something broken. Darker, and italic so a
   prompt can never be mistaken for a value somebody typed.
   → memory 0.5 in CLAUDE.md: no faint low-opacity grey on anything Kevin reads. */
::placeholder{color:#6b7691;opacity:1;font-style:italic}
textarea::placeholder,input::placeholder{color:#6b7691;opacity:1;font-style:italic}
textarea{resize:vertical;min-height:82px;line-height:1.55}
.autonote{display:inline-flex;align-items:center;gap:6px;background:var(--brand-tintbg);color:var(--brand-2);
  font-size:11.5px;font-weight:600;padding:3px 9px;border-radius:99px;margin-top:8px}
.autonote svg{width:13px;height:13px}

.voicepick{display:flex;align-items:center;gap:12px;border:1px solid var(--line);border-radius:12px;padding:11px 13px;background:#fbfcfe}
.voicepick .av{width:38px;height:38px;border-radius:10px;background:linear-gradient(135deg,#eaf0ff,#dbe6ff);display:grid;place-items:center;color:#1e4fd6}
.voicepick .meta{flex:1;min-width:0}
.voicepick .meta b{font-size:14px}
.voicepick .tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:3px}
.tag{font-size:10.5px;font-weight:700;color:var(--ink-soft);background:#eef2f8;border-radius:6px;padding:2px 7px}
.miniplay{border:0;cursor:pointer;width:34px;height:34px;border-radius:9px;background:#fff;border:1px solid var(--line);display:grid;place-items:center;color:var(--brand-2)}
.miniplay:hover{background:var(--brand-tintbg)}

.toggle{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:#fbfcfe}
.toggle .t b{font-size:13.5px}
.toggle .t span{display:block;font-size:12px;color:var(--ink-faint);margin-top:1px}
.sw{width:42px;height:24px;border-radius:99px;background:#d6deea;position:relative;cursor:pointer;flex:none;transition:background .15s}
.sw i{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.2);transition:left .15s}
.sw.on{background:var(--brand)}
.sw.on i{left:20px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}

/* ---- PREVIEW COLUMN ---- */
.preview{position:sticky;top:88px}
.preview .hd{display:flex;align-items:center;gap:8px}
.preview .hd .live{margin-left:auto;display:inline-flex;align-items:center;gap:6px;color:var(--good);font-weight:700;font-size:11.5px;background:var(--good-bg);padding:3px 9px;border-radius:99px}
.preview .hd .live .pulse{width:7px;height:7px;border-radius:50%;background:var(--good);box-shadow:0 0 0 0 rgba(18,183,106,.5);animation:pulse 1.8s infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(18,183,106,.5)}70%{box-shadow:0 0 0 7px rgba(18,183,106,0)}100%{box-shadow:0 0 0 0 rgba(18,183,106,0)}}
.phone{margin:6px auto 2px;width:290px;background:linear-gradient(180deg,#0f1729,#182238);border-radius:34px;padding:12px;box-shadow:var(--shadow-lg)}
.phone .screen{background:#f2f5fb;border-radius:24px;overflow:hidden;height:430px;display:flex;flex-direction:column}
.phone .callbar{background:#fff;padding:14px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:11px}
.phone .callbar .ring{width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,#3d78ff,#1e4fd6);display:grid;place-items:center;color:#fff}
.phone .callbar b{font-size:13.5px;display:block}
.phone .callbar span{font-size:11px;color:var(--ink-faint)}
.phone .chat{flex:1;padding:16px;display:flex;flex-direction:column;gap:10px;overflow:auto}
.bubble{max-width:82%;padding:10px 13px;border-radius:15px;font-size:13px;line-height:1.5;box-shadow:0 1px 2px rgba(16,26,48,.06)}
.bubble.ai{background:#fff;border:1px solid var(--line);border-bottom-left-radius:5px;align-self:flex-start}
.bubble.caller{background:linear-gradient(135deg,#3d78ff,#1e4fd6);color:#fff;border-bottom-right-radius:5px;align-self:flex-end}
.bubble .lbl{font-size:9.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;opacity:.6;margin-bottom:3px}

/* ── ONE CONVERSATION LOOKS THE SAME EVERYWHERE (Emmet, 2026-08-24) ─────────────────────────
   Kevin, having seen the coloured containers on Customer Messages and then opened a lead:
   "I thought we were changing the interior side of going back and forth within the lead section
   to match the customer and team messages… I would like that to make it consistent."

   Fair. Customer Messages coloured a message by the road it travelled — their text green, their
   email white, anything WE sent blue — and the customer's own record drew its own plain blue and
   grey bubbles that said nothing about which was which. Same conversation, two looks, and only
   one of them told you anything.

   The rules moved here so BOTH pages read from one place. conversations.html carried them in its
   own <style>, which is exactly why the record never got them. Left/right still says who is
   talking; colour says how it reached us.
   ⚠️ These deliberately come AFTER .bubble.caller above, which is the older call-transcript look
   (caller = blue, right-hand). A page using the thread classes gets the thread colours. */
.thr{display:flex;flex-direction:column;gap:9px}
.thr .bubble.caller{align-self:flex-start;background:#fff;border:1px solid var(--line);color:var(--ink);
  border-bottom-left-radius:5px;border-bottom-right-radius:15px}
.thr .bubble.caller.ch-text{background:#eafaf1;border-color:#bfe7d2}
.thr .bubble.caller.ch-text .lbl{color:#0b6b43}
.thr .bubble.caller.ch-email{background:#fff;border-color:var(--line)}
.thr .bubble.you{align-self:flex-end;background:var(--brand);color:#fff;border:0;
  border-bottom-right-radius:5px;border-bottom-left-radius:15px}
.thr .bubble.you .lbl{color:rgba(255,255,255,.74)}
.thr .bubble.you.ch-text{background:linear-gradient(135deg,#12915a,#0b6b43)}
.thr .chan{display:inline-flex;align-items:center;gap:3px;margin-left:7px;
  font-size:9.5px;font-weight:900;letter-spacing:.06em;text-transform:uppercase;opacity:.78}
/* Kevin's floor is ~14px and she reads this on a phone. → memory: hq-type-scale */
.thr .bubble{font-size:14px}

/* ══ WHO IS SPEAKING (Kevin, 2026-08-25) ══════════════════════════════════════
   "It's getting all mushed together… we need to be really clear on who is
   speaking, the prospect or us."

   Colour alone was doing the work, and on a busy thread it stopped reading at a
   glance. Three things now say it, so no single one has to carry it:
     · a solid bar down the OUTSIDE edge — theirs on the left, ours on the right
     · the word THEM or US in front of the name, not just the name
     · the bubble's own fill, which is what it always had
   Sides and fills are unchanged; this only makes them unmissable.
   ═══════════════════════════════════════════════════════════════════════════ */
.thr .bubble.caller{border-left:4px solid #94a3c4}
.thr .bubble.caller.ch-text{border-left-color:#12915a}
/* HIE's own gold, not one mixed by eye — and it is OURS, not theirs (Kevin, 2026-08-25). */
.thr .bubble.you{border-right:4px solid var(--hie-gold,#d5a12e)}
.thr .bubble.you.ch-text{border-right-color:#0b6b43}
/* The name line was 10.5px — the smallest type in the product, on the one line
   that answers "who said this". */
.thr .bubble .lbl{font-size:12px;font-weight:800;letter-spacing:.05em}
.thr .bubble.caller .lbl{color:#5a6178}
.thr .bubble.caller .lbl::before{content:'THEM · ';color:#8a90a6}
.thr .bubble.you .lbl::before{content:'US · ';color:rgba(255,255,255,.9)}
@media (max-width:640px){ .thr .bubble .lbl{font-size:14px} }
@media (max-width:640px){ .thr .chan{font-size:14px} }
.wave{display:flex;align-items:center;gap:3px;height:26px;margin-top:8px}
.wave i{width:3px;background:var(--brand);border-radius:9px;opacity:.85;animation:w 1s ease-in-out infinite}
@keyframes w{0%,100%{height:6px}50%{height:22px}}
.playbtn{margin:14px 20px 4px;width:calc(100% - 40px);justify-content:center;padding:12px}
.previewfoot{padding:2px 20px 18px;text-align:center;color:var(--ink-faint);font-size:12px}

/* ---- CALL FLOW specifics ---- */
.pillrow{display:flex;gap:8px;flex-wrap:wrap}
.pilltab{border:1px solid var(--line);background:#fff;border-radius:10px;padding:8px 13px;font-size:13px;font-weight:600;color:var(--ink-soft);cursor:pointer;display:inline-flex;align-items:center;gap:7px}
.pilltab .n{background:#eef2f8;color:var(--ink-faint);border-radius:6px;font-size:10.5px;padding:1px 6px;font-weight:800}
.pilltab.active{border-color:var(--brand);background:var(--brand-tintbg);color:var(--brand-2)}
.pilltab.active .n{background:var(--brand);color:#fff}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{display:inline-flex;align-items:center;gap:7px;background:#fbfcfe;border:1px solid var(--line);border-radius:99px;padding:6px 8px 6px 12px;font-size:13px;font-weight:600;color:var(--ink)}
.chip x{cursor:pointer;color:var(--ink-faint);font-weight:700;display:grid;place-items:center;width:18px;height:18px;border-radius:50%}
.chip x:hover{background:#eef2f8;color:var(--ink)}
.chip.add{border-style:dashed;color:var(--brand-2);cursor:pointer;padding:6px 12px}
.checkgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px 14px}
.check{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--ink);cursor:pointer}
.check .box{width:19px;height:19px;border-radius:6px;border:1.5px solid #cdd7e6;display:grid;place-items:center;flex:none}
.check.on .box{background:var(--brand);border-color:var(--brand);color:#fff}
.check .box svg{width:12px;height:12px;opacity:0}
.check.on .box svg{opacity:1}
.radiocards{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}
.rc{border:1.5px solid var(--line);border-radius:12px;padding:12px;cursor:pointer;background:#fbfcfe;text-align:center}
.rc svg{width:20px;height:20px;color:var(--ink-faint);margin-bottom:6px}
.rc b{display:block;font-size:13px}
.rc span{font-size:11px;color:var(--ink-faint)}
.rc.active{border-color:var(--brand);background:var(--brand-tintbg)}
.rc.active svg{color:var(--brand-2)}
.subcard{margin-top:12px;border:1px solid var(--line-soft);background:#fbfcfe;border-radius:12px;padding:14px}
/* flow steps in preview */
.flow{padding:14px 18px 4px}
.fstep{display:flex;gap:12px;align-items:flex-start;position:relative;padding-bottom:16px}
.fstep:not(:last-child):before{content:"";position:absolute;left:15px;top:30px;bottom:0;width:2px;background:var(--line)}
.fstep .ic{width:32px;height:32px;border-radius:9px;flex:none;display:grid;place-items:center;background:var(--brand-tintbg);color:var(--brand-2);z-index:1}
.fstep.done .ic{background:var(--good-bg);color:var(--good)}
.fstep .fx b{font-size:13px;display:block}
.fstep .fx span{font-size:11.5px;color:var(--ink-faint)}

/* ---- LEADS BOARD (Trello) ---- */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:20px}
/* ⭐ TWO CONTAINERS, and a line under each saying what it means (Kevin, 2026-09-07). Four tiles
   across is right when there are four; two stretched across the same width read as a mistake.
   → memory hie-proposals-two-containers */
/* Four containers, and each one is a BUTTON that narrows the list below it. Kevin, 2026-09-07:
   *"maybe these are our containers?"* — the tiles and the filter row were two rows saying the
   same thing, so the filter row went and the tiles took the job. */
.stats.stats-4{grid-template-columns:repeat(4,1fr)}
/* Five across on a wide screen; on anything narrower they wrap two-up rather than shrinking to
   nothing, and the names stay readable — which is the whole reason they were made bigger. */
.stats.stats-5{grid-template-columns:repeat(5,1fr)}
@media (max-width:1100px){ .stats.stats-5{grid-template-columns:repeat(3,1fr)} }
@media (max-width:760px){ .stats.stats-5{grid-template-columns:repeat(2,1fr)} }
.stats .statbtn{font-family:inherit;text-align:left;cursor:pointer;border:1px solid var(--line);
  transition:border-color .12s,box-shadow .12s}
.stats .statbtn:hover{border-color:#0f1729}
/* 🔴 THE CHOSEN ONE IS MARKED, NOT REPAINTED (Kevin, 2026-09-07: "I don't like the container
   colour when you click on it"). Filling the whole container navy turned the one she had just
   chosen into the darkest thing on a white page — the number and its description had to flip to
   white to survive, and the row stopped looking like four of the same thing.
   A navy edge and a soft tint instead: unmistakably the chosen one, still plainly a container. */
.stats .statbtn.on{background:#f4f7ff;border-color:#0f1729;box-shadow:inset 0 0 0 1px #0f1729}
.stats .statbtn.on .k{color:#0f1729}
.stats .sd{margin-top:4px;font-size:13.5px;font-weight:600;color:#5a6178;line-height:1.4}
@media (max-width:640px){
  .stats.stats-2{grid-template-columns:1fr;max-width:none}
  .stats .sd{font-size:14px}
}
.stat{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:15px 16px;box-shadow:var(--shadow)}
/* 🔴 THE NAME IS THE POINT, NOT THE NUMBER (Kevin, 2026-09-07: "can you make these bigger, the
   names"). At 12px, faint and only semi-bold, "Needs following up" was smaller than the smallest
   type anywhere else on the page — under his own 14px floor, on the four words that say what the
   container IS. The number underneath was 26px and needed no help.
   → memory hq-type-scale · hq-leads-board-design-rules */
.stat .k{font-size:15px;color:var(--ink);font-weight:800;display:flex;align-items:center;gap:8px;line-height:1.3}
.stat .k .di{width:22px;height:22px;border-radius:7px;display:grid;place-items:center;color:#fff}
.stat .v{font-size:26px;font-weight:800;letter-spacing:-.02em;margin-top:8px}
.stat .v small{font-size:13px;font-weight:600;color:var(--good);margin-left:6px}
.toolbar{display:flex;align-items:center;gap:10px;margin-bottom:16px}
.search{flex:1;max-width:320px;position:relative}
.search svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:15px;height:15px;color:var(--ink-faint)}
.search input{padding-left:34px}
.seg{display:flex;background:#fff;border:1px solid var(--line);border-radius:10px;overflow:hidden}
.seg b{padding:8px 13px;font-size:12.5px;color:var(--ink-soft);cursor:pointer;font-weight:600}
.seg b.on{background:var(--brand-tintbg);color:var(--brand-2)}

.board{display:flex;gap:16px;overflow-x:auto;padding-bottom:10px}
.col{flex:0 0 286px;background:#eaeef6;border-radius:14px;padding:10px;display:flex;flex-direction:column;gap:10px}
.colhd{display:flex;align-items:center;gap:8px;padding:4px 6px 2px;font-weight:700;font-size:13px;color:var(--ink)}
.colhd .cdot{width:9px;height:9px;border-radius:50%}
.colhd .ct{margin-left:auto;background:#dbe2ee;color:var(--ink-soft);border-radius:7px;font-size:11px;font-weight:800;padding:1px 8px}
.lead{background:#fff;border:1px solid var(--line);border-radius:12px;padding:12px;box-shadow:var(--shadow);cursor:pointer;transition:transform .1s,box-shadow .1s}
.lead:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg)}
.lead .lt{display:flex;gap:10px;align-items:center}
.lead .ava{width:34px;height:34px;border-radius:9px;background:linear-gradient(135deg,#eaf0ff,#dbe6ff);color:#1e4fd6;display:grid;place-items:center;font-weight:800;font-size:12.5px;flex:none}
.lead .nm{min-width:0}
.lead .nm b{font-size:13.5px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lead .nm span{font-size:11.5px;color:var(--ink-faint)}
.jrny{display:flex;gap:5px;margin-top:11px}
.jico{width:25px;height:25px;border-radius:7px;background:#f1f4f9;color:#b8c2d4;display:grid;place-items:center}
.jico svg{width:13px;height:13px}
.jico.on{background:var(--brand-tintbg);color:var(--brand-2)}
.jico.ok{background:var(--good-bg);color:var(--good)}
.lead .lf{display:flex;align-items:center;justify-content:space-between;margin-top:11px}
.srcchip{font-size:10.5px;font-weight:700;color:var(--ink-soft);background:#eef2f8;border-radius:6px;padding:2px 7px}
.lead .ago{font-size:11px;color:var(--ink-faint)}
.lead.win{border-color:#bfeed4;background:linear-gradient(180deg,#f2fdf7,#fff)}

/* ---- LEAD DETAIL / TIMELINE ---- */
.backlink{display:inline-flex;align-items:center;gap:7px;color:var(--ink-soft);font-size:13px;text-decoration:none;font-weight:600;margin-bottom:14px}
.backlink:hover{color:var(--brand-2)}
.backlink svg{width:15px;height:15px}
.detailhead{display:flex;align-items:center;gap:14px;margin-bottom:20px}
.detailhead .ava{width:50px;height:50px;border-radius:13px;background:linear-gradient(135deg,#eaf0ff,#dbe6ff);color:#1e4fd6;display:grid;place-items:center;font-weight:800;font-size:17px;flex:none}
.detailhead h2{margin:0;font-size:20px;letter-spacing:-.02em}
.detailhead p{margin:3px 0 0;color:var(--ink-faint);font-size:13px}
.stagebadge{display:inline-flex;align-items:center;gap:7px;font-size:11.5px;font-weight:800;padding:5px 12px;border-radius:99px;background:#fef4e2;color:#a4670a;letter-spacing:.02em}
.stagebadge .cdot{width:8px;height:8px;border-radius:50%;background:#f59e0b}
/* recording player */
.player{display:flex;align-items:center;gap:14px;padding:16px 18px}
.player .pbtn{width:46px;height:46px;border-radius:50%;background:linear-gradient(135deg,#3d78ff,#1e4fd6);color:#fff;display:grid;place-items:center;border:0;cursor:pointer;flex:none;box-shadow:0 6px 16px rgba(47,107,255,.32)}
.player .pbtn svg{width:19px;height:19px}
.player .pw{flex:1}
.player .pw .bars{display:flex;align-items:center;gap:2px;height:32px}
.player .pw .bars i{flex:1;background:#d3ddec;border-radius:9px;min-width:2px}
.player .pw .bars i.p{background:var(--brand)}
.player .time{font-size:12px;color:var(--ink-faint);font-variant-numeric:tabular-nums;white-space:nowrap}
/* timeline */
.tl{padding:4px 4px 4px 2px}
.tl .ev{display:flex;gap:14px;position:relative;padding-bottom:20px}
.tl .ev:not(:last-child):before{content:"";position:absolute;left:17px;top:38px;bottom:0;width:2px;background:var(--line)}
.tl .ev .eic{width:36px;height:36px;border-radius:10px;flex:none;display:grid;place-items:center;z-index:1}
.tl .ev .eic svg{width:16px;height:16px}
.eic.call{background:var(--brand-tintbg);color:var(--brand-2)}
.eic.text{background:#eaf6ff;color:#0284c7}
.eic.book{background:#fef4e2;color:#a4670a}
.eic.mail{background:#f0edff;color:#6d5ae0}
.tl .ev .ec{flex:1;min-width:0;background:#fbfcfe;border:1px solid var(--line);border-radius:12px;padding:12px 14px}
.tl .ev .ec .eh{display:flex;justify-content:space-between;align-items:baseline;gap:10px;margin-bottom:5px}
.tl .ev .ec .eh b{font-size:13.5px}
.tl .ev .ec .eh span{font-size:11.5px;color:var(--ink-faint);white-space:nowrap}
.tl .ev .ec p{margin:0;font-size:13px;color:var(--ink-soft);line-height:1.55}
.msgq{background:#fff;border:1px solid var(--line);border-radius:9px;padding:9px 11px;font-size:12.5px;color:var(--ink);margin-top:8px;line-height:1.5}
.linkghost{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--brand-2);margin-top:9px;cursor:pointer}
.linkghost svg{width:13px;height:13px}
/* detail panel */
.drow{padding:11px 0;border-bottom:1px solid var(--line-soft)}
.drow:last-child{border-bottom:0}
.drow .dl{font-size:10.5px;color:var(--ink-faint);font-weight:800;letter-spacing:.05em;text-transform:uppercase}
.drow .dv{font-size:13.5px;margin-top:3px}
.collected{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}

/* ---- DASHBOARD ---- */
.statusbar{display:flex;align-items:center;gap:18px;background:linear-gradient(135deg,#0f1729,#1b2942);border-radius:16px;padding:18px 22px;color:#fff;margin-bottom:20px;box-shadow:var(--shadow)}
.statusbar .live2{display:inline-flex;align-items:center;gap:8px;background:rgba(18,183,106,.18);color:#5ff0a8;font-weight:800;font-size:11.5px;padding:6px 12px;border-radius:99px;letter-spacing:.03em}
.statusbar .live2 .pulse{width:8px;height:8px;border-radius:50%;background:#22e08a;box-shadow:0 0 0 0 rgba(34,224,138,.5);animation:pulse 1.8s infinite}
.statusbar h3{margin:0;font-size:16px;font-weight:700}
.statusbar p{margin:3px 0 0;font-size:12.5px;color:#9fb0cf}
.statusbar .num{font-size:18px;font-weight:800;letter-spacing:.02em}
.statusbar .btn-test{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.18);color:#dcecff}
.statusbar .btn-test:hover{background:rgba(255,255,255,.18)}
.dashcols{display:grid;grid-template-columns:1.6fr 1fr;gap:20px;align-items:start}
@media(max-width:1100px){.dashcols{grid-template-columns:1fr}}
.legend{display:flex;gap:16px;padding:0 20px 8px;font-size:12px;color:var(--ink-soft)}
.legend b{display:inline-flex;align-items:center;gap:6px;font-weight:600}
.legend .sw2{width:10px;height:10px;border-radius:3px}
.chartwrap{padding:4px 12px 14px}
.recent .r{display:flex;align-items:center;gap:11px;padding:11px 8px;border-bottom:1px solid var(--line-soft);cursor:pointer}
.recent .r:last-child{border-bottom:0}
.recent .r:hover{background:#fbfcfe}
.recent .r .ava{width:32px;height:32px;border-radius:8px;background:linear-gradient(135deg,#eaf0ff,#dbe6ff);color:#1e4fd6;display:grid;place-items:center;font-weight:800;font-size:11.5px;flex:none}
.recent .r .nm{flex:1;min-width:0}
.recent .r .nm b{font-size:13px;display:block}
.recent .r .nm span{font-size:11.5px;color:var(--ink-faint)}
.stagedot{font-size:10px;font-weight:800;padding:3px 9px;border-radius:99px;white-space:nowrap}

/* ---- CONVERSATIONS (inbox) ---- */
.inbox{display:grid;grid-template-columns:290px 1fr 288px;border:1px solid var(--line);border-radius:16px;overflow:hidden;background:#fff;box-shadow:var(--shadow);height:calc(100vh - 150px);min-height:520px}
.inbox .list{border-right:1px solid var(--line);overflow:auto;background:#fbfcfe}
.inbox .lhd{padding:14px 15px 10px;font-weight:700;font-size:14px;border-bottom:1px solid var(--line-soft);position:sticky;top:0;background:#fbfcfe}
.litem{padding:12px 15px;border-bottom:1px solid var(--line-soft);cursor:pointer}
.litem:hover{background:#f2f5fb}
.litem.active{background:var(--brand-tintbg);box-shadow:inset 3px 0 0 var(--brand)}
.litem .lt{display:flex;align-items:center;gap:8px}
.litem .ava{width:30px;height:30px;border-radius:8px;background:linear-gradient(135deg,#eaf0ff,#dbe6ff);color:#1e4fd6;display:grid;place-items:center;font-weight:800;font-size:11px;flex:none}
.litem b{font-size:13px;flex:1}
.litem .tm{font-size:10.5px;color:var(--ink-faint)}
.litem p{margin:6px 0 0;font-size:12px;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 🔴 min-height:0 IS WHAT MAKES THE CONVERSATION SCROLL (Kevin, 2026-09-01):
   "this page is locked up, it doesn't even fucking move." Customer Messages sits in a fixed-height
   box and .msgs below is meant to take the leftover space and scroll. Without min-height:0 a
   column flex item refuses to shrink below its own content, so .msgs simply grew as tall as the
   letter inside it and the overflow was clipped off the bottom of the box - no scrollbar, no way
   to reach anything underneath. Kevin is right that this used to work: it only broke when
   Justine's packages letter started being stored in full on the thread, which made one message
   taller than the whole pane for the first time. His reply to Eric Single-Family was sitting
   right under that letter the whole time and he could not get to it, so he believed his text had
   never arrived. → memory hq-customer-messages-merged-inbox */
.thread{display:flex;flex-direction:column;min-width:0;min-height:0}
.thread .thd{padding:13px 18px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.thread .thd .ava{width:34px;height:34px;border-radius:9px;background:linear-gradient(135deg,#eaf0ff,#dbe6ff);color:#1e4fd6;display:grid;place-items:center;font-weight:800;font-size:12px}
.thread .thd b{font-size:14px}
.thread .thd span{font-size:11.5px;color:var(--ink-faint);display:block}
/* 🔴 THE LAST MESSAGE MUST CLEAR THE REPLY BOX — Kevin, 2026-09-08: *"I don't like that these
   containers are cut off by the box that we have down at the bottom. Can it not scroll down
   beneath it?"* The reply box is pinned at the bottom, so the newest message ended its scroll
   half-hidden behind it and he could not read his own newest message without dragging it up
   by hand. Extra room at the foot of the conversation lets the last bubble scroll clear —
   the same thing Messages does. */
.thread .msgs{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding:18px 18px 34px;display:flex;flex-direction:column;gap:12px;background:#f7f9fc}
.thread .msgs > *{flex:none}   /* a tall letter keeps its height and scrolls; it never squashes the ones above it */
.thread .reply{border-top:1px solid var(--line);padding:12px 16px;display:flex;align-items:center;gap:10px;background:#fff}
.thread .reply input{flex:1}
.aitag{display:inline-flex;align-items:center;gap:5px;background:var(--good-bg);color:var(--good);font-size:10px;font-weight:800;padding:2px 7px;border-radius:6px;letter-spacing:.03em}
.inbox .side{border-left:1px solid var(--line);overflow:auto;padding:16px;background:#fbfcfe}
.sidehd{font-weight:700;font-size:13.5px;margin-bottom:6px}

/* PHONE: the inbox is three columns and TWO OF THEM ARE FIXED (290px + 288px = 578px). On a
   375px screen that leaves the middle column — the conversation you are trying to read — at
   ZERO width. The list rendered fine, so it looked like it worked; you simply could not open
   anything. There was no phone breakpoint for it at all; the only mobile rule on that page
   adjusts text size. Stack them instead, list first. Jeannine works on a phone.
   (Emmet 2026-08-21 — found by measuring the real page at 375, not by reading the CSS.) */
@media(max-width:760px){
  .inbox{grid-template-columns:minmax(0,1fr);height:auto;min-height:0}
  .inbox .list{border-right:0;border-bottom:1px solid var(--line);max-height:40vh}
  .thread{min-height:58vh}
  .inbox .side{border-left:0;border-top:1px solid var(--line)}
}

/* ---- CONNECTIONS (integrations) ---- */
.integ-sec{margin-bottom:24px}
.integ-sec .sh{font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint);margin:0 2px 12px}
.integ-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
@media(max-width:900px){.integ-grid{grid-template-columns:1fr}}
.integ{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:15px 17px;display:flex;align-items:center;gap:14px;box-shadow:var(--shadow)}
.integ .ilogo{width:44px;height:44px;border-radius:11px;display:grid;place-items:center;flex:none;font-weight:800;font-size:14px;color:#fff}
.integ .im{flex:1;min-width:0}
.integ .im b{font-size:14.5px;display:block}
.integ .im span{font-size:12.5px;color:var(--ink-faint)}
.integ .connected{display:inline-flex;align-items:center;gap:6px;color:var(--good);font-weight:700;font-size:12px;background:var(--good-bg);padding:6px 11px;border-radius:9px;white-space:nowrap}
.btn-connect{background:var(--brand-tintbg);color:var(--brand-2);border:1px solid #d5e2ff;padding:8px 15px;border-radius:9px;font-weight:700;font-size:12.5px;cursor:pointer;font-family:inherit;white-space:nowrap}
.btn-connect:hover{background:#e2ecff}

/* ============ MOBILE SHELL (mobile-first — Jeannine runs this on her phone) ============ */
.hamburger{display:none;width:40px;height:40px;flex:none;border:1px solid var(--line);background:#fff;border-radius:10px;cursor:pointer;align-items:center;justify-content:center;color:var(--ink);padding:0}
/* Kevin, 2026-08-23, on his iPhone: "the home icon looks like a dot, it doesn't look like a
   hamburger menu." At phone size a 2px stroke on a 20px box collapses into a grey smear. Bigger,
   thicker, rounded — it has to read as three bars at arm's length on a moving phone. */
.hamburger svg{width:24px;height:24px;flex:none;stroke-width:2.6;stroke-linecap:round}
.navscrim{position:fixed;inset:0;background:rgba(10,14,26,.5);z-index:39;opacity:0;pointer-events:none;transition:opacity .2s}
.navscrim.show{opacity:1;pointer-events:auto}
@media(max-width:760px){
  .app{grid-template-columns:1fr}
  .nav{position:fixed;top:0;left:0;height:100vh;width:270px;z-index:40;transform:translateX(-100%);transition:transform .22s ease;box-shadow:0 0 44px rgba(0,0,0,.45)}
  .nav.open{transform:none}
  .hamburger{display:inline-flex}
  .topbar{padding:0 13px;gap:9px;flex-wrap:wrap;height:auto;min-height:60px;padding-top:9px;padding-bottom:9px}
  .topbar .crumb{display:none}
  .topbar h1{font-size:16px}
  .topbar .btn{padding:8px 12px;font-size:12.5px}
  .content{padding:16px}
  .split{gap:16px}
  .preview{position:static}
  .stats{grid-template-columns:1fr 1fr}
  .grid2{grid-template-columns:1fr}
}
@media(max-width:400px){
  .topbar h1{font-size:15px}
  .topbar .btn span{display:none}
  .topbar .btn{padding:9px}
}

/* ============ ZERO-MANUAL HELP — add data-help="..." to any element ============ */
/* The mark is an "i" now, not a "?" (Kevin, 2026-08-25). A lower-case i is narrow, so it needs
   a serif-ish face and a touch of letter-spacing or it reads as a speck; 18px and the italic
   give it enough shape to be recognised at a glance without shouting over the heading it sits
   beside. */
.helpdot{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;
  background:var(--brand-tintbg);color:var(--brand-2);font:italic 700 12px/1 Georgia,'Times New Roman',serif;
  cursor:pointer;border:1px solid #d5e2ff;padding-right:1px;
  margin-left:6px;vertical-align:middle;user-select:none;flex:none;transition:background .12s,transform .12s}
.helpdot:hover{background:#deeaff;transform:scale(1.08)}
/* 🔴 THE "WHAT THIS IS" DOT WAS 18px ON A PHONE (19 Sept sweep, measured live at 430px on
   nine different screens). An 18px circle is a miss-tap with a thumb, and the same dot sits
   beside the title on nearly every office screen, so one size here fixes all of them.
   The dot grows to a real 38px target with 10px of clear space all round, and the circle you
   SEE stays exactly 18px because the tint is painted only inside that space. Nothing moves
   sideways: the 10px it gains on the left is given back from its own left margin. */
@media (max-width:760px){
  .helpdot{width:38px;height:38px;padding:10px;box-sizing:border-box;
    background-clip:content-box;border:0;margin-left:-4px;padding-right:10px}
}
.helppop{position:fixed;z-index:60;max-width:280px;background:#0f1729;color:#eef2fb;font-size:14px;line-height:1.5;
  padding:12px 14px;border-radius:12px;box-shadow:0 14px 38px rgba(10,14,26,.42);border:1px solid rgba(255,255,255,.09);
  opacity:0;transform:translateY(-5px);pointer-events:none;transition:opacity .14s ease,transform .14s ease;font-weight:500}
.helppop.show{opacity:1;transform:none;pointer-events:auto}
.helppop:after{content:"";position:absolute;top:-6px;left:var(--ax,16px);width:11px;height:11px;background:#0f1729;
  border-left:1px solid rgba(255,255,255,.09);border-top:1px solid rgba(255,255,255,.09);transform:rotate(45deg)}
.helppop.flip:after{top:auto;bottom:-6px;border-left:none;border-top:none;border-right:1px solid rgba(255,255,255,.09);border-bottom:1px solid rgba(255,255,255,.09)}

/* ===== Ported from 827-HQ build: HIE brand vars + intake/proposal/customers/reviews page CSS ===== */
:root{ --hie-navy:#2d2160; --hie-navy-2:#3a2d7a; --hie-gold:#d5a12e; --hie-gold-2:#e7b743; --hie-ink:#1c1540; }

/* client logo chip in the left nav */
.client .dot.logo{background:#fff;padding:3px}
.client .dot.logo img{width:100%;height:100%;object-fit:contain;display:block}

/* ---- INCOMING-CALL BANNER ---- */
.callbanner{display:flex;align-items:center;gap:16px;background:linear-gradient(135deg,var(--hie-navy),var(--hie-navy-2));
  border-radius:16px;padding:16px 20px;color:#fff;margin-bottom:20px;box-shadow:var(--shadow);position:relative;overflow:hidden}
.callbanner:before{content:"";position:absolute;right:-40px;top:-40px;width:180px;height:180px;border-radius:50%;
  background:radial-gradient(circle,rgba(213,161,46,.35),transparent 65%)}
.callbanner .ph{width:46px;height:46px;border-radius:12px;background:rgba(255,255,255,.14);display:grid;place-items:center;flex:none}
.callbanner .ph svg{width:22px;height:22px;color:#fff}
.callbanner .ring{position:absolute;inset:0;border-radius:12px;border:2px solid rgba(213,161,46,.6);animation:cbring 1.6s ease-out infinite}
@keyframes cbring{0%{transform:scale(1);opacity:.8}100%{transform:scale(1.5);opacity:0}}
.callbanner h3{margin:0;font-size:16px;font-weight:800;letter-spacing:-.01em}
.callbanner p{margin:2px 0 0;font-size:12.5px;color:#c9c1ef}
.callbanner .hielogo{margin-left:auto;height:40px;background:#fff;border-radius:9px;padding:5px 10px;display:flex;align-items:center}
.callbanner .hielogo img{height:100%;object-fit:contain}
.callbanner .live2{position:relative;display:inline-flex;align-items:center;gap:7px;background:rgba(213,161,46,.22);color:#ffdd8a;
  font-weight:800;font-size:11.5px;padding:6px 12px;border-radius:99px;letter-spacing:.03em}
.callbanner .live2 .pulse{width:8px;height:8px;border-radius:50%;background:var(--hie-gold-2);box-shadow:0 0 0 0 rgba(231,183,67,.5);animation:pulse 1.6s infinite}

/* ---- INTAKE LAYOUT ---- */
/* The right column was pinned at exactly 400px with the left on 1fr, and the two columns
   only stack below 860px — so at any window between those the page came out wider than the
   screen and the whole right column hung off the edge. Kevin, 2026-08-22, at 1181px wide:
   "I don't remember it ever going off the page." It needed 1195.
   minmax lets the column give up to 80px before the stack point, so it always fits. */
.intake{display:grid;grid-template-columns:minmax(0,1fr) minmax(320px,400px);gap:22px;align-items:start}
@media(max-width:1180px){.intake{grid-template-columns:1fr}}
.sectlabel{display:flex;align-items:center;gap:9px;flex-wrap:wrap;row-gap:8px;font-size:11px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-faint);margin:0 2px 12px}
.sectlabel>span:not(.n){white-space:nowrap}
.sectlabel .n{width:20px;height:20px;border-radius:6px;background:var(--hie-navy);color:#fff;display:grid;place-items:center;font-size:11px;font-weight:800}

/* property auto-pull card — Redfin-style: photos → facts → portal buttons */
.property{border:1px solid var(--line);border-radius:14px;overflow:hidden;background:#fff;margin-top:4px}

/* ── photo strip (Street View + Satellite; tap → full-screen swipe) ── */
/* ONE ROW, TWO TILES. It used to be a 2x2 grid with the street view spanning both rows —
   which left the bottom-right cell EMPTY, and that grey rectangle under the satellite is
   what Kevin was looking at when he said "I don't like the way this looks". There are only
   ever two pictures, so there should only ever be two cells.
   Taller too (212 → 248): at the old height both photos were cropped to a letterbox band,
   so you saw a strip of house rather than the house. */
.pgal{position:relative;display:grid;grid-template-columns:1.5fr 1fr;grid-template-rows:1fr;gap:2px;background:var(--line);height:248px;cursor:zoom-in}
.pgal .pshot{position:relative;overflow:hidden;background:linear-gradient(135deg,#dfe7f2,#eef3fa)}
.pgal .pshot img{width:100%;height:100%;object-fit:cover;display:block}
/* A picture that failed shows nothing — no description, no broken-image mark. */
.pgal .pshot img[alt='']{color:transparent;font-size:0}
/* placeholder grid look until Elon wires real Street View / satellite images */
.pgal .pshot.ph:before{content:"";position:absolute;inset:0;
  background-image:linear-gradient(rgba(120,140,170,.16) 1px,transparent 1px),linear-gradient(90deg,rgba(120,140,170,.16) 1px,transparent 1px);
  background-size:22px 22px}
.pgal .pshot.ph .picon{position:absolute;left:50%;top:44%;transform:translate(-50%,-50%);width:30px;height:30px;color:var(--hie-gold);filter:drop-shadow(0 3px 4px rgba(0,0,0,.22))}
.pgal .plabel{position:absolute;left:8px;top:8px;font-size:10px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;color:#fff;background:rgba(28,21,64,.62);backdrop-filter:blur(3px);padding:3px 8px;border-radius:6px;z-index:2}
/* Centred, not wedged in a corner. Pinned bottom-right it straddled the seam between the
   two photos and read as clutter sitting on them rather than an invitation to open them. */
.pgal .pmore{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);z-index:3;font-size:12.5px;font-weight:800;color:#1c1540;background:rgba(255,255,255,.94);backdrop-filter:blur(4px);padding:8px 14px;border-radius:999px;display:inline-flex;align-items:center;gap:7px;box-shadow:0 4px 14px rgba(28,21,64,.22);pointer-events:none;white-space:nowrap}
.pgal .pmore svg{width:14px;height:14px}
.pgal.noshot .pmore{display:none}

/* ── facts ── */
/* Six facts across three columns = two rows. Narrow screens fall back to two columns,
   then one — three columns of "Property type / Single-family" is unreadable on a phone. */
.property .facts{padding:14px 16px;display:grid;grid-template-columns:1fr 1fr 1fr;gap:13px 16px}
@media(max-width:640px){.property .facts{grid-template-columns:1fr 1fr}}
@media(max-width:380px){.property .facts{grid-template-columns:1fr}}
.property .facts .f .l{font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-faint)}
.property .facts .f .d{font-size:15px;font-weight:800;margin-top:2px;color:var(--hie-ink)}
.property .facts .d.pf-edit{outline:none;border-bottom:1px dashed #cdd7e6;cursor:text;display:inline-block;min-width:30px;padding-bottom:1px}
.property .facts .d.pf-edit:hover{border-bottom-color:#8aa0c8}
.property .facts .d.pf-edit:focus{background:#f2f6ff;border-bottom-color:#2f6bff;border-radius:3px}
.property .facts .l .pf-edithint{font-size:9px;font-weight:700;color:#b9c3d6;text-transform:none;letter-spacing:0;margin-left:6px;opacity:0;transition:opacity .12s}
.property .facts .f:hover .pf-edithint{opacity:1}

/* ── portal buttons (Zillow / Redfin / Realtor / Homes) ── */
.pportals{border-top:1px solid var(--line);padding:13px 16px 15px;background:#fbfbfd}
.pportals .plede{font-size:11px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-faint);margin:0 2px 9px;display:flex;align-items:center;gap:6px}
.pportals .plede svg{width:13px;height:13px;color:var(--hie-gold)}
.pbtns{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:8px}
@media(max-width:560px){ .pbtns{grid-template-columns:1fr 1fr} }
.pbtn{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;text-decoration:none;border:1px solid var(--line);border-radius:11px;background:#fff;padding:11px 6px;cursor:pointer;transition:border-color .15s,box-shadow .15s,transform .1s}
.pbtn:hover{border-color:var(--hie-navy);box-shadow:0 5px 14px rgba(45,33,96,.14);transform:translateY(-1px)}
.pbtn .pbico{width:26px;height:26px;border-radius:7px;display:grid;place-items:center;font-weight:900;font-size:13px;color:#fff;flex:none}
.pbtn .pbname{font-size:12px;font-weight:800;color:var(--hie-ink);line-height:1}
.pbtn .pbsub{font-size:9.5px;font-weight:700;color:var(--ink-faint);letter-spacing:.02em}

/* ── full-screen photo lightbox ── */
.plight{position:fixed;inset:0;z-index:1000;background:rgba(16,12,38,.94);display:none;flex-direction:column}
.plight.on{display:flex}
.plight .plx{position:absolute;top:14px;right:14px;z-index:5;width:40px;height:40px;border-radius:50%;border:0;background:rgba(255,255,255,.14);color:#fff;font-size:22px;cursor:pointer;display:grid;place-items:center}
.plight .plcount{position:absolute;top:20px;left:18px;z-index:5;color:#fff;font-size:13px;font-weight:700;letter-spacing:.03em;opacity:.9}
.plstage{flex:1;display:flex;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch}
.plstage::-webkit-scrollbar{display:none}
.plslide{flex:0 0 100%;scroll-snap-align:center;display:grid;place-items:center;position:relative}
.plslide img{max-width:100%;max-height:78vh;object-fit:contain}
.plslide .phbox{width:88%;max-width:560px;aspect-ratio:4/3;border-radius:16px;background:linear-gradient(135deg,#2a3566,#1c1540);display:grid;place-items:center;position:relative;overflow:hidden}
.plslide .phbox:before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.07) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.07) 1px,transparent 1px);background-size:34px 34px}
.plslide .phbox .plabel2{position:relative;text-align:center;color:#fff}
.plslide .phbox .plabel2 svg{width:44px;height:44px;color:var(--hie-gold-2);margin-bottom:10px}
.plslide .phbox .plabel2 .t{font-size:15px;font-weight:800}
.plslide .phbox .plabel2 .s{font-size:12px;opacity:.72;margin-top:3px}
.plnav{position:absolute;top:50%;transform:translateY(-50%);z-index:4;width:44px;height:44px;border-radius:50%;border:0;background:rgba(255,255,255,.16);color:#fff;font-size:24px;cursor:pointer;display:grid;place-items:center}
.plnav.prev{left:12px} .plnav.next{right:12px}
@media(max-width:640px){ .plnav{display:none} }
.plfoot{padding:14px 16px calc(14px + env(safe-area-inset-bottom));background:rgba(16,12,38,.6)}
.plfoot .pllede{color:#cfd3e6;font-size:12px;font-weight:700;text-align:center;margin:0 0 10px}
.plfoot .pbtns .pbtn{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.16)}
.plfoot .pbtns .pbtn .pbname{color:#fff}
.plfoot .pbtns .pbtn .pbsub{color:#aab0cc}

.autopull{display:inline-flex;align-items:center;gap:6px;background:#eef7f0;color:#0b6b43;font-size:11px;font-weight:700;padding:3px 9px;border-radius:99px}
.autopull svg{width:12px;height:12px}

/* package selector */
.pkgs{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
@media(max-width:720px){.pkgs{grid-template-columns:1fr}}
.pkg{border:1.5px solid var(--line);border-radius:14px;padding:15px 15px 14px;cursor:pointer;background:#fbfcfe;position:relative;transition:border .12s,box-shadow .12s,transform .1s}
.pkg:hover{border-color:#c9d3e6;transform:translateY(-2px);box-shadow:var(--shadow)}
.pkg .tier{display:flex;align-items:center;gap:7px;font-weight:800;font-size:14px;color:var(--hie-ink)}
.pkg .dotg{width:11px;height:11px;border-radius:50%}
.pkg .price{font-size:24px;font-weight:900;letter-spacing:-.02em;margin:8px 0 6px;color:var(--hie-navy)}
.pkg .desc{font-size:11.5px;color:var(--ink-soft);line-height:1.45}
.pkg .rb{position:absolute;top:13px;right:13px;width:20px;height:20px;border-radius:50%;border:2px solid #cdd7e6;display:grid;place-items:center}
.pkg .rb svg{width:12px;height:12px;opacity:0;color:#fff}
.pkg.on{border-color:var(--hie-gold);background:linear-gradient(180deg,#fffdf6,#fff);box-shadow:0 8px 24px rgba(213,161,46,.18)}
.pkg.on .rb{background:var(--hie-gold);border-color:var(--hie-gold)}
.pkg.on .rb svg{opacity:1}
.pkg .best{position:absolute;top:-10px;left:14px;background:var(--hie-gold);color:#3a2a05;font-size:9.5px;font-weight:900;letter-spacing:.06em;padding:3px 8px;border-radius:6px;text-transform:uppercase}

/* add-ons */
.addons{display:flex;flex-direction:column;gap:9px}
.addon{display:flex;align-items:center;gap:12px;border:1px solid var(--line);border-radius:11px;padding:11px 13px;background:#fbfcfe;cursor:pointer}
.addon .box{width:20px;height:20px;border-radius:6px;border:1.5px solid #cdd7e6;display:grid;place-items:center;flex:none}
.addon .box svg{width:12px;height:12px;opacity:0;color:#fff}
.addon.on{border-color:var(--hie-gold);background:#fffdf6}
.addon.on .box{background:var(--hie-gold);border-color:var(--hie-gold)}
.addon.on .box svg{opacity:1}
.addon .an{flex:1}
.addon .an b{font-size:13.5px}
.addon .an span{display:block;font-size:11.5px;color:var(--ink-faint)}
.addon .ap{font-weight:800;color:var(--hie-navy);font-size:14px}

/* ---- RIGHT RAIL: quote + status ---- */
/* 🔴 THE RIGHT-HAND COLUMN HAS TO FOLLOW HER DOWN THE PAGE (Kevin, 2026-08-27): "this needs to
   be locked to the page, I think it stops while everything moves down the page… it stays when it
   should go up."

   It was already `position:sticky`, and it still let go, for two reasons that both had to be
   fixed:
     1 · a sticky item inside a grid or flex row STRETCHES to the height of the row by default,
         and an item as tall as its container has nothing left to stick within — so it simply
         scrolled away. `align-self:start` makes it only as tall as its own cards.
     2 · once the quote card, the next-email card and the inspection card are stacked up, the
         column is TALLER than the screen. A sticky column taller than the screen pins its top
         and hides its own bottom, which reads exactly as "it stops". Capping the height and
         letting the column scroll inside itself keeps every card reachable.
   → memory kevin-button-design-prefs */
/* 🔴 THE WHOLE PAGE MOVES AS ONE (Kevin, 2026-08-27, and this is the plain version of it):
   "basically what I want is that the whole page is locked down. The left side is moving
   independently and the right side is staying… it's confusing, so I just want it all to stay
   together."

   That is the answer, and it is simpler than everything I tried first. This column used to be
   pinned, so the form on the left slid past while the quote card on the right hung in place —
   two halves of one screen moving at different speeds, which is exactly the confusion he
   describes and which the office had complained about too.

   Nothing is pinned now. Both sides scroll together, like a sheet of paper.

   ⚠️ Do NOT reintroduce sticky here without asking him. Two earlier attempts made it worse: one
   left the column stretching and it let go anyway, and one gave the column its own scroll and
   HID the quote card completely. → memory hq-sticky-column-lesson */
.rail{display:flex;flex-direction:column;gap:18px}
.quote{background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow);overflow:hidden}
.quote .qh{background:linear-gradient(135deg,var(--hie-navy),var(--hie-navy-2));color:#fff;padding:12px 16px;display:flex;align-items:center;gap:10px}
.quote .qh .hielogo{height:26px;background:#fff;border-radius:7px;padding:3px 6px}
.quote .qh .hielogo img{height:100%}
.quote .qh b{font-size:14px;font-weight:800}
.quote .qb{padding:13px 16px 14px}
.qline{display:flex;justify-content:space-between;align-items:baseline;padding:6px 0;font-size:13.5px;color:var(--ink-soft)}
.qline b{color:var(--ink)}
.qline+.qline{border-top:1px solid var(--line-soft)}
.qline.qdiscline{color:#c2410c;font-weight:800}
.qline.qdiscline b{color:#c2410c;font-weight:900}
.qbuf{margin:2px 0 2px;padding:8px 11px;border:1.4px dashed #c5c9ea;border-radius:10px;background:#f4f4fc}
.qbuf-t{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;color:#4a3f8f;margin-bottom:5px}
.qbuf-t svg{width:14px;height:14px;flex:none}
.qbuf-r{display:flex;justify-content:space-between;align-items:center;gap:10px;font-size:14px;font-weight:800;color:var(--ink)}
.qbuf-step{display:inline-flex;align-items:center;background:#fff;border:1px solid #d3d7ec;border-radius:9px;overflow:hidden;flex:none}
.qbuf-step button{border:0;background:#eef0fb;color:#2d2160;font-weight:900;font-size:18px;line-height:1;width:30px;height:32px;cursor:pointer;transition:background .12s}
.qbuf-step button:hover{background:#e2e6fa}
.qbuf-cur{display:inline-flex;align-items:center;font-weight:900;color:#2d2160;font-size:15px;padding:0 3px}
.qbuf-cur input{border:0;background:transparent;font:inherit;font-weight:900;color:#2d2160;width:48px;text-align:center;outline:none;padding:0}
/* phone: bigger − / + so the office can tap it easily */
@media(max-width:640px){
  .qbuf-step button{width:46px;height:46px;font-size:22px}
  .qbuf-cur{font-size:16px}
  .qbuf-cur input{width:56px}
}
/* "what the customer sees" divider between the internal box and the client lines */
.qdiv{display:flex;align-items:center;gap:9px;font-size:11px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:#aab1c5;margin:11px 0 3px}
.qdiv:before,.qdiv:after{content:"";flex:1;height:1px;background:var(--line-soft)}
.qtotal{display:flex;justify-content:space-between;align-items:center;margin-top:10px;padding:11px 14px;background:linear-gradient(135deg,#f6f5fc,#eef0fb);border:1px solid #e4e5f4;border-radius:13px;font-size:15px;font-weight:800}
.qtotal .big{font-size:23px;font-weight:900;color:var(--hie-navy);letter-spacing:-.02em}
/* What they already paid — sits under the Total because that is where a person looks for money.
   Green, and quieter than the Total: this is money that has ALREADY come in, not a figure being
   quoted, and the two must never be mistaken for each other. */
.qpaid{display:flex;justify-content:space-between;align-items:center;margin-top:7px;padding:8px 16px;
  background:#f0faf4;border:1px solid #cfe9da;border-radius:11px;font-size:13px;font-weight:700;color:#0b6b43}
.qpaid[hidden]{display:none}
.qpaid b{font-weight:850}
/* ── A PAYMENT THAT JUST LANDED SAYS SO (Kevin, 2026-08-28) ───────────────────
   "Maybe even pulses so they know it got paid." Money arriving is the one thing on this card
   that happens WITHOUT her — Square tells us while she is on another call — so the line has to
   catch her eye when she next opens the customer, and then stop.

   Three pulses and it settles. An animation that never stops is a thing people learn to ignore,
   and it would still be flashing at 5pm about money that came in at 9. Anybody who has asked
   their phone not to animate gets the calm version and loses nothing: the green tick and the
   words say the same thing. */
.qpaid.justin{border-color:#12b76a;box-shadow:0 0 0 0 rgba(18,183,106,.55);animation:qpaidPulse 1.5s ease-out 3}
@keyframes qpaidPulse{
  0%{box-shadow:0 0 0 0 rgba(18,183,106,.55);background:#e2f7ec}
  70%{box-shadow:0 0 0 10px rgba(18,183,106,0);background:#f0faf4}
  100%{box-shadow:0 0 0 0 rgba(18,183,106,0);background:#f0faf4}
}
@media (prefers-reduced-motion: reduce){ .qpaid.justin{animation:none;border-color:#12b76a} }

/* ── YES / NO ─────────────────────────────────────────────────────────────────
   Kevin, 2026-08-24, looking at "Contact the agent / broker directly?" on the Quotes page:
   *"this isn't our font. It doesn't look like our page at all."* It wasn't ours — they were the
   browser's own raw buttons. These classes were written for the inspector's form and styled
   INSIDE that one page, so when the markup was reused on Quotes the look stayed behind and two
   naked grey buttons appeared in the middle of the card.

   Page-local styles are how that happens. They live here now, so any screen that asks a yes/no
   question gets the same pair, and nobody has to remember to copy the CSS with the HTML.
   → memory hq-one-rule-not-two-copies · hq-shared-ux-layer */
.undone-q{font-size:15px;font-weight:800;color:var(--ink)}
.undone-yn{display:flex;gap:9px;margin-top:10px}
.undone-yn button{flex:0 0 auto;min-width:92px;font-family:inherit;font-size:15px;font-weight:800;
  line-height:1;color:var(--ink-soft);background:#fff;border:1px solid var(--line);border-radius:11px;
  padding:12px 18px;cursor:pointer;transition:border-color .12s,background .12s,color .12s}
.undone-yn button:hover{border-color:#aab4cc;background:#f7f9fd;color:var(--ink)}
.undone-yn button.on{background:var(--hie-navy,#262161);border-color:var(--hie-navy,#262161);color:#fff}
/* Jeannine works on a phone: 44px is the floor for anything she has to hit. */
@media (max-width:640px){ .undone-yn button{flex:1 1 0;min-width:0;padding:14px 12px;font-size:15px} }
.qactions{display:flex;flex-direction:column;gap:8px;margin-top:12px}
/* REFUND IS NOT A FULL-WIDTH BAR. Kevin, 2026-08-24: *"the button stretches all the way across
   the page and is very pale, so it looks like an empty box you'd type into."* He is right — in a
   column layout every child stretches, so a quiet outlined button became a wide pale slab that
   reads as a form field. "Review & send" is the action of this card and keeps the full width;
   money going back out is the rare one, so it sits centred at its own width, with enough border
   to read as a control. Not red, not primary: it should look deliberate, never inviting. */
/* Kevin, 2026-08-24: *"I don't like the font colour."* It was a brown-on-cream that read as a
   warning about the button rather than a label on it. Ordinary ink, ordinary border — this is a
   normal action the office takes, not an alarm. It just should not look inviting. */
.btn-refund{align-self:center;width:auto;padding:8px 15px;gap:9px;align-items:center;
  border-color:#d6dbe8;color:#2b3450;background:#fff}
.btn-refund:hover:not(:disabled){border-color:#aab4cc;background:#f7f9fd;color:#141b2e}
.btn-refund:disabled{align-self:center}
/* Sized and weighted to sit level with the label, in a tinted round so it reads as a mark
   rather than a stray character in the middle of the words. */
.btn-refund .rf-dollar{flex:none;width:20px;height:20px;border-radius:50%;display:grid;place-items:center;
  font-size:13px;font-weight:900;line-height:1;background:#eaf4ee;color:#0b6b43}
.btn-refund:hover:not(:disabled) .rf-dollar{background:#dcefe4}
/* 🔴 THE INSPECTOR HAS ASKED FOR A REFUND (Kevin, 2026-09-09): *"when the inspector notifies
   office, that is a great idea."* The button goes red and reads "Refund needed", so she is not
   hunting through Team Messages for a job she was told about an hour ago. It came from the plain
   Refund button that used to sit in the header row; that button is gone and this behaviour moved
   here rather than being lost with it. → memory hie-inspector-refund-request */
/* 🔴 SOLID, NOT A TINT (Kevin, 2026-09-09, shown the pale version): *"I'd make it a solid red to
   really pop."* A pale red button sits quietly among the other pale buttons on the card, which is
   the opposite of the job — this one is the only control on the page that means somebody is owed
   money back and nobody has done it yet. */
.btn-refund.asked{color:#fff;border-color:#a3231f;background:#c62a2f;font-weight:800;
  box-shadow:0 4px 12px rgba(198,42,47,.28)}
.btn-refund.asked:hover:not(:disabled){border-color:#8d1c19;background:#b0242a;color:#fff}
.btn-refund.asked .rf-dollar{background:#fff;color:#c62a2f}
/* 🔴 ONCE THE MONEY HAS GONE BACK, THE BUTTON SAYS SO — Kevin, 2026-09-10: *"when there's a
   refund needed and we do it right then and there, then refund needed... needs to be made green
   that says refund paid."* A red button still shouting "Refund needed" after the refund has been
   sent is the card telling her to do a job she has already done. */
.btn-refund.paidback{color:#fff;border-color:#0f7a45;background:#12915a;font-weight:800;
  box-shadow:0 4px 12px rgba(18,145,90,.26)}
.btn-refund.paidback:hover:not(:disabled){border-color:#0b6437;background:#0f7e4e;color:#fff}
.btn-refund.paidback .rf-dollar{background:#fff;color:#12915a}

.btn-hie{color:#fff;background:linear-gradient(135deg,var(--hie-navy),var(--hie-navy-2));box-shadow:0 6px 16px rgba(45,33,96,.3);justify-content:center;padding:12px}
.btn-hie:hover{filter:brightness(1.08)}
.btn-gold{color:#3a2a05;background:linear-gradient(135deg,var(--hie-gold-2),var(--hie-gold));box-shadow:0 6px 16px rgba(213,161,46,.35);justify-content:center;padding:12px;font-weight:800}
.btn-gold:hover{filter:brightness(1.05)}

/* status timeline (the "where is this lead" bar) */
.statuscard{background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow);padding:16px 18px}
.statuscard h4{margin:0 0 14px;font-size:12.5px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-faint)}
.stl{display:flex;flex-direction:column}
.stl .s{display:flex;gap:12px;position:relative;padding-bottom:16px}
/* 🔴 A HIDDEN ROW WAS STILL ON SCREEN (Kevin, 2026-09-09, looking at Tom Lee): *"this should only
   show up in the list if quote was clicked to update it."* The Quote updated row was correctly
   MARKED hidden and drew anyway, because the line above sets display on every row and a plain
   "hidden" cannot beat a display rule. So Tom Lee, who has never had an updated quote, was being
   shown a step that never happened. → memory success-before-the-write-defect */
.stl .s[hidden]{display:none}
.stl .s:not(:last-child):before{content:"";position:absolute;left:12px;top:26px;bottom:0;width:2px;background:var(--line)}
.stl .s.done:not(:last-child):before{background:var(--good)}
.stl .s .si{width:26px;height:26px;border-radius:50%;flex:none;display:grid;place-items:center;background:#eef2f8;color:#b3c0d4;z-index:1;border:2px solid #fff;box-shadow:0 0 0 1px var(--line)}
.stl .s .si svg{width:13px;height:13px}
.stl .s.done .si{background:var(--good);color:#fff;box-shadow:0 0 0 1px var(--good)}
.stl .s.now .si{background:var(--hie-gold);color:#fff;box-shadow:0 0 0 1px var(--hie-gold),0 0 0 5px rgba(213,161,46,.2)}
.stl .s .sx b{font-size:14px;display:block;color:var(--ink);font-weight:750}
.stl .s .sx span{font-size:13px;color:#4a5468;line-height:1.45;display:block;margin-top:1px}
/* A step still to come is lighter than a finished one — but it is never faint. */
.stl .s.todo .sx b{color:#5a6178;font-weight:700}
.stl .s.todo .sx span{color:#6b7386}
.stl .s.now .sx b{color:#8a5a06}
.stl .s.now .sx span{color:#8a5a06;font-weight:650}
.stl .s.done .sx span{color:#0b6b43;font-weight:650}

/* ---- PROPOSAL (premium branded email) ---- */
.proposal-wrap{background:#eef1f6;min-height:100vh;padding:34px 18px;display:flex;justify-content:center}
.envelope{width:100%;max-width:640px}
.envbar{display:flex;align-items:center;gap:10px;margin-bottom:14px;color:var(--ink-faint);font-size:13px}
.envbar .btn{margin-left:auto}
.paper{background:#fff;border-radius:20px;overflow:hidden;box-shadow:0 24px 60px rgba(28,21,64,.18)}
.phero{background:linear-gradient(150deg,var(--hie-navy) 0%,var(--hie-navy-2) 60%,#4a3a95 100%);padding:34px 36px 30px;color:#fff;position:relative;overflow:hidden}
.phero:before{content:"";position:absolute;right:-60px;top:-60px;width:280px;height:280px;border-radius:50%;background:radial-gradient(circle,rgba(213,161,46,.4),transparent 62%)}
.phero .plogo{height:74px;background:#fff;border-radius:14px;padding:10px 16px;display:inline-flex;box-shadow:0 8px 22px rgba(0,0,0,.18)}
.phero .plogo img{height:100%;object-fit:contain}
.phero h1{margin:20px 0 6px;font-size:26px;font-weight:900;letter-spacing:-.02em;position:relative}
.phero p{margin:0;font-size:14.5px;color:#d7d0f2;max-width:78%;line-height:1.5;position:relative}
.pbody{padding:30px 36px 8px}
.pbody h2{font-size:12px;font-weight:900;letter-spacing:.08em;text-transform:uppercase;color:var(--hie-gold);margin:0 0 4px}
.pbody .lede{font-size:15px;color:var(--ink);line-height:1.6;margin:0 0 22px}
.coverage{display:grid;grid-template-columns:1fr 1fr;gap:10px 18px;background:#fbfaf5;border:1px solid #f0e7cf;border-radius:14px;padding:18px 20px;margin-bottom:26px}
.coverage .c{display:flex;align-items:center;gap:10px;font-size:13.5px;color:var(--hie-ink);font-weight:600}
.coverage .c svg{width:17px;height:17px;color:var(--hie-gold);flex:none}
.ppkgs{display:flex;flex-direction:column;gap:12px;margin-bottom:22px}
.ppkg{border:1.5px solid var(--line);border-radius:15px;padding:17px 20px;display:flex;align-items:center;gap:16px;position:relative}
.ppkg.sel{border-color:var(--hie-gold);background:linear-gradient(120deg,#fffdf6,#fff);box-shadow:0 10px 28px rgba(213,161,46,.16)}
.ppkg .pmed{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;flex:none;font-size:20px;background:#f3f1fb}
.ppkg .pinfo{flex:1;min-width:0}
.ppkg .pinfo .pt{display:flex;align-items:center;gap:9px}
.ppkg .pinfo .pt b{font-size:16px;color:var(--hie-ink);font-weight:800}
.ppkg .pinfo .pt .selbadge{background:var(--hie-gold);color:#3a2a05;font-size:9.5px;font-weight:900;letter-spacing:.05em;padding:2px 8px;border-radius:5px;text-transform:uppercase}
.ppkg .pinfo p{margin:4px 0 0;font-size:12.5px;color:var(--ink-soft);line-height:1.45}
.ppkg .pprice{font-size:23px;font-weight:900;color:var(--hie-navy);letter-spacing:-.02em}
.paddons{border-top:1px dashed var(--line);padding-top:16px;margin-bottom:8px}
.paddon{display:flex;align-items:center;gap:10px;font-size:13.5px;color:var(--ink);padding:6px 0}
.paddon svg{width:16px;height:16px;color:var(--hie-gold)}
.paddon .amt{margin-left:auto;font-weight:800;color:var(--hie-navy)}
.ptotal{display:flex;justify-content:space-between;align-items:center;background:var(--hie-navy);color:#fff;border-radius:14px;padding:18px 22px;margin:8px 0 26px}
.ptotal span{font-size:13px;color:#c9c1ef;font-weight:700;letter-spacing:.03em;text-transform:uppercase}
.ptotal b{font-size:30px;font-weight:900;letter-spacing:-.02em}
.pcta{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:8px}
.pcta a{padding:15px;font-size:15px;border-radius:13px}
.psample{display:flex;justify-content:center;margin:16px 0 4px}
.psample a{display:inline-flex;align-items:center;gap:8px;color:var(--hie-navy);font-weight:700;font-size:13.5px;text-decoration:none;border-bottom:2px solid var(--hie-gold);padding-bottom:2px}
.pfoot{background:#faf9fc;border-top:1px solid var(--line);padding:24px 36px 28px;text-align:center;margin-top:22px}
.pfoot .sig{font-size:14px;color:var(--ink)}
.pfoot .sig b{color:var(--hie-ink)}
.pfoot .contact{font-size:13px;color:var(--ink-soft);margin-top:6px}
.pfoot .socials{display:flex;justify-content:center;gap:10px;margin:16px 0 12px}
.pfoot .socials a{width:36px;height:36px;border-radius:10px;background:var(--hie-navy);color:#fff;display:grid;place-items:center}
.pfoot .socials a svg{width:17px;height:17px}
.pfoot .socials a:hover{background:var(--hie-gold);color:#3a2a05}
.pfoot .powered{margin-top:12px;font-size:11px;color:var(--ink-faint);letter-spacing:.02em}
.pfoot .powered b{color:var(--brand-2)}
.pill-cert{display:inline-flex;align-items:center;gap:7px;background:#eef7f0;color:#0b6b43;font-size:12px;font-weight:700;padding:6px 13px;border-radius:99px;margin-top:6px}
.pill-cert svg{width:14px;height:14px}

/* sq-ft auto-pricing control (Intake, package section) */
.sqftctl{margin-left:auto;display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap;row-gap:6px;font-weight:600;text-transform:none;letter-spacing:0;font-size:12.5px;color:var(--ink-soft)}
.sqftctl #sqft{width:62px;font-family:inherit;font-size:13px;font-weight:700;color:var(--hie-navy);text-align:center;
  border:1px solid var(--line);border-radius:8px;padding:5px 6px;background:#fff}
.sqftctl #sqft:focus{outline:none;border-color:var(--hie-gold);box-shadow:0 0 0 3px rgba(213,161,46,.15)}
.sqftctl #tierlabel{color:var(--ink-faint);font-weight:600;white-space:normal}
/* Below this the control gets its own line rather than crushing the title into two words. */
@media(max-width:820px){ .sectlabel .sqftctl{margin-left:0;flex:1 1 100%} }

/* ---- CONFIRMATION email extras (reuses proposal styles) ---- */
.confbar{display:inline-flex;align-items:center;gap:8px;background:var(--good-bg);color:#0b6b43;font-size:12px;font-weight:800;padding:6px 13px;border-radius:99px;position:relative}
.confbar svg{width:14px;height:14px}
.apptbox{display:grid;grid-template-columns:1fr 1fr;gap:14px 20px;background:#f6f9fc;border:1px solid var(--line);border-radius:14px;padding:18px 20px;margin-bottom:22px}
.apptbox .a .l{font-size:10px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-faint)}
.apptbox .a .d{font-size:15px;font-weight:700;color:var(--hie-ink);margin-top:2px}
.inspector{display:flex;align-items:center;gap:14px;border:1px solid var(--line);border-radius:14px;padding:15px 18px;margin-bottom:22px;background:#fff}
.inspector .iav{width:46px;height:46px;border-radius:12px;flex:none;display:grid;place-items:center;color:#fff;font-weight:800;font-size:15px;background:linear-gradient(135deg,var(--hie-navy),var(--hie-navy-2))}
.inspector .im b{font-size:15px;color:var(--hie-ink)}
.inspector .im span{display:block;font-size:12.5px;color:var(--ink-soft);margin-top:2px}
.itemized{border:1px solid var(--line);border-radius:14px;overflow:hidden;margin-bottom:8px}
.itemized .ir{display:flex;justify-content:space-between;padding:12px 18px;font-size:14px;color:var(--ink-soft);border-bottom:1px solid var(--line-soft)}
.itemized .ir b{color:var(--ink)}
.itemized .ir.tot{background:var(--hie-navy);color:#fff;border-bottom:0;font-weight:800;font-size:16px;padding:15px 18px}
.itemized .ir.tot span{color:#c9c1ef}
.policy{border:1px solid #f0e7cf;background:#fbfaf5;border-radius:13px;padding:15px 18px;margin-bottom:14px}
.policy h3{margin:0 0 6px;font-size:12px;font-weight:900;letter-spacing:.05em;text-transform:uppercase;color:var(--hie-navy)}
.policy p{margin:0;font-size:13px;line-height:1.55;color:var(--ink-soft)}
.policy .editnote{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:700;color:var(--ink-faint);margin-top:8px}
.excl{font-size:12.5px;color:var(--ink-faint);font-style:italic;margin:-8px 0 22px}

/* ---- PAY OPTIONS (ACH + card) ---- */
.payopts{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:8px 0 6px}
@media(max-width:520px){.payopts{grid-template-columns:1fr}}
.payopt{position:relative;display:flex;align-items:center;gap:13px;border:1.5px solid var(--line);border-radius:14px;
  padding:15px 16px;text-decoration:none;background:#fff;transition:border .12s,box-shadow .12s,transform .1s;cursor:pointer}
.payopt:hover{transform:translateY(-2px);box-shadow:var(--shadow)}
.payopt .pi{width:42px;height:42px;border-radius:11px;flex:none;display:grid;place-items:center;color:#fff}
.payopt .pi svg{width:20px;height:20px}
.payopt .px b{display:block;font-size:14.5px;color:var(--hie-ink)}
.payopt .px span{font-size:12px;color:var(--ink-faint)}
.payopt.ach{border-color:var(--hie-gold);background:linear-gradient(120deg,#fffdf6,#fff)}
.payopt.ach .pi{background:linear-gradient(135deg,var(--hie-gold-2),var(--hie-gold));color:#3a2a05}
.payopt.card .pi{background:linear-gradient(135deg,var(--hie-navy),var(--hie-navy-2))}
.payopt .flag{position:absolute;top:-9px;right:12px;background:var(--hie-gold);color:#3a2a05;font-size:9.5px;font-weight:900;letter-spacing:.05em;text-transform:uppercase;padding:2px 8px;border-radius:6px}

/* ---- INSPECTOR PROFILE ---- */
.insphead{display:flex;align-items:center;gap:16px;margin-bottom:20px}
.insphead .iava{width:60px;height:60px;border-radius:15px;flex:none;display:grid;place-items:center;color:#fff;font-weight:800;font-size:20px;background:linear-gradient(135deg,var(--hie-navy),var(--hie-navy-2))}
.insphead h2{margin:0;font-size:21px;letter-spacing:-.02em}
.insphead p{margin:3px 0 0;color:var(--ink-faint);font-size:13px}
.insphead .st{margin-left:auto;display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:800;color:#0b6b43;background:var(--good-bg);padding:6px 13px;border-radius:99px}
.jobrow{display:flex;align-items:center;gap:13px;padding:12px 4px;border-bottom:1px solid var(--line-soft);cursor:pointer}
.jobrow:last-child{border-bottom:0}
.jobrow:hover{background:#fbfcfe}
.jobrow .jd{width:58px;text-align:center;flex:none}
.jobrow .jd b{display:block;font-size:14px;color:var(--hie-navy)}
.jobrow .jd span{font-size:10.5px;color:var(--ink-faint);text-transform:uppercase}
.jobrow .jm{flex:1;min-width:0}
.jobrow .jm b{font-size:13.5px;display:block}
.jobrow .jm span{font-size:12px;color:var(--ink-faint)}

/* ---- DISPATCH / JOB TICKET (inspector-facing) ---- */
.ticket-wrap{background:#eef1f6;min-height:100vh;padding:30px 16px;display:flex;justify-content:center}
.ticket{width:100%;max-width:460px;background:#fff;border-radius:22px;overflow:hidden;box-shadow:0 20px 50px rgba(28,21,64,.16)}
.ticket .th{background:linear-gradient(150deg,var(--hie-navy),var(--hie-navy-2));color:#fff;padding:22px 24px}
.ticket .th .tag{font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#c9c1ef}
.ticket .th h1{margin:6px 0 2px;font-size:22px;font-weight:900;letter-spacing:-.02em}
.ticket .th .when{font-size:14px;color:#e7e2fb;margin-top:4px}
.ticket .map{height:150px;background:linear-gradient(135deg,#dfe7f2,#eef3fa);position:relative;border-bottom:1px solid var(--line)}
.ticket .map:before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(120,140,170,.16) 1px,transparent 1px),linear-gradient(90deg,rgba(120,140,170,.16) 1px,transparent 1px);background-size:22px 22px}
.ticket .map .pin{position:absolute;left:50%;top:44%;transform:translate(-50%,-50%);width:30px;height:30px;color:var(--hie-gold);filter:drop-shadow(0 3px 4px rgba(0,0,0,.28))}
.ticket .map .addr{position:absolute;left:12px;right:12px;bottom:12px;background:#fff;border-radius:11px;padding:9px 12px;font-size:13px;font-weight:700;color:var(--hie-ink);box-shadow:var(--shadow)}
.ticket .tb{padding:18px 22px 22px}
.dirbtns{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:18px}
.dirbtns a{display:flex;align-items:center;justify-content:center;gap:7px;padding:12px;border-radius:12px;font-weight:700;font-size:13.5px;text-decoration:none;border:1px solid var(--line);color:var(--hie-navy);background:#fbfcfe}
.dirbtns a svg{width:16px;height:16px}
.dirbtns a:hover{border-color:var(--hie-gold);background:#fffdf6}
.trow{display:flex;gap:12px;padding:12px 0;border-bottom:1px solid var(--line-soft)}
.trow:last-child{border-bottom:0}
.trow .ti{width:34px;height:34px;border-radius:10px;flex:none;display:grid;place-items:center;background:var(--brand-tintbg);color:var(--hie-navy)}
.trow .ti svg{width:16px;height:16px}
.trow .tx{flex:1;min-width:0}
.trow .tx .l{font-size:10.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-faint)}
.trow .tx .d{font-size:14px;color:var(--ink);margin-top:2px;font-weight:600}
.trow .tx .d small{display:block;font-weight:500;color:var(--ink-soft);font-size:12.5px;margin-top:2px}
.tflag{display:inline-flex;align-items:center;gap:6px;background:#fef4e2;color:#a4670a;font-size:11.5px;font-weight:800;padding:5px 11px;border-radius:99px;margin-top:2px}
.ticket .tsms{margin-top:16px;display:flex;gap:9px}
.ticket .tsms a{flex:1;justify-content:center}

/* ---- TEAM & ACCESS ---- */
.member{display:flex;align-items:center;gap:13px;padding:14px 4px;border-bottom:1px solid var(--line-soft)}
.member:last-child{border-bottom:0}
.member .mav{width:40px;height:40px;border-radius:11px;flex:none;display:grid;place-items:center;color:#fff;font-weight:800;font-size:13px}
.member .mm{flex:1;min-width:0}
.member .mm b{font-size:14px;display:block}
.member .mm span{font-size:12px;color:var(--ink-faint)}
.rolebadge{font-size:10.5px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;padding:4px 10px;border-radius:99px;white-space:nowrap}
.rb-admin{background:#ece9f7;color:var(--hie-navy)}
.rb-staff{background:#eef3ff;color:#1e4fd6}
.rb-insp{background:var(--good-bg);color:#0b6b43}
.rb-acct{background:#fef4e2;color:#a4670a}
.access{font-size:11.5px;color:var(--ink-faint);margin-left:10px;white-space:nowrap}

/* ---- FOLLOW-UPS (sequences) ---- */
.seq{display:flex;align-items:center;gap:15px;border:1px solid var(--line);border-radius:14px;padding:16px 18px;background:#fff;box-shadow:var(--shadow)}
.seq+.seq{margin-top:12px}
.seq .sic{width:42px;height:42px;border-radius:12px;flex:none;display:grid;place-items:center;background:var(--brand-tintbg);color:var(--hie-navy)}
.seq .sic svg{width:20px;height:20px}
.seq .sinfo{flex:1;min-width:0}
.seq .sinfo b{font-size:14.5px}
.seq .sinfo p{margin:3px 0 0;font-size:12.5px;color:var(--ink-faint)}
.chans{display:flex;gap:6px;margin-top:8px}
.chan{font-size:10.5px;font-weight:800;padding:3px 9px;border-radius:6px}
.chan.sms{background:var(--good-bg);color:#0b6b43}
.chan.email{background:#eef3ff;color:#1e4fd6}

/* ---- REVIEWS ---- */
.stars{color:var(--hie-gold);letter-spacing:1px;font-size:14px}
.stars .off{color:#dfe3ea}
.reviewitem{display:flex;gap:13px;padding:15px 4px;border-bottom:1px solid var(--line-soft)}
.reviewitem:last-child{border-bottom:0}
.reviewitem .rav{width:38px;height:38px;border-radius:10px;flex:none;display:grid;place-items:center;color:#fff;font-weight:800;font-size:12px}
.reviewitem .rc{flex:1;min-width:0}
.reviewitem .rc .rh{display:flex;align-items:center;gap:9px}
.reviewitem .rc .rh b{font-size:13.5px}
.reviewitem .rc p{margin:5px 0 0;font-size:13px;color:var(--ink-soft);line-height:1.5}
.reviewitem .src{font-size:10.5px;font-weight:800;padding:2px 8px;border-radius:6px;background:#eef2f8;color:var(--ink-soft);margin-left:auto}

/* ---- DASHBOARD source bars ---- */
.srcbar{display:flex;align-items:center;gap:12px;padding:9px 0}
.srcbar .sl{width:96px;font-size:12.5px;color:var(--ink-soft);font-weight:600;flex:none}
.srcbar .st{flex:1;height:12px;background:#eef2f8;border-radius:99px;overflow:hidden}
.srcbar .st i{display:block;height:100%;border-radius:99px;background:linear-gradient(90deg,var(--hie-navy),var(--hie-gold))}
.srcbar .sv{width:40px;text-align:right;font-size:12.5px;font-weight:800;color:var(--hie-ink);flex:none}

/* ---- generic "coming soon" (unused once built, kept for safety) ---- */
.soon{max-width:520px;margin:40px auto;text-align:center}

/* ═══════════════════════════════════════════════════════════════
   MOBILE / PHONE PASS (Emmet, 2026-07-26). Off-canvas nav + hamburger
   (injected by nav.js), stacked layouts. Jeannine runs this on her iPhone.
   ═══════════════════════════════════════════════════════════════ */
.navtoggle{display:none}
.navbackdrop{display:none}
@media(max-width:860px){
  .app{grid-template-columns:1fr}
  /* off-canvas drawer */
  .nav{position:fixed;top:0;left:0;height:100vh;width:262px;z-index:70;transform:translateX(-102%);
    transition:transform .25s ease;box-shadow:0 0 40px rgba(0,0,0,.4)}
  .nav.open{transform:translateX(0)}
  .navbackdrop{display:block;position:fixed;inset:0;background:rgba(15,23,41,.55);z-index:60;opacity:0;pointer-events:none;transition:opacity .2s}
  .navbackdrop.show{opacity:1;pointer-events:auto}
  .navtoggle{display:grid;place-items:center;position:fixed;top:11px;left:11px;z-index:40;width:42px;height:42px;
    border-radius:12px;background:#0f1729;color:#fff;border:0;box-shadow:var(--shadow);cursor:pointer}
  .navtoggle svg{width:21px;height:21px}
  /* topbar makes room for the hamburger */
  .topbar{height:60px;padding:0 14px 0 64px;gap:8px}
  .topbar h1{font-size:16px}
  .topbar .crumb{font-size:12px}
  .btn{padding:8px 12px;font-size:13px}
  .content{padding:16px}
  /* stacking (inline repeat() needs !important) */
  .stats{grid-template-columns:1fr 1fr !important;gap:10px}
  .grid2{grid-template-columns:1fr}
  .pkgs{grid-template-columns:1fr !important}
  .payopts{grid-template-columns:1fr}
  .apptbox{grid-template-columns:1fr}
  .coverage{grid-template-columns:1fr}
  .dashcols,.split,.intake{grid-template-columns:minmax(0,1fr)}   /* see the note at .split above */
  .rail,.preview{position:static}
  .callbanner{flex-wrap:wrap}
  .callbanner .hielogo{margin-left:0}
  .sqftctl{margin-left:0;width:100%;justify-content:flex-start;margin-top:8px}
  /* customers table: hide low-priority cols so it fits, no sideways scroll */
  .ctable th:nth-child(2),.ctable td:nth-child(2),
  .ctable th:nth-child(3),.ctable td:nth-child(3){display:none}
  /* jobs rows wrap tidily */
  .job{flex-wrap:wrap}
  .job .jinfo{border-left:0;padding-left:0;flex-basis:100%;order:3}
  .insphead{flex-wrap:wrap}
  .insphead .st{margin-left:0}
}
@media(max-width:430px){
  /* 🔴 FOUR NUMBERS USED TO EAT THE WHOLE SCREEN. Kevin, 2026-08-29, on the Customers screen:
     "there's a lot of information on this screen" — and there was, before a single customer.
     One card per row meant Total customers, Repeat / referrals, Lifetime revenue and Due for
     follow-up filled the phone top to bottom and the list of people started below the fold.
     Two across, and each card trimmed: the number sits closer to its label, the padding comes
     in, and the whole block is about a third of the height it was. The words keep Kevin's 14px
     floor — nothing here is shrunk to fit. → memory hq-type-scale */
  .stats{grid-template-columns:1fr 1fr !important; gap:8px}
  .stat{padding:10px 11px; border-radius:11px}
  .stat .k{font-size:15.5px; line-height:1.3}   /* the name stays the biggest thing after the number */
  .stat .v{font-size:21px; margin-top:3px}
  .pcta{grid-template-columns:1fr}
  .content{padding:13px}
}

/* ══════════════════════════════════════════════════════════════════════════════
   PHONE LEGIBILITY FLOOR — Emmet, 2026-08-17 (Kevin's mobile sweep)

   Jeannine works on a phone. Two of Kevin's standing rules get broken silently at
   375px and nowhere else: nothing under ~14px, and no faint grey. Measured across
   the sidebar pages, the same offenders came back on every screen — sub-tekst at
   10–13px, secondary labels at under 2.5:1 contrast, and buttons 29–34px tall
   when a thumb needs ~44.

   Deliberately a FLOOR, not a redesign: desktop keeps its density, and this only
   lifts what is too small or too pale to use on the device she actually holds.
   Fixing it here rather than page-by-page means it holds on all 38 pages, and on
   pages nobody has built yet.
   ══════════════════════════════════════════════════════════════════════════════ */
@media (max-width:640px){
  /* 1 · nothing below the floor */
  .main, .content, .card, .bd, .hd p, .crumb,
  .main p, .main span, .main small, .main li, .main td, .main th, .main label,
  .stat .k, .stat .v small, .r .nm span, .recent .r span, .soon, .muted, .dim{
    font-size:14px;
  }
  .main h1{ font-size:21px; }
  .main h2{ font-size:18px; }

  /* 2 · a thumb needs a real target — 29px "Open" buttons were the worst case */
  .main .btn, .main button, .main a.btn, .main input[type=submit]{
    min-height:44px; font-size:15px; padding:11px 16px;
  }

  /* 3 · the faint greys. Measured at 1.97:1 and 2.45:1 on live screens — that is
        invisible in a car or in sunlight, which is where she reads these. */
  .muted, .dim, .sub, .hd p, .r .nm span, .stat .k{ color:#5b6480; }

  /* 4 · nothing may push the page sideways. A phone that scrolls horizontally
        feels broken even when every element on it is correct.

     🔴 LOCKED DOWN 2026-08-28. Kevin, on his iPhone: "the whole page kinda moves to the left
     and to the right. Can we lock that down?" Nothing on the page is actually wider than the
     screen — measured at 375px, the page is exactly 375 wide — so what he was feeling was
     Safari's own sideways rubber-band, which `overflow-x:hidden` alone never stops. Three
     things together do: the page may not be wider than the screen, it may not be dragged
     sideways at all, and `clip` holds where `hidden` quietly gives up on iOS. */
  html, body{ overflow-x:hidden; overflow-x:clip; width:100%; max-width:100%;
              overscroll-behavior-x:none; }

  /* 🔴 THE MENU BUTTON IS NOT A CONTENT BUTTON — the "stray dot" Kevin has now reported twice.
     Rule 2 above gives every button on a phone 11px/16px of padding. Inside a 40px-wide menu
     button that leaves 8px of room, so the three-line menu icon squashed to a 6px-wide sliver
     and read as a dot sitting next to the page title. Both the button and its icon are pinned
     here so no later rule can squeeze either one again. */
  .hamburger, .main .hamburger, .topbar .hamburger, .main button.hamburger{
    width:44px !important; height:44px !important; min-height:44px !important;
    padding:0 !important; flex:0 0 44px;
  }
  .hamburger svg{ width:24px !important; height:24px !important; flex:none; }
  .main table{ display:block; overflow-x:auto; -webkit-overflow-scrolling:touch; }

  /* 5 · THE TOPBAR OVERLAP — the bug on the open task chip, and visible on every
        control-panel page at 375px. Cause: the @media(max-width:860px) block near
        line 805 sets .topbar{height:60px}, and being LATER in the file it overrides
        the earlier @media(max-width:400px) rule that correctly said height:auto +
        flex-wrap:wrap. So once the title and the action button wrap onto two lines,
        the bar stays 60px tall and its own contents spill over the content beneath.
        Letting it grow is the whole fix. */
  .topbar{
    height:auto !important; min-height:60px;
    flex-wrap:wrap; align-items:center;
    padding:10px 14px 10px 64px;   /* left gutter keeps clear of the hamburger */
    row-gap:8px;
  }
  .topbar .grow{ flex:1 1 100%; height:0; }   /* forces the action button onto its own row */
  .topbar .btn{ flex:0 0 auto; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   THE TYPE SCALE — Emmet, 2026-08-17, at Kevin's ask: "is there a consistency we
   have with the font sizes that we could stay true to, or do you feel like that
   might put us in a corner?"

   It's the opposite of a corner. I measured one page (calendar.html) and found
   SIXTEEN different font sizes on it: 8.5 · 9.5 · 10 · 10.5 · 11 · 11.5 · 12 ·
   12.5 · 13 · 13.5 · 14 · 14.5 · 15 · 16 · 18 · 22. That isn't a scale, it's
   drift — and drift is what makes every new element a guess. It's why the
   scheduling strip shipped at 19px and needed two rounds of correction.

   Six steps, each tied to a ROLE rather than a look, so the question stops being
   "what size?" and becomes "what is this?".

     --fs-micro  11    UPPERCASE eyebrows and micro-labels
     --fs-meta   12.5  secondary text — timestamps, sub-lines, notes
     --fs-ctl    13    controls: buttons, selects, toggles, tabs
                       (Kevin picked this one: "I like the font size of Combined /
                        By inspector")
     --fs-body   14    body copy, table cells, anything read as a sentence
     --fs-title  16    card and section titles
     --fs-num    18    day numbers and figures that carry weight
     --fs-h1     22    the page heading

   ⚠️ TENSION worth knowing rather than papering over: Kevin's standing rule is
   nothing under ~14px, and this control panel's density lives at 11–12.5. Both
   are right for their own screen, so the mobile floor above lifts everything to
   14px at ≤640px and the desktop keeps its density. If those two ever have to be
   reconciled properly, that's a decision for him, not a default for me.
   ══════════════════════════════════════════════════════════════════════════════ */
:root{
  --fs-micro:11px;
  --fs-meta:12.5px;
  --fs-ctl:13px;
  --fs-body:14px;
  --fs-title:16px;
  --fs-num:18px;
  --fs-h1:22px;
}

/* ══════════════════════════════════════════════════════════════════════════
   PHONE: DARK AROUND THE CARDS. Kevin, 2026-08-23, looking at HQ on his iPhone:
   "I don't like the white around the background — maybe we can make it black on
   the phone, I think it'd be more appealing."

   Only the ground changes. Every card, field and letter stays exactly as it is,
   because those hold the words and their contrast was picked deliberately. On a
   phone the ground is most of what you see between cards, and pale grey there
   reads as unfinished next to the navy header.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:768px){
  body{
    background:
      radial-gradient(900px 420px at 90% -60px, rgba(123,108,255,.20), transparent 60%),
      radial-gradient(760px 380px at -5% 4%, rgba(45,140,255,.14), transparent 55%),
      linear-gradient(180deg,#0f1729 0%,#141c31 50%,#0f1729 100%);
    background-attachment:fixed;
  }
}

/* The top strip, on a phone, with the dark ground behind it. Kevin, 2026-08-23: "I don't like
   the white around the background." The strip is part of that white — leaving it pale put a
   bright band across the top of an otherwise dark screen. The title and the menu button turn
   light with it, or they vanish. */
@media (max-width:768px){
  .topbar{background:rgba(15,23,41,.92) !important; border-bottom-color:rgba(255,255,255,.10)}
  .topbar h1, .topbar .crumb{color:#f3f6ff}
  .topbar .crumb{opacity:.75}
  .hamburger{background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.22); color:#f3f6ff}
}

/* ── THE LINE UNDER THE HEADING, ON THAT SAME DARK GROUND ────────────────────────────────────
   Found 2026-08-24 while building the Archive: the explaining line under a page title is
   --ink-soft (#48566e) and sits directly on the ground with no card behind it. On a phone that
   ground is #0f1729, which puts it at a contrast of 2.4 — under half of readable. It is on nine
   pages, so nine of Jeannine's screens open with their one line of explanation greyed into the
   background. The topbar above it was turned light when the ground went dark; this was missed.

   The SECOND time tonight, same shape, same cause: a colour picked against the light desktop
   ground, left alone when the phone ground went dark. Anything that sits on the ground rather
   than inside a card has to be listed here.
   → memory: verify-on-mobile-jeannine-works-on-a-phone
   ⚠️ 768px to match where the ground actually changes, NOT the 760px used in page files. */
@media (max-width:768px){
  .stephint{color:rgba(243,246,255,.80)}
  .stephint .b{background:rgba(255,255,255,.12); color:#cfe0ff}
}


/* ── WHERE EVERY CLIENT STANDS ──────────────────────────────────────────────────────────────
   Kevin, 2026-08-24: "I want follow-up to look like the image attached… They're exactly the same.
   They just live in two different places." These rules lived inside index.html's own <style>,
   which is why the second screen could never look like the first. They are shared now, and
   client-stands.js draws the rows on both. Moved verbatim — nothing about Home's look changed. */
.wcs-wrap{padding:0 16px 12px}
.wcs-sum{display:flex;flex-wrap:wrap;gap:9px 18px;font-size:13px;font-weight:700;color:#5b667c;margin:2px 0 6px}
.wcs-sum b{color:#0f1830}
.wcs-sum .pill{display:inline-flex;align-items:center;gap:7px}
.wcs-sum .pill i{width:9px;height:9px;border-radius:50%}
.wcs-item{background:#fff;border:1px solid #e9edf5;border-radius:15px;padding:16px 18px;margin-top:12px;box-shadow:0 2px 10px rgba(16,26,51,.04)}
.wcs-item:first-of-type{margin-top:4px}
.wcs-empty{background:#fff;border:1px solid #e9edf5;border-radius:15px;padding:20px 18px;margin-top:4px;font-size:13.5px;font-weight:600;color:#64748b;box-shadow:0 2px 10px rgba(16,26,51,.04)}
/* 🔴 THE SOURCE BUBBLE MUST START IN THE SAME PLACE ON EVERY ROW (Kevin, 2026-09-07:
   "can we make sure these are always lined up, the Justine took the call and Yelp bubbles").

   The row was `justify-content:space-between` with three children — the name, the source
   bubble, then the chips on the right. With space-between the MIDDLE child is pushed to
   wherever the leftover space happens to put it, so a short "⭐ Yelp" and a long
   "📞 Justine took the call" started at completely different points down the page.

   A grid fixes it at the source: the middle column sizes itself to the WIDEST bubble on the
   screen and every bubble starts at that column's left edge, so they stack in a straight line
   however long the words are. The name still takes all the room it can, the right-hand chips
   still sit hard right. Nothing about what the row SAYS changes.
   → memory hq-leads-board-design-rules */
.wcs-top{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;
  gap:12px;margin-bottom:16px}
.wcs-top>.wcs-src{justify-self:start}
/* A narrow screen has no room for three across; the row stacks and the bubble sits under the
   name, which is where it reads best on a phone anyway. */
@media (max-width:640px){
  .wcs-top{grid-template-columns:1fr;gap:8px}
  .wcs-top>.wcs-src{margin-left:0}
}
.wcs-name{font-size:15px;font-weight:800;color:#0f1830;text-decoration:none}
.wcs-name span{display:block;font-size:12.5px;color:#64748b;font-weight:600;margin-top:1px}
.wcs-name:hover{color:#2f6bff}
/* WHERE THE PERSON CAME FROM — Kevin, 2026-08-31. Sits beside the name, quiet on purpose: it is
   something to READ before you ring, not something to press. Justine's own chip is the navy one
   because "she took the call" is the fact that changes what Jeannine says when she picks up —
   the questions are already asked. */
.wcs-src{display:inline-flex;align-items:center;gap:5px;margin-left:9px;vertical-align:middle;
  font-size:12px;font-weight:750;letter-spacing:.01em;white-space:nowrap;
  padding:3px 9px;border-radius:999px;background:#eef1f7;color:#4a5468;border:1px solid #dde3ee}
.wcs-src.ju{background:#eae6ff;color:#4433a8;border-color:#cfc6f5}
.wcs-src.ye{background:#fff;color:#d32323;border-color:#f1b9b9;font-weight:900}
.wcs-src.ye svg{flex:none;display:block}
/* The email door wears the same green as its bubble on the Leads Board — one source, one colour,
   on every screen. → memory hie-email-lead-becomes-a-card */
.wcs-src.em{background:#e7f8ef;color:#0b6b43;border-color:#bfeed4}

/* ⭐ THE DOOR BUTTONS — All · Yelp · Justine · Email (Kevin, 2026-09-07).
   Navy, never grey: a quiet button in grey reads as a broken one, and this row is four quiet
   buttons. The chosen one fills navy so there is never any doubt which list you are looking at.
   The count rides inside each button, because a number answers the question before she taps.
   → memory hq-leads-board-design-rules */
/* "Showing the 6 most recent of 12" — Kevin, 2026-09-07. The list has always been capped at six
   and never said so, so on a busy week somebody fell off the bottom and nobody could tell whether
   they had been dealt with or lost. Quiet navy, not grey: it is information, not a warning. */
.wcs-more{font-size:13.5px;font-weight:600;color:#5a6178;margin:-6px 0 12px}
@media (max-width:640px){ .wcs-more{font-size:14px} }
/* 🔴 THE FOUR DOORS GOT A LOOK OF THEIR OWN — Kevin, 2026-09-10: *"these buttons are all jammed
   in the left hand corner… they just do not look like the rest of our website. Give them a little
   colour."*

   Each door now wears the colour it means, the same colours already used everywhere else on this
   product: HIE navy for All, Yelp red, Justine's purple, and the slate that Emails wears on every
   customer card. Unpicked they are a soft tint of that colour; picked they fill with it. And they
   sit apart from the count line above rather than being crushed under it. */
.wcs-seg{display:flex;flex-wrap:wrap;gap:9px;margin:12px 0 16px}
.wcs-seg-b{--dc:#2d2160;--dt:#f2f1f8;
  display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:0 16px;
  border-radius:999px;border:1px solid transparent;background:var(--dt);color:var(--dc);
  font-size:14px;font-weight:800;cursor:pointer;letter-spacing:.01em;
  transition:background .13s,color .13s,box-shadow .13s,transform .13s}
.wcs-seg-b:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(16,26,51,.12)}
.wcs-seg-b .n{font-size:13px;font-weight:800;padding:2px 9px;border-radius:999px;
  background:rgba(255,255,255,.75);color:var(--dc)}
.wcs-seg-b.on{background:var(--dc);color:#fff;box-shadow:0 5px 14px rgba(16,26,51,.22)}
.wcs-seg-b.on .n{background:rgba(255,255,255,.2);color:#fff}
.wcs-seg-b[data-door="yelp"]   {--dc:#c0332b;--dt:#fdeeec}
.wcs-seg-b[data-door="justine"]{--dc:#6d4bd8;--dt:#f2eefd}
.wcs-seg-b[data-door="email"]  {--dc:#475569;--dt:#eef1f6}
@media (max-width:640px){
  /* A thumb, not a mouse pointer. → memory verify-on-mobile-jeannine-works-on-a-phone */
  .wcs-seg-b{min-height:44px;font-size:15px;padding:0 16px}
  .wcs-seg-b .n{font-size:14px}
}
@media (max-width:768px){
  /* On a phone the ground goes navy, so the pale chip has to come with it or it disappears
     against its own background. → memory verify-on-mobile-jeannine-works-on-a-phone */
  .wcs-src{background:rgba(255,255,255,.12);color:#e6ecff;border-color:rgba(180,195,255,.28)}
  .wcs-src.ju{background:rgba(150,132,255,.26);color:#dcd4ff;border-color:rgba(180,160,255,.4)}
  .wcs-src.ye{background:#fff;color:#d32323;border-color:#f1b9b9}   /* white chip, solid Yelp red — readable on a light card or a dark panel (Kevin, 21 Sept: "still can't read the word yelp") */
  .wcs-src.em{background:rgba(110,230,170,.22);color:#c9f5df;border-color:rgba(130,240,185,.38)}
  /* On the navy phone ground the door buttons flip too, or a white pill glares. */
  /* On the dark strip the tints would vanish, so the doors keep their colour in the TEXT and
     the dot instead, and the picked one still fills. */
  .wcs-seg-b{background:rgba(255,255,255,.10);color:#e6ecff}
  .wcs-seg-b .n{background:rgba(255,255,255,.16);color:#e6ecff}
  .wcs-seg-b.on{background:#fff;color:#0f1729}
  .wcs-seg-b.on .n{background:#eef1f7;color:#4a5468}
}
.wcs-right{display:flex;align-items:center;gap:12px}
.wcs-badge{font-size:13px;font-weight:800;padding:6px 12px;border-radius:999px;white-space:nowrap}
@media (max-width:760px){
  /* A 21px-tall link is a miss on a phone — Apple's own floor for anything you tap is 44.
     "See the full numbers" is a real destination, so it gets a real target. */
  .ps-more{min-height:40px; display:inline-flex; align-items:center}
  .wcs-right{flex-wrap:wrap; row-gap:8px; max-width:100%}
  .wcs-badge{white-space:normal; max-width:100%}
  .wcs-name{min-height:34px; display:inline-flex; align-items:center}
}
.wcs-when{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;padding:2px 0 8px;font-size:13px}
.wcs-when b{font-weight:800;color:#1f2438}
.wcs-when span{font-weight:700;color:#5b667c}
.wcs-when i{font-style:normal;font-weight:700;color:#2f6bff}
.wcs-badge.pay{color:#c2410c;background:#fdefe6}.wcs-badge.clear{color:#0b8a4b;background:#e7f8ef}
.wcs-badge.progress{color:#2b3fa0;background:#eef3ff}.wcs-badge.done{color:#54627d;background:#eef2f8}
.wcs-rev{display:inline-flex;align-items:center;gap:8px;cursor:pointer;user-select:none;font-size:12px;font-weight:800;color:#8894ab}
.wcs-rev .sw{width:38px;height:22px;border-radius:999px;background:#cfd6e4;position:relative;transition:background .16s;flex:none}
.wcs-rev .sw i{position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.25);transition:left .16s}
.wcs-rev.on .sw{background:#12915a}.wcs-rev.on .sw i{left:19px}.wcs-rev.on{color:#0b8a4b}
/* 🔴 A THUMB TARGET ON A PHONE. Found 2026-08-29 by the phone-width checker: the "Review: not
   decided" switch on the Home screen is tappable but only 22px tall — half what a thumb needs.
   Deciding whether a customer gets asked for a review is a real decision Jeannine makes from
   this screen; a control she has to aim at is a control she gets wrong.
   The little switch keeps its shape — the row around it grows, because what must be easy to hit
   is the thing she presses, not the picture of it.
   → memory verify-on-mobile-jeannine-works-on-a-phone */
@media (max-width:760px){ .wcs-rev{ min-height:44px; padding:0 4px; } }
.wcs-rev.undecided{color:#a4670a}.wcs-rev.undecided .sw{background:#f0c88a}
.wcs-rev.skipped{color:#8894ab}
/* 🔴 READ-ONLY on Where every client stands — Kevin, 2026-09-10: "we don't need toggles here.
   This is not where we decide." The words stay, the switch and everything that made it look
   pressable go with it. */
.wcs-rev.is-label{cursor:inherit;gap:0;min-height:0;padding:0}
/* Delete for good, on the Follow-up card only (Kevin, 2026-09-03). Quiet by default and red
   only on hover: it is the one control here that cannot be undone from the screen, so it must
   be findable without ever being the thing the eye lands on first.
   → memory hq-leads-board-design-rules (red = waiting on us, never decoration) */
.wcs-del{font:inherit;font-size:12.5px;font-weight:800;cursor:pointer;background:#fff;
  border:1px solid var(--line);border-radius:999px;padding:5px 12px;color:var(--ink-soft);white-space:nowrap}
.wcs-del:hover{border-color:#e7b6ae;background:#fdf3f1;color:#a32d20}
.wcs-del:disabled{opacity:.6;cursor:default}
/* 🗄️ Archive sits beside Delete and must read as the SAFE one — Kevin, 2026-09-06: "delete is
   extreme… I think we archive it." Same shape so the pair looks deliberate, navy on hover rather
   than red, because filing something away is an ordinary Tuesday and deleting is not. NEVER grey
   on hover. → memory hq-leads-board-design-rules */
.wcs-arch{font:inherit;font-size:12.5px;font-weight:800;cursor:pointer;background:#fff;
  border:1px solid var(--line);border-radius:999px;padding:5px 12px;color:var(--ink-soft);white-space:nowrap}
.wcs-arch:hover{border-color:#bcd0ff;background:#eef3ff;color:#1e4fd6}
.wcs-arch:disabled{opacity:.6;cursor:default}
/* A thumb target on a phone — same rule as the review switch above. */
@media (max-width:760px){ .wcs-del,.wcs-arch{ min-height:44px; font-size:14px; padding:0 14px; } }
.wcs-sentby{display:block;width:100%;margin-top:5px;font-size:13px;color:var(--ink-soft);font-weight:600}
.wcs-who{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}
.wcs-who .wl{font-size:10.5px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:#94a1b6;margin-right:1px}
.wcs-who-chip{display:inline-flex;align-items:center;gap:6px;background:#f6f8fc;border:1px solid #e7ecf3;border-radius:999px;padding:3px 11px 3px 3px;font-size:12.5px;font-weight:800;color:#33415c;white-space:nowrap}
.wcs-who-chip .wa{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;color:#fff;font-size:10px;font-weight:800;flex:none}
/* The ten steps are wider than a phone on purpose — the row slides sideways, and it opens on the
   step the customer is actually ON (client-stands.js does the positioning).
   Kevin, 2026-08-29: "they don't scroll across the screen so we can see where they're at."
   `nowrap` on the label is part of the same fix: "Confirmation" was breaking into "Confirm / ion"
   against the right edge, which reads as a broken screen rather than as more to scroll to. */
.wcs-steps{display:flex;overflow-x:auto;padding-bottom:2px;scroll-behavior:smooth;
  overscroll-behavior-x:contain}
.wcs-steps::-webkit-scrollbar{height:4px}
.wcs-steps::-webkit-scrollbar-thumb{background:#d5dceb;border-radius:99px}
/* 🔴 THE LABELS WRAP NOW, because they carry the same words as "Where this lead is" on the quote
   screen — "Confirming day & time", not "Day & time". Kevin, 2026-09-06: *"we made sure that Where
   this lead is matches what's on Follow-up and what's on the home page."* Held on one line those
   words would push the strip off the card. → memory journey-steps-must-match-everywhere */
.wcs-step .lbl{white-space:normal}
.wcs-step{flex:1 0 92px;display:flex;flex-direction:column;align-items:center;gap:6px;position:relative}
/* ⭐ THE ONE STEP YOU CAN OPEN (Kevin, 2026-09-08): *"where it says inspector assigned — maybe we
   click there, and we can read the actual card that went out."* Only INSPECTOR ASSIGNED opens,
   and only once it has happened, so the rest of the strip keeps reading as a picture of where
   somebody is rather than a row of buttons. → memory hie-requested-held-booked */
a.wcs-step.opens{text-decoration:none;color:inherit;cursor:pointer;border-radius:10px;padding:2px 4px 4px;
  transition:background .12s, box-shadow .12s}
a.wcs-step.opens:hover{background:#f4f7ff;box-shadow:inset 0 0 0 1px #0f1729}
.wcs-read{font-size:12px;font-weight:800;color:#2f6bff;line-height:1.2;margin-top:1px}
a.wcs-step.opens:hover .wcs-read{text-decoration:underline}
@media (max-width:640px){ .wcs-read{font-size:13px} }
.wcs-step::before{content:"";position:absolute;top:11px;right:50%;width:100%;height:2px;background:#e5e9f2;z-index:0}
.wcs-step:first-child::before{display:none}
.wcs-step .d{position:relative;z-index:1;width:24px;height:24px;border-radius:50%;display:grid;place-items:center;background:#eef1f7;border:2px solid #eef1f7;color:#9aa4ba;font-size:11px;font-weight:800}
.wcs-step .d svg{width:13px;height:13px}
.wcs-step .lbl{font-size:12.5px;font-weight:700;color:#9aa4ba;line-height:1.25;text-align:center}
/* The date each step actually happened, under its own step. A step with no date shows nothing —
   "not yet" and "we lost the time" must never look the same. → memory receipt-rule-carry-the-source */
.wcs-step .dt{font-size:11.5px;font-weight:600;color:#8a93a8;line-height:1.2;text-align:center}
.wcs-step.done .dt{color:#5c6580}
.wcs-step.done .d{background:#12915a;border-color:#12915a;color:#fff}
.wcs-step.done::before{background:#12915a}
.wcs-step.done .lbl{color:#4a5578}
.wcs-step.now .d{background:#fff;border-color:#3a4fd0;color:#3a4fd0;box-shadow:0 0 0 4px rgba(58,79,208,.15)}
.wcs-step.now .lbl{color:#1e2f8f;font-weight:800}
.wcs-step.gate.now .d{border-color:#e0851c;color:#e0851c;box-shadow:0 0 0 4px rgba(224,133,28,.2)}
.wcs-step.gate.now .lbl{color:#c2410c}

/* 🔴 THIS BLOCK HAD NO BRACES AND NO MEDIA QUERY (found 2026-08-25 doing the phone sweep).
   A bare list of selectors ending in a comma, with no declarations — so the browser threw away
   this rule AND EVERY RULE AFTER IT IN THE FILE. Silent: the page still looked fine, because
   what was lost was only the phone sizes, and nobody reads a stylesheet on a phone to check.
   It is the reason a new mobile block appeared to do nothing at all.

   Restored as what it was plainly meant to be: the 14px floor on the walkthrough card's own
   small type, at phone width. → memory: verify-on-mobile-jeannine-works-on-a-phone */
@media (max-width:640px){
  .wcs-badge,
  .wcs-name span,
  .wcs-rev,
  .wcs-step .d,
  .wcs-step .lbl,
  .wcs-step .dt,
  .wcs-sum,
  .wcs-sentby,
  .wcs-who .wl,
  .wcs-who-chip{font-size:14px !important}
}

/* ══════════════════════════════════════════════════════════════════════════════
   THE PHONE SWEEP (Emmet, 2026-08-25). Kevin: "make sure all of our pages are
   mobile ready."

   Nearly every problem on every page turned out to be the SAME problem: the
   sidebar. It is on all 55 screens, and at phone width it was carrying about
   44 tap targets under 40px tall and 56 pieces of text under 14px — the same
   two faults counted 55 times. Fixed once here, they are fixed everywhere, which
   is also why this belongs in the shared stylesheet and not on a page.

   Sizes only. Nothing here changes what the sidebar IS, what it says, or where
   anything sits — a desktop screen is untouched, because a sweep that redesigns
   working screens the week of go-live is how you break the ones that worked.
   → memory: verify-on-mobile-jeannine-works-on-a-phone
   ══════════════════════════════════════════════════════════════════════════════ */
@media (max-width:640px){
  /* Every row you tap is at least 44px tall — a thumb, not a mouse pointer. */
  .navitem{padding:12px 13px;font-size:15px;min-height:46px}
  .navitem svg{width:19px;height:19px}
  .navmsg{padding:12px;min-height:48px}
  .navmsg .navmsg-tx b,.navmsg .navmsg-tx span{font-size:14px}
  .navhome{font-size:14px;padding:11px 6px 13px;min-height:44px}
  .navhome svg{width:17px;height:17px}
  /* Section headings and the usage box were the smallest type in the product. */
  .navgroup{font-size:14px;margin:20px 6px 9px;padding-bottom:8px}
  .usage .row{font-size:14px}
  .navtip{font-size:14px}
  /* The client card at the top of the sidebar. */
  .nav .who b,.nav .who span,.navclient b,.navclient span{font-size:14px}
}

/* ── THE 14px FLOOR ON A PHONE (Emmet, 2026-08-25) ────────────────────────────
   Kevin's standing rule is nothing under 14px, and he asks for bigger every time.
   These are the classes the sweep found sitting between 9.5px and 13.5px on a
   375px screen — hints, sub-lines, labels, roles, timestamps, footers.

   Every one of them is currently SMALLER than 14px, so this can only raise them.

   Deliberately NOT in this list: avatar initials, count bubbles, status pills,
   step numbers, calendar day cells and the "Popular" flag. 14px bursts the circle
   or the chip they sit inside, and a label that overflows its own badge is worse
   than a small one. Those stay as they are on purpose.
   → memory: hq-type-scale · verify-on-mobile-jeannine-works-on-a-phone
   ──────────────────────────────────────────────────────────────────────────── */
@media (max-width:640px){
  .addr, .aotitle, .cf-cell, .cf-lbl, .chg, .desc, .dl, .dlbl, .dline,
  .eyebrow, .foot, .gfoot, .grole, .grp, .hint, .kicker, .ktlbl, .label,
  .lbfh, .lbrto, .live, .mh, .note, .orsep, .pbname, .phaselbl, .plabel,
  .pn, .previewfoot, .proglbl, .qdiv, .role, .sec-tag, .sh, .sidetog,
  .sq-hint, .sq-lbl, .sr-tag, .sub, .today, .tt, .us, .usline, .when,
  .who, .wtag, .wd-day{font-size:14px !important}
  /* Line-height has to come with it or a raised label crowds the line above. */
  .sub, .hint, .desc, .note, .foot{line-height:1.5}
}

/* ════════════════════════════════════════════════════════════════════════════
   🔒 NOTHING SLIDES SIDEWAYS ON A PHONE — added 2026-08-26

   Kevin, holding his phone on the inspector screen: "we need to lock it down.
   Right now it's going to the left, it's going to the right. It's not staying
   steady."

   He is describing the page itself moving under his thumb. One item wider than
   the screen drags the WHOLE page with it, so every heading, every card and
   every button shifts while he is trying to tap one — and the right-hand end of
   every line is off-screen. The cause is always the same shape: something that
   cannot be broken (a long web address, a wide table, an oversized image) sitting
   in a box that is happy to grow.

   Three rules, in the order they matter:
     1. The page may not scroll sideways. Full stop.
     2. Anything genuinely wide gets its OWN sideways scroll, inside its own box,
        so a table is still readable — the page stays still, the table moves.
     3. A long unbroken word wraps instead of stretching its container.

   ⚠️ Rule 1 alone would HIDE the overflowing edge, which is why rule 2 exists
   and why it comes with it. Hiding a wide table without giving it a way to be
   scrolled would trade a moving page for unreachable content.
   → memory verify-on-mobile-jeannine-works-on-a-phone
   ════════════════════════════════════════════════════════════════════════════ */
@media (max-width:820px){
  html, body{ max-width:100%; overflow-x:hidden; overscroll-behavior-x:none; }

  /* Wide things scroll inside themselves, not by moving the page. */
  table, pre, .tbl, .ptbl, .scrollx{ display:block; max-width:100%; overflow-x:auto; -webkit-overflow-scrolling:touch; }

  /* Never let a picture or a frame set the width of the page. */
  img, svg, video, canvas, iframe{ max-width:100%; height:auto; }

  /* A web address, an email or a file name has nowhere to break — let it wrap
     rather than stretch the card it sits in. This is what put the inspector's
     notes 631px wide inside a 485px screen. */
  p, li, td, th, dd, dt, .note, .msg, .mtxt, .sub, .hint, .desc, .addr,
  .card, .cell, .row{ overflow-wrap:anywhere; word-break:break-word; }

  /* Flex and grid children default to refusing to shrink below their longest
     word. This is the half people forget, and without it the wrapping above
     never gets a chance to happen. */
  .card > *, .msg > *, .row > *, .grid > *{ min-width:0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   🔴 THE PAGE THAT ZOOMS IN AND THEN SLIDES — 2026-08-29

   Kevin, on his iPhone, with a photo of the Quotes screen half off the side:
   *"It doesn't fit on the screen, and it bounces back and forth on the mobile."*

   It is not a layout fault. iPhone Safari ZOOMS THE WHOLE PAGE IN the instant a
   person taps a typing field whose text is smaller than 16px — it assumes the
   field is too small to read. Once zoomed, the page really is wider than the
   screen, so it drags sideways and rubber-bands. Every field in HQ was 14px, and
   Kevin's own control size is 13px, so tapping "Name, phone or address" on the
   Quotes screen zoomed the page every single time.
   → memory verify-on-mobile-jeannine-works-on-a-phone

   16px on a phone is the whole fix, and it is the ONLY size that works — 15.9px
   still zooms. Desktop is untouched: the 13px control size Kevin picked stays
   exactly as it is on a laptop. → memory hq-type-scale

   ⚠️ !important is deliberate and is not a workaround. Roughly sixty screens set
   their own field sizes in their own page styles, which load AFTER this file and
   would otherwise win. One rule that cannot be beaten is safer than sixty copies
   that drift. → memory hq-one-rule-not-two-copies

   ⚠️ The other way to stop the zoom is `maximum-scale=1` on the viewport, which
   also stops a person pinching to enlarge anything on the page. Not on a screen
   Jeannine reads in a car. Never add it.

   ⚠️ The long `html body ...:not()` selectors are not decoration either. A handful of screens
   already carry their own `!important` on a 14px field (the Quotes screen's why-price boxes were
   one), and between two !important rules the MORE SPECIFIC one wins — so this rule has to out-rank
   a two-class page rule or it silently does nothing. Measured on the Quotes screen before and
   after. → memory verify-dont-guess */
@media (max-width: 820px){
  html body input:not([type=checkbox]):not([type=radio]):not([type=range]),
  html body textarea,
  html body select,
  /* A typed-into box is often a bare `contenteditable` with no value at all, so matching
     ="true" alone missed the signing page's fill-in blanks. */
  html body [contenteditable]:not([contenteditable="false"]){ font-size: 16px !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PHONE SWEEP, 2026-08-29 — rows that refused to wrap

   Kevin: "make sure the page doesn't go back and forth." Every screen was measured at 390px,
   and the same shape came up again and again: a flex row whose children cannot shrink, so
   either the row hangs off the right-hand edge or one child is squeezed to a couple of
   letters wide and its words stack one per line.

   These are the SHARED pieces. Anything page-local is fixed in that page's own styles. */
@media (max-width: 820px){
  /* "Step 3 of 6" was being crushed to 51px, so the four words ran down the screen. The chip
     keeps its own width and the sentence beside it wraps underneath. */
  .stephint{flex-wrap:wrap; row-gap:6px}
  .stephint .b{flex:none; white-space:nowrap}

  /* A section label carries a heading and a hint. The hint is a sentence and was pushing the
     whole label past the edge of the screen. */
  .sectlabel{min-width:0}
  .sectlabel .hint{flex:1 1 100%; white-space:normal}
}

/* ── A THUMB NEEDS 40px — phone widths only, 2026-08-29 ────────────────────────────────
   Measured across all 84 screens at 390px. Everything named below came back under 38px tall,
   which is smaller than a fingertip: "Sign out" was 16px, the Calendar's week arrows 30px.

   ⚠️ PLAIN INLINE LINKS ARE DELIBERATELY LEFT ALONE. Nineteen of the small targets were bare
   <a> tags sitting inside a sentence — an email address in a letter, a name in a line of text.
   Forcing those to 40px tall would blow the paragraphs apart, and a link inside a sentence is
   read, not aimed at. Only NAMED controls are raised. */
@media (max-width: 820px){
  .back, .backhq, .backlink, .backchat, .home, .tocall, .plink, .pbtn, .go,
  .wcs-name, .micbtn, .idxbtn, .tnbtn,
  #weekPrev, #weekNext, #graceX, #gcalConnect, #sendAsSel, #idxBtn, #idxClose{
    min-height: 40px !important;
  }
  /* A link only obeys a height if it is told to lay itself out as a box. */
  a.back, a.backhq, a.backlink, a.home, a.tocall, a.plink, a.pbtn, a.go, a.wcs-name{
    display: inline-flex !important; align-items: center;
  }
}
