/* ═══════════════════════════════════════════════════════════════════════
   Quote-Quick Modal styles — loaded sitewide via layouts/app.blade.php

   Single-column scrollable layout (2026-05-24 rewrite).
   Previous 2-column "intro + stage" layout clipped the Continue button
   on any viewport shorter than ~880px (.qqm-card had max-height:92vh
   with overflow:hidden and no scrollable child).

   New structure:
     .qqm-card                 — flex column, overflow:hidden, capped height
       .qqm-head (sticky)      — title + close
       .qqm-body (scrolls)     — sections; flex:1 + overflow-y:auto + min-height:0
       .qqm-foot (sticky)      — Continue + phone fallback
   ═══════════════════════════════════════════════════════════════════════ */

.qqm {
  padding: 0;
  border: 0;
  background: transparent;
  /* 880px is enough for a 2-col body (map left / headcount right) so
     content fits at 13" laptop heights (1366×768, 1280×800) without
     forcing a scrollbar inside the modal. */
  width: min(600px, 94vw);
  max-width: 600px;
  /* dvh (dynamic viewport height) instead of vh so the mobile browser's
     collapsing address bar never makes the modal taller than the visible
     area (the classic "100vh is taller than the screen" clip). Capped so
     content fits without an internal scrollbar on any device. vh fallback
     first for browsers that don't understand dvh (pre-2022). */
  max-height: 92vh;
  max-height: 94dvh;
  overflow: visible;
  color: var(--text, #0D1829);
}
/* iOS Chrome / WebKit fallback: when modal.showModal() throws (rare on
   iOS 15.4+ but possible inside certain stacking contexts), JS falls
   back to setAttribute('open',''). UA-default <dialog> positioning is
   absolute, so force explicit fixed centering for both code paths. */
.qqm[open] {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  z-index: 9999;
}
@media (max-width: 640px) {
  .qqm { width: 100vw; max-width: 100vw; max-height: 100vh; max-height: 100dvh; }
  .qqm[open] {
    top: 0;
    left: 0;
    transform: none;
  }
}
.qqm::backdrop {
  background: rgba(7, 25, 46, .68);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
body.qqm-open { overflow: hidden; }

/* ── Card: flex column with sticky head + scrollable body + sticky foot ─ */
.qqm-card {
  position: relative;
  background: #fff;
  border-radius: 16px;
  overflow: hidden;
  isolation: isolate;
  box-shadow:
    0 0 0 1px rgba(13,24,41,.08),
    0 20px 50px -18px rgba(7,25,46,.20),
    0 40px 120px -20px rgba(7,25,46,.38);
  max-height: 92vh;
  max-height: 94dvh;
  display: flex;
  flex-direction: column;
}

/* ── Header (sticky) ──────────────────────────────────────────────────── */
.qqm-head {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  /* Vertical padding scales down on short viewports so the header doesn't
     eat into the space the body needs to stay scroll-free. */
  padding: clamp(12px, 2vh, 18px) 20px clamp(10px, 1.6vh, 14px);
  border-bottom: 1px solid rgba(13,24,41,.06);
  background: #fff;
}
.qqm-head-text { min-width: 0; }
.qqm-title {
  font: 700 18px/1.3 'Poppins', system-ui, sans-serif;
  color: var(--navy, #07192E);
  letter-spacing: -.018em;
  margin: 0;
}
.qqm-sub {
  font: 500 12.5px/1.4 'Inter', system-ui, sans-serif;
  color: var(--muted, #5B6B7E);
  margin: 3px 0 0;
}
.qqm-sub[hidden] { display: none; }
.qqm-close {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  /* Defeat sitewide button{min-width/height:var(--touch-min)} accessibility
     rule — close X doesn't need a 48px target. */
  min-width: 0; min-height: 0;
  padding: 0;
  background: #fff;
  border: 1px solid rgba(13,24,41,.12);
  border-radius: 50%;
  /* Flex centering (not grid): a single-item grid with place-items:center
     sizes its auto track to the icon's content, which the responsive
     `svg{max-width:100%}` reset collapses to ~6px. Flex centers a definite-
     size child reliably in the full 40/44px box. */
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--navy, #07192E);
  box-shadow: 0 1px 2px rgba(7,25,46,.06), 0 4px 12px -6px rgba(7,25,46,.16);
  /* Twist-on-hover: spring easing overshoots 90° so the X visibly spins
     (passing through a +) before settling, then fills navy + flips white.
     Two distinct signals — motion AND color — so it never reads as "standard". */
  transition:
    background .25s cubic-bezier(.34,1.56,.64,1),
    border-color .2s ease,
    color .2s ease,
    box-shadow .25s ease,
    transform .4s cubic-bezier(.34,1.56,.64,1);
}
.qqm-close:hover {
  background: var(--navy, #07192E);
  border-color: var(--navy, #07192E);
  color: #fff;
  transform: rotate(90deg) scale(1.07);
  box-shadow: 0 2px 6px rgba(7,25,46,.18), 0 12px 28px -8px rgba(7,25,46,.42);
}
.qqm-close:active { transform: rotate(90deg) scale(.97); }
.qqm-close:focus-visible { outline: 2px solid var(--orange, #F97316); outline-offset: 2px; }
/* !important is required: the sitewide responsive-media reset forces
   `svg { max-width: 100% !important }`, which (combined with the centering
   parent) collapsed this icon to ~6px on mobile. Scoped tightly to the
   close glyph only. */
.qqm-close svg { width: 17px !important; height: 17px !important; max-width: none !important; flex: 0 0 auto; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }

/* ── Body — single flex column that NEVER scrolls ─────────────────────
   The modal must fit on any device with no vertical scrollbar (hard
   requirement). We make the body a flex column with overflow:hidden and
   let the states section (the map) be the single flex-shrink element —
   the map absorbs whatever vertical space is left over so the whole
   stack always fits inside the capped card height. Every fixed dimension
   below the card height (head, foot, headcount block) is small and the
   map scales via a vh-relative height, so the sum stays within the
   viewport at every size. overflow:hidden is the belt-and-suspenders
   guarantee that a sub-pixel rounding error can never surface a scrollbar. */
.qqm-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  overscroll-behavior: contain;
  padding: clamp(10px, 1.6vh, 14px) 18px clamp(8px, 1.2vh, 10px);
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 2vh, 18px);
}

/* ── Section (state-picker + headcount blocks) ──────────────────────── */
.qqm-section {
  display: flex;
  flex-direction: column;
  gap: clamp(5px, 1vh, 8px);
  min-width: 0;
  min-height: 0; /* allow this flex child to shrink below its content */
  /* CRITICAL: the sitewide `section { padding: 48px 0 }` rule was injecting
     96px of phantom vertical padding into EACH <section> here (192px total),
     which is what pushed the modal past the viewport and starved the map's
     flex space. These modal sections set their own spacing via gap. */
  padding: 0;
  margin: 0;
}
/* States section (map) is the squeeze valve: it grows/shrinks to fill the
   space the fixed-height headcount block + footer leave behind. */
.qqm-section--states { flex: 1 1 auto; }
/* Headcount block keeps its natural (small) height. */
.qqm-section--headcount { flex: 0 0 auto; }
/* The sitewide rule `section[class*="-sec"]{ padding:48px !important }`
   (specificity 0,2,1, !important) matches our <section class="qqm-section">
   and was injecting 96px of phantom vertical padding into EACH section.
   ID-scope (specificity 1,1,0) so this override always wins. */
#quoteQuickModal .qqm-section { padding: 0 !important; margin: 0 !important; }
.qqm-section-hd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.qqm-section-h {
  font: 600 14.5px/1.3 'Poppins', system-ui, sans-serif;
  color: var(--navy, #07192E);
  letter-spacing: -.012em;
  margin: 0;
}
.qqm-section-meta {
  font: 500 12.5px/1.3 'Inter', system-ui, sans-serif;
  color: var(--muted, #5B6B7E);
  font-variant-numeric: tabular-nums;
}
.qqm-section-meta strong {
  font: 700 14px/1 'Poppins', system-ui, sans-serif;
  color: var(--navy, #07192E);
  margin-right: 1px;
}

/* ── Geographic US map (real state shapes via SVG paths) ──────────── */
.qqm-map {
  position: relative;
  padding: clamp(8px, 1.4vh, 14px) clamp(10px, 2vw, 16px);
  background: #FFFFFF;
  border: 1px solid rgba(13,24,41,.10);
  border-radius: 13px;
  overflow: hidden;
  box-shadow: inset 0 1px 3px rgba(13,24,41,.05);
}
.qqm-map-frame {
  position: relative;
  touch-action: none; /* pinch-zoom handled in JS */
}
.qqm-map-frame.is-zoomed { cursor: grab; }
.qqm-map-frame.is-panning { cursor: grabbing; }
.qqm-map-svg {
  display: block;
  width: 100%;
  /* Height tracks viewport height so the whole modal stays scroll-free on
     short screens (laptops, landscape) while staying generous on tall
     phones/tablets. preserveAspectRatio (default "meet") keeps the map
     centered and uncropped at any height. This single vh-relative value is
     the main lever that keeps content within the card. */
  height: min(230px, 23vh);
  max-height: none;
}
.qqm-map-svg, .qqm-map-svg * { user-select: none; }

/* Visible filled states with white separators — a clean, premium choropleth
   that's obvious to read and easy to click (was near-invisible white-on-white
   2026-06-02). */
.qqm-st {
  fill: #DDE6F0;
  stroke: #FFFFFF;
  stroke-width: 1.4;
  stroke-linejoin: round;
  cursor: pointer;
  transition: fill .14s ease, stroke .14s ease, filter .14s ease;
  outline: none;
}
.qqm-map-frame.is-panning .qqm-st { cursor: grabbing; }
.qqm-st:hover {
  fill: #8FBCDD;
  stroke: #FFFFFF;
  stroke-width: 1.4;
  filter: drop-shadow(0 1px 3px rgba(13,24,41,.22));
}
.qqm-st:focus-visible {
  stroke: var(--orange, #F97316);
  stroke-width: 2;
  filter: drop-shadow(0 0 4px rgba(249,115,22,.5));
}
/* Selected = VSHR canonical 5-stop brand gradient (defined in SVG <defs>) */
.qqm-st.is-selected {
  fill: url(#qqmGrad);
  stroke: #FFFFFF;
  stroke-width: 1.4;
  filter: drop-shadow(0 1px 3px rgba(7,25,46,.24));
}
.qqm-st.is-selected:hover {
  filter: drop-shadow(0 2px 7px rgba(232,18,92,.34));
  stroke-width: 1.6;
}

/* ── Zoom controls — hidden by default (2026-05-24 simplification).
   The map is small enough at the new modal width (640px max) that zoom
   isn't useful; wheel/pinch still work for power users via JS. Bringing
   the buttons back is a single-line `display: flex` swap. ─────────── */
.qqm-map-zoom {
  display: none;
  position: absolute;
  bottom: 8px; right: 8px;
  flex-direction: column;
  gap: 4px;
  z-index: 2;
}
.qqm-zoom-btn {
  width: 30px; height: 30px;
  display: grid; place-items: center;
  background: rgba(255,255,255,.95);
  border: 1px solid rgba(13,24,41,.10);
  border-radius: 6px;
  color: var(--navy, #07192E);
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(7,25,46,.08);
  transition: background .14s, transform .14s, box-shadow .14s;
}
.qqm-zoom-btn:hover {
  background: #fff;
  transform: scale(1.06);
  box-shadow: 0 2px 8px rgba(7,25,46,.16);
}
.qqm-zoom-btn:active { transform: scale(.96); }
.qqm-zoom-btn:focus-visible {
  outline: 2px solid var(--orange, #F97316);
  outline-offset: 2px;
}
.qqm-zoom-btn svg {
  width: 14px; height: 14px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.qqm-map-fallback {
  padding: 24px 16px;
  text-align: center;
  font: 500 13px/1.5 'Inter', system-ui, sans-serif;
  color: var(--muted, #5B6B7E);
}
.qqm-map-foot {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  align-items: center;
  margin-top: 6px;
}
.qqm-map-action {
  background: transparent;
  border: 1px solid rgba(13,24,41,.10);
  border-radius: 6px;
  padding: 5px 10px;
  font: 600 11px/1 'Inter', system-ui, sans-serif;
  color: var(--muted, #5B6B7E);
  cursor: pointer;
  transition: color .14s, border-color .14s, background .14s;
}
.qqm-map-action:hover {
  color: var(--navy, #07192E);
  border-color: var(--blue-deep, #0D5B7F);
  background: rgba(20,121,163,.06);
}
.qqm-map-action:focus-visible {
  outline: 2px solid var(--orange, #F97316);
  outline-offset: 2px;
}

/* ── Headcount slider ───────────────────────────────────────────────── */
.qqm-count { padding-top: 4px; }
.qqm-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  background: linear-gradient(90deg, var(--blue-deep, #0D5B7F) 0%, var(--orange, #F97316) 100%);
  border-radius: 999px;
  outline: 0;
  margin: 6px 0 4px;
}
/* VSHR icon as slider thumb. Fixed 2026-05-14 — earlier 28x36 thumb with
   24x24 background-size mangled the V because the source PNG is 167x268
   (aspect ratio 0.623, taller than wide). Forcing it into a square cropped
   most of the V away. Now: 26x36 thumb (aspect 0.722, close to V's natural
   shape) with `background: center / contain` so the V renders at its true
   proportions, filling the full thumb height. The V's tip sits naturally
   at the bottom of the thumb (it's already at the bottom of the V shape). */
.qqm-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 26px; height: 36px;
  border: 0;
  /* v2 (2026-05-20): swapped img-vshr-icon.png → logos/vshr-icon.svg.
     SVG is universally supported (every browser since IE9), crisper at all
     sizes, smaller payload, and doesn't 404 on certain CDN/proxy setups
     where the PNG was reported missing. Same 82.89×133.53 viewBox = same
     0.621 aspect ratio so `background-size: contain` renders identically. */
  background: transparent url('logos/vshr-icon.svg') center / contain no-repeat;
  -webkit-filter: drop-shadow(0 2px 4px rgba(13,24,41,.32));
  filter: drop-shadow(0 2px 4px rgba(13,24,41,.32));
  cursor: pointer;
  animation: qqm-v-glow 3.2s cubic-bezier(.4,0,.6,1) infinite;
  transition: -webkit-filter .15s cubic-bezier(.22,1,.36,1),
              filter .15s cubic-bezier(.22,1,.36,1),
              transform .15s cubic-bezier(.22,1,.36,1);
}
.qqm-slider::-moz-range-thumb {
  width: 26px; height: 36px;
  border: 0;
  background: transparent url('logos/vshr-icon.svg') center / contain no-repeat;
  filter: drop-shadow(0 2px 4px rgba(13,24,41,.32));
  cursor: pointer;
  animation: qqm-v-glow 3.2s cubic-bezier(.4,0,.6,1) infinite;
}

/* Brand-gold glow pulse on the drop-shadow chain — VSHR canonical gold
   (#F7D44C). Slow, subtle, breath-paced. No moving background, no swept
   highlight — the V's own colors do the visual work. */
@keyframes qqm-v-glow {
  0%, 100% {
    -webkit-filter: drop-shadow(0 2px 6px rgba(13,24,41,.28));
    filter: drop-shadow(0 2px 6px rgba(13,24,41,.28));
  }
  50% {
    -webkit-filter: drop-shadow(0 2px 6px rgba(13,24,41,.28))
                    drop-shadow(0 0 6px rgba(247,212,76,.55));
    filter: drop-shadow(0 2px 6px rgba(13,24,41,.28))
            drop-shadow(0 0 6px rgba(247,212,76,.55));
  }
}

.qqm-slider:hover::-webkit-slider-thumb {
  -webkit-filter: drop-shadow(0 4px 10px rgba(232,93,4,.40));
  filter: drop-shadow(0 4px 10px rgba(232,93,4,.40));
  transform: scale(1.10);
  animation-play-state: paused;
}
.qqm-slider:active::-webkit-slider-thumb {
  transform: scale(1.06);
  animation-play-state: paused;
}
.qqm-slider:focus-visible::-webkit-slider-thumb {
  -webkit-filter: drop-shadow(0 0 0 4px rgba(249,115,22,.35)) drop-shadow(0 2px 6px rgba(13,24,41,.28));
  filter: drop-shadow(0 0 0 4px rgba(249,115,22,.35)) drop-shadow(0 2px 6px rgba(13,24,41,.28));
}
.qqm-slider:focus-visible { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .qqm-slider::-webkit-slider-thumb,
  .qqm-slider::-moz-range-thumb {
    animation: none !important;
  }
}
/* Tick labels positioned via calc() to match the thumb's actual center.
   Thumb is 26px wide. Native range slider centers the thumb on the track
   value, with `thumb_center_x = thumb_w/2 + (V/100) * (track_w - thumb_w)`.
   Without compensation, flex space-between puts labels at 0%/25%/50%/75%/
   100% of the OUTER track width, which is ~16px off at the endpoints. */
.qqm-slider-ticks {
  position: relative;
  height: 14px;
  margin-top: 6px;
  font: 500 10.5px/1 'Inter', system-ui, sans-serif;
  color: var(--muted, #5B6B7E);
  letter-spacing: -.005em;
}
.qqm-slider-ticks > span {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
  /* --pct (0..100) set inline on each span. Match the thumb-center formula:
     center_x = thumb_w/2 + (pct/100) * (track_w - thumb_w)
              = 13px + (pct/100) * (100% - 26px)                          */
  left: calc(13px + (var(--pct) / 100) * (100% - 26px));
}

/* ── Footer (sticky, sits at the bottom of .qqm-card) ──────────────── */
.qqm-foot {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: clamp(6px, 1.2vh, 8px);
  padding: clamp(10px, 1.6vh, 12px) 20px clamp(12px, 2vh, 16px);
  border-top: 1px solid rgba(13,24,41,.06);
  background: #fff;
}
.qqm-continue {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: clamp(11px, 1.8vh, 14px) 22px;
  background: linear-gradient(135deg, var(--orange, #F97316) 0%, #EA580C 100%);
  color: #fff;
  font: 700 15px/1 'Inter', system-ui, sans-serif;
  letter-spacing: -.005em;
  border: 0;
  border-radius: 10px;
  cursor: pointer;
  box-shadow:
    0 1px 0 rgba(255,255,255,.18) inset,
    0 4px 14px rgba(249,115,22,.30),
    0 10px 28px -8px rgba(249,115,22,.36);
  transition: transform .18s cubic-bezier(.22,1,.36,1), box-shadow .18s;
  position: relative;
  overflow: hidden;
}
.qqm-continue::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(110deg, transparent 0%, rgba(255,255,255,.30) 50%, transparent 100%);
  transform: translateX(-120%);
  transition: transform .9s cubic-bezier(.22,1,.36,1);
  pointer-events: none;
}
.qqm-continue:hover {
  transform: translateY(-1px);
  box-shadow:
    0 1px 0 rgba(255,255,255,.22) inset,
    0 8px 22px rgba(249,115,22,.38),
    0 16px 40px -10px rgba(249,115,22,.42);
}
.qqm-continue:hover::before { transform: translateX(120%); }
.qqm-continue:focus-visible { outline: 2px solid var(--navy, #07192E); outline-offset: 3px; }
.qqm-continue svg {
  width: 17px; height: 17px;
  stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.qqm-foot-phone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* The sitewide touch-min floor inflated this text link to a 44px-tall row,
     wasting vertical space the modal needs to stay scroll-free. It's a
     secondary "or call" link, not a primary tap target, so reset the floor. */
  min-height: 0;
  padding: 2px 0;
  font: 600 12.5px/1 'Inter', system-ui, sans-serif;
  color: var(--muted, #5B6B7E);
  text-decoration: none;
  transition: color .15s;
}
.qqm-foot-phone:hover { color: var(--orange, #F97316); }
.qqm-foot-phone svg {
  width: 12px; height: 12px;
  stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ── Defeat sitewide touch-floor / baseline rules that out-specify our
   single-class declarations (e.g. `input[type=number]{min-height:48px}` at
   0,1,1 and `a>svg:not([width]){width:24px}` at 0,1,2). ID-scoping lifts
   these to specificity 1,x,x so they win without !important. These free up
   the vertical space the modal needs to stay scroll-free on small phones.
   NOTE: the name/email lead inputs intentionally KEEP the 48px touch floor —
   they are bare inputs and serve as their own tap targets. ───────────────── */
#quoteQuickModal .qqm-lookup-input,
#quoteQuickModal .qqm-headcount-input { min-height: 0; }
#quoteQuickModal .qqm-foot-phone { min-height: 0; }
#quoteQuickModal .qqm-foot-phone svg { width: 13px; height: 13px; }

/* ── Mobile (≤640px): full-screen sheet ───────────────────────────────
   The card has a DEFINITE height here (100dvh), so we let the map flex to
   fill whatever space the fixed-height header/search/headcount/footer
   leave behind. That removes any dead gap above the footer AND guarantees
   the stack exactly fills the screen with no scrollbar. */
@media (max-width: 640px) {
  .qqm-card {
    border-radius: 0;
    max-height: 100vh;
    max-height: 100dvh;
    height: 100vh;
    height: 100dvh;
  }
  .qqm-head { padding: 14px 16px 12px; }
  .qqm-title { font-size: 16px; }
  /* The X read "microscopic" on the full-screen mobile sheet at 40/17.
     Bump to a comfortable thumb-friendly target with a larger glyph —
     matches the demo modal's mobile close sizing so the funnel feels
     consistent step-to-step. */
  .qqm-close { width: 44px; height: 44px; }
  .qqm-close svg { width: 20px !important; height: 20px !important; stroke-width: 2.3; }
  .qqm-body { padding: 12px 16px 6px; gap: clamp(8px, 1.6vh, 16px); }
  .qqm-section-h { font-size: 14px; }
  .qqm-map { padding: 8px 10px; border-radius: 12px; }
  /* Map fills the leftover vertical space. The card has a definite height
     (100dvh) so the flex chain resolves; the SVG is absolutely positioned to
     fill the frame, which avoids the flex/percentage-height collapse that
     leaves an in-flow `height:100%` SVG at 0px. preserveAspectRatio keeps the
     map centered and uncropped at whatever height it lands on. */
  .qqm-section--states { flex: 1 1 auto; }
  .qqm-map { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
  .qqm-map-frame { flex: 1 1 auto; min-height: 36px; }
  .qqm-map-svg { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none; }
  .qqm-foot { padding: 10px 16px 14px; }
  .qqm-continue { padding: 13px 18px; font-size: 14.5px; }
}

/* ── Short viewports (landscape phones, very small laptops) ────────────
   When height is the binding constraint, squeeze the map hard and trim
   spacing so the whole modal still fits with no scroll. Tiered so normal
   portrait phones / tablets / laptops keep the comfortable sizing above. */
@media (max-height: 680px) {
  /* Short screens: drop the secondary subtitle and trim chrome + control
     padding so the full stack stays scroll-free without an ugly sliver map. */
  #quoteQuickModal .qqm-sub { display: none; }
  .qqm-head { padding-top: 10px; padding-bottom: 8px; }
  .qqm-headcount-input-wrap { padding: 7px 13px; }
  .qqm-headcount-input { font-size: 18px; }
  .qqm-slider { margin: 4px 0 2px; }
  .qqm-slider-ticks { margin-top: 4px; }
  .qqm-foot { padding-top: 8px; padding-bottom: 10px; gap: 6px; }
  .qqm-continue { padding-top: 11px; padding-bottom: 11px; }
}
@media (max-height: 560px) {
  .qqm-map-svg { height: min(150px, 24vh); }
  .qqm-title { font-size: 15.5px; }
  .qqm-section-h { font-size: 13.5px; }
}
/* Landscape phones (wide + short): stack the two sections side-by-side so the
   map and headcount use the horizontal space the device has instead of the
   vertical space it lacks. The card is height-capped here (definite height),
   so the map flex-fill resolves correctly. */
@media (max-height: 520px) and (orientation: landscape) {
  .qqm { width: min(880px, 96vw); max-width: 880px; }
  /* The mobile sheet rules (≤640px wide) force a full-height card + column
     body; in landscape we want a row body. Keep a DEFINITE card height so the
     map flex-fill resolves (an auto height would collapse the absolute SVG). */
  .qqm-card { height: 96vh; height: 96dvh; max-height: 96vh; max-height: 96dvh; }
  .qqm-head { padding-top: 7px; padding-bottom: 6px; }
  .qqm-title { font-size: 15px; }
  .qqm-body { flex-direction: row; align-items: stretch; gap: 16px; padding-top: 6px; padding-bottom: 4px; }
  .qqm-section--states    { flex: 1 1 0; min-width: 0; }
  .qqm-section--headcount { flex: 1 1 0; min-width: 0; align-self: center; }
  .qqm-map { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
  .qqm-map-frame { flex: 1 1 auto; min-height: 0; }
  .qqm-map-svg { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none; }
  .qqm-section { gap: 4px; }
  .qqm-headcount-input-wrap { padding-top: 6px; padding-bottom: 6px; }
  .qqm-slider { margin: 3px 0 1px; }
  .qqm-slider-ticks { margin-top: 2px; }
  /* Footer goes horizontal too: lead fields + CTA on one row, phone tucked
     under, so the footer costs one row of height instead of three. Lead
     inputs lose the 48px touch floor here to keep the row short. */
  .qqm-foot { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px; padding: 6px 16px 8px; }
  /* min-width:0 lets the lead pair and CTA shrink below their content's
     intrinsic width so they share ONE row instead of each wrapping to its own
     line (which would defeat the height savings). */
  .qqm-lead { flex: 1 1 240px; min-width: 0; margin: 0; }
  .qqm-continue { flex: 1 1 190px; min-width: 0; width: auto; padding: 10px 18px; }
  .qqm-foot-phone { flex: 1 1 100%; order: 3; }
  #qqmEmailErr { flex: 1 1 100%; order: 2; }
  #quoteQuickModal #qqmName, #quoteQuickModal #qqmEmail { min-height: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .qqm-st,
  .qqm-continue,
  .qqm-continue::before,
  .qqm-close { transition: none !important; transform: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════
   State lookup (search autocomplete) — sits above the map for users who'd
   rather type a state name than hunt for it on the map.

   IMPORTANT: z-index: 30 lifts the entire lookup ABOVE the map's own
   stacking context (`.qqm-map` is position:relative, paints later in
   DOM order). Without this, the dropdown rendered "behind" the map even
   though the dropdown itself had z-index: 4 — z-index on a positioned
   child only sorts within its parent's stacking context.
   ═══════════════════════════════════════════════════════════════════════ */
.qqm-lookup {
  position: relative;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 clamp(6px, 1.2vh, 12px);
  padding: clamp(8px, 1.4vh, 12px) 16px;
  background:
    linear-gradient(180deg, rgba(255,255,255,.96) 0%, rgba(255,255,255,.82) 100%);
  border: 1.5px solid rgba(13,24,41,.10);
  border-radius: 14px;
  -webkit-backdrop-filter: blur(28px) saturate(1.5);
  backdrop-filter: blur(28px) saturate(1.5);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 -1px 0 rgba(13,24,41,.06),
    0 2px 6px rgba(7,25,46,.06);
  transition: border-color .15s, box-shadow .15s;
}
.qqm-lookup:focus-within {
  border-color: var(--orange, #F97316);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 -1px 0 rgba(13,24,41,.06),
    0 0 0 4px rgba(249,115,22,.18);
}
.qqm-lookup-ico {
  width: 18px; height: 18px;
  flex-shrink: 0;
  color: var(--blue-deep, #0D5B7F);
  stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.qqm-lookup-input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  font: 500 15px/1.4 'Inter', system-ui, sans-serif;
  color: var(--navy, #07192E);
  letter-spacing: -.005em;
  padding: 4px 0;
  min-width: 0;
  /* The sitewide `input{min-height:48px}` touch floor inflated this field by
     ~26px. The padded .qqm-lookup wrap IS the 48px tap target, so the inner
     input doesn't need its own floor — reclaim the height. */
  min-height: 0;
}
.qqm-lookup-input::placeholder {
  color: rgba(91,107,126,.75);
  font-weight: 500;
}
.qqm-lookup-clear {
  flex-shrink: 0;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  background: rgba(13,24,41,.06);
  border: 0;
  border-radius: 50%;
  color: var(--muted, #5B6B7E);
  cursor: pointer;
  transition: background .14s, color .14s;
}
.qqm-lookup-clear:hover { background: rgba(13,24,41,.12); color: var(--navy, #07192E); }
.qqm-lookup-clear:focus-visible { outline: 2px solid var(--orange, #F97316); outline-offset: 2px; }
.qqm-lookup-clear svg {
  width: 11px; height: 11px;
  stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
}

.qqm-lookup-list {
  position: absolute;
  top: calc(100% + 8px);
  left: 0; right: 0;
  /* z-index here is relative to .qqm-lookup which is z-index: 30 — together
     they put the dropdown well above the map's stacking context. */
  z-index: 1;
  list-style: none;
  margin: 0;
  padding: 8px;
  background: #fff;
  border: 1.5px solid rgba(13,24,41,.10);
  border-radius: 14px;
  box-shadow:
    0 0 0 1px rgba(13,24,41,.04),
    0 24px 60px -10px rgba(7,25,46,.30),
    0 8px 20px -4px rgba(7,25,46,.14);
  max-height: 320px;
  overflow-y: auto;
  /* Slide-in animation so it's obvious the dropdown opened */
  animation: qqm-lookup-in 180ms cubic-bezier(.22,1,.36,1);
  transform-origin: top center;
}
@keyframes qqm-lookup-in {
  from { opacity: 0; transform: translateY(-6px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.qqm-lookup-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border-radius: 10px;
  cursor: pointer;
  font: 500 14px/1.3 'Inter', system-ui, sans-serif;
  color: var(--navy, #07192E);
  transition: background .12s;
}
.qqm-lookup-item:hover,
.qqm-lookup-item:focus {
  background: rgba(20,121,163,.08);
  outline: none;
}
.qqm-lookup-item.is-selected {
  background: linear-gradient(135deg, rgba(247,212,76,.12) 0%, rgba(240,113,40,.10) 50%, rgba(123,33,162,.08) 100%);
}
.qqm-lookup-item.is-selected:hover {
  background: linear-gradient(135deg, rgba(247,212,76,.20) 0%, rgba(240,113,40,.16) 50%, rgba(123,33,162,.14) 100%);
}
.qqm-lookup-flag {
  width: 28px; height: 22px;
  display: grid; place-items: center;
  border-radius: 5px;
  background: rgba(20,121,163,.10);
  color: var(--blue-deep, #0D5B7F);
  font: 700 10.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: .02em;
  flex-shrink: 0;
}
.qqm-lookup-item.is-selected .qqm-lookup-flag {
  background: linear-gradient(135deg, #F7D44C 0%, #F07128 50%, #7B21A2 100%);
  color: #fff;
}
.qqm-lookup-flag svg { width: 11px; height: 11px; }
.qqm-lookup-code { display: block; }
.qqm-lookup-name { flex: 1; }
.qqm-lookup-empty {
  padding: 12px 10px;
  font: 500 13px/1.4 'Inter', system-ui, sans-serif;
  color: var(--muted, #5B6B7E);
  font-style: italic;
}

/* ═══════════════════════════════════════════════════════════════════════
   Type-able headcount input — full-width row above the slider
   (2026-05-24: simplified — icon + "Type:" prefix removed; the section
   header makes the purpose obvious and the visible border + cursor are
   enough to signal it's an input.)
   ═══════════════════════════════════════════════════════════════════════ */
.qqm-headcount-input-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: #fff;
  border: 1.5px solid rgba(13,24,41,.14);
  border-radius: 10px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.85);
  transition: border-color .15s, box-shadow .15s;
  cursor: text;
}
.qqm-headcount-input-wrap:hover {
  border-color: var(--blue-deep, #0D5B7F);
}
.qqm-headcount-input-wrap:focus-within {
  border-color: var(--orange, #F97316);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.85),
    0 0 0 3px rgba(249,115,22,.18);
}
.qqm-headcount-input {
  flex: 1;
  min-width: 0;
  /* The .qqm-headcount-input-wrap provides the tap target; defeat the
     sitewide 48px input touch-floor on the inner field to save height. */
  min-height: 0;
  background: transparent;
  border: 0;
  outline: 0;
  font: 700 20px/1 'Poppins', system-ui, sans-serif;
  color: var(--navy, #07192E);
  text-align: left;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  cursor: text;
  /* Hide native spinner (Chrome/Edge/Firefox) — slider IS the spinner */
  -moz-appearance: textfield;
  appearance: textfield;
}
.qqm-headcount-input::-webkit-outer-spin-button,
.qqm-headcount-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.qqm-headcount-input::placeholder {
  color: rgba(13,24,41,.25);
  font-weight: 600;
}
.qqm-headcount-input-unit {
  font: 500 13px/1 'Inter', system-ui, sans-serif;
  color: var(--muted, #5B6B7E);
  flex-shrink: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   Cross-browser slider track styling — fixes Firefox/legacy thumb rendering
   ═══════════════════════════════════════════════════════════════════════ */
/* Firefox track (without this, Firefox can render its native gray track
   on top of our gradient on some versions) */
.qqm-slider::-moz-range-track {
  width: 100%;
  height: 6px;
  background: linear-gradient(90deg, var(--blue-deep, #0D5B7F) 0%, var(--orange, #F97316) 100%);
  border-radius: 999px;
  border: 0;
}
.qqm-slider::-ms-track {
  width: 100%;
  height: 6px;
  background: transparent;
  border-color: transparent;
  color: transparent;
}
.qqm-slider::-ms-fill-lower,
.qqm-slider::-ms-fill-upper {
  background: linear-gradient(90deg, var(--blue-deep, #0D5B7F) 0%, var(--orange, #F97316) 100%);
  border-radius: 999px;
}
/* Firefox fallback: -moz-appearance for older versions that don't honor
   the unprefixed `appearance: none` on input[type=range]. */
@-moz-document url-prefix() {
  .qqm-slider {
    -moz-appearance: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Demo-modal intro panel polish (2026-05-14)

   This modal is STEP 02 in the funnel — fires after the quote-quick
   qualifier (step 01) hands off identity + states + headcount. The intro
   panel needed three fixes:
     1. "01" -> "02" (handled in demo-modal.js content)
     2. Humanized copy (handled in demo-modal.js content)
     3. Better design language to match the qqm modal — same eyebrow pill,
        brand-gold step numeral, brand-green checkmarks, tighter spacing
   ═══════════════════════════════════════════════════════════════════════════ */

/* Brand-gold step numeral with subtle gradient — replaces the flat
   light-gray "01" watermark for a more polished feel. */
.demo-modal-num {
  background: linear-gradient(135deg, #F7D44C 0%, #F07128 35%, #E8125C 70%, #7B21A2 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
  opacity: .14 !important;
  font-weight: 800 !important;
  letter-spacing: -.06em !important;
}

/* Eyebrow pill — matches the qqm modal eyebrow exactly so the two modals
   read as a paired system. */
.demo-modal-eyebrow {
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px;
  background: transparent !important;
  color: inherit !important;
  text-transform: none !important;
  letter-spacing: normal !important;
  font-size: inherit !important;
  font-weight: normal !important;
  margin-bottom: 16px !important;
  padding: 0 !important;
}
.demo-modal-eyebrow-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  background: rgba(20,121,163,.10);
  color: var(--blue-deep, #0D5B7F);
  font: 700 10.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: .14em;
  text-transform: uppercase;
  border-radius: 999px;
}
.demo-modal-eyebrow-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--orange-bright, #F97316);
  box-shadow: 0 0 0 3px rgba(249,115,22,.18);
}

/* Brand-green checkmarks instead of the default dark. Reads as "verified"
   instead of "checkbox". */
.demo-modal-trust-item svg {
  stroke: var(--green-bright, #22C55E) !important;
  stroke-width: 3 !important;
  stroke-linecap: round !important;
  stroke-linejoin: round !important;
}
/* Small ring around each check for a polished "stamp" feel */
.demo-modal-trust-item {
  align-items: center !important;
  gap: 12px !important;
  padding: 6px 0 !important;
}
.demo-modal-trust-item svg {
  width: 18px !important;
  height: 18px !important;
  flex-shrink: 0;
  padding: 3px;
  background: rgba(34,197,94,.10);
  border-radius: 50%;
  box-sizing: border-box;
}
.demo-modal-trust-item span {
  font: 500 13.5px/1.4 'Inter', system-ui, sans-serif !important;
  color: var(--text, #0D1829) !important;
  letter-spacing: -.002em !important;
}

/* Tighten title + lede typography to feel more conversational */
.demo-modal-title {
  font: 800 26px/1.18 'Poppins', system-ui, sans-serif !important;
  letter-spacing: -.022em !important;
  margin-bottom: 14px !important;
}
.demo-modal-lede {
  font: 400 14.5px/1.55 'Inter', system-ui, sans-serif !important;
  color: var(--muted, #5B6B7E) !important;
  letter-spacing: -.002em !important;
  margin-bottom: 22px !important;
}

@media (max-width: 760px) {
  .demo-modal-title { font-size: 22px !important; }
  .demo-modal-lede { font-size: 13.5px !important; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Workflow hardening (2026-06-02) — defeat the sitewide
   button{min-width/height:var(--touch-min)} inflation for ALL modal
   controls. The state-search clear button was ballooning to a ~44px gray
   circle; map "Select all / Clear" and zoom buttons risked the same. Each
   control is sized intentionally below, so the global floor must be reset.
   ═══════════════════════════════════════════════════════════════════════ */
.qqm button { min-width: 0; min-height: 0; }
/* Reliable centering + icon size for the search clear (same WebKit/responsive
   svg-collapse fix the close-X uses). */
.qqm-lookup-clear {
  display: flex;
  align-items: center;
  justify-content: center;
}
/* The element-class `display:flex` above overrides the [hidden] attribute's
   display:none (equal specificity, later rule wins), which left the clear-X
   visible as a gray circle even with an empty search box. Restore the hide. */
.qqm-lookup-clear[hidden] { display: none; }
.qqm-lookup-clear svg {
  width: 11px !important;
  height: 11px !important;
  max-width: none !important;
  flex: 0 0 auto;
}
