/* EA Spotless Rides — Client Portal (EAS-27)
   Extends the main site (styles.css): same dark theme, gold accent, Barlow
   fonts and button styles. Only portal-specific components live here.
   Design tokens come from global.css (loaded first on portal.html); the
   canonical set lives in css/tokens.css. */

.pt-app{min-height:100vh}

/* Auth screen — dark, matches the site hero */
.pt-auth{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;
  background:radial-gradient(1200px 520px at 50% -10%, var(--dark3) 0%, var(--black) 60%)}
.pt-auth-card{background:var(--dark2);border:1px solid var(--dark3);border-radius:14px;padding:38px 30px;width:100%;max-width:390px;text-align:center;box-shadow:0 24px 70px rgba(0,0,0,.6)}
.pt-auth-logo{height:56px;width:auto;margin-bottom:16px}
.pt-auth-title{font-family:var(--font-display);font-weight:800;letter-spacing:.05em;text-transform:uppercase;font-size:28px;margin:0 0 6px;color:var(--white)}
.pt-auth-sub{color:var(--gray);font-size:var(--t-md);margin:0 0 22px}
.pt-or{display:flex;align-items:center;gap:10px;color:var(--gray);font-size:var(--t-sm);margin:18px 0;text-transform:uppercase;letter-spacing:.1em}
.pt-or::before,.pt-or::after{content:"";flex:1;height:1px;background:var(--dark3)}
.pt-auth-msg{font-size:var(--t-base);margin-top:10px;min-height:18px;color:var(--gold-light)}
/* Auth feedback states — shared status tokens, readable on the dark card. */
.pt-auth-msg.ok{color:var(--success)}
.pt-auth-msg.err{color:var(--danger)}
.pt-auth-fine{font-size:var(--t-sm);color:var(--gray);margin-top:18px}
#ptAuthInstall:not(:empty){margin-top:16px;padding-top:16px;border-top:1px solid var(--dark3)}
#ptAuthInstall .pt-btn{width:100%}
.pt-auth-install{font-size:var(--t-sm);color:var(--gray);line-height:1.55}

/* Inputs + buttons (reuse site .btn-primary where possible) */
.pt-input{width:100%;padding:12px 14px;font-size:var(--t-md-plus);font-family:inherit;color:var(--white);
  background:var(--dark3);border:1px solid rgba(255,255,255,.12);border-radius:6px;margin-bottom:10px}
.pt-input:focus{outline:none;border-color:var(--gold)}
/* Invalid state — once the field's been touched (:user-invalid) or flagged by
   JS (aria-invalid), so it doesn't read as broken before the customer types. */
.pt-input:user-invalid,.pt-input[aria-invalid="true"]{border-color:var(--danger)}
.pt-input:disabled{opacity:.6}
/* Turnstile mount (EAS-584). The container ships empty on a portal with no site
   key, so it must take no vertical space until the widget is actually there —
   :empty keeps the sign-in card exactly as it looks today until the day the key
   is set. */
.pt-turnstile{margin-bottom:10px}
.pt-turnstile:empty{display:none}
/* The base sets shape and type only; the modifiers below set the colour. It
   therefore has to carry its OWN background/colour too — a bare `pt-btn` with
   neither used to fall straight through to the user agent's default button,
   which iOS Safari paints in the system accent. Two "Add email"/"Add phone"
   buttons shipped bright blue in a gold-and-black app because of it.
   `appearance:none` kills the native chrome so the platform can never repaint
   a button we styled. Every modifier is declared after this rule, so each still
   wins on equal specificity. */
.pt-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:12px 18px;
  font-family:var(--font-display);font-weight:700;font-size:var(--t-md-plus);letter-spacing:.05em;text-transform:uppercase;
  border-radius:5px;border:1px solid transparent;cursor:pointer;
  -webkit-appearance:none;appearance:none;background:var(--dark3);color:var(--white)}
.pt-btn-primary{background:var(--gold);color:var(--black)}
.pt-btn-primary:hover{background:var(--gold-light)}
.pt-btn-google{background:transparent;border-color:rgba(255,255,255,.18);color:var(--white)}
.pt-btn-google:hover{border-color:var(--gold)}
.pt-btn-sm{width:auto;padding:8px 15px;font-size:var(--t-base);background:var(--gold);color:var(--black)}
a.pt-btn{display:inline-flex;text-decoration:none}
.pt-link{background:none;border:none;color:var(--gold);font-family:var(--font-display);font-weight:700;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;font-size:var(--t-base);padding:0}
.pt-link.danger{color:var(--danger);margin-left:14px}
.pt-btn-link{display:block;width:100%;background:none;border:none;color:var(--gray);font-size:var(--t-base);cursor:pointer;padding:10px 0 0;text-decoration:underline}
.pt-btn-link:hover{color:var(--white)}

/* App nav (site look) */
.pt-nav{display:flex;align-items:center;justify-content:space-between;padding:12px 5vw;background:rgba(10,10,10,.96);border-bottom:1px solid var(--dark3);position:sticky;top:0;z-index:var(--z-nav)}
.pt-nav-right{display:flex;align-items:center;gap:16px}
.pt-user{font-size:var(--t-md);color:var(--gray)}
/* Signed-in identity + service-area weather, matching Command HQ's header. */
.pt-signedin{display:flex;align-items:center;gap:8px}
.pt-user-avatar{border-radius:50%;object-fit:cover;border:1px solid var(--dark3);display:block}
.pt-signout{background:none;border:none;color:var(--gray);font-size:var(--t-base);cursor:pointer;font-family:inherit}
.pt-signout:hover{color:var(--white)}

/* Tabs */
.pt-tabs{display:flex;gap:2px;overflow-x:auto;background:var(--dark);border-bottom:1px solid var(--dark3);padding:0 max(12px,4vw);position:sticky;top:61px;z-index:var(--z-sticky)}
.pt-tab{flex-shrink:0;background:none;border:none;border-bottom:3px solid transparent;padding:14px 16px;font-family:var(--font-display);font-size:var(--t-md);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--gray);cursor:pointer}
.pt-tab.active{color:var(--gold);border-bottom-color:var(--gold)}

.pt-main{max-width:880px;margin:0 auto;padding:28px 5vw 70px}
/* THE DRIVEWAY IS PHONE-FIRST, BUT IT IS NOT PHONE-ONLY (EAS-498).
   880px was the whole app at every size, which left 280px of dead space
   down each side of a 1440px screen and made a correctly-rendering page
   still read as a mobile layout. The feed stays comfortable at 880 — it is
   a column of cards — so the extra width is given only where there is
   plenty of it, and the booking grids inside pick up another column. */
@media (min-width:1180px){ .pt-main{max-width:1120px} }
/* Each tab panel is a <section>, and global.css gives every bare section
   3.5rem/1.5rem of padding — so every portal screen has been carrying ~48px of
   dead space above its first line and a second, narrower gutter inside
   .pt-main's own. The panel is a container, not a page section. */
.pt-panel{padding:0}
.pt-loading{color:var(--gray);text-align:center;padding:48px}
.pt-h2{font-family:var(--font-display);font-weight:800;text-transform:uppercase;letter-spacing:.03em;font-size:var(--t-3xl);margin:0 0 18px;color:var(--white)}
.pt-h3{font-family:var(--font-display);font-size:var(--t-base);text-transform:uppercase;letter-spacing:.08em;color:var(--gold);margin:24px 0 10px}
.pt-head-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;gap:12px}
.pt-head-row .pt-h2{margin:0}
.pt-muted{color:var(--text-faint);font-size:var(--t-base)}

.pt-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px}
.pt-card{background:var(--dark2);border:1px solid var(--dark3);border-radius:12px;padding:18px}
.pt-card-label{font:var(--type-eyebrow);letter-spacing:var(--track-eyebrow);text-transform:uppercase;color:var(--gray);margin-bottom:10px}
.pt-card-big{font-family:var(--font-display);font-weight:800;font-size:var(--t-2xl);color:var(--white);text-transform:uppercase}
.pt-cta{margin-top:24px}

.pt-row,.pt-card2{display:flex;align-items:center;justify-content:space-between;gap:12px;background:var(--dark2);border:1px solid var(--dark3);border-radius:10px;padding:14px 16px;margin-bottom:8px}
.pt-row-title{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.pt-row-right{display:flex;align-items:center;gap:12px;flex-shrink:0}
.pt-amt{font-family:var(--font-display);font-weight:800;color:var(--white);font-size:var(--t-lg)}
.pt-tag{display:inline-block;font-family:var(--font-display);font-size:var(--t-2xs);font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--gold);background:rgba(212,160,23,.14);border-radius:4px;padding:1px 6px;vertical-align:middle}
.pt-pill{font-family:var(--font-display);font-size:var(--t-xs);font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:3px 9px;border-radius:999px;background:rgba(255,255,255,.07);color:var(--gray)}
.pt-pill.paid{background:var(--success-bg);color:var(--success)}
.pt-pill.up{background:rgba(212,160,23,.16);color:var(--gold)}
.pt-pill.due{background:var(--danger-bg);color:var(--danger)}
.pt-empty{color:var(--text-faint);font-size:var(--t-md);padding:26px 20px;background:var(--dark2);border:1px dashed var(--dark3);border-radius:12px;text-align:center}
.pt-empty-ico{font-size:30px;line-height:1;margin-bottom:10px}
.pt-empty-title{font-family:var(--font-display);font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--white);font-size:var(--t-md-plus);margin-bottom:5px}
.pt-empty-sub{color:var(--text-faint);font-size:var(--t-base);line-height:1.5;margin:0 auto 14px;max-width:340px}

/* Appointment cards: stacked, labelled detail lines + inline forecast */
.pt-row-appt{align-items:flex-start}
.pt-row-main{display:flex;flex-direction:column;gap:4px;min-width:0}
.pt-row-appt .pt-row-title{margin-bottom:2px}
.pt-meta-line{display:flex;align-items:flex-start;gap:7px;font-size:var(--t-base);color:var(--gray);line-height:1.4}
.pt-meta-ico{flex-shrink:0;opacity:.85}
.pt-wx{display:flex;align-items:center;gap:7px;margin-top:5px;font-size:var(--t-base);color:var(--gray);background:rgba(255,255,255,.04);border:1px solid var(--dark3);border-radius:8px;padding:5px 9px;width:fit-content;max-width:100%}
/* The pill is emitted with the `hidden` attribute and unhidden only once a
   forecast lands (portal.js). `display:flex` above outranks the UA's
   `[hidden]{display:none}`, so every upcoming hero showed an empty grey box
   while the forecast was loading — the same trap css/detailer-day.css
   documents for .dd-cond-opts (EAS-624). */
.pt-wx[hidden]{display:none}
/* Risky, the worst of three levels, is red as on the other apps (owner, 6 Oct 2026). */
.pt-wx[data-risk=risky]{color:var(--danger);background:rgba(255,140,140,.08);border-color:rgba(255,140,140,.25)}
.pt-wx-emoji{font-size:var(--t-md);flex-shrink:0}
@media (max-width:600px){ .pt-row-appt{flex-direction:column} .pt-row-appt .pt-row-right{align-self:flex-start} }

.pt-form{display:flex;flex-direction:column;gap:8px;max-width:430px}
.pt-label{display:flex;flex-direction:column;gap:5px;font-family:var(--font-display);font-size:var(--t-sm);font-weight:700;color:var(--gray);text-transform:uppercase;letter-spacing:.05em}
.pt-form .pt-btn{align-self:flex-start;width:auto;margin-top:10px}

@media (max-width:600px){ .pt-user{display:none} }

/* CRUD modal */
.pt-modal{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;padding:18px}
.pt-modal[hidden]{display:none}
.pt-modal-backdrop{position:absolute;inset:0;background:rgba(0,0,0,.66)}
.pt-modal-card{position:relative;width:100%;max-width:440px;background:var(--dark2);border:1px solid var(--dark3);border-radius:14px;box-shadow:0 24px 70px rgba(0,0,0,.6);max-height:90vh;overflow-y:auto}
.pt-modal-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--dark3)}
.pt-modal-title{font-family:var(--font-display);font-weight:800;text-transform:uppercase;letter-spacing:.04em;font-size:var(--t-xl);margin:0;color:var(--white)}
.pt-modal-x{background:none;border:none;color:var(--gray);font-size:var(--t-xl);cursor:pointer;line-height:1;display:flex;align-items:center;justify-content:center;min-width:36px;min-height:36px;padding:6px;margin:-6px -8px -6px 0}
.pt-modal-x:hover{color:var(--white)}
.pt-modal-body{display:flex;flex-direction:column;gap:8px;padding:18px 20px}
.pt-form-row{display:flex;gap:10px}
.pt-form-row .pt-label{flex:1;min-width:0}
.pt-check{display:flex;align-items:center;gap:8px;font-size:var(--t-base);color:var(--gray);cursor:pointer;margin-top:4px}
.pt-modal-actions{display:flex;gap:10px;margin-top:10px}
.pt-modal-actions .pt-btn{flex:1}
.pt-modal-msg{padding:0 20px 16px;font-size:var(--t-base);color:var(--gold-light);min-height:14px}

/* Booking-style step flow (ported qp-card system from book-now) */
.pt-step{margin-bottom:30px}
.pt-step-head{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.pt-step-num{width:26px;height:26px;border-radius:50%;background:var(--gold);color:var(--black);font-family:var(--font-display);font-weight:800;font-size:var(--t-md);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.pt-step-title{font-family:var(--font-display);font-weight:800;font-size:var(--t-xl);text-transform:uppercase;letter-spacing:.04em;color:var(--white)}
.pt-step-opt{color:var(--gray);font-size:var(--t-base);font-family:var(--font-body);font-weight:400;text-transform:none;letter-spacing:0}
.qp-grid{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
.qp-card{position:relative;cursor:pointer;border:1px solid var(--dark3);border-radius:8px;padding:16px 36px 14px 16px;background:var(--dark2);transition:border-color .14s,background .14s,box-shadow .14s;user-select:none;display:block}
button.qp-card{width:100%;appearance:none;-webkit-appearance:none;font:inherit;color:inherit;text-align:left}
.qp-card:hover{border-color:rgba(212,160,23,.4)}
.qp-card:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.qp-card.qp-on{border-color:var(--gold);background:rgba(212,160,23,.07);box-shadow:0 0 0 1px rgba(212,160,23,.1)}
.qp-card-svg{width:38px;height:38px;color:var(--gold);margin-bottom:10px;display:block;stroke:currentColor;fill:none}
.qp-card-svg path,.qp-card-svg circle,.qp-card-svg line,.qp-card-svg polyline,.qp-card-svg rect{stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.qp-card-name{font-family:var(--font-display);font-size:var(--t-md-plus);font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--white);line-height:1.15;margin-bottom:4px}
.qp-card-desc{font-size:var(--t-sm);color:var(--gray);line-height:1.4}
.qp-card-price{font-family:var(--font-display);font-size:var(--t-md-plus);font-weight:700;color:var(--gold);margin-top:10px}
.qp-dot{position:absolute;top:11px;right:11px;width:18px;height:18px;border-radius:50%;border:1.5px solid rgba(255,255,255,.22);display:flex;align-items:center;justify-content:center;background:transparent;transition:all .14s}
.qp-card.qp-on .qp-dot{background:var(--gold);border-color:var(--gold)}
.qp-dot-check{opacity:0;transition:opacity .14s}
.qp-card.qp-on .qp-dot-check{opacity:1}
.qp-card.qp-add{border-style:dashed;text-align:center;padding:24px 16px;color:var(--gray)}
.pt-book-foot{position:sticky;bottom:0;background:rgba(10,10,10,.96);border-top:1px solid var(--dark3);margin:24px -5vw 0;padding:14px 5vw;display:flex;align-items:center;justify-content:space-between;gap:14px}
/* The AI chat widget's host is a click-through fixed layer (inset:0) that pins
   its bubble to its own bottom edge. Page styles outrank the widget's :host
   rule, so raising that edge lifts the bubble clear of the Book footer instead
   of parking it on "Book Appointment". js/portal.js liftConvai() sets the lift
   to the footer's height while Book is open, and to 0 everywhere else. */
elevenlabs-convai{bottom:var(--pt-convai-lift,0px) !important;transition:bottom .2s ease}
.pt-book-total{font-family:var(--font-display);font-weight:800;font-size:var(--t-xl-plus);color:var(--gold)}
.pt-book-total .pt-strike{color:var(--gray);text-decoration:line-through;font-size:var(--t-md-plus);font-weight:600;margin-right:6px}

/* Discount code (Book tab) — mirrors the booking page's compact code field */
.pt-book-discount{margin-bottom:24px}
.pt-disc-row{display:flex;gap:8px;max-width:430px}
.pt-disc-row .pt-input{margin-bottom:0;text-transform:uppercase}
.pt-disc-msg{font-size:var(--t-sm);margin-top:6px;min-height:14px}
.pt-disc-msg.err{color:var(--danger)}
.pt-disc-msg.ok{color:var(--success)}
.pt-disc-applied{display:flex;align-items:center;gap:12px;color:var(--success);font-size:var(--t-md)}

/* Flatpickr calendar — gold theme, matches the booking page */
.flatpickr-calendar{background:var(--dark);border:1px solid var(--dark3);box-shadow:0 18px 45px rgba(0,0,0,.45);color:var(--white);font-family:var(--font-body)}
.flatpickr-months,.flatpickr-weekdays{background:var(--dark2)}
.flatpickr-current-month,.flatpickr-monthDropdown-months,.flatpickr-weekday,.flatpickr-day{color:var(--white) !important}
.flatpickr-day.weekend,.flatpickr-day.weekend:hover{color:var(--white) !important}
.flatpickr-day.today{border-color:rgba(212,160,23,.7)}
.flatpickr-day.selected,.flatpickr-day.startRange,.flatpickr-day.endRange,.flatpickr-day.selected:hover{background:var(--gold);border-color:var(--gold);color:var(--black) !important}
.flatpickr-day:hover{background:rgba(212,160,23,.16);border-color:rgba(212,160,23,.35)}
.flatpickr-day.flatpickr-disabled,.flatpickr-day.prevMonthDay,.flatpickr-day.nextMonthDay{color:rgba(255,255,255,.28) !important}
.flatpickr-months .flatpickr-prev-month svg,.flatpickr-months .flatpickr-next-month svg{fill:var(--gold)}

/* Branded toast (EAS-151) — replaces native alert() */
/* Auto-update prompt (EAS-33), shown when a new build is live and a reload
   would interrupt something. portal.html has loaded version-check.js all along
   and had no rule for its banner, so it would have rendered as a bare browser
   button — found by the coverage test written for EAS-556. The portal's tabs
   are sticky-top, not fixed-bottom, so this sits above the toast and nothing
   else. */
#opsUpdateBanner{position:fixed;left:50%;bottom:calc(26px + env(safe-area-inset-bottom,0px));
  transform:translateX(-50%);z-index:calc(var(--z-toast) + 1);max-width:92vw;padding:12px 18px;
  border:none;border-radius:999px;background:var(--gold);color:var(--black);font:inherit;
  font-size:var(--t-base);font-weight:800;letter-spacing:.02em;cursor:pointer;box-shadow:0 12px 34px rgba(0,0,0,.5)}
.pt-toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(10px);z-index:var(--z-toast);display:flex;gap:10px;align-items:flex-start;max-width:min(92vw,460px);background:var(--dark2);border:1px solid var(--dark3);border-left:4px solid var(--gold);border-radius:12px;padding:14px 18px;color:var(--white);font-size:var(--t-md);line-height:1.45;box-shadow:0 18px 50px rgba(0,0,0,.55);opacity:0;transition:opacity .22s ease,transform .22s ease}
.pt-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.pt-toast.success{border-left-color:var(--success)}
.pt-toast.error{border-left-color:var(--danger)}
.pt-toast-ic{flex-shrink:0;font-weight:800;color:var(--gold)}
.pt-toast.success .pt-toast-ic{color:var(--success)}
.pt-toast.error .pt-toast-ic{color:var(--danger)}

/* Notification preferences (Account → Notifications) ──────────────────────── */
.pt-notif-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 0;border-bottom:1px solid var(--dark3);cursor:pointer}
.pt-notif-row:last-of-type{border-bottom:none}
.pt-notif-info{display:flex;flex-direction:column;gap:5px;min-width:0}
.pt-notif-label{color:var(--white);font-size:var(--t-md);font-weight:600}
.pt-notif-chips{display:flex;gap:6px}
.pt-chip{font-size:var(--t-2xs);letter-spacing:.05em;text-transform:uppercase;color:var(--gray);border:1px solid var(--dark3);border-radius:999px;padding:2px 8px}
/* iOS-style switch built on a checkbox so the row stays a plain <label> */
.pt-switch{appearance:none;-webkit-appearance:none;position:relative;width:46px;height:28px;border-radius:999px;background:var(--dark3);border:1px solid rgba(255,255,255,.14);cursor:pointer;flex:0 0 auto;transition:background .15s}
.pt-switch:checked{background:var(--gold)}
.pt-switch::after{content:"";position:absolute;top:2px;left:2px;width:22px;height:22px;border-radius:50%;background:var(--white);transition:transform .15s}
.pt-switch:checked::after{transform:translateX(18px)}
.pt-switch:disabled{opacity:.5;cursor:default}

/* Review CTA card (dashboard) ─────────────────────────────────────────────── */
.pt-review-cta{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-top:14px;border-color:rgba(212,160,23,.4)}
.pt-review-cta-text{min-width:0}
@media (max-width:560px){.pt-review-cta{flex-direction:column;align-items:flex-start}.pt-review-cta .pt-btn{width:100%}}

/* Dashboard push/install nudge (EAS-39) — like the review CTA, with a dismiss × */
.pt-push-cta{position:relative;display:flex;align-items:center;justify-content:space-between;gap:16px;margin:0 0 16px;padding-right:40px;border-color:rgba(212,160,23,.4)}
.pt-push-dismiss{position:absolute;top:6px;right:10px;background:none;border:0;color:var(--gray);font-size:var(--t-2xl);line-height:1;cursor:pointer;padding:4px}
.pt-push-dismiss:hover{color:var(--white)}
@media (max-width:560px){.pt-push-cta{flex-direction:column;align-items:flex-start}.pt-push-cta .pt-btn{width:100%}}
/* Brief attention flash when we deep-link to the App & notifications card */
.pt-flash{animation:ptFlash 1.6s ease-out}
@keyframes ptFlash{0%,100%{box-shadow:0 0 0 0 rgba(212,160,23,0)}18%{box-shadow:0 0 0 3px rgba(212,160,23,.7)}}

/* Appointment card: title left, amount top-right ─────────────────────────── */
.pt-appt-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.pt-appt-head .pt-row-title{flex:1;min-width:0}
.pt-amt-top{flex:0 0 auto;white-space:nowrap}

/* Live appointment status pill (on the way / in progress) ─────────────────── */
.pt-pill.live{background:rgba(212,160,23,.16);color:var(--gold);border:1px solid rgba(212,160,23,.5)}
@keyframes ptLivePulse{0%,100%{opacity:1}50%{opacity:.45}}
.pt-pill.live::before{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--gold);margin-right:6px;vertical-align:middle;animation:ptLivePulse 1.4s ease-in-out infinite}

/* Status stepper: Confirmed → On the way → In progress → Done. The standalone
   pre-visit panel it used to live in retired with The Driveway — the stepper
   moved into the Right Now hero rather than repeating the appointment twice. */
.pt-stepper{display:flex;gap:4px;margin-bottom:18px}
/* SCOPED to the stepper (EAS-498). This rule and .pt-step at line 141 are two
   different components that happened to pick the same class name: one is a
   progress-dot in .pt-stepper, the other is a numbered step on the booking
   form. This one is written later, so it won — and align-items:center made
   every booking step shrink-to-fit, which collapsed the .qp-grid inside it to
   a single column at EVERY viewport. */
.pt-stepper .pt-step{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:6px;position:relative;text-align:center}
.pt-step-dot{width:12px;height:12px;border-radius:50%;background:var(--dark3);border:1px solid rgba(255,255,255,.16);flex-shrink:0;z-index:1}
.pt-step-label{font-size:var(--t-xs);color:var(--gray);line-height:1.2}
.pt-stepper .pt-step:not(:last-child)::after{content:"";position:absolute;top:6px;left:50%;width:100%;height:2px;background:var(--dark3);z-index:0}
.pt-stepper .pt-step.is-done .pt-step-dot{background:var(--gold);border-color:var(--gold)}
.pt-stepper .pt-step.is-done:not(:last-child)::after{background:var(--gold)}
.pt-stepper .pt-step.is-done .pt-step-label{color:var(--white)}
.pt-stepper .pt-step.is-current .pt-step-dot{background:var(--gold);border-color:var(--gold);animation:ptLivePulse 1.4s ease-in-out infinite}
.pt-stepper .pt-step.is-current .pt-step-label{color:var(--gold);font-weight:700}
/* Loading spinner — gives the "Loading your account…" state visible motion so a
   slow mobile connection doesn't read as frozen. */
.pt-spinner{display:inline-block;width:18px;height:18px;border:2px solid rgba(255,255,255,.18);border-top-color:var(--gold);border-radius:50%;animation:ptSpin .7s linear infinite;vertical-align:middle;margin-right:10px}
/* Inline button spinner — inherits the button's text color (currentColor) so
   it stays visible on the gold primary button and the dark secondary alike. */
.pt-btn-spin{display:inline-block;width:13px;height:13px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:ptSpin .7s linear infinite;vertical-align:-1px;margin-right:8px}
@keyframes ptSpin{to{transform:rotate(360deg)}}

/* Visible keyboard focus on all interactive elements (a11y). Cards already have
   their own :focus-visible; this covers buttons, links, tabs, inputs, toggles. */
.pt-btn:focus-visible,.pt-link:focus-visible,.pt-tab:focus-visible,.pt-input:focus-visible,
.pt-modal-x:focus-visible,.pt-switch:focus-visible,.pt-signout:focus-visible,
.pt-notif-row:focus-visible,a.pt-link:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:4px}

@media (prefers-reduced-motion:reduce){
  .pt-spinner,.pt-btn-spin{animation-duration:1.4s}
  .pt-pill.live::before{animation:none}
  .pt-stepper .pt-step.is-current .pt-step-dot{animation:none}
  .pt-toast{transition:none}
}

/* ================================================
   MODERN REFRESH (UX consistency pass)
   Shared tokens from css/tokens.css. Unified depth, radius, motion and
   status colors so the portal reads like Command HQ. Visual-only.
   ================================================ */
/* One card (Phase 6H, EAS-747): the canvas, panel, line and corner Command HQ
   draws, from css/tokens.css. The Driveway had its own: the sheen over --dark2,
   14px corners on the hero and 10px on rows. */
body{background:var(--canvas)}
.pt-auth-card,.pt-card,.pt-row,.pt-card2{background:var(--panel);border-color:var(--line);border-radius:var(--r-card)}
.pt-card{box-shadow:var(--shadow-sm)}
.pt-empty{background:var(--inset);border-color:var(--line);border-radius:var(--r-card)}
.pt-btn{border-radius:var(--r-sm);transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease),transform var(--dur-fast) var(--ease),box-shadow var(--dur) var(--ease)}
.pt-btn-primary{box-shadow:var(--shadow-gold)}
.pt-btn-primary:hover{transform:translateY(-1px);box-shadow:0 8px 24px rgba(212,160,23,.30)}
.pt-btn:active{transform:translateY(1px)}
.pt-input{border-radius:var(--r-xs);transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.pt-input:focus{box-shadow:0 0 0 2px rgba(212,160,23,.12)}
/* Status pills → canonical tokens */
.pt-pill.paid{background:var(--success-bg);color:var(--success)}
.pt-pill.up{background:var(--warning-bg);color:var(--gold)}
.pt-pill.due{background:var(--danger-bg);color:var(--danger)}
@media (prefers-reduced-motion:reduce){
  .pt-btn{transition:none}
  .pt-btn-primary:hover,.pt-btn:active{transform:none}
}

/* ================================================
   THE DRIVEWAY (docs/plans/the-driveway.md)
   Two blocks: an adaptive Right Now that owns the event, and uniform vehicle
   rows that own the record. Built from the tokens already here — same gold,
   same Barlow Condensed, same 12px card / 5px button radii. Recomposition,
   not a restyle.
   ================================================ */
.dw-greet{font-family:var(--font-display);font-weight:800;font-size:var(--t-md-plus);letter-spacing:.06em;text-transform:uppercase;color:var(--gray);margin:0 0 14px}

/* Right Now — one card, tone-coded by what it is asking of the customer. The
   left rule is the only place severity is expressed as colour, so an invoice
   that is merely available can never read as an alarm. */
.dw-now{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--dark3);
  border-radius:var(--r-card);padding:20px 18px;margin-bottom:14px;box-shadow:var(--shadow-sm)}
/* The wash is a layer over the panel. It used var(--surface-card) as a colour
   stop, which is a gradient and a colour, so the declaration was invalid at
   computed-value time and "Your payment didn't go through" had no card at all. */
.dw-now.dw-tone-red{border-left-color:var(--danger);background:linear-gradient(180deg,var(--danger-bg) 0%,transparent 46%),var(--panel)}
.dw-now.dw-tone-gold{border-left-color:var(--gold)}
.dw-now.dw-tone-green{border-left-color:var(--success)}
.dw-now.dw-tone-neutral{border-left-color:rgba(255,255,255,.22)}
.dw-now.dw-tone-quiet{border-left-color:var(--dark3);background:var(--panel-flat)}
.dw-hero-kicker{display:flex;align-items:center;gap:6px;font:var(--type-eyebrow);letter-spacing:var(--track-eyebrow);text-transform:uppercase;
  color:var(--gray);margin-bottom:8px}
.dw-hero-kicker svg{width:14px;height:14px;flex-shrink:0}
.dw-hero-title{font-family:var(--font-display);font-weight:800;font-size:var(--t-3xl);line-height:1.15;letter-spacing:.02em;
  text-transform:uppercase;color:var(--white);margin:0}
.dw-tone-red .dw-hero-title{color:var(--danger)}
.dw-tone-gold .dw-hero-title{color:var(--gold)}
.dw-tone-green .dw-hero-title{color:var(--success)}
.dw-hero-sub{color:var(--gray);font-size:var(--t-md);line-height:1.5;margin-top:6px}
.dw-hero-detail{color:var(--gray);font-size:var(--t-base);margin-top:4px;opacity:.85}
.dw-stepper{margin:18px 0 4px}
.dw-hero-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}
.dw-act{width:auto}
.dw-now .pt-wx{margin-top:12px}
/* All clear is deliberately understated — a quiet screen is the good outcome. */
.dw-tone-quiet .dw-hero-title{font-size:var(--t-2xl);color:var(--white);opacity:.92}

/* Queue — everything else that is pending, compact and in tier order. */
.dw-queue{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
.dw-qrow{display:flex;align-items:center;gap:12px;background:var(--panel);border:1px solid var(--line);
  border-left:3px solid var(--dark3);border-radius:var(--r-card);padding:12px 14px}
.dw-qrow.dw-tone-red{border-left-color:var(--danger)}
.dw-qrow.dw-tone-gold{border-left-color:var(--gold)}
.dw-qrow.dw-tone-green{border-left-color:var(--success)}
.dw-qrow-main{min-width:0;flex:1}
.dw-qrow-title{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.dw-qrow-meta{color:var(--gray);font-size:var(--t-base);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A queue row now carries every action its card has (EAS-555) — cancel and
   reschedule used to exist only on the hero. They are text links, so they wrap
   onto a second line at 390px instead of stealing the width the title needs,
   which is what the single-action rule was protecting. */
.dw-qrow-act{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:4px 12px;flex-shrink:0;max-width:46%}
.dw-qrow-act .pt-btn{width:auto;padding:8px 13px;font-size:var(--t-sm)}
.dw-qrow-act .pt-link{white-space:nowrap}
.dw-more{display:block;margin:0 0 18px}

/* Your Vehicles — uniform rows, never the next visit. */
.dw-block-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:22px 0 10px}
/* The section role (EAS-748): sentence case, like every section heading in
   Command HQ. Uppercase is the eyebrow's and the page headline's. */
.dw-block-title{font:var(--type-section);letter-spacing:0;color:var(--white);margin:0}
.dw-veh{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);margin-bottom:8px;overflow:hidden}
.dw-veh.is-open{border-color:var(--line-accent)}
.dw-veh-row{display:flex;align-items:center;gap:12px;width:100%;text-align:left;background:none;border:0;padding:13px 14px;cursor:pointer;color:inherit}
.dw-veh-ico{flex-shrink:0;width:34px;display:flex;align-items:center;justify-content:center;color:var(--gray)}
.dw-veh-ico svg{width:30px;height:auto}
.dw-veh-main{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}
.dw-veh-title{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.dw-veh-meta{color:var(--gray);font-size:var(--t-base)}
/* "Due for a detail" (Phase 3) — a state of the record, not a call to action.
   Sits beside the Plan tag on the title line; warning-toned, never red, because
   a car being due is a nudge and not a problem. */
.dw-due{display:inline-block;margin-left:7px;padding:1px 7px;border-radius:999px;font-family:var(--font-display);font-weight:700;font-size:var(--t-xs);letter-spacing:.05em;text-transform:uppercase;vertical-align:middle;color:var(--warning);background:rgba(240,212,136,.12);border:1px solid rgba(240,212,136,.34)}
.dw-due.is-lapsed{color:var(--danger);background:rgba(255,138,138,.1);border-color:rgba(255,138,138,.3)}
.dw-veh-chev{color:var(--gray);font-size:var(--t-xl-plus);line-height:1;transition:transform var(--dur) var(--ease)}
.dw-veh.is-open .dw-veh-chev{transform:rotate(90deg)}
.dw-veh-body{padding:2px 14px 14px;border-top:1px solid var(--surface-line)}
.dw-veh-body .pt-card-label{margin:12px 0 6px}
.dw-veh-body .pt-row{background:transparent;border:0;border-bottom:1px solid var(--surface-line);border-radius:0;padding:9px 0}
.dw-veh-notes{margin:10px 0 0;font-style:italic}
.dw-veh-tools{display:flex;align-items:center;gap:0;margin-top:12px}

/* Phase 2 — the timeline the vehicle row opens into. The plan and the next
   visit sit ABOVE the history: what happens next outranks what happened. */
.dw-plan{margin:12px 0 0;padding:10px 12px;border-radius:var(--r-sm);background:rgba(212,160,23,.08);border:1px solid rgba(212,160,23,.28)}
.dw-plan.is-paused{background:rgba(154,154,154,.08);border-color:var(--surface-line)}
.dw-plan-title{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.dw-plan-note{margin-top:5px;font-size:var(--t-base);color:var(--warning)}
.dw-veh-next{margin:10px 0 0;font-size:var(--t-md);font-weight:600;color:var(--white)}
.dw-veh-where{margin:4px 0 0;font-size:var(--t-base)}
.dw-veh-more{margin:10px 0 0;font-size:var(--t-base)}
.dw-veh-spend{float:right;font-weight:600;color:var(--gray);letter-spacing:0;text-transform:none}
.dw-visit{border-bottom:1px solid var(--surface-line);padding:9px 0}
.dw-visit:last-of-type{border-bottom:0}
/* "This figure covers the whole stop, not just this car." */
.dw-shared{color:var(--warning)}
.dw-visit-acts{display:flex;gap:14px;margin-top:6px}
/* A horizontal strip, not a grid: a phone screen shows two or three and the
   customer scrolls, rather than the drawer growing by a screenful per visit. */
.dw-shots{display:flex;gap:8px;overflow-x:auto;margin:8px 0 2px;padding-bottom:4px;-webkit-overflow-scrolling:touch}
.dw-shot{position:relative;flex:0 0 auto;display:block;width:88px;height:66px;border-radius:var(--r-sm);overflow:hidden;border:1px solid var(--surface-line)}
.dw-shot img{width:100%;height:100%;object-fit:cover;display:block}
.dw-shot{padding:0;background:none;cursor:zoom-in}
.dw-shot-tag{position:absolute;left:0;bottom:0;padding:1px 5px;font-size:var(--t-2xs);letter-spacing:.04em;text-transform:uppercase;background:rgba(10,10,10,.72);color:var(--white)}

/* Photo lightbox (Phase 3) — stays inside the app. */
.pt-noscroll{overflow:hidden}
.dw-lb[hidden]{display:none}
.dw-lb{position:fixed;inset:0;z-index:1200;display:flex;align-items:center;justify-content:center;gap:6px;padding:16px;background:rgba(6,6,6,.94);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.dw-lb-fig{margin:0;max-width:100%;max-height:100%;display:flex;flex-direction:column;align-items:center;gap:10px;min-width:0}
.dw-lb-img{max-width:100%;max-height:78vh;object-fit:contain;border-radius:var(--r-md);background:var(--dark2)}
.dw-lb-cap{color:var(--gray);font-size:var(--t-base);text-align:center;letter-spacing:.02em}
.dw-lb-close{position:absolute;top:10px;right:12px;width:40px;height:40px;border:0;border-radius:999px;background:rgba(26,26,26,.9);color:var(--white);font-size:var(--t-3xl);line-height:1;cursor:pointer}
.dw-lb-nav{flex:0 0 auto;width:40px;height:56px;border:0;border-radius:var(--r-sm);background:rgba(26,26,26,.72);color:var(--white);font-size:var(--t-3xl);line-height:1;cursor:pointer}
.dw-lb-nav[hidden]{display:none}
.dw-lb-close:hover,.dw-lb-nav:hover{background:var(--dark3);color:var(--gold)}
.dw-lb-close:focus-visible,.dw-lb-nav:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* On a phone the arrows would eat the photo's width — swipe covers it there. */
@media (max-width:520px){ .dw-lb-nav{display:none} }

/* Visits we can't attribute to a vehicle — a disclosure, not a section, so it
   never competes with the record it is an exception to. */
.dw-orphans{margin:14px 0 0;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);padding:10px 14px}
.dw-orphans summary{cursor:pointer;font-family:var(--font-display);font-weight:700;font-size:var(--t-base);letter-spacing:.05em;text-transform:uppercase;color:var(--gray)}
.dw-orphans summary:hover{color:var(--white)}
.dw-orphans-note{font-size:var(--t-base);margin:10px 0 4px}
.dw-orphans .pt-row{background:transparent;border:0;border-bottom:1px solid var(--surface-line);border-radius:0;padding:9px 0}

/* Account was a composite of four stacked sections, divided by a rule here.
   Since EAS-768 it is a hub and one page at a time (see "Account hub"), so
   the divider went: it drew between the hub, the back bar and the pages. */

/* Sign-in recovery disclosure */
.pt-auth-help{margin-top:14px;text-align:left;font-size:var(--t-sm);color:var(--gray)}
.pt-auth-help summary{cursor:pointer;color:var(--gold);font-family:var(--font-display);font-weight:700;text-transform:uppercase;letter-spacing:.04em;text-align:center}
.pt-auth-help p{margin:10px 0 0;line-height:1.55}
.pt-auth-help a{color:var(--gold)}

@media (max-width:520px){
  .dw-hero-title{font-size:var(--t-2xl)}
  .dw-hero-actions .pt-btn{flex:1 1 auto}
}
@media (prefers-reduced-motion:reduce){ .dw-veh-chev{transition:none} }

/* ================================================
   THE VEHICLE PAGE (docs/VEHICLE-PLATFORM.md, EAS-758/760)
   The drawer a vehicle row opens into: a compact hero, a segmented control
   (Overview · Care Record · Protection · Photos) and the segment. Lines, not
   nested cards — the drawer is already the card. Tokens only.
   ================================================ */
.dw-vp{padding-top:12px}
.dw-vp-hero{display:flex;align-items:center;gap:12px;margin:0 0 12px}
.dw-vp-visual{flex:0 0 auto;width:56px;display:flex;flex-direction:column;align-items:center;justify-content:center;margin:0;color:var(--gray)}
.dw-vp-visual .qp-card-svg{width:44px;height:44px;margin:0;color:var(--gold)}
.dw-vp-visual.has-img{width:120px}
.dw-vp-visual.has-img img{display:block;width:120px;height:78px;object-fit:cover;border-radius:var(--r-sm);background:var(--inset);border:1px solid var(--line-soft)}
/* Always shown with a stock image, never smaller than legible. */
.dw-vp-visual figcaption{margin-top:5px;font-size:var(--t-xs);line-height:1.3;color:var(--text-faint);text-align:center}
.dw-vp-id{min-width:0;display:flex;flex-direction:column;gap:3px}
.dw-vp-name{font-family:var(--font-display);font-weight:800;font-size:var(--t-xl);line-height:1.15;letter-spacing:.02em;text-transform:uppercase;color:var(--white)}
.dw-vp-spec{font-size:var(--t-md);font-weight:600;color:var(--white)}
.dw-vp-sub{font-size:var(--t-base);color:var(--gray)}
.dw-vp-flag{display:inline-flex;align-items:center;gap:5px;font-size:var(--t-sm);color:var(--gold)}

/* Segmented control — a tablist. 44px targets, the selected segment in gold. */
.dw-seg{display:flex;gap:4px;padding:4px;margin:0 0 6px;background:var(--inset);border:1px solid var(--line);border-radius:var(--r-sm)}
.dw-seg{align-items:stretch}
/* Never narrower than its longest word, the spare width shared equally, and
   allowed to break at a SPACE ("Care / Record") — never mid-word and never
   behind an ellipsis: a segment you cannot read is one nobody taps. */
.dw-seg-btn{flex:1 1 0;min-width:min-content;min-height:44px;padding:4px 8px;border:0;border-radius:var(--r-xs);background:transparent;color:var(--gray);cursor:pointer;
  font-family:var(--font-display);font-weight:700;font-size:var(--t-base);line-height:1.1;letter-spacing:.02em;text-transform:uppercase;white-space:normal;overflow-wrap:normal;word-break:keep-all}
.dw-seg-btn:hover{color:var(--white)}
.dw-seg-btn.is-on{background:rgba(212,160,23,.14);color:var(--gold);box-shadow:inset 0 0 0 1px var(--line-accent)}
.dw-seg-btn:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
@media (max-width:420px){ .dw-seg{gap:2px;padding:3px} .dw-seg-btn{font-size:var(--t-sm);letter-spacing:0;padding:4px 4px} }
@media (max-width:370px){ .dw-seg-btn{font-size:var(--t-sm);padding:4px 3px} }

/* Every text link on the page is a real touch target, not a 16px line. */
.dw-vp .pt-link,.pt-modal-body .dw-back,.dw-entry-side .pt-link{min-height:44px;display:inline-flex;align-items:center;text-align:left}
.dw-vp .pt-link.danger{margin-left:0}

/* Overview — one block per question, separated by a hairline. */
.dw-ov{padding:12px 0;border-bottom:1px solid var(--surface-line)}
.dw-ov:last-child{border-bottom:0}
.dw-ov .pt-card-label{margin:0 0 5px}
.dw-ov-line{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px}
.dw-ov-main{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.dw-ov-next.is-due .dw-ov-main{color:var(--gold)}
.dw-ov-msg{margin-top:6px;padding:8px 10px;border-left:2px solid var(--line-accent);background:var(--raised);border-radius:var(--r-xs);font-size:var(--t-base);color:var(--white)}
.dw-ov-counts{font-size:var(--t-base);color:var(--white);font-weight:600}
.dw-ov-invest{margin-top:6px;font-size:var(--t-md);color:var(--white)}
.dw-ov-invest strong{color:var(--gold)}
.dw-ov-fine{font-size:var(--t-sm);line-height:1.45;margin:4px 0 0}
.dw-ov-acts{display:flex;flex-wrap:wrap;gap:10px}
.dw-ov-acts .pt-btn{flex:1 1 200px;min-height:44px;font-size:var(--t-md)}
.dw-ov .dw-plan{margin-top:8px}
.dw-ov .dw-veh-next{margin:0}
.dw-ov .dw-veh-where{margin-top:8px}
@media (min-width:900px){
  /* The drawer is 1120px wide on a desktop; two columns keep lines readable. */
  .dw-vp-panel.is-overview{display:grid;grid-template-columns:1fr 1fr;column-gap:32px}
  .dw-vp-panel.is-overview > .dw-ov-acts,.dw-vp-panel.is-overview > .dw-notice{grid-column:1 / -1}
}
/* Past a phone, the Book button is a button, not a band across the page. */
@media (min-width:600px){ .dw-ov-next .dw-ov-acts .pt-btn{flex:0 1 auto;min-width:220px} }

/* "Why?" and the other small disclosures. */
.dw-why{margin-top:4px}
.dw-why summary{display:inline-flex;align-items:center;min-height:44px;cursor:pointer;color:var(--gold);font-family:var(--font-display);font-weight:700;font-size:var(--t-base);letter-spacing:.04em;text-transform:uppercase}
.dw-why summary:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:var(--r-xs)}
.dw-why p{margin:2px 0 6px;font-size:var(--t-md);line-height:1.5;color:var(--white)}
.dw-recall summary{text-transform:none;letter-spacing:0;font-family:var(--font-body);font-weight:600;font-size:var(--t-md);color:var(--white)}
.dw-recall.is-park summary{color:var(--danger)}
.dw-recall-park{color:var(--danger);font-weight:600}

/* Provenance — on the shared pill, coloured by what it is. */
.pt-pill.dw-prov.is-ea{--tone:var(--tone-warn)}
.pt-pill.dw-prov.is-owner{--tone:var(--tone-neutral)}
.pt-pill.dw-prov.is-external{--tone:var(--tone-neutral);background:transparent}
.pt-pill.dw-prov .eas-ico{flex-shrink:0}

/* Care Record — one list, newest first. */
.dw-cr-tools{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 6px}
.pt-btn.dw-btn-compact{width:auto;min-height:44px;padding:9px 14px;font-size:var(--t-base)}
.dw-cr-latest{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px;padding:10px 0;font-size:var(--t-md);color:var(--white);border-bottom:1px solid var(--surface-line)}
.dw-entry{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:10px 0;border-bottom:1px solid var(--surface-line)}
.dw-entry:last-child{border-bottom:0}
.dw-entry-main{min-width:0;flex:1}
.dw-entry-title{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.dw-entry-side{display:flex;flex-direction:column;align-items:flex-end;gap:2px;flex-shrink:0}
.dw-entry.is-off .dw-entry-title{color:var(--gray)}
.dw-cr-list .dw-visit{padding:10px 0}
.dw-visit-prov{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px;margin-top:6px}
.dw-visit-acts{flex-wrap:wrap;align-items:center}
.dw-prior{margin-top:18px;padding:12px;border:1px dashed var(--line);border-radius:var(--r-sm);background:var(--raised)}

/* Protection */
.dw-pr-group{padding:6px 0 4px}
.dw-pr-title{margin:10px 0 8px;font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.dw-pr-title .pt-muted{font-weight:400}
.dw-pr-empty{margin:0 0 8px;line-height:1.5}
.dw-prot{padding:12px;margin:0 0 10px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--raised)}
.dw-prot.is-owner{border-style:dashed}
.dw-prot.is-past{opacity:.72}
.dw-prot-head{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px}
.dw-prot-kind{font-family:var(--font-display);font-weight:800;font-size:var(--t-lg);letter-spacing:.03em;text-transform:uppercase;color:var(--white)}
.dw-prot-product{margin-top:4px;font-size:var(--t-md);font-weight:600;color:var(--white)}
.dw-prot-facts{margin:10px 0 0;display:grid;gap:6px}
.dw-prot-facts div{display:grid;grid-template-columns:104px 1fr;gap:10px;align-items:baseline}
.dw-prot-facts dt{font:var(--type-eyebrow);letter-spacing:var(--track-eyebrow);text-transform:uppercase;color:var(--gray)}
.dw-prot-facts dd{margin:0;font-size:var(--t-md);color:var(--white);min-width:0}
.dw-prot-acts{display:flex;flex-wrap:wrap;gap:0 18px;margin-top:4px}
.dw-pr-foot{padding-top:6px;display:flex;flex-direction:column;align-items:flex-start}
@media (min-width:900px){
  .dw-pr-group{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));column-gap:12px}
  .dw-pr-group > .dw-pr-title,.dw-pr-group > .dw-pr-empty{grid-column:1 / -1}
}

/* Photos — filter chips, then each visit's photos in a grid. */
.dw-chips{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 4px}
.dw-chip{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 14px;border:1px solid var(--line);border-radius:var(--r-pill);background:transparent;color:var(--gray);cursor:pointer;
  font-family:var(--font-display);font-weight:700;font-size:var(--t-base);letter-spacing:.03em;text-transform:uppercase}
.dw-chip.is-on{border-color:var(--line-accent);background:rgba(212,160,23,.12);color:var(--gold)}
.dw-chip:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.dw-chip-n{font-family:var(--font-body);font-size:var(--t-sm);font-weight:700;opacity:.8}
.dw-ph-group{padding:10px 0;border-bottom:1px solid var(--surface-line)}
.dw-ph-group:last-child{border-bottom:0}
.dw-ph-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:8px}
.dw-ph-title{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white);min-width:0}
.dw-ph-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:8px}
.dw-shot.dw-ph{width:auto;height:auto;aspect-ratio:4 / 3}

.dw-veh-tools{flex-wrap:wrap;gap:0 20px;border-top:1px solid var(--surface-line);margin-top:8px}
.dw-veh-tools .pt-link{min-height:44px;display:inline-flex;align-items:center}
.dw-veh-tools .pt-link.danger{margin-left:0}

/* ── Sheets (share, transfer, report, add) — the shared dialog ─────────── */
.dw-sheet-lede{margin:0 0 4px;line-height:1.5}
.dw-sheet-fine{margin:2px 0 0;font-size:var(--t-sm);line-height:1.5}
.dw-label-note{font-family:var(--font-body);font-weight:400;text-transform:none;letter-spacing:0;color:var(--text-faint)}
.dw-fs{border:0;margin:4px 0 2px;padding:0}
.dw-fs legend{padding:0;margin-bottom:2px}
.pt-modal-body .pt-check{min-height:40px}
.pt-modal-body .pt-check input{width:18px;height:18px;accent-color:var(--gold);flex-shrink:0}
.dw-confirm{align-items:flex-start;line-height:1.45;color:var(--white)}
.dw-confirm input{margin-top:2px}
.dw-callout{padding:10px 12px;border:1px solid var(--line-accent);border-radius:var(--r-sm);background:rgba(212,160,23,.08);font-size:var(--t-base);line-height:1.5;color:var(--white)}
.dw-callout strong{color:var(--gold)}
.dw-link-out{margin-top:10px;padding:12px;border:1px solid var(--line-accent);border-radius:var(--r-sm);background:var(--raised)}
.dw-link-out .pt-input{font-size:var(--t-lg)}
.dw-link-acts{display:flex;flex-wrap:wrap;gap:8px}
.dw-sheet-sec{margin-top:14px;padding-top:12px;border-top:1px solid var(--surface-line)}
.dw-sell p{margin:2px 0 8px}
.dw-file{position:relative;display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 16px;margin-top:4px;border:1px dashed var(--line-accent);border-radius:var(--r-sm);
  color:var(--gold);cursor:pointer;font-family:var(--font-display);font-weight:700;font-size:var(--t-base);letter-spacing:.04em;text-transform:uppercase;align-self:flex-start}
.dw-file input{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%}
.dw-file:focus-within{outline:2px solid var(--gold);outline-offset:2px}
.dw-rp-thumbs{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.dw-rp-thumbs:empty{display:none}
.dw-rp-thumb{position:relative;width:84px;height:64px;border-radius:var(--r-sm);overflow:hidden;border:1px solid var(--line)}
.dw-rp-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.dw-rp-x{position:absolute;top:2px;right:2px;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:0;border-radius:999px;background:rgba(10,10,10,.8);color:var(--white);cursor:pointer}
.dw-rp-x:focus-visible{outline:2px solid var(--gold)}

/* Add a vehicle — plate first. */
.dw-plate-row{display:flex;gap:10px}
.dw-plate{flex:1 1 auto;min-width:0}
.dw-plate .pt-input{text-transform:uppercase;letter-spacing:.08em}
.dw-plate-state{flex:0 0 96px}
.dw-av-result:empty{display:none}
.dw-av-result{margin-top:4px}
.dw-av-msg{margin:6px 0 2px;color:var(--warning);font-size:var(--t-md);line-height:1.45}
.dw-av-q{margin:8px 0 8px;font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.dw-av-cands{display:grid;gap:8px;margin-bottom:10px}
.dw-av-alt{margin-top:12px;padding-top:12px;border-top:1px solid var(--surface-line)}
.dw-av-alt-btns{display:flex;flex-wrap:wrap;gap:8px}
.dw-av-alt-btns .pt-btn{flex:1 1 140px}
.dw-av-vin{margin-top:6px}

/* Booking that started from a vehicle page's "Next". */
.dw-book-from{display:flex;align-items:center;gap:8px;margin:-8px 0 16px;padding:8px 12px;border:1px solid var(--line-accent);border-radius:var(--r-sm);background:rgba(212,160,23,.08);font-size:var(--t-md);color:var(--white)}


/* ── Account hub (EAS-768) ─────────────────────────────────────────────────
   Account opens on a short index, each row a door to one page, instead of
   every section stacked into a 16-screen scroll. Tokens only. */
.pt-acc-who{margin:-6px 0 16px}
.pt-acc-name{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white);font-size:var(--t-lg)}
.pt-acc-sum{display:block;font:var(--type-support);color:var(--text-muted);overflow-wrap:anywhere}
.pt-acc-attn{display:flex;flex-direction:column;gap:8px;margin:0 0 18px}
.pt-acc-attn-row{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  background:linear-gradient(180deg,var(--danger-bg) 0%,transparent 70%),var(--panel);border:1px solid var(--line);
  border-left:3px solid var(--danger);border-radius:var(--r-card);padding:12px 14px}
.pt-acc-attn-txt{display:flex;align-items:center;gap:8px;font:var(--type-record);color:var(--white);min-width:0;flex:1 1 200px}
.pt-acc-attn-txt svg{color:var(--danger);flex-shrink:0}
.pt-acc-group-label{font:var(--type-eyebrow);letter-spacing:var(--track-eyebrow);text-transform:uppercase;color:var(--gray);margin:18px 0 8px}
.pt-acc-group{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden}
.pt-acc-row{display:flex;align-items:center;gap:12px;width:100%;min-height:60px;text-align:left;background:none;border:0;
  border-top:1px solid var(--line);padding:12px 14px;cursor:pointer;color:inherit;font:inherit}
.pt-acc-row:first-child{border-top:0}
.pt-acc-row:hover,.pt-acc-row:focus-visible{background:var(--raised)}
.pt-acc-row:focus-visible{outline:2px solid var(--gold);outline-offset:-2px}
.pt-acc-ico{display:flex;align-items:center;justify-content:center;width:34px;height:34px;flex-shrink:0;border-radius:var(--r-sm);
  background:var(--inset);color:var(--gold)}
.pt-acc-txt{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.pt-acc-title{font:var(--type-record);letter-spacing:var(--track-record);color:var(--white)}
.pt-acc-txt .pt-acc-sum{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pt-acc-chev{display:flex;color:var(--text-faint);transform:rotate(-90deg);flex-shrink:0}
.pt-acc-bar{position:sticky;top:0;z-index:var(--z-sticky);background:var(--canvas);margin:-4px 0 10px;padding:6px 0}
.pt-acc-back{display:inline-flex;align-items:center;gap:6px;min-height:44px;background:none;border:0;padding:0 4px 0 0;
  color:var(--gold);font:var(--type-button);letter-spacing:var(--track-button);text-transform:uppercase;cursor:pointer}
.pt-acc-back::before{content:'';width:9px;height:9px;border-left:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg);margin-left:4px}
@media (prefers-reduced-motion:reduce){
  .dw-seg-btn,.dw-chip{transition:none}
}
