/* =============================================================================
   ATTIC BREEZE VENTILATION — APPLICATION COMPONENTS
   Every value comes from abv-tokens.css. A literal colour or radius below is a
   bug; fix the token instead.
   ========================================================================== */

.abv-root { font-family: var(--abv-font); color: var(--abv-text); position: relative; }
.abv-root *, .abv-root *::before, .abv-root *::after { box-sizing: border-box; }

/* ---------------------------------------------------------------------------
   SHELL — a working surface, not a floating modal on grey. The page already
   carries the site header; this is the application inside it.
------------------------------------------------------------------------- */
.abv-shell { max-width: var(--abv-max); margin: 0 auto; padding: var(--abv-7) var(--abv-5) var(--abv-8); }

.abv-bar {
  display: flex; align-items: center; gap: var(--abv-4);
  padding-bottom: var(--abv-4); margin-bottom: var(--abv-6);
  border-bottom: 1px solid var(--abv-hairline);
}
.abv-bar__name {
  font-size: var(--abv-eyebrow-size); font-weight: var(--abv-w-strong);
  letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase; color: var(--abv-orange);
}
.abv-bar__spacer { flex: 1 1 auto; }
/* The property label that replaces the map on later steps. */
.abv-bar__prop { text-align: right; line-height: 1.3; }
.abv-bar__prop b { display: block; font-size: var(--abv-small); font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-bar__prop span { font-size: var(--abv-tiny); color: var(--abv-muted); }

/* ---------------------------------------------------------------------------
   TYPE
------------------------------------------------------------------------- */
.abv-eyebrow {
  display: block; margin-bottom: var(--abv-3);
  font-size: var(--abv-eyebrow-size); font-weight: var(--abv-w-strong);
  letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase; color: var(--abv-orange);
}
.abv-q {
  margin: 0 0 var(--abv-3);
  font-size: var(--abv-h1); line-height: var(--abv-h1-lh); letter-spacing: var(--abv-h1-ls);
  font-weight: var(--abv-w-head); color: var(--abv-ink-head); text-wrap: balance;
}
.abv-sub { margin: 0 0 var(--abv-6); max-width: 52ch; font-size: var(--abv-body); line-height: var(--abv-body-lh); color: var(--abv-muted); }

/* ---------------------------------------------------------------------------
   BUTTONS — orange primary, navy pill secondary, quiet tertiary.
------------------------------------------------------------------------- */
.abv-btn, .abv-btn--ghost, .abv-btn--quiet {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--abv-2);
  min-height: var(--abv-tap); padding: 14px 26px;
  font-family: var(--abv-font); font-size: 12px; font-weight: var(--abv-w-strong);
  letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase;
  border: 2px solid transparent; border-radius: var(--abv-radius-pill);
  cursor: pointer; text-decoration: none;
  transition: background-color var(--abv-dur) var(--abv-ease),
              border-color var(--abv-dur) var(--abv-ease),
              color var(--abv-dur) var(--abv-ease);
}
.abv-btn { background: var(--abv-navy); color: #fff; }
.abv-btn:hover { background: var(--abv-navy); box-shadow: inset 0 0 0 2px var(--abv-orange); }
.abv-btn--ghost { background: transparent; color: var(--abv-ink-head); border-color: var(--abv-ink-head); }
.abv-btn--ghost:hover { background: var(--abv-ink-head); color: #fff; }
.abv-btn--quiet {
  background: transparent; color: var(--abv-muted); border-color: transparent;
  text-transform: none; letter-spacing: .2px; font-size: var(--abv-small); padding: 10px 12px;
}
.abv-btn--quiet:hover { color: var(--abv-ink-head); }
.abv-btn:disabled, .abv-btn[aria-disabled='true'] { opacity: .45; cursor: not-allowed; }
.abv-root :is(button, a, input):focus-visible { outline: 3px solid var(--abv-blue-lt); outline-offset: 2px; }

/* ---------------------------------------------------------------------------
   STEPS — one screen visible at a time, with a short crossfade.
------------------------------------------------------------------------- */
.abv-screen { display: none; }
.abv-screen.is-on { display: block; animation: abv-in var(--abv-dur) var(--abv-ease) both; }
@keyframes abv-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .abv-screen.is-on { animation: none; } }

.abv-steps { display: flex; align-items: center; gap: var(--abv-3); margin-bottom: var(--abv-5); }
.abv-steps__label { font-size: var(--abv-tiny); font-weight: var(--abv-w-strong); letter-spacing: 1.4px; text-transform: uppercase; color: var(--abv-muted); }
.abv-back {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: none; border-radius: 50%;
  border: 1px solid var(--abv-line); background: #fff; color: var(--abv-ink-head); cursor: pointer;
}
.abv-back:hover { border-color: var(--abv-ink-head); background: var(--abv-bg-soft); }
.abv-meter { display: flex; gap: 5px; margin-left: auto; }
.abv-meter i { width: 18px; height: 3px; border-radius: 2px; background: var(--abv-line); }
.abv-meter i.is-done { background: var(--abv-orange); opacity: .45; }
.abv-meter i.is-now { background: var(--abv-orange); }

/* ---------------------------------------------------------------------------
   WELCOME — brand-forward but restrained. No frozen full-bleed photograph:
   the interface is the subject, the navy panel supplies the brand.
------------------------------------------------------------------------- */
.abv-welcome { display: grid; grid-template-columns: minmax(0,1.1fr) minmax(0,.9fr); gap: var(--abv-8); align-items: center; }
.abv-welcome__body { max-width: 34ch; }
.abv-welcome .abv-q { font-size: clamp(30px, 3.6vw, 46px); }
.abv-welcome .abv-q em { font-style: normal; color: var(--abv-orange); }
.abv-welcome__meta { margin-top: var(--abv-4); font-size: var(--abv-small); color: var(--abv-muted); }

/* An original branded composition: navy ground, roof profile, airflow. */
.abv-welcome__art {
  position: relative; border-radius: var(--abv-radius); overflow: hidden;
  background: var(--abv-navy);
  aspect-ratio: 4 / 3; display: grid; place-items: center; box-shadow: var(--abv-shadow);
}
.abv-welcome__art svg { width: 76%; height: auto; }
.abv-welcome__art img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 900px) {
  .abv-welcome { grid-template-columns: 1fr; gap: var(--abv-5); }
  .abv-welcome__art { order: -1; aspect-ratio: 16 / 9; }
  .abv-welcome__body { max-width: none; }
}

/* ---------------------------------------------------------------------------
   ADDRESS — the property is the subject. The field sits ON the map, not in a
   form above it, which is what makes it read as a property tool.
------------------------------------------------------------------------- */
.abv-addr { position: relative; }
.abv-mapwrap {
  position: relative; border-radius: var(--abv-radius); overflow: hidden;
  border: 1px solid var(--abv-line); background: var(--abv-bg-soft);
  min-height: 460px; box-shadow: var(--abv-shadow-sm);
}
@media (max-width: 768px) { .abv-mapwrap { min-height: 380px; } }
.abv-map { position: absolute; inset: 0; }

/* The search field floats over the map. */
.abv-search {
  position: absolute; z-index: 3; top: var(--abv-4); left: var(--abv-4); right: var(--abv-4);
  max-width: 520px;
}
.abv-search__field {
  display: flex; align-items: center; gap: var(--abv-3);
  height: var(--abv-field-h); padding: 0 var(--abv-4);
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  box-shadow: var(--abv-shadow);
}
.abv-search__field svg { flex: none; color: var(--abv-muted); }
.abv-search input {
  flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent;
  font-family: var(--abv-font); font-size: var(--abv-body); color: var(--abv-ink-head);
}
.abv-search input::placeholder { color: var(--abv-muted); }

/* Google injects .pac-container into <body>; it must clear the field and sit
   above Elementor's own stacking contexts. */
.pac-container { z-index: 100000 !important; border-radius: var(--abv-radius); border: 1px solid var(--abv-line); box-shadow: var(--abv-shadow); font-family: var(--abv-font); }
.pac-item { padding: 8px 12px; font-size: var(--abv-small); cursor: pointer; }
.pac-item-query { font-size: var(--abv-body); color: var(--abv-ink-head); }

/* ---- map states: loading is NOT an error ---- */
.abv-mapstate {
  position: absolute; inset: 0; z-index: 2; display: grid; place-content: center; justify-items: center;
  gap: var(--abv-3); text-align: center; padding: var(--abv-6);
  background: var(--abv-bg-soft); color: var(--abv-muted);
}
.abv-mapstate[hidden] { display: none; }
.abv-mapstate b { color: var(--abv-ink-head); font-size: var(--abv-h3); font-weight: var(--abv-w-head); letter-spacing: var(--abv-h3-ls); }
.abv-mapstate p { margin: 0; max-width: 34ch; font-size: var(--abv-small); }
.abv-spin { width: 26px; height: 26px; border-radius: 50%; border: 3px solid var(--abv-line); border-top-color: var(--abv-orange); animation: abv-spin .8s linear infinite; }
@keyframes abv-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .abv-spin { animation-duration: 2.4s; } }

/* ---- confirmation bar, docked to the bottom of the map ---- */
.abv-confirm {
  position: absolute; z-index: 3; left: var(--abv-4); right: var(--abv-4); bottom: var(--abv-4);
  display: flex; align-items: center; gap: var(--abv-4); flex-wrap: wrap;
  padding: var(--abv-4) var(--abv-5);
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  box-shadow: var(--abv-shadow);
}
.abv-confirm[hidden] { display: none; }
.abv-confirm__text { flex: 1 1 220px; min-width: 0; }
.abv-confirm__text b { display: block; font-size: var(--abv-h3); font-weight: var(--abv-w-head); color: var(--abv-ink-head); letter-spacing: var(--abv-h3-ls); }
.abv-confirm__text span { display: block; margin-top: 2px; font-size: var(--abv-small); color: var(--abv-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.abv-confirm__actions { display: flex; gap: var(--abv-3); flex-wrap: wrap; }

@media (max-width: 620px) {
  .abv-search { top: var(--abv-3); left: var(--abv-3); right: var(--abv-3); }
  .abv-confirm { left: var(--abv-3); right: var(--abv-3); bottom: var(--abv-3); padding: var(--abv-4); }
  .abv-confirm__actions { width: 100%; }
  .abv-confirm__actions .abv-btn, .abv-confirm__actions .abv-btn--ghost { flex: 1 1 auto; }
}

/* ---------------------------------------------------------------------------
   ERRORS — say what to do, never show an API string.
------------------------------------------------------------------------- */
.abv-error {
  margin-top: var(--abv-4); padding: var(--abv-4) var(--abv-5);
  border-left: 3px solid var(--abv-orange); background: var(--abv-tint);
  border-radius: 0 var(--abv-radius) var(--abv-radius) 0; font-size: var(--abv-small); color: var(--abv-ink-head);
}
.abv-error[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   ELEMENTOR EDITOR PREVIEW — real content, no map, no report.
------------------------------------------------------------------------- */
.abv-editor-preview { padding: var(--abv-6); border: 1px dashed var(--abv-line); border-radius: var(--abv-radius); background: var(--abv-bg-soft); }
.abv-ep__tag { display: inline-block; margin-bottom: var(--abv-3); padding: 3px 10px; border-radius: var(--abv-radius-pill); background: var(--abv-navy); color: #fff; font-size: var(--abv-tiny); font-weight: var(--abv-w-strong); }
.abv-ep__eyebrow { display: block; color: var(--abv-orange); font-size: var(--abv-eyebrow-size); font-weight: var(--abv-w-strong); letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase; }
.abv-editor-preview h2 { margin: var(--abv-2) 0; font-size: var(--abv-h2); font-weight: var(--abv-w-head); color: var(--abv-ink-head); }
.abv-ep__q { margin: var(--abv-4) 0 var(--abv-2); font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-ep__list { margin: 0; padding-left: 18px; font-size: var(--abv-small); }
.abv-ep__list code { background: #fff; border: 1px solid var(--abv-line); border-radius: 3px; padding: 1px 5px; font-size: var(--abv-tiny); }
.abv-ep__note { margin-top: var(--abv-4); font-size: var(--abv-tiny); color: var(--abv-muted); }

/* ---------------------------------------------------------------------------
   CHOICE CARDS — real radios inside labels, so keyboard and screen readers
   work without inventing ARIA. Selection carries a tick and a tinted ground,
   never colour alone.
------------------------------------------------------------------------- */
.abv-split { display: grid; grid-template-columns: minmax(0,1fr); gap: var(--abv-6); }
.abv-split__main { max-width: 760px; }

.abv-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--abv-4); margin: 0 0 var(--abv-5); }
.abv-card {
  position: relative; display: flex; flex-direction: column; gap: var(--abv-3);
  min-height: var(--abv-tap); padding: var(--abv-5);
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  box-shadow: var(--abv-shadow-sm); cursor: pointer;
  transition: border-color var(--abv-dur) var(--abv-ease), box-shadow var(--abv-dur) var(--abv-ease);
}
.abv-card:hover { border-color: var(--abv-orange); box-shadow: var(--abv-shadow); }
.abv-card input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.abv-card:focus-within { outline: 3px solid var(--abv-blue-lt); outline-offset: 2px; }
.abv-card__art { display: block; color: var(--abv-navy); }
.abv-card__art svg { width: 100%; max-width: 150px; height: auto; }
.abv-card__body b { display: block; font-size: 16px; font-weight: var(--abv-w-head); color: var(--abv-ink-head); letter-spacing: -.1px; }
.abv-card__body small { display: block; margin-top: 3px; font-size: var(--abv-small); line-height: 1.4; color: var(--abv-muted); }

.abv-card.is-on { border-color: var(--abv-orange); box-shadow: var(--abv-shadow), inset 0 0 0 1px var(--abv-orange); background: var(--abv-tint); }
.abv-card.is-on::after {
  content: ''; position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; border-radius: 50%;
  background: var(--abv-orange) no-repeat center / 12px 9px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 9'%3E%3Cpath d='M1 4.6 4.3 8 11 1' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  box-shadow: 0 0 0 2px #fff;
}

/* Compact variant for the yes/no/one-story sub-questions. */
.abv-sub-q { border: 0; margin: 0 0 var(--abv-5); padding: 0; }
.abv-sub-q legend { padding: 0 0 var(--abv-3); font-size: var(--abv-body); font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-sub-q .abv-cards { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--abv-3); }
.abv-sub-q .abv-card { padding: var(--abv-4); }
.abv-sub-q .abv-card__body b { font-size: 15px; }

/* ---------------------------------------------------------------------------
   CONDITIONAL PANELS + NUMERIC FIELD
------------------------------------------------------------------------- */
.abv-panel { margin: 0 0 var(--abv-5); padding: var(--abv-5); background: var(--abv-bg-soft); border-radius: var(--abv-radius); }
.abv-panel[hidden] { display: none; }

.abv-field { display: block; margin-bottom: var(--abv-5); }
.abv-field__label { display: block; margin-bottom: var(--abv-2); font-size: var(--abv-body); font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-field__wrap {
  display: flex; align-items: center; gap: var(--abv-2);
  max-width: 320px; height: var(--abv-field-h); padding: 0 var(--abv-4);
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
}
.abv-field__wrap:focus-within { border-color: var(--abv-orange); box-shadow: 0 0 0 3px var(--abv-tint); }
.abv-field input {
  flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent;
  font-family: var(--abv-font); font-size: 22px; font-weight: var(--abv-w-head); color: var(--abv-ink-head);
}
.abv-field__unit { flex: none; font-size: var(--abv-small); color: var(--abv-muted); }
.abv-field__hint { display: block; margin-top: var(--abv-2); font-size: var(--abv-small); color: var(--abv-muted); }

/* ---------------------------------------------------------------------------
   ESTIMATE + NOTES
------------------------------------------------------------------------- */
.abv-estimate { padding: var(--abv-5); background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius); }
.abv-estimate[hidden] { display: none; }
.abv-estimate b { display: block; font-size: 34px; line-height: 1.1; font-weight: var(--abv-w-head); color: var(--abv-ink-head); letter-spacing: -.6px; }
.abv-estimate p { margin: var(--abv-2) 0 var(--abv-3); font-size: var(--abv-small); color: var(--abv-muted); }

.abv-note { margin: 0 0 var(--abv-5); padding: var(--abv-4) var(--abv-5); border-left: 3px solid var(--abv-orange); background: var(--abv-tint); border-radius: 0 var(--abv-radius) var(--abv-radius) 0; }
.abv-note[hidden] { display: none; }
.abv-note b { display: block; margin-bottom: 4px; color: var(--abv-ink-head); font-size: var(--abv-body); }
.abv-note p { margin: 0; font-size: var(--abv-small); line-height: 1.55; color: var(--abv-text); }

.abv-why { margin: 0 0 var(--abv-5); }
.abv-why summary { cursor: pointer; font-size: var(--abv-small); font-weight: var(--abv-w-strong); color: var(--abv-navy); }
.abv-why p { margin: var(--abv-3) 0 0; font-size: var(--abv-small); line-height: 1.6; color: var(--abv-muted); max-width: 56ch; }

/* ---------------------------------------------------------------------------
   NAV
------------------------------------------------------------------------- */
.abv-nav { display: flex; align-items: center; gap: var(--abv-4); margin-top: var(--abv-7); padding-top: var(--abv-5); border-top: 1px solid var(--abv-hairline); }
.abv-nav__spacer { flex: 1 1 auto; }

@media (max-width: 620px) {
  .abv-cards { grid-template-columns: 1fr; gap: var(--abv-3); }
  .abv-card { flex-direction: row; align-items: center; padding: var(--abv-4); }
  .abv-card__art svg { max-width: 74px; }
  .abv-sub-q .abv-cards { grid-template-columns: 1fr 1fr; }
  .abv-sub-q .abv-card { flex-direction: column; text-align: center; }
  .abv-nav { position: sticky; bottom: 0; background: #fff; margin-top: var(--abv-6);
    padding: var(--abv-3) 0 calc(var(--abv-3) + env(safe-area-inset-bottom)); box-shadow: 0 -8px 20px rgba(5,17,36,.06); }
  .abv-nav .abv-btn { flex: 1 1 auto; }
  .abv-field__wrap { max-width: none; }
}

/* ---------------------------------------------------------------------------
   PHOTO CHOICE — roof material. The picture answers the question; the words
   only confirm it, so the image runs to the card edge and gets real height.
------------------------------------------------------------------------- */
.abv-cards--photo { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.abv-card--photo { padding: 0; overflow: hidden; gap: 0; }
.abv-card__photo {
  display: block; position: relative; width: 100%; height: auto;
  aspect-ratio: 3 / 2; background: var(--abv-bg-soft); overflow: hidden;
}
.abv-card__photo img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform var(--abv-dur) var(--abv-ease); }
.abv-card--photo:hover .abv-card__photo img { transform: scale(1.03); }
/* A hairline so a bright sky never bleeds into the white card. */
.abv-card__photo::after { content: ''; position: absolute; inset: auto 0 0 0; height: 1px; background: rgba(5,17,36,.10); }
/* "Not sure" is deliberately NOT a photograph — a fourth photo would read as
   a fourth roofing material. */
.abv-card__photo--none {
  display: grid; place-items: center; color: var(--abv-navy);
  background: repeating-linear-gradient(135deg, rgba(57,147,223,.10) 0 10px, transparent 10px 20px), #fff;
}
.abv-card__photo--none svg { width: 46%; height: auto; }
.abv-card--photo .abv-card__body { padding: var(--abv-4); }

/* ---------------------------------------------------------------------------
   COLOUR BANDS — swatches are the engine's own colours for that material.
------------------------------------------------------------------------- */
.abv-cards--band { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.abv-card--band { gap: var(--abv-4); }
.abv-swatches { display: flex; gap: 6px; }
.abv-swatches i {
  display: block; width: 34px; height: 34px; border-radius: 4px;
  border: 1px solid rgba(5,17,36,.15); box-shadow: inset 0 1px 2px rgba(255,255,255,.25);
}
@media (max-width: 620px) {
  .abv-cards--photo { grid-template-columns: 1fr 1fr; }
  .abv-card--photo { flex-direction: column; }
  .abv-card--photo .abv-card__body { padding: var(--abv-3); }
  .abv-card--photo .abv-card__body b { font-size: 15px; }
  .abv-cards--band { grid-template-columns: 1fr; }
  .abv-card--band { flex-direction: row; align-items: center; }
  .abv-swatches i { width: 28px; height: 28px; }
}

/* ---------------------------------------------------------------------------
   ROOF PITCH — architectural line profile, deliberately unlike the material
   photography and the colour swatches so the three roof questions never read
   as the same question asked three times.
------------------------------------------------------------------------- */
.abv-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.abv-pitch { max-width: 560px; padding: var(--abv-6); background: var(--abv-bg-soft); border-radius: var(--abv-radius); }
.abv-pitch__art { display: grid; place-items: center; color: var(--abv-navy); min-height: 190px; }
.abv-pitch__art svg { width: 100%; max-width: 340px; height: auto; }

.abv-pitch__read { display: flex; align-items: baseline; gap: var(--abv-3); flex-wrap: wrap; margin: var(--abv-4) 0 var(--abv-5); }
.abv-pitch__word { font-size: var(--abv-h3); font-weight: var(--abv-w-head); color: var(--abv-ink-head); letter-spacing: var(--abv-h3-ls); }
.abv-pitch__exact {
  font-size: var(--abv-h3); font-weight: var(--abv-w-head); color: var(--abv-orange);
  padding: 2px 10px; background: #fff; border-radius: var(--abv-radius); border: 1px solid var(--abv-line);
}
.abv-pitch__deg { font-size: var(--abv-small); color: var(--abv-muted); }

.abv-pitch__slider { display: block; }
.abv-pitch__slider input[type=range] { width: 100%; height: 44px; margin: 0; accent-color: var(--abv-orange); cursor: pointer; }
.abv-pitch__ends { display: flex; justify-content: space-between; font-size: var(--abv-tiny); color: var(--abv-muted); margin-bottom: var(--abv-5); }

.abv-field--inline { margin: var(--abv-3) 0 0; }
.abv-field--inline select {
  width: 100%; max-width: 220px; height: var(--abv-tap); padding: 0 var(--abv-3);
  font-family: var(--abv-font); font-size: var(--abv-body); color: var(--abv-ink-head);
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
}
@media (max-width: 620px) { .abv-pitch { padding: var(--abv-4); } .abv-pitch__art { min-height: 150px; } }

/* ---------------------------------------------------------------------------
   SUN — its own visual language again: lit roof, shaded roof, undecided sky.
   A five-second question, so the cards are wide and there is nothing to tune.
------------------------------------------------------------------------- */
.abv-cards--sun { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.abv-card__art--sun { display: grid; place-items: center; color: var(--abv-navy); padding: var(--abv-2) 0; }
.abv-card__art--sun svg { width: 100%; max-width: 168px; height: auto; }
@media (max-width: 620px) {
  .abv-cards--sun { grid-template-columns: 1fr; }
  .abv-card--sun { flex-direction: row; align-items: center; }
  .abv-card__art--sun svg { max-width: 92px; }
}

/* ---------------------------------------------------------------------------
   INSTALLATION — roof vs gable shown as installation context, distinct again
   from photography / swatches / profile / sunlight.
------------------------------------------------------------------------- */
.abv-cards--install { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.abv-card__art--install { display: grid; place-items: center; color: var(--abv-navy); padding: var(--abv-2) 0; }
.abv-card__art--install svg { width: 100%; max-width: 160px; height: auto; }

.abv-cards--count { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--abv-3); max-width: 380px; }
.abv-card--count { align-items: center; justify-content: center; padding: var(--abv-4) var(--abv-2); }
.abv-card--count .abv-card__body { text-align: center; }
.abv-card--count .abv-card__body b { font-size: 24px; }

.abv-gablehelp { display: flex; gap: var(--abv-4); align-items: center; margin-top: var(--abv-3); }
.abv-gablehelp svg { flex: none; width: 130px; height: auto; color: var(--abv-navy); }
.abv-gablehelp p { margin: 0; font-size: var(--abv-small); line-height: 1.6; color: var(--abv-muted); }

@media (max-width: 620px) {
  .abv-cards--install { grid-template-columns: 1fr; }
  .abv-card--install { flex-direction: row; align-items: center; }
  .abv-card__art--install svg { max-width: 92px; }
  .abv-gablehelp { flex-direction: column; align-items: flex-start; }
}

/* ---------------------------------------------------------------------------
   RESULT — the payoff. Recommendation dominates; technical detail is behind
   disclosure. No dense table at the top.
------------------------------------------------------------------------- */
.abv-plan { max-width: 860px; }
.abv-plan__head { padding-bottom: var(--abv-5); border-bottom: 3px solid var(--abv-orange); margin-bottom: var(--abv-6); }
.abv-plan__title { margin: 0; font-size: clamp(32px, 4.4vw, 52px); line-height: 1.04; letter-spacing: -1px; font-weight: var(--abv-w-head); color: var(--abv-ink-head); }
.abv-plan__addr { margin: var(--abv-3) 0 0; }
.abv-plan__addr b { display: block; font-size: var(--abv-h4, 18px); font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-plan__addr span { font-size: var(--abv-small); color: var(--abv-muted); }

.abv-rec { padding: var(--abv-6); border-radius: var(--abv-radius); background: var(--abv-navy); color: #fff; margin-bottom: var(--abv-5); box-shadow: var(--abv-shadow); }
.abv-rec .abv-eyebrow { color: var(--abv-orange); }
.abv-rec__qty { margin: 0; font-size: var(--abv-body); color: rgba(255,255,255,.75); }
.abv-rec__qty b { font-size: clamp(40px, 6vw, 68px); line-height: 1; font-weight: var(--abv-w-head); color: #fff; margin-right: 8px; }
.abv-rec__name { margin: var(--abv-2) 0 var(--abv-2); font-size: clamp(22px, 3vw, 32px); font-weight: var(--abv-w-head); letter-spacing: -.4px; color: #fff; }
.abv-rec__mount { margin: 0; font-size: var(--abv-small); color: rgba(255,255,255,.7); }

.abv-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--abv-4); margin-bottom: var(--abv-6); }
.abv-stat { padding: var(--abv-5); background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius); box-shadow: var(--abv-shadow-sm); }
.abv-stat span { display: block; font-size: var(--abv-tiny); font-weight: var(--abv-w-strong); letter-spacing: 1.2px; text-transform: uppercase; color: var(--abv-muted); }
.abv-stat b { display: block; margin-top: 6px; font-size: 26px; font-weight: var(--abv-w-head); color: var(--abv-ink-head); letter-spacing: -.4px; }
.abv-stat small { display: block; margin-top: 4px; font-size: var(--abv-small); color: var(--abv-muted); }

.abv-block { margin-bottom: var(--abv-6); }
.abv-block h4 { margin: 0 0 var(--abv-3); font-size: var(--abv-h3); font-weight: var(--abv-w-head); color: var(--abv-ink-head); letter-spacing: var(--abv-h3-ls); }
.abv-block p { margin: 0 0 var(--abv-3); font-size: var(--abv-body); line-height: var(--abv-body-lh); }
.abv-fine { font-size: var(--abv-small); color: var(--abv-muted); }

.abv-note--warn { border-left-color: var(--abv-blue); background: rgba(57,147,223,.07); }

.abv-alts { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--abv-3); }
.abv-alt { padding: var(--abv-4) var(--abv-5); background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius); }
.abv-alt b { display: block; font-size: var(--abv-body); color: var(--abv-ink-head); }
.abv-alt span { display: block; margin-top: 2px; font-size: var(--abv-small); color: var(--abv-muted); }
.abv-alt em { display: block; margin-top: 6px; font-style: normal; font-size: var(--abv-tiny); font-weight: var(--abv-w-strong); letter-spacing: .6px; text-transform: uppercase; color: #2f7d55; }
.abv-alt.is-below { border-left: 3px solid var(--abv-orange); }
.abv-alt.is-below em { color: var(--abv-orange); }

.abv-details { border: 1px solid var(--abv-line); border-radius: var(--abv-radius); padding: var(--abv-4) var(--abv-5); background: #fff; }
.abv-details summary { cursor: pointer; list-style: none; }
.abv-details summary h4 { display: inline; }
.abv-details summary::-webkit-details-marker { display: none; }
.abv-details summary::after { content: '＋'; float: right; color: var(--abv-orange); font-weight: var(--abv-w-head); }
.abv-details[open] summary::after { content: '－'; }
.abv-kvs { margin-top: var(--abv-4); }
.abv-kv { display: flex; justify-content: space-between; gap: var(--abv-4); padding: 9px 0; border-bottom: 1px solid var(--abv-hairline); font-size: var(--abv-small); }
.abv-kv:last-child { border-bottom: 0; }
.abv-kv span { color: var(--abv-muted); }
.abv-kv b { color: var(--abv-ink-head); text-align: right; }
.abv-assume { margin-top: var(--abv-4); padding: var(--abv-4); background: var(--abv-tint); border-radius: var(--abv-radius); }
.abv-assume b { display: block; margin-bottom: var(--abv-2); color: var(--abv-ink-head); font-size: var(--abv-small); }
.abv-assume ul { margin: 0; padding-left: 18px; font-size: var(--abv-small); color: var(--abv-text); }
.abv-assume li { margin-bottom: 4px; }

.abv-cta { padding: var(--abv-6); background: var(--abv-bg-soft); border-radius: var(--abv-radius); }
.abv-cta__row { display: flex; gap: var(--abv-3); flex-wrap: wrap; margin-bottom: var(--abv-3); }

@media (max-width: 620px) {
  .abv-stats { grid-template-columns: 1fr; }
  .abv-cta__row .abv-btn, .abv-cta__row .abv-btn--ghost { flex: 1 1 100%; }
  .abv-kv { flex-direction: column; gap: 2px; }
  .abv-kv b { text-align: left; }
}

/* ---------------------------------------------------------------------------
   PROPERTY PLAN — real aerial and original schematic side by side, never
   overlaid, so a concept can't be mistaken for a measured roof plan.
------------------------------------------------------------------------- */
.abv-planrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--abv-4); margin-bottom: var(--abv-4); }
.abv-planmap, .abv-planschem { margin: 0; border: 1px solid var(--abv-line); border-radius: var(--abv-radius); overflow: hidden; background: #fff; }
.abv-planmap .abv-map { position: relative; inset: auto; width: 100%; aspect-ratio: 4 / 3; background: var(--abv-bg-soft); }
.abv-planmap figcaption { padding: var(--abv-3) var(--abv-4); font-size: var(--abv-small); color: var(--abv-muted); border-top: 1px solid var(--abv-hairline); }
.abv-planschem { display: grid; place-items: center; padding: var(--abv-3); }
.abv-schem { width: 100%; height: auto; }

.abv-legend { display: flex; flex-wrap: wrap; gap: var(--abv-4); margin-bottom: var(--abv-4); font-size: var(--abv-small); color: var(--abv-text); }
.abv-legend span { display: inline-flex; align-items: center; gap: 7px; }
.abv-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--abv-orange); }
.abv-sq { width: 14px; height: 14px; border-radius: 3px; background: var(--abv-blue); }
.abv-arr { width: 3px; height: 14px; background: var(--abv-orange); }

.abv-plan__lead { margin: 0 0 var(--abv-2); font-size: var(--abv-body); }
.abv-tips { margin: 0 0 var(--abv-3); padding-left: 20px; font-size: var(--abv-body); line-height: 1.6; }
.abv-tips li { margin-bottom: 5px; }

@media (max-width: 620px) {
  .abv-planrow { grid-template-columns: 1fr; }
  .abv-planmap .abv-map { aspect-ratio: 16 / 10; }
}

/* Action feedback + start-over */
.abv-error.is-mild { border-left-color: var(--abv-blue); background: rgba(57,147,223,.07); }
.abv-cta [aria-busy="true"] { opacity: .8; }
.abv-cta .abv-fine .abv-btn--quiet { padding: 4px 0; }

/* =============================================================================
   PROFESSIONAL VENTILATION WORKSPACE — Phase 18A
   =============================================================================
   Everything below is scoped to [data-abv-mode='professional']. The homeowner
   wizard above this line is untouched and cannot see any of it.

   WHY THE CLASS NAMES ARE DOUBLED. Markup carries both its historical name
   (.abv-pr, .abv-pstat, .abv-fan, .abv-kv …) and a new .abvp- name. The old
   names are now inert test hooks — the Phase 11-16 engineering suites read the
   engine's figures through them, and that contract is what proves a rebuild of
   this size changed presentation only. All styling hangs off .abvp-.

   THE COUNT THAT MATTERED. Before: 81 bordered elements, 19 distinct font
   sizes, 60 text runs under 11.5px, 94 uppercase runs, a six-column strip that
   broke "CONTINUOUS INTAKE AVAILABLE" into three lines and split "1,210" away
   from "in²". The fix is not smaller type. It is fewer containers, one type
   scale, and rows instead of columns.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   0. NEUTRALISE THE SHARED HOOKS
   Four class names are used by BOTH calculators (.abv-plan, .abv-plan__head,
   .abv-alt, .abv-alts). The homeowner rules above would otherwise leak in
   here — a border and a max-width the professional rail never asked for.
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='professional'] .abv-plan,
.abv-root[data-abv-mode='professional'] .abv-plan__head,
.abv-root[data-abv-mode='professional'] .abv-alt,
.abv-root[data-abv-mode='professional'] .abv-alts,
.abv-root[data-abv-mode='professional'] .abv-kv,
.abv-root[data-abv-mode='professional'] .abv-kvs {
  max-width: none; border: 0; border-radius: 0; padding: 0; margin: 0;
  background: none; box-shadow: none;
}

/* ---------------------------------------------------------------------------
   1. SHELL
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='professional'] .abvp,
.abv-root[data-abv-mode='professional'] .abvp * { box-sizing: border-box; }

/* [hidden] is a STATE, and a state must beat a layout rule. Every display
   value set below would otherwise out-specify the UA's [hidden] rule — which is
   exactly how the map's 'Loading the property…' overlay stayed painted over a
   perfectly good aerial. One guard, once, at the top. */
.abv-root[data-abv-mode='professional'] [hidden] { display: none !important; }

.abvp {
  max-width: var(--p-max);
  margin: 0 auto;
  padding: var(--p-4) var(--p-3) var(--p-5);
  color: var(--p-ink-2);
  font-size: var(--p-control);
  line-height: 1.6;
}

.abvp-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--p-3); flex-wrap: wrap;
  padding-bottom: var(--p-3); margin-bottom: var(--p-3);
  border-bottom: 2px solid var(--p-rule);
}
.abvp-head__id { min-width: 0; }
.abvp-title {
  margin: var(--p-1) 0 0; font-size: var(--p-title); font-weight: var(--p-w-head);
  line-height: 1.1; letter-spacing: -0.6px; color: var(--p-ink);
}
.abvp-head__sub { margin: var(--p-1) 0 0; font-size: var(--p-help); color: var(--p-ink-3); max-width: 62ch; }

/* Job identity chip — the property, never more than three lines. */
.abvp-jobchip {
  margin-left: auto; text-align: right; line-height: 1.4;
  padding: var(--p-1) 0 var(--p-1) var(--p-2);
  border-left: 3px solid var(--p-accent);
}
.abvp-jobchip b { display: block; font-size: var(--p-sub); font-weight: var(--p-w-sub); color: var(--p-ink); }
.abvp-jobchip span { display: block; font-size: var(--p-help); color: var(--p-ink-3); }
.abvp-jobchip em { display: block; font-style: normal; font-size: var(--p-help); color: var(--p-ink-2); }

/* ---- ONE principal container per major section -------------------------- */
.abvp-sec {
  background: var(--p-card);
  border: 1px solid var(--p-rule);
  border-radius: var(--p-radius);
  box-shadow: var(--p-shadow);
  margin-bottom: var(--p-3);
  overflow: hidden;
}
.abvp-sec[hidden] { display: none; }
.abvp-sec__head {
  display: flex; align-items: flex-start; gap: var(--p-2);
  padding: var(--p-3) var(--p-4);
  border-bottom: 1px solid var(--p-rule-2);
  background: var(--p-ground);
}
.abvp-sec__heading { min-width: 0; }
.abvp-sec__title {
  margin: 0; font-size: var(--p-section); font-weight: var(--p-w-head);
  line-height: 1.2; letter-spacing: -0.3px; color: var(--p-ink);
}
.abvp-sec__note { margin: var(--p-hair) 0 0; font-size: var(--p-help); color: var(--p-ink-3); max-width: 78ch; }
.abvp-sec__body { padding: var(--p-4); }

/* Step marker. Numeral in a navy chip, the rest in plain sentence case, so
   the workspace has a spine without another shouty label. */
.abvp-step { display: flex; align-items: center; gap: var(--p-1); margin: 3px 0 0; flex: none; }
.abvp-step__n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--p-navy); color: #fff;
  font-size: var(--p-label); font-weight: 700; line-height: 1;
}
.abvp-step__of { font-size: var(--p-help); color: var(--p-ink-3); }
.abvp-step--hero { margin: 0 0 var(--p-2); }
.abvp-step--hero .abvp-step__n { background: rgba(255,255,255,.16); color: #fff; }
.abvp-step--hero .abvp-step__of { color: rgba(255,255,255,.7); }

/* ---------------------------------------------------------------------------
   2. TYPE PRIMITIVES
   The eyebrow is the ONLY uppercase level in the workspace. It appears six
   times on a full page: the brand line, the recommendation, three verdicts and
   the layout label. That is a hierarchy level. Ninety-four was decoration.
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='professional'] .abvp-eyebrow {
  display: block; font-size: var(--p-eyebrow); font-weight: 700;
  letter-spacing: 1.6px; text-transform: uppercase; color: var(--p-ink-3);
  margin: 0;
}
.abvp-eyebrow--hero { color: rgba(255,255,255,.72); }

.abvp-grp__title {
  margin: 0 0 var(--p-2); padding-bottom: var(--p-1);
  font-size: var(--p-sub); font-weight: var(--p-w-sub); color: var(--p-ink);
  border-bottom: 1px solid var(--p-rule-2);
  display: flex; align-items: baseline; justify-content: flex-start; gap: var(--p-2);
}
/* Only where the trailing element is a live count, not a qualifier. */
.abvp-grp__title--split { justify-content: space-between; }
.abvp-grp__note { margin: 0 0 var(--p-2); }
.abvp-block__title {
  margin: 0 0 var(--p-2); font-size: var(--p-sub); font-weight: var(--p-w-sub); color: var(--p-ink);
}
.abv-root[data-abv-mode='professional'] .abvp-help {
  font-size: var(--p-help); font-weight: 400; font-style: normal;
  line-height: 1.6; color: var(--p-ink-3);
}
.abvp-opt {
  font-size: var(--p-help); font-weight: 400; color: var(--p-ink-3);
  text-transform: none; letter-spacing: normal;
}
.abvp-rule { height: 1px; background: var(--p-rule-2); margin: var(--p-3) 0; border: 0; }
/* VALIDATION IS RED. It was #b0402a — a brown-red that read as "advisory"
   next to genuinely orange advisories. An error has to be unmistakable. */
.abvp-err {
  display: flex; align-items: flex-start; gap: 6px;
  margin: 0 0 var(--p-2); font-size: var(--p-help); font-weight: 600; color: var(--p-err);
}
.abvp-err::before {
  content: '!'; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; margin-top: 1px; border-radius: 50%;
  background: var(--p-err); color: #fff; font-size: 11px; font-weight: 700; line-height: 1;
}
.abvp-err[hidden] { display: none; }

/* The field itself carries the state too — colour alone is never the signal,
   but a red edge is how you find the field the message is about. */
.abv-root[data-abv-mode='professional'] .is-invalid > .abvp-f__ctrl,
.abv-root[data-abv-mode='professional'] .abvp-f__unit.is-invalid,
.abv-root[data-abv-mode='professional'] .abvp-f__ctrl.is-invalid {
  border-color: var(--p-err-rule); background: var(--p-err-bg);
}
.abv-root[data-abv-mode='professional'] .abvp-mat.is-invalid,
.abv-root[data-abv-mode='professional'] .abvp-sw.is-invalid,
.abv-root[data-abv-mode='professional'] .abvp-seg.is-invalid {
  outline: 2px solid var(--p-err-rule); outline-offset: 4px; border-radius: var(--p-radius-sm);
}
.abvp-err[hidden] { display: none; }
.abvp-band {
  margin: var(--p-1) 0 var(--p-2); font-size: var(--p-help); font-weight: 600; color: var(--p-ink-2);
  background: rgba(57,147,223,.07); border-left: 3px solid var(--p-info-rule);
  padding: var(--p-1) var(--p-2); border-radius: 0 4px 4px 0;
}
.abvp-band[hidden] { display: none; }
.abv-root[data-abv-mode='professional'] .abvp-link {
  appearance: none; background: none; border: 0; padding: 0;
  font: inherit; font-size: var(--p-help); font-weight: 600;
  color: var(--p-focus); text-decoration: underline; cursor: pointer;
  /* The kit uppercases and letter-spaces every bare <button>. A link that
     reads "GO TO PLANNING" is the kit talking, not us. */
  text-transform: none; letter-spacing: normal; line-height: inherit;
}
.abv-root[data-abv-mode='professional'] .abvp-link:focus-visible {
  outline: 3px solid var(--p-focus); outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   3. FIELDS
   One control height everywhere, so rows line up across the three input
   groups without a single alignment hack.
------------------------------------------------------------------------- */
.abvp-f { display: block; min-width: 0; }
.abvp-f__label {
  display: block; margin-bottom: 6px;
  font-size: var(--p-label); font-weight: var(--p-w-label); color: var(--p-ink);
  text-transform: none; letter-spacing: normal; line-height: 1.35;
}
.abv-root[data-abv-mode='professional'] .abvp-f__ctrl {
  display: block; width: 100%; min-width: 0; height: var(--p-ctrl-h);
  padding: 0 var(--p-2);
  font: inherit; font-size: var(--p-control); font-weight: var(--p-w-val);
  color: var(--p-ink); background: #fff;
  border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm);
  transition: border-color var(--abv-dur-fast) var(--abv-ease);
}
.abv-root[data-abv-mode='professional'] select.abvp-f__ctrl {
  -webkit-appearance: none; appearance: none; padding-right: 38px;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none' stroke='%23667283' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
}
.abv-root[data-abv-mode='professional'] .abvp-f__ctrl:hover { border-color: #b9c2cd; }
.abv-root[data-abv-mode='professional'] .abvp-f__ctrl:focus-visible,
.abv-root[data-abv-mode='professional'] .abvp-f__ctrl:focus {
  outline: 3px solid var(--p-focus); outline-offset: 0; border-color: var(--p-focus);
}
.abv-root[data-abv-mode='professional'] .abvp-f__ctrl:disabled { background: var(--p-ground); color: var(--p-ink-3); }
.abvp-f .abvp-help { display: block; margin-top: 6px; }

/* Unit suffix. A DIV-free flex wrapper with the input unstyled inside, so the
   figure and its unit can never separate. The old build let "6,000" and
   "SQ FT" land on two lines. */
.abvp-f__unit {
  display: flex; align-items: center; gap: var(--p-1);
  height: var(--p-ctrl-h); padding-right: var(--p-2);
  background: #fff; border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm);
}
.abv-root[data-abv-mode='professional'] .abvp-f__unit .abvp-f__ctrl {
  flex: 1 1 auto; min-width: 0; height: 100%;
  border: 0; border-radius: 0; background: transparent;
}
.abv-root[data-abv-mode='professional'] .abvp-f__unit:focus-within {
  outline: 3px solid var(--p-focus); border-color: var(--p-focus);
}
.abv-root[data-abv-mode='professional'] .abvp-f__unit .abvp-f__ctrl:focus,
.abv-root[data-abv-mode='professional'] .abvp-f__unit .abvp-f__ctrl:focus-visible { outline: 0; }
.abvp-f__suffix {
  flex: none; font-style: normal; font-size: var(--p-help);
  font-weight: 600; color: var(--p-ink-3); white-space: nowrap;
}
.abvp-f__pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--p-2); }

/* Search field — the only control that is wider than its group. */
.abv-root[data-abv-mode='professional'] .abvp-search {
  display: flex; align-items: center; gap: var(--p-1);
  height: var(--p-ctrl-h); padding: 0 var(--p-2);
  background: #fff; border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm);
  color: var(--p-ink-3); position: relative; inset: auto; box-shadow: none; max-width: none;
}
.abv-root[data-abv-mode='professional'] .abvp-search .abvp-f__ctrl {
  border: 0; height: 100%; padding: 0; background: transparent;
}
.abv-root[data-abv-mode='professional'] .abvp-search:focus-within {
  outline: 3px solid var(--p-focus); border-color: var(--p-focus);
}
.abv-root[data-abv-mode='professional'] .abvp-search .abvp-f__ctrl:focus,
.abv-root[data-abv-mode='professional'] .abvp-search .abvp-f__ctrl:focus-visible { outline: 0; }

/* The legacy .abvp-seg segmented component is RETIRED. It has been fully
   superseded by the choice-chip system at the end of this file, which owns
   this control in both calculators. Removed rather than overridden: it was
   still supplying a #f4f6f8 grey hover, a 1px shared right border, an inline
   tick glyph glued in front of the label, and a 3-column grid that
   never applied — every one of them something the chip rules then had to
   fight. An override stack that deep is how the control ended up looking
   half-finished in the first place. */

.abvp-check { display: flex; align-items: center; gap: var(--p-1); margin: var(--p-1) 0; font-size: var(--p-control); color: var(--p-ink); }
.abvp-check[hidden] { display: none; }
.abvp-check input { width: 18px; height: 18px; accent-color: var(--p-accent); flex: none; margin: 0; }

/* ---------------------------------------------------------------------------
   4. THE BUTTON SYSTEM
   The Elementor kit (post-1333) sets padding:32px 48px and white-space:nowrap
   on every bare <button>. That is why "Calculate system" rendered 80px tall in
   17.6px type. Three-class specificity keeps every calculator button off that
   path WITHOUT touching the global kit, and without reaching into .abv-map,
   where Google owns the controls.
------------------------------------------------------------------------- */
/* NO element qualifier here: 'button.abvp-btn' would out-specify every
   .abvp-btn--* variant below and repaint the primary action white. */
.abv-root[data-abv-mode='professional'] .abvp-btn {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--p-1);
  min-height: var(--ab-cta-h);
  padding: var(--ab-cta-pad-y) var(--ab-cta-pad-x);
  font: inherit; font-family: var(--abv-font);
  font-size: var(--ab-cta-size); font-weight: 700; line-height: var(--ab-cta-lh);
  letter-spacing: var(--ab-cta-ls); text-transform: uppercase; text-decoration: none;
  /* The site breaks on WORDS, not anywhere. `anywhere` was splitting
     "Ventilation" mid-word once caps + tracking widened the label. */
  white-space: normal; overflow-wrap: break-word;
  width: auto; max-width: 100%;
  color: var(--p-ink); background: #fff;
  border: var(--ab-cta-bw) solid var(--p-rule); border-radius: var(--ab-cta-radius);
  box-shadow: none;
  cursor: pointer;
  transition: background-color var(--ab-cta-dur) var(--abv-ease),
              border-color var(--ab-cta-dur) var(--abv-ease),
              color var(--ab-cta-dur) var(--abv-ease);
}
/* THE PRESS. The site kills transform on :hover and :focus — deliberately —
   but says nothing about :active, and a button that does not acknowledge the
   click is the single thing that makes an interface feel dead. 1px, once. */
.abv-root[data-abv-mode='professional'] .abvp-btn:active:not(:disabled) {
  transform: translateY(1px);
}
@media (prefers-reduced-motion: reduce) {
  .abv-root[data-abv-mode='professional'] .abvp-btn:active:not(:disabled) { transform: none; }
}
/* =========================================================================
   THE BRAND RULE — AN ORANGE BACKGROUND ALWAYS CARRIES WHITE
   =========================================================================
   Orange background with navy text is banned everywhere in this calculator.
   The rule is enforced structurally, not by discipline: every declaration
   below that paints `--p-accent` sets `color: #fff` in the SAME block, so
   there is no cascade path that can deliver one without the other. A hover
   rule that set only a background — leaving the foreground to whatever won
   earlier — is exactly how that pairing gets broken.

   qa/p18btn.mjs forces every state on every button and FAILS if any resolved
   orange background is paired with non-white text.

   Hover is the brand gesture: every fillable button turns orange on hover.
   Focus is deliberately independent — a blue outline, never a fill — so a
   keyboard user can always tell focus from hover.
   ====================================================================== */
.abv-root[data-abv-mode='professional'] .abvp-btn--primary {
  background: var(--p-btn-fill); border-color: var(--p-btn-fill); color: #fff;
}
/* THE PRIMARY HAD NO HOVER STATE AT ALL. --p-btn-fill and
   --p-btn-fill-hover both resolve to the one navy, so the loudest control in
   the product — "Calculate system", "Verify & unlock ProFlow" — rendered
   identical pixels at rest and on hover.

   The fix uses the accent the way the approved calculator palette says to:
   "Breeze Orange ... marks selection, emphasis and hover instead". The navy
   fill and its white label are untouched, so the resting 18.88:1 contrast
   survives and no state ever pairs an orange fill with a text label. */
.abv-root[data-abv-mode='professional'] .abvp-btn--primary:hover:not(:disabled),
.abv-root[data-abv-mode='professional'] .abvp-btn--primary:active:not(:disabled) {
  background: var(--p-btn-fill-hover); border-color: var(--p-accent); color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-btn--secondary {
  background: #fff; color: var(--p-navy); border-color: var(--p-rule);
}
/* Secondary had no hover feedback at all before this pass — default, hover,
   focus and active resolved to identical pixels. */
.abv-root[data-abv-mode='professional'] .abvp-btn--secondary:hover:not(:disabled) {
  background: var(--p-btn-fill); border-color: var(--p-btn-fill); color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-btn--secondary:active:not(:disabled) {
  background: var(--p-btn-fill-hover); border-color: var(--p-btn-fill-hover); color: #fff;
}
/* THE TERTIARY IS A TEXT LINK, NOT A PILL. This is what carries every
   "Continue with the Ventilation Calculator" — the deliberate quiet option
   beside a loud primary. A third tracked-caps pill would give the view three
   equally loud controls, which is exactly what the CTA hierarchy forbids, so
   this variant opts out of the caps and the tracking on purpose. */
.abv-root[data-abv-mode='professional'] .abvp-btn--quiet {
  background: none; border-color: transparent; color: var(--p-ink-3);
  text-transform: none; letter-spacing: normal; font-size: var(--p-label);
  text-decoration: underline; padding-left: 0; padding-right: 0; min-height: var(--p-btn-mini);
}
.abv-root[data-abv-mode='professional'] .abvp-btn--quiet:hover:not(:disabled) { color: var(--p-ink); }
.abv-root[data-abv-mode='professional'] .abvp-btn--lg {
  min-height: var(--ab-cta-lg-h);
  padding: var(--ab-cta-lg-pad-y) var(--ab-cta-lg-pad-x);
  font-size: var(--ab-cta-lg-size);
}
.abv-root[data-abv-mode='professional'] .abvp-btn--sm,
.abv-root[data-abv-mode='professional'] .abvp-btn--mini {
  min-height: var(--ab-cta-sm-h);
  padding: var(--ab-cta-sm-pad-y) var(--ab-cta-sm-pad-x);
  font-size: var(--ab-cta-sm-size); letter-spacing: var(--ab-cta-sm-ls);
}
.abv-root[data-abv-mode='professional'] .abvp-btn--ghostmini { color: var(--p-ink-3); }
/* Mini buttons had no hover state either — seven planning controls that gave
   no feedback at all. Same brand gesture, same pairing. */
.abv-root[data-abv-mode='professional'] .abvp-btn--mini:hover:not(:disabled),
.abv-root[data-abv-mode='professional'] .abvp-btn--ghostmini:hover:not(:disabled) {
  background: var(--p-btn-fill); border-color: var(--p-btn-fill); color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-btn--mini:active:not(:disabled),
.abv-root[data-abv-mode='professional'] .abvp-btn--ghostmini:active:not(:disabled) {
  background: var(--p-btn-fill-hover); border-color: var(--p-btn-fill-hover); color: #fff;
}
/* The engaged toggle: "Draw outline" while drawing, "Click the map…" while
   placing. Orange because it is an ACTIVE STATE, white because it is orange. */
.abv-root[data-abv-mode='professional'] .abvp-btn--mini.is-on,
.abv-root[data-abv-mode='professional'] .abvp-btn--mini.is-on:hover {
  background: var(--p-btn-fill); border-color: var(--p-btn-fill); color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-btn:disabled,
.abv-root[data-abv-mode='professional'] .abvp-btn[aria-disabled='true'] {
  opacity: .45; cursor: not-allowed;
}
.abv-root[data-abv-mode='professional'] .abvp-btn:focus-visible {
  outline: 3px solid var(--p-focus); outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   5. ALERTS — the second thing orange is allowed to mean
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='professional'] .abvp-alert {
  background: rgba(57,147,223,.07); border: 0; border-left: 3px solid var(--p-info-rule);
  border-radius: 0 var(--p-radius-sm) var(--p-radius-sm) 0;
  padding: var(--p-2) var(--p-3); margin: 0 0 var(--p-3); color: var(--p-ink-2);
}
.abv-root[data-abv-mode='professional'] .abvp-alert b {
  display: block; font-size: var(--p-control); font-weight: 700; color: var(--p-ink); margin-bottom: 4px;
}
.abv-root[data-abv-mode='professional'] .abvp-alert p {
  margin: 0; font-size: var(--p-help); line-height: 1.65;
}
.abv-root[data-abv-mode='professional'] .abvp-alert--accent {
  background: var(--p-accent-bg); border-left-color: var(--p-accent);
}
.abv-root[data-abv-mode='professional'] .abvp-alert--slim {
  font-size: var(--p-help); padding: var(--p-1) var(--p-2); margin-bottom: var(--p-2);
}
.abvp-stale {
  background: var(--p-accent-bg); border-left: 3px solid var(--p-accent);
  color: var(--p-ink); font-size: var(--p-help); font-weight: 600;
  padding: var(--p-2) var(--p-3); margin: 0 0 var(--p-2);
}
.abvp-stale[hidden] { display: none; }
.abv-root[data-abv-mode='professional'] .abvp-error {
  font-size: var(--p-help); font-weight: 600; color: var(--p-err); margin-top: var(--p-1);
  background: none; border: 0; padding: 0;
}

/* ---------------------------------------------------------------------------
   6. KEY / VALUE ROWS
   THE central correction. A row has a label on the left and a figure on the
   right, and it cannot become a micro-column, because it is not a column. Two
   columns of ROWS at desk width, one below 780. A figure never wraps.
------------------------------------------------------------------------- */
/* Three-class specificity throughout: these elements also carry .abv-kv, the
   Phase-14 read hook, and the HOMEOWNER stylesheet above already defines
   .abv-kv as a nowrap flex row. Matching its specificity is not enough — a
   single-class rule here loses to whichever declaration happens to come later
   in a 1300-line file. */
.abvp-rows { display: grid; grid-template-columns: 1fr; column-gap: var(--p-4); }
.abvp-rows--2 { grid-template-columns: 1fr 1fr; }
.abv-root[data-abv-mode='professional'] .abvp-row {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: var(--p-2); min-width: 0;
  padding: 11px 0; margin: 0; border: 0; border-bottom: 1px solid var(--p-rule-2);
  font-size: var(--p-label); background: none;
}
.abv-root[data-abv-mode='professional'] .abvp-row__k {
  flex: 1 1 auto; min-width: 0; display: block;
  font-size: var(--p-label); font-weight: var(--p-w-label); color: var(--p-ink-2);
  text-transform: none; letter-spacing: normal;
}
.abv-root[data-abv-mode='professional'] .abvp-row__v {
  flex: 0 1 auto; min-width: 0; text-align: right; max-width: 70%;
}
.abv-root[data-abv-mode='professional'] .abvp-row__v b {
  display: block; font-size: var(--p-sub); font-weight: 700; color: var(--p-ink);
  white-space: nowrap; font-variant-numeric: tabular-nums; text-align: inherit;
}
.abv-root[data-abv-mode='professional'] .abvp-row__v small {
  display: block; margin-top: 2px; font-size: var(--p-help); font-weight: 400;
  color: var(--p-ink-3); line-height: 1.45; overflow-wrap: anywhere;
}
.abv-root[data-abv-mode='professional'] .abvp-row.is-ok .abvp-row__v b { color: var(--p-ok); }
/* Navy, not orange. A shortfall figure has to be READ; the orange lives in
   the block's left rule and its verdict mark, where it costs no legibility. */
.abv-root[data-abv-mode='professional'] .abvp-row.is-short .abvp-row__v b { color: var(--p-ink); }

/* ---------------------------------------------------------------------------
   7. STEP 1 — PROJECT & PROPERTY
------------------------------------------------------------------------- */
.abvp-ident { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: var(--p-3); align-items: end; }
.abvp-ident__find { min-width: 0; }
.abv-root[data-abv-mode='professional'] .abvp-ident__found {
  display: flex; align-items: center; gap: var(--p-2); min-width: 0;
  margin: 0; padding: var(--p-2); background: var(--p-ok-bg);
  border: 1px solid var(--p-ok-rule); border-radius: var(--p-radius-sm);
}
.abvp-ident__found[hidden] { display: none; }
.abvp-found__tick {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--p-ok); color: #fff; font-size: var(--p-label); font-weight: 700;
}
.abvp-found__txt { min-width: 0; }
.abv-root[data-abv-mode='professional'] .abvp-found__txt b {
  display: block; font-size: var(--p-control); font-weight: 700; color: var(--p-ink);
}
.abv-root[data-abv-mode='professional'] .abvp-found__txt span {
  display: block; font-size: var(--p-help); color: var(--p-ink-2);
}

.abvp-fields { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--p-2) var(--p-3); }

.abvp-prop__top {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--p-2); flex-wrap: wrap; margin-bottom: var(--p-2);
}
.abvp-prop__top .abvp-grp__title { border: 0; padding: 0; margin: 0; flex: none; }
.abv-root[data-abv-mode='professional'] .abvp-prop__top .abvp-help { flex: 1 1 340px; text-align: right; }

/* THE MAP. One node, two homes. */
.abv-root[data-abv-mode='professional'] .abvp-map {
  position: relative; width: 100%;
  border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm);
  overflow: hidden; background: var(--p-ground);
}
.abv-root[data-abv-mode='professional'] .abvp-prop .abvp-map { aspect-ratio: 21 / 9; min-height: 340px; }
.abv-root[data-abv-mode='professional'] .abvp-map .abv-map { position: absolute; inset: 0; width: 100%; height: 100%; }
.abv-root[data-abv-mode='professional'] .abvp-mapstate {
  position: absolute; inset: 0; display: grid; align-content: center; justify-items: center;
  gap: var(--p-1); padding: var(--p-3); text-align: center; background: var(--p-ground);
}
.abv-root[data-abv-mode='professional'] .abvp-mapstate b { font-size: var(--p-sub); font-weight: 700; color: var(--p-ink); }
.abv-root[data-abv-mode='professional'] .abvp-mapstate p { margin: 0; font-size: var(--p-help); color: var(--p-ink-3); }
.abvp-moved {
  margin: var(--p-2) 0 0; padding: var(--p-2) var(--p-3);
  background: rgba(57,147,223,.07); border-left: 3px solid var(--p-info-rule);
  border-radius: 0 var(--p-radius-sm) var(--p-radius-sm) 0;
  font-size: var(--p-help); color: var(--p-ink-2);
}
.abvp-moved[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   8. STEP 2 — DESIGN INPUTS
   Three groups, three columns, one control height. Rows align across the
   groups because every control is the same height, not because of a hack.
------------------------------------------------------------------------- */
/* Not three equal columns: attic asks two questions, roof asks four and system
   carries the longest option strings in the tool. Weighting the tracks is what
   stops "Best fit — may mix two adjacent power tiers" from clipping. */
.abvp-groups { display: grid; grid-template-columns: 0.9fr 1.15fr 1.15fr; gap: var(--p-3) var(--p-4); }
.abvp-grp { min-width: 0; }
.abvp-grp__fields { display: grid; gap: var(--p-2); align-content: start; }

.abvp-est { margin: 0; }
.abv-root[data-abv-mode='professional'] .abvp-est__summary {
  cursor: pointer; font-size: var(--p-label); font-weight: 600; color: var(--p-focus);
  padding: var(--p-1) 0; list-style-position: inside;
}
.abvp-est__summary:focus-visible { outline: 3px solid var(--p-focus); outline-offset: 2px; }
.abvp-est__body {
  display: grid; gap: var(--p-2); margin-top: var(--p-1);
  padding: var(--p-2); background: var(--p-ground); border-radius: var(--p-radius-sm);
}
.abvp-est__out {
  display: flex; align-items: center; justify-content: space-between; gap: var(--p-2); flex-wrap: wrap;
  padding-top: var(--p-2); border-top: 1px solid var(--p-rule);
}
.abvp-est__out[hidden] { display: none; }
.abvp-est__fig b { display: block; font-size: var(--p-metric-2); font-weight: var(--p-w-head); color: var(--p-ink); }
.abvp-est__fig small { display: block; font-size: var(--p-help); color: var(--p-ink-3); }

/* The calculate bar closes step 2 — a band, not a floating button. */
.abvp-calcbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--p-3); flex-wrap: wrap;
  margin: var(--p-4) calc(var(--p-4) * -1) calc(var(--p-4) * -1);
  padding: var(--p-3) var(--p-4);
  background: var(--p-ground); border-top: 1px solid var(--p-rule);
}
.abvp-calcbar__txt b { display: block; font-size: var(--p-sub); font-weight: 700; color: var(--p-ink); }
.abv-root[data-abv-mode='professional'] .abvp-calcbar__txt p { margin: 2px 0 0; }
.abvp-calcbar .abvp-btn { flex: none; min-width: 240px; }

/* ---------------------------------------------------------------------------
   9. STEP 3 — RECOMMENDED SYSTEM
   The strongest surface on the page, and it costs no accent: navy ground,
   white type, five metrics that read from across a truck cab.
------------------------------------------------------------------------- */
.abvp-sec--hero { border-color: var(--p-navy); }
.abvp-sec--hero .abvp-sec__body { padding: 0; }
.abvp-rec.is-stale .abvp-rec__head,
.abvp-rec.is-stale .abvp-block { opacity: .6; }
.abvp-rec__head {
  background: var(--p-navy); color: #fff;
  padding: var(--p-4) var(--p-4) 0;
}
.abvp-rec__top { display: flex; align-items: center; gap: var(--p-2); margin-bottom: var(--p-1); }
.abvp-rec__top .abvp-step { margin: 0; }
.abvp-rec__name {
  margin: var(--p-1) 0 var(--p-2);
  font-size: var(--p-title); font-weight: var(--p-w-head);
  line-height: 1.12; letter-spacing: -0.5px; color: #fff;
}
.abvp-basis { display: flex; flex-wrap: wrap; gap: var(--p-1); list-style: none; margin: 0 0 var(--p-3); padding: 0; }
.abvp-basis li {
  font-size: var(--p-help); color: rgba(255,255,255,.88);
  background: rgba(255,255,255,.1); border-radius: 999px; padding: 4px 12px;
}

.abvp-metrics {
  display: flex; flex-wrap: wrap; gap: 1px;
  background: rgba(255,255,255,.14);
  margin: 0 calc(var(--p-4) * -1); padding: 0;
  border-top: 1px solid rgba(255,255,255,.14);
}
/* Two lead metrics on the first row, three on the second. Explicit bases, not
   auto-fit: auto-fit put four on one row and orphaned the fifth across the
   whole width, which reads as a mistake rather than a hierarchy. */
.abv-root[data-abv-mode='professional'] .abvp-metric {
  order: 2; flex: 1 1 calc(33.333% - 1px); min-width: 190px;
  background: var(--p-navy); padding: var(--p-3) var(--p-4);
  border: 0;
}
/* Promoted in the hero, NOT moved in the DOM — .abv-pstat order is a contract
   the Phase-13 suite reads by index. */
.abv-root[data-abv-mode='professional'] .abvp-metric.is-lead {
  order: 1; flex: 1 1 calc(50% - 1px); background: var(--p-navy-2);
}
/* % of target is one of the figures the brief singles out, so it is a marked
   value, not a footnote. */
.abvp-metric__chip {
  display: inline-block; margin-top: 8px;
  font-size: var(--p-label); font-weight: 700; line-height: 1.3;
  padding: 3px 12px; border-radius: 999px;
  background: rgba(255,255,255,.14); color: #fff;
}
.abvp-metric__chip.is-ok { background: rgba(122,201,155,.2); color: #a9e3c0; }
.abvp-metric__chip.is-short { background: rgba(239,125,72,.24); color: #ffbf9d; }
.abvp-metric__label {
  display: block; font-size: var(--p-label); font-weight: var(--p-w-label);
  color: rgba(255,255,255,.72); text-transform: none; letter-spacing: normal;
}
.abv-root[data-abv-mode='professional'] .abvp-metric__val {
  display: block; margin-top: 6px;
  font-size: var(--p-metric-2); font-weight: var(--p-w-head); line-height: 1.05;
  color: #fff; font-variant-numeric: tabular-nums; overflow-wrap: normal;
}
.abv-root[data-abv-mode='professional'] .abvp-metric.is-lead .abvp-metric__val { font-size: var(--p-metric); }
.abv-root[data-abv-mode='professional'] .abvp-metric__note {
  display: block; margin-top: 4px; font-size: var(--p-help); color: rgba(255,255,255,.78);
}

.abvp-rec .abvp-alert { margin: var(--p-3) var(--p-4) 0; }
.abvp-block { padding: var(--p-4); }
.abv-root[data-abv-mode='professional'] .abvp-block__note { margin: var(--p-2) 0 0; }

/* Equipment schedule — a row per line, never a four-column table. */
.abvp-sched { display: grid; }
.abvp-sched__row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px var(--p-3); align-items: baseline;
  padding: var(--p-2) 0; border-bottom: 1px solid var(--p-rule-2);
}
.abvp-sched__row:last-child { border-bottom: 0; }
.abv-root[data-abv-mode='professional'] .abvp-sched__row > b {
  grid-column: 1; font-size: var(--p-sub); font-weight: 700; color: var(--p-ink);
}
.abv-root[data-abv-mode='professional'] .abvp-sched__row > code {
  grid-column: 2; grid-row: 1; justify-self: end;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--p-label);
  background: var(--p-ground); border-radius: 4px; padding: 4px 10px;
  color: var(--p-navy); white-space: nowrap;
}
.abvp-sched__spec, .abvp-sched__mount {
  grid-column: 1 / -1; font-size: var(--p-help); color: var(--p-ink-3); line-height: 1.55;
}

/* ---------------------------------------------------------------------------
   10. STEP 4 — REVIEW ANOTHER SYSTEM
   Deliberately quieter than step 3. No navy, no hero metric, no accent unless
   an alternate is actually pinned.
------------------------------------------------------------------------- */
.abvp-review { display: grid; gap: var(--p-4); }
.abvp-review__pick { display: grid; gap: var(--p-2); }
.abvp-f--lead { max-width: 520px; }
.abv-root[data-abv-mode='professional'] .abvp-review__note { margin: 0; max-width: 78ch; }
.abvp-review__figs { padding-left: var(--p-2); border-left: 3px solid var(--p-rule); }
.abvp-review.is-alt .abvp-review__figs { border-left-color: var(--p-accent); }

.abvp-alts { list-style: none; display: grid; }
.abv-root[data-abv-mode='professional'] .abvp-alt {
  padding: var(--p-2) 0 var(--p-2) var(--p-2);
  border-bottom: 1px solid var(--p-rule-2); border-left: 3px solid transparent;
}
.abv-root[data-abv-mode='professional'] .abvp-alt:last-child { border-bottom: 0; }
.abv-root[data-abv-mode='professional'] .abvp-alt.is-below { border-left-color: var(--p-accent); background: var(--p-accent-bg); }
.abvp-alt__top { display: flex; justify-content: space-between; gap: var(--p-2); flex-wrap: wrap; align-items: baseline; }
.abv-root[data-abv-mode='professional'] .abvp-alt__top > b {
  font-size: var(--p-sub); font-weight: 700; color: var(--p-ink);
}
.abv-root[data-abv-mode='professional'] .abvp-alt__top > span {
  font-size: var(--p-help); color: var(--p-ink-2); white-space: nowrap;
}
.abvp-alt__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.abv-root[data-abv-mode='professional'] .abvp-alt__tags > em {
  font-style: normal; font-size: var(--p-help); font-weight: 600;
  letter-spacing: normal; text-transform: none;
  padding: 3px 10px; border-radius: 999px; background: var(--p-ground); color: var(--p-ink-2);
}
.abv-root[data-abv-mode='professional'] .abvp-alt__tags > em.is-good { background: var(--p-ok-bg); color: var(--p-ok); }
.abv-root[data-abv-mode='professional'] .abvp-alt__tags > em.is-warn { background: var(--p-accent-bg); color: var(--p-ink); }
/* TEXT is never the info blue. A mid-blue word sitting beside navy words
   reads as a second, slightly-wrong navy — the drift this pass removes. The
   info blue survives only as a PANEL ACCENT (left rule), where it is a
   semantic marker rather than a near-miss of the brand colour. */
.abv-root[data-abv-mode='professional'] .abvp-alt__tags > em.is-note { background: rgba(57,147,223,.07); color: var(--abv-navy); }

/* ---------------------------------------------------------------------------
   11. STEP 5 — VENTILATION ANALYSIS
------------------------------------------------------------------------- */
.abvp-vinputs { display: grid; gap: var(--p-3); }
.abvp-scope {
  background: rgba(57,147,223,.07); border-left: 3px solid var(--abv-blue);
  border-radius: 0 var(--p-radius-sm) var(--p-radius-sm) 0;
  padding: var(--p-2) var(--p-3); font-size: var(--p-help); line-height: 1.65; color: var(--p-ink-2);
}
.abvp-scope b { color: var(--p-ink); }
.abvp-vbasis { max-width: 520px; }
.abvp-vgroup { display: grid; gap: 0; }
.abv-root[data-abv-mode='professional'] .abvp-vgroup .abvp-grp__title { margin-bottom: var(--p-2); }

/* One hairline per family instead of one bordered box per family. */
.abv-root[data-abv-mode='professional'] .abvp-fam {
  border: 0; border-bottom: 1px solid var(--p-rule-2); border-radius: 0;
  margin: 0; padding: var(--p-1) 0;
}
.abvp-fam__head {
  display: flex; align-items: center; gap: var(--p-1);
  padding: var(--p-1) 0; cursor: pointer; margin: 0;
}
.abvp-fam__head input { width: 18px; height: 18px; accent-color: var(--p-accent); flex: none; margin: 0; }
.abvp-fam__title { font-size: var(--p-control); font-weight: 600; color: var(--p-ink); }
.abv-root[data-abv-mode='professional'] .abvp-fam.is-on .abvp-fam__title { font-weight: 700; }
.abv-root[data-abv-mode='professional'] .abvp-fam__note { margin: 0 0 var(--p-1) 26px; }
.abvp-fam__body {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--p-2); padding: var(--p-1) 0 var(--p-2) 26px;
}
.abvp-fam__body[hidden] { display: none; }
.abv-root[data-abv-mode='professional'] .abvp-src {
  color: var(--p-focus); font-size: var(--p-help); text-decoration: underline;
}

/* ---- the three verdicts ------------------------------------------------- */
.abvp-verdicts { display: grid; gap: var(--p-4); margin-top: var(--p-4); padding-top: var(--p-3); border-top: 2px solid var(--p-rule); }
.abvp-fanside, .abvp-codeside { display: grid; gap: var(--p-4); }
.abv-root[data-abv-mode='professional'] .abvp-vd__ctx {
  margin: 0; font-size: var(--p-help); color: var(--p-ink-2);
}
.abvp-vd__ctx b { color: var(--p-ink); }

/* CONCLUSION FIRST. Verdict, then headline, then the arithmetic. */
.abvp-vd { border-left: 4px solid var(--p-rule); padding-left: var(--p-3); }
.abvp-vd.is-ok { border-left-color: var(--p-ok); }
.abvp-vd.is-short { border-left-color: var(--p-accent); }
.abvp-vd.is-empty { border-left-color: var(--p-rule); }
.abvp-vd__head { margin-bottom: var(--p-2); }
.abvp-vd__eyebrow { margin-bottom: var(--p-1); }
.abvp-vd__verdict {
  display: flex; align-items: center; gap: var(--p-1);
  margin: 0; font-size: var(--p-section); font-weight: var(--p-w-head);
  line-height: 1.2; color: var(--p-ink);
}
.abvp-vd__mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  font-size: var(--p-label); font-weight: 700; color: #fff; background: var(--p-ink-3);
}
.abvp-vd.is-ok .abvp-vd__mark { background: var(--p-ok); }
.abvp-vd.is-short .abvp-vd__mark { background: var(--p-accent); }
.abvp-vd.is-short .abvp-vd__verdict { color: var(--p-ink); }
.abvp-vd__headline {
  margin: var(--p-1) 0 0; font-size: var(--p-sub); font-weight: 600;
  line-height: 1.5; color: var(--p-ink-2); max-width: 70ch;
}
.abv-root[data-abv-mode='professional'] .abvp-vd__advice {
  margin: var(--p-2) 0 0; font-size: var(--p-help); line-height: 1.65;
  color: var(--p-ink-2); max-width: 82ch;
}
.abvp-vd__fine {
  margin: var(--p-2) 0 0; font-size: var(--p-help); font-weight: 600;
  color: var(--p-ink-3); line-height: 1.6;
}

/* ---------------------------------------------------------------------------
   12. STEP 6 — PROPERTY & FAN PLANNING
   One workspace: the aerial on the left holds still while the rail scrolls.
------------------------------------------------------------------------- */
.abvp-sec--plan .abvp-sec__body { padding: var(--p-3); }
.abvp-plan { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--p-3); align-items: stretch; }
/* The canvas cell is a panel that runs the full height of the rail, and the
   aerial is sticky INSIDE it. Sticking the cell instead left a bare white
   column under the map that read as missing content rather than as a map that
   follows you. A planning workspace where the map scrolls away is two screens,
   not one, so sticky stays — it just needs a floor to sit on. */
.abvp-plan__canvas {
  min-width: 0; background: var(--p-ground);
  border-radius: var(--p-radius-sm); padding: var(--p-1);
}
.abv-root[data-abv-mode='professional'] .abvp-plan__canvas .abvp-map {
  position: sticky; top: var(--p-2); aspect-ratio: 5 / 6; min-height: 640px;
}
.abvp-plan__rail { min-width: 0; display: grid; gap: var(--p-3); }

.abvp-rail { display: grid; gap: var(--p-3); }
.abvp-rail__head { display: grid; gap: 2px; }
.abvp-rail__name { margin: var(--p-hair) 0 0; font-size: var(--p-section); font-weight: var(--p-w-head); color: var(--p-ink); line-height: 1.2; }
.abv-root[data-abv-mode='professional'] .abvp-rail__note { margin: var(--p-2) 0 0; }
.abvp-railgrp { display: grid; gap: var(--p-2); }
.abvp-railgrp--notes { padding-top: var(--p-2); border-top: 1px solid var(--p-rule-2); }
.abvp-count {
  flex: none; font-size: var(--p-help); font-weight: 600; color: var(--p-ink);
  background: var(--p-accent-bg); border-radius: 999px; padding: 3px 12px;
}
.abvp-count.is-done { color: var(--p-ok); background: var(--p-ok-bg); }
.abvp-toolbar { display: flex; flex-wrap: wrap; gap: var(--p-1); }
.abvp-status {
  margin: 0; font-size: var(--p-help); font-weight: 600; color: var(--p-navy);
  background: var(--p-ground); border-radius: var(--p-radius-sm); padding: var(--p-1) var(--p-2);
}

/* A fan is a row, not a card. */
.abvp-fans { list-style: none; margin: 0; padding: 0; display: grid; }
.abv-root[data-abv-mode='professional'] .abvp-fan {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--p-1) var(--p-2); align-items: center;
  padding: var(--p-2) 0 var(--p-2) var(--p-1);
  border: 0; border-bottom: 1px solid var(--p-rule-2); border-left: 3px solid transparent;
  border-radius: 0; background: none;
}
.abv-root[data-abv-mode='professional'] .abvp-fan.is-placed { border-left-color: var(--p-ok); }
.abv-root[data-abv-mode='professional'] .abvp-fan.is-target { border-left-color: var(--p-accent); background: var(--p-accent-bg); }
.abvp-fan__id {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; height: 34px; padding: 0 8px; border-radius: var(--p-radius-sm);
  background: var(--p-navy); color: #fff; font-size: var(--p-label); font-weight: 700;
}
.abvp-fan__id.is-gable { background: var(--p-accent); }
.abvp-fan__body { min-width: 0; }
.abv-root[data-abv-mode='professional'] .abvp-fan__body b {
  display: block; font-size: var(--p-control); font-weight: 700; color: var(--p-ink); overflow-wrap: anywhere;
}
.abv-root[data-abv-mode='professional'] .abvp-fan__body em {
  display: block; font-style: normal; font-size: var(--p-help); color: var(--p-ink-3); overflow-wrap: anywhere;
}
.abvp-fan__state {
  font-size: var(--p-help); font-weight: 600; color: var(--p-ink-3);
  text-transform: none; letter-spacing: normal; white-space: nowrap;
}
.abv-root[data-abv-mode='professional'] .abvp-fan.is-placed .abvp-fan__state { color: var(--p-ok); }
/* Aligned under the model name, not under the ID chip. */
.abvp-fan__act { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: var(--p-1); }
.abv-root[data-abv-mode='professional'] .abvp-railgrp--notes .abv-plan__guide { margin: 0 0 var(--p-2); }
.abv-root[data-abv-mode='professional'] .abvp-railgrp--notes .abv-plan__guide:last-of-type { margin-bottom: 0; }

/* ---------------------------------------------------------------------------
   13. STEP 7 — PROPOSAL
   Completion of the workflow, not a utility strip. One primary at 54px, two
   real secondaries beside it, and start-over demoted below a rule.
------------------------------------------------------------------------- */
.abvp-sec--final { border-color: var(--p-navy); }
.abvp-sec--final .abvp-sec__head { background: var(--p-navy); border-bottom-color: var(--p-navy); }
.abvp-sec--final .abvp-sec__title { color: #fff; }
.abvp-sec--final .abvp-sec__note { color: rgba(255,255,255,.75); }
.abvp-sec--final .abvp-step__n { background: rgba(255,255,255,.16); }
.abvp-sec--final .abvp-step__of { color: rgba(255,255,255,.7); }
.abv-root[data-abv-mode='professional'] .abvp-acts { border: 0; padding: 0; margin: 0; background: none; }
.abvp-acts__lead { margin-bottom: var(--p-3); }
.abvp-acts__title { margin: 0 0 var(--p-hair); font-size: var(--p-section); font-weight: var(--p-w-head); color: var(--p-ink); }
.abvp-acts__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--p-2); }
.abv-root[data-abv-mode='professional'] .abvp-acts__primary { flex: 0 1 340px; min-width: 260px; }
.abvp-acts__second { display: flex; flex-wrap: wrap; gap: var(--p-1); }
.abvp-acts__status { margin: var(--p-2) 0 0; font-size: var(--p-help); font-weight: 600; color: var(--p-navy); min-height: 1.2em; }
.abv-root[data-abv-mode='professional'] .abvp-acts__fine { margin: var(--p-1) 0 0; max-width: 82ch; }
.abvp-acts__foot {
  display: flex; align-items: center; gap: var(--p-2); flex-wrap: wrap;
  margin-top: var(--p-3); padding-top: var(--p-2); border-top: 1px solid var(--p-rule-2);
}

/* ---------------------------------------------------------------------------
   14. RESPONSIVE
   Stack, never squeeze. Every multi-column construct below has an explicit
   width at which it becomes one column — no auto-fit is allowed to invent a
   90px column and break a number away from its unit.
------------------------------------------------------------------------- */
@media (max-width: 1180px) {
  .abvp-plan { grid-template-columns: 1fr; }
  .abvp-plan__canvas { background: none; padding: 0; }
  /* relative, NOT static: .abv-map inside is absolutely positioned, so
     removing the wrapper's positioning context lets it escape to the nearest
     positioned ancestor and size itself to the whole document. */
  .abv-root[data-abv-mode='professional'] .abvp-plan__canvas .abvp-map {
    position: relative; aspect-ratio: 16 / 10; min-height: 380px;
  }
}
@media (max-width: 1040px) {
  .abvp-groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .abvp-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .abv-root[data-abv-mode='professional'] .abvp-metric.is-lead { flex: 1 1 280px; }
}
@media (max-width: 860px) {
  .abvp-ident { grid-template-columns: 1fr; align-items: stretch; }
  .abvp-rows--2 { grid-template-columns: 1fr; }
  .abv-root[data-abv-mode='professional'] .abvp-prop__top .abvp-help { text-align: left; flex: 1 1 100%; }
  .abv-root[data-abv-mode='professional'] .abvp-prop .abvp-map { aspect-ratio: 16 / 10; min-height: 300px; }
}
@media (max-width: 768px) {
  .abvp { padding: var(--p-3) var(--p-2) var(--p-4); }
  .abvp-sec__head { padding: var(--p-2) var(--p-3); }
  .abvp-sec__body { padding: var(--p-3); }
  .abvp-groups { grid-template-columns: 1fr; gap: var(--p-3); }
  .abvp-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .abvp-rec__head { padding: var(--p-3) var(--p-3) 0; }
  .abvp-metrics { margin: 0 calc(var(--p-3) * -1); }
  .abv-root[data-abv-mode='professional'] .abvp-metric { padding: var(--p-2) var(--p-3); }
  .abvp-block { padding: var(--p-3); }
  .abvp-rec .abvp-alert { margin: var(--p-3) var(--p-3) 0; }
  .abvp-calcbar {
    margin: var(--p-3) calc(var(--p-3) * -1) calc(var(--p-3) * -1);
    padding: var(--p-3); align-items: stretch; flex-direction: column;
  }
  .abvp-calcbar .abvp-btn { min-width: 0; width: 100%; }
  .abvp-jobchip { margin-left: 0; text-align: left; }
  .abvp-sec--plan .abvp-sec__body { padding: var(--p-3); }
}
@media (max-width: 620px) {
  .abvp-fields { grid-template-columns: 1fr; }
  .abvp-f__pair { grid-template-columns: 1fr; }
  .abvp-fam__body { grid-template-columns: 1fr; padding-left: 0; }
  .abv-root[data-abv-mode='professional'] .abvp-fam__note { margin-left: 0; }
  .abvp-alt__top > span { white-space: normal; }
  .abv-root[data-abv-mode='professional'] .abvp-acts__primary { flex: 1 1 100%; min-width: 0; }
  .abvp-acts__second { width: 100%; }
  .abv-root[data-abv-mode='professional'] .abvp-acts__second .abvp-btn { flex: 1 1 140px; }
}
@media (max-width: 560px) {
  /* The chip system handles narrow widths itself — see its own 600px block. */
  .abv-root[data-abv-mode='professional'] .abvp-metric,
  .abv-root[data-abv-mode='professional'] .abvp-metric.is-lead { flex: 1 1 100%; }
  /* Not "wrap and hope" — display:block, so the label and the figure stack
     deterministically. A wrapped flex row that fails to wrap does not scroll
     here, it gets clipped by the section's overflow:hidden, which loses the
     number entirely. */
  .abv-root[data-abv-mode='professional'] .abvp-row { display: block; }
  .abv-root[data-abv-mode='professional'] .abvp-row__v {
    text-align: left; max-width: 100%; margin-top: 2px;
  }
  .abv-root[data-abv-mode='professional'] .abvp-row__v b { white-space: normal; overflow-wrap: anywhere; }
  .abvp-vd { padding-left: var(--p-2); }
  .abvp-sched__row { grid-template-columns: 1fr; }
  .abv-root[data-abv-mode='professional'] .abvp-sched__row > code { grid-column: 1; grid-row: auto; justify-self: start; }
}

/* Reduced motion is already zeroed at the token level; nothing here animates
   position, only colour. */

/* Alternate equipment schedule — step 4 only, and visually quieter than the
   recommendation's. */
.abvp-review__sched { margin-top: var(--p-3); padding-top: var(--p-2); border-top: 1px solid var(--p-rule-2); }

/* =============================================================================
   PHASE 18B — VISUAL ROOF SELECTORS
   =============================================================================
   Material and colour are the two roof inputs a contractor RECOGNISES faster
   than they read. Pitch and sun stay compact selects on purpose — a photograph
   of "6/12" helps nobody, and twelve visual controls is clutter, not clarity.

   Both selectors are real radio groups. The input is visually hidden but is
   still the focusable, checkable, screen-reader-announced control; the picture
   is its label. Nothing here is clickable-only.
   ========================================================================== */

/* ---- MATERIAL: three photographs ---------------------------------------- */
.abvp-mat {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--p-1); max-width: 560px;
}
.abv-root[data-abv-mode='professional'] .abvp-mat__card {
  position: relative; margin: 0; min-width: 0; cursor: pointer;
}
.abvp-mat__card input {
  position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none;
}
.abvp-mat__inner {
  display: block; overflow: hidden; background: #fff;
  border: 2px solid var(--p-rule); border-radius: var(--p-radius-sm);
  transition: border-color var(--abv-dur-fast) var(--abv-ease),
              box-shadow var(--abv-dur-fast) var(--abv-ease);
}
.abvp-mat__shot { position: relative; display: block; aspect-ratio: 3 / 2; background: var(--p-ground); }
.abvp-mat__shot img { display: block; width: 100%; height: 100%; object-fit: cover; }
.abvp-mat__tick {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  /* orange chip, white glyph */
  background: var(--p-btn-fill); color: #fff; font-size: var(--p-label); font-weight: 700;
  box-shadow: 0 1px 4px rgba(5,17,36,.35);
}
.abvp-mat__name {
  display: block; padding: 9px 8px; text-align: center;
  font-size: var(--p-label); font-weight: 700; color: var(--p-ink);
  transition: background var(--abv-dur-fast) var(--abv-ease), color var(--abv-dur-fast) var(--abv-ease);
}
.abvp-mat__card:hover .abvp-mat__inner { border-color: var(--p-accent); }
.abv-root[data-abv-mode='professional'] .abvp-mat__card:hover .abvp-mat__name {
  background: var(--p-btn-fill); color: #fff;          /* orange -> white */
}
.abvp-mat__card input:checked + .abvp-mat__inner {
  border-color: var(--p-accent); box-shadow: 0 0 0 3px var(--p-accent-bg);
}
.abv-root[data-abv-mode='professional'] .abvp-mat__card input:checked + .abvp-mat__inner .abvp-mat__name {
  background: var(--p-btn-fill); color: #fff;          /* orange -> white */
}
.abvp-mat__card input:checked + .abvp-mat__inner .abvp-mat__tick { display: inline-flex; }
/* Focus is a ring, never a fill, so it never reads as "selected". */
.abvp-mat__card input:focus-visible + .abvp-mat__inner {
  outline: 3px solid var(--p-focus); outline-offset: 2px;
}

/* ---- COLOR: swatch cards ------------------------------------------------ */
.abvp-sw {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  gap: 6px; max-width: 760px;
}
.abv-root[data-abv-mode='professional'] .abvp-sw__card {
  position: relative; margin: 0; min-width: 0; cursor: pointer;
}
.abvp-sw__card input {
  position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none;
}
.abvp-sw__inner {
  display: flex; align-items: center; gap: var(--p-1); min-width: 0;
  padding: 6px 8px; background: #fff;
  border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm);
  transition: border-color var(--abv-dur-fast) var(--abv-ease),
              background var(--abv-dur-fast) var(--abv-ease);
}
/* The chip is the engine registry's own hex for that colour — row[2]. */
.abvp-sw__chip {
  flex: none; width: 30px; height: 30px; border-radius: 5px;
  box-shadow: inset 0 0 0 1px rgba(5,17,36,.22);
}
.abvp-sw__txt { min-width: 0; }
/* Wrap, never ellipsis. "Weathered Wood" truncated to "Weathered …" is a roof
   colour the contractor cannot read back, and these are the exact names on the
   order. Two lines is cheaper than a hidden one. */
.abv-root[data-abv-mode='professional'] .abvp-sw__txt b {
  display: block; font-size: var(--p-label); font-weight: 600; color: var(--p-ink);
  white-space: normal; overflow-wrap: break-word; line-height: 1.25;
}
.abv-root[data-abv-mode='professional'] .abvp-sw__txt em {
  display: block; font-style: normal; font-size: var(--p-help); color: var(--p-ink-3); line-height: 1.3;
}
.abvp-sw__tick {
  display: none; margin-left: auto; flex: none; padding-left: 4px;
  color: var(--p-ink); font-size: var(--p-sub); font-weight: 800; line-height: 1;
}
.abvp-sw__card:hover .abvp-sw__inner { border-color: var(--p-accent); }
.abvp-sw__card input:checked + .abvp-sw__inner {
  border-color: var(--p-accent); background: var(--p-accent-bg);
  box-shadow: inset 0 0 0 1px var(--p-accent);
}
.abvp-sw__card input:checked + .abvp-sw__inner .abvp-sw__tick { display: block; }
.abvp-sw__card input:focus-visible + .abvp-sw__inner {
  outline: 3px solid var(--p-focus); outline-offset: 2px;
}
.abv-root[data-abv-mode='professional'] .abvp-sw__empty {
  grid-column: 1 / -1; margin: 0; padding: var(--p-2);
  background: var(--p-ground); border-radius: var(--p-radius-sm);
  font-size: var(--p-help); color: var(--p-ink-3);
}
/* REV4 IMAGERY — photographic band group headers in the color grid: a real
   roof in that band's tone above its colors. Full-width rows inside the
   grid, NOT interactive: selection stays on the per-color radios. The images
   are the same 8:3 band crops the homeowner band tiles use. */
.abvp-sw__bandhead {
  grid-column: 1 / -1; position: relative; margin-top: 4px;
  border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm);
  overflow: hidden; line-height: 0;
}
.abvp-sw__bandhead:first-child { margin-top: 0; }
/* .abv-root prefix: the theme's `.elementor img { height: auto }` ties a bare
   `.abvp-sw__bandhead img` on specificity and wins on order, blowing the
   64px strip up to the image's intrinsic ratio. Measured live 2026-08-21. */
.abv-root .abvp-sw__bandhead img { display: block; width: 100%; height: 64px; object-fit: cover; }
.abvp-sw__bandname {
  position: absolute; left: 0; bottom: 0; padding: 3px 10px;
  background: rgba(5, 17, 36, 0.82); color: #fff; line-height: 1.4;
  font-size: var(--p-help); font-weight: 700; letter-spacing: 0.02em;
  border-top-right-radius: var(--p-radius-sm);
}

/* Roof now carries the two visual controls, so it earns more of the row. */
.abvp-groups { grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.55fr) minmax(0, 1.12fr); }

@media (max-width: 1180px) {
  /* One column below this: the swatch grid and the three photographs both read
     better full width than squeezed into a third of it. */
  .abvp-groups { grid-template-columns: 1fr; gap: var(--p-3); }
}
@media (max-width: 560px) {
  .abvp-sw { grid-template-columns: repeat(auto-fill, minmax(146px, 1fr)); }
  .abvp-mat { gap: 6px; }
  .abvp-mat__name { padding: 7px 4px; }
}

/* ---- MAP MODE BANNER ----------------------------------------------------
   Rides on the map itself. Neutral while viewing; accent while a mode is
   armed, because an armed mode changes what every click on the map means. */
.abv-root[data-abv-mode='professional'] .abvp-mapmode {
  position: absolute; top: var(--p-1); left: var(--p-1); z-index: 3;
  max-width: calc(100% - var(--p-3));
  display: grid; gap: 1px;
  padding: 8px 14px; border-radius: var(--p-radius-sm);
  background: rgba(255,255,255,.94); color: var(--p-ink);
  box-shadow: 0 2px 10px rgba(5,17,36,.28);
  backdrop-filter: saturate(160%) blur(2px);
  pointer-events: none;   /* it explains the map, it never intercepts it */
}
.abv-root[data-abv-mode='professional'] .abvp-mapmode[hidden] { display: none !important; }
.abv-root[data-abv-mode='professional'] .abvp-mapmode b {
  font-size: var(--p-label); font-weight: 700; line-height: 1.25;
}
.abv-root[data-abv-mode='professional'] .abvp-mapmode span {
  font-size: var(--p-help); color: var(--p-ink-3); line-height: 1.35;
}
/* Armed: orange ground, and therefore white type. */
.abv-root[data-abv-mode='professional'] .abvp-mapmode.is-active {
  background: var(--p-btn-fill); color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-mapmode.is-active b,
.abv-root[data-abv-mode='professional'] .abvp-mapmode.is-active span { color: #fff; }

/* ---- interactive feedback on the remaining pickable surface -------------
   The unpicked swatch is clickable, so it says so.

   The matching .abvp-seg rule that used to live here is GONE. It painted an
   unselected segment with --p-accent-bg on hover and set the label to
   --p-accent-ink (#a8481c) — a brown-orange that is explicitly off-brand, and
   it out-specified the chip system's own hover, so it won. The chip keeps its
   white ground on hover and takes the accent as a 2px edge plus a soft ring
   instead, which is the same gesture without the muddy fill. */
.abv-root[data-abv-mode='professional'] .abvp-sw__card:hover .abvp-sw__inner {
  border-color: var(--p-accent); background: var(--p-accent-bg);
}

/* =============================================================================
   PHASE 18C — CONFIGURED PRODUCT PREVIEW
   =============================================================================
   Real photographs, keyed on the exact SKU, from the site's own product
   registry. If the registry has no photograph the card degrades to the model
   name and the finish — it never substitutes a different product's picture.
   ========================================================================== */
.abvp-finish { display: grid; gap: var(--p-1); }
.abvp-finish__pick { display: block; margin: 0; }
.abv-root[data-abv-mode='professional'] .abvp-finish__field { padding-left: var(--p-1); gap: var(--p-1); }
.abvp-finish__chip {
  flex: none; width: 24px; height: 24px; border-radius: 5px;
  box-shadow: inset 0 0 0 1px rgba(5,17,36,.22);
}
/* GableBreeze carries no colour option — the control says so rather than
   offering a choice the SKU rules do not have. */
.abv-root[data-abv-mode='professional'] .abvp-finish__field.is-na { opacity: .55; }
.abv-root[data-abv-mode='professional'] .abvp-finish__field.is-na .abvp-finish__chip {
  background: repeating-linear-gradient(45deg, rgba(57,147,223,.16) 0 4px, rgba(57,147,223,.05) 4px 8px) !important;
}

.abvp-prod {
  display: flex; align-items: center; gap: var(--p-2);
  padding: var(--p-1); margin-top: var(--p-1);
  background: var(--p-ground); border-radius: var(--p-radius-sm);
}
.abvp-prod[hidden] { display: none !important; }
.abvp-prod__shot {
  flex: none; width: 72px; height: 72px; border-radius: var(--p-radius-sm);
  background: #fff; box-shadow: inset 0 0 0 1px var(--p-rule);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.abvp-prod__shot img { width: 100%; height: 100%; object-fit: contain; }
.abvp-prod__none {
  width: 26px; height: 26px; border-radius: 50%;
  background: repeating-linear-gradient(45deg, rgba(57,147,223,.16) 0 5px, rgba(57,147,223,.05) 5px 10px);
}
.abvp-prod__txt { min-width: 0; display: grid; gap: 2px; }
.abv-root[data-abv-mode='professional'] .abvp-prod__txt b {
  font-size: var(--p-label); font-weight: 700; color: var(--p-ink); line-height: 1.3;
}
.abvp-prod__finish {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--p-help); color: var(--p-ink-2); overflow-wrap: anywhere;
}
.abvp-prod__chip {
  flex: none; width: 14px; height: 14px; border-radius: 3px;
  box-shadow: inset 0 0 0 1px rgba(5,17,36,.25);
}
.abv-root[data-abv-mode='professional'] .abvp-prod__txt .abvp-help { margin: 2px 0 0; }

/* Fan-mix: the full engine sentence, under the control instead of clipped
   inside it. */
.abv-root[data-abv-mode='professional'] .abvp-mixfull {
  display: block; margin-top: 6px; color: var(--p-ink-2);
}

/* Schedule rows gain the product photo. */
.abvp-sched__row.has-shot { grid-template-columns: 56px minmax(0, 1fr) auto; }
.abvp-sched__shot {
  grid-row: 1 / span 3; grid-column: 1; align-self: start;
  width: 56px; height: 56px; border-radius: var(--p-radius-sm);
  background: #fff; box-shadow: inset 0 0 0 1px var(--p-rule);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.abvp-sched__shot img { width: 100%; height: 100%; object-fit: contain; }
/* Three-class specificity: the base .abvp-sched__row > b rule is scoped to
   .abv-root[data-abv-mode='professional'] and pins b to column 1. Without
   matching that here the title lands in the 56px thumbnail column and the
   model name overflows it. */
.abv-root[data-abv-mode='professional'] .abvp-sched__row.has-shot > b { grid-column: 2; }
.abv-root[data-abv-mode='professional'] .abvp-sched__row.has-shot > code { grid-column: 3; grid-row: 1; }
.abv-root[data-abv-mode='professional'] .abvp-sched__row.has-shot .abvp-sched__spec,
.abv-root[data-abv-mode='professional'] .abvp-sched__row.has-shot .abvp-sched__mount { grid-column: 2 / -1; }

@media (max-width: 560px) {
  .abvp-sched__row.has-shot { grid-template-columns: 44px minmax(0, 1fr); }
  .abvp-sched__shot { width: 44px; height: 44px; }
  .abv-root[data-abv-mode='professional'] .abvp-sched__row.has-shot > code { grid-column: 2; grid-row: auto; justify-self: start; }
}

/* Model description under the model name, clamped so a long registry sentence
   cannot push the card taller than the control it belongs to. */
.abvp-prod__spec {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: var(--p-help); color: var(--p-ink-3); line-height: 1.35;
}

/* =============================================================================
   HOMEOWNER EXPERIENCE — Phase 19
   =============================================================================
   Scoped entirely to [data-abv-mode='homeowner']. The professional workspace
   above cannot see any of it, and none of its markup is reused here.

   What was wrong, measured on the live build:
     - every button was being repainted by the Elementor kit: 12px in the
       stylesheet, 17.6px on screen, and the BACK control rendered as a 57px
       orange square with a tiny chevron — the loudest thing on a step
     - the result screen ran to 20 uppercase runs and 13 distinct font sizes,
       against 3-4 and 6-7 on the wizard steps
     - at 1440 the whole result sat in a ~510px column with half the viewport
       empty, which reads as unfinished rather than as a prose measure
     - four bottom actions, two of them orange, with "Start a new plan" — the
       destructive one — styled as a primary
   ========================================================================== */

.abv-root[data-abv-mode='homeowner'] .abv-shell,
.abv-root[data-abv-mode='homeowner'] .abv-shell * { box-sizing: border-box; }
.abv-root[data-abv-mode='homeowner'] [hidden] { display: none !important; }

.abv-root[data-abv-mode='homeowner'] .abv-shell {
  max-width: var(--h-wizard);
  padding: var(--h-4) var(--h-3) var(--h-5);
  color: var(--h-body);
}
/* The result is a document, not a question — it earns the page. */
.abv-root[data-abv-mode='homeowner'] .abv-shell:has(.abv-screen[data-abv-screen='result'].is-on) {
  max-width: var(--h-wide);
}

/* ---------------------------------------------------------------------------
   1. TYPE
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='homeowner'] .abv-q {
  font-size: var(--h-q); line-height: 1.18; letter-spacing: -0.5px;
  font-weight: 800; color: var(--h-ink); margin: 0 0 var(--h-1);
}
.abv-root[data-abv-mode='homeowner'] .abv-welcome .abv-q { font-size: var(--h-hero); }
.abv-root[data-abv-mode='homeowner'] .abv-sub {
  margin: 0 0 var(--h-3); max-width: 58ch;
  font-size: var(--h-help); line-height: 1.6; color: var(--h-muted);
}
.abv-root[data-abv-mode='homeowner'] .abv-eyebrow {
  font-size: var(--h-eyebrow); font-weight: 700; letter-spacing: 1.6px;
  text-transform: uppercase; color: var(--h-muted);
}
.abv-root[data-abv-mode='homeowner'] .abv-block h4,
.abv-root[data-abv-mode='homeowner'] .abv-details summary h4 {
  font-size: var(--h-sub); font-weight: 700; color: var(--h-ink);
  letter-spacing: -0.2px; margin: 0;
}
.abv-root[data-abv-mode='homeowner'] .abv-fine {
  font-size: var(--h-help); color: var(--h-muted); line-height: 1.6;
}

/* ---------------------------------------------------------------------------
   2. THE BUTTON SYSTEM
   Three-class specificity so the Elementor kit cannot reach in. Pills, because
   a consumer tool should feel softer than a schedule — but ONE size language,
   sentence case, and never a button whose text touches its edge.

   THE BRAND RULE: an orange background always carries white. Every rule that
   paints the accent sets the foreground in the same block, so no cascade path
   can deliver one without the other.
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='homeowner'] .abv-btn,
.abv-root[data-abv-mode='homeowner'] .abv-btn--ghost,
.abv-root[data-abv-mode='homeowner'] .abv-btn--quiet {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  /* Same measured Attic Breeze CTA geometry as the professional side and as
     /contractor-programs/. BreezeMatch earns its softer feel from bigger
     touch targets, imagery and fewer questions — not from a private button
     language that makes it look like a different company's product. */
  min-height: var(--ab-cta-h); padding: var(--ab-cta-pad-y) var(--ab-cta-pad-x);
  font-family: var(--abv-font); font-size: var(--ab-cta-size); font-weight: 700;
  line-height: var(--ab-cta-lh); letter-spacing: var(--ab-cta-ls); text-transform: uppercase;
  white-space: normal; overflow-wrap: break-word;
  text-decoration: none; width: auto; max-width: 100%;
  border: var(--ab-cta-bw) solid transparent; border-radius: var(--ab-cta-radius);
  box-shadow: none; cursor: pointer;
  transition: background-color var(--ab-cta-dur) var(--abv-ease),
              border-color var(--ab-cta-dur) var(--abv-ease),
              color var(--ab-cta-dur) var(--abv-ease);
}
.abv-root[data-abv-mode='homeowner'] .abv-btn:active:not(:disabled),
.abv-root[data-abv-mode='homeowner'] .abv-btn--ghost:active:not(:disabled) {
  transform: translateY(1px);
}
@media (prefers-reduced-motion: reduce) {
  .abv-root[data-abv-mode='homeowner'] .abv-btn:active:not(:disabled),
  .abv-root[data-abv-mode='homeowner'] .abv-btn--ghost:active:not(:disabled) { transform: none; }
}
.abv-root[data-abv-mode='homeowner'] .abv-btn {
  background: var(--h-btn-fill); border-color: var(--h-btn-fill); color: #fff;
}
/* Same missing-hover defect as the professional primary, same fix: the accent
   arrives as the 2px edge, never as a fill behind a label. */
.abv-root[data-abv-mode='homeowner'] .abv-btn:hover:not(:disabled),
.abv-root[data-abv-mode='homeowner'] .abv-btn:active:not(:disabled) {
  background: var(--h-btn-fill-hover); border-color: var(--abv-orange); color: #fff;
}
/* Secondary: navy outline at rest, orange fill on hover — and therefore white. */
.abv-root[data-abv-mode='homeowner'] .abv-btn--ghost {
  background: #fff; color: var(--h-navy); border-color: var(--h-rule);
}
.abv-root[data-abv-mode='homeowner'] .abv-btn--ghost:hover:not(:disabled) {
  background: var(--h-btn-fill); border-color: var(--h-btn-fill); color: #fff;
}
.abv-root[data-abv-mode='homeowner'] .abv-btn--ghost:active:not(:disabled) {
  background: var(--h-btn-fill-hover); border-color: var(--h-btn-fill-hover); color: #fff;
}
/* Tertiary is a text link. It never takes a fill, so it never takes the rule. */
.abv-root[data-abv-mode='homeowner'] .abv-btn--quiet {
  background: none; border-color: transparent; color: var(--h-muted);
  min-height: var(--h-btn-sm); padding: 10px 4px;
  font-size: var(--h-help); font-weight: 600; text-decoration: underline;
  /* Not a pill, so it opts out of the pill's caps and tracking — the same
     hierarchy rule as the professional tertiary. */
  text-transform: none; letter-spacing: normal;
}
.abv-root[data-abv-mode='homeowner'] .abv-btn--quiet:hover:not(:disabled) { color: var(--h-ink); }

.abv-root[data-abv-mode='homeowner'] .abv-btn:disabled,
.abv-root[data-abv-mode='homeowner'] .abv-btn[aria-disabled='true'],
.abv-root[data-abv-mode='homeowner'] .abv-btn--ghost:disabled {
  opacity: .4; cursor: not-allowed;
}
.abv-root[data-abv-mode='homeowner'] :is(button, a, input, select, summary):focus-visible {
  outline: 3px solid var(--h-focus); outline-offset: 2px; border-radius: var(--h-radius-sm);
}

/* BACK is not a primary action. It was a 57px orange square. */
.abv-root[data-abv-mode='homeowner'] .abv-back {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; min-height: 0; padding: 0; flex: none;
  background: #fff; color: var(--h-muted);
  border: 1px solid var(--h-rule); border-radius: 50%;
  text-transform: none; letter-spacing: normal; cursor: pointer;
}
.abv-root[data-abv-mode='homeowner'] .abv-back:hover {
  background: var(--h-ground); color: var(--h-ink); border-color: var(--h-rule);
}

/* ---------------------------------------------------------------------------
   3. STEP HEADER — quieter, and no shouting
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='homeowner'] .abv-steps {
  display: flex; align-items: center; gap: var(--h-2);
  margin-bottom: var(--h-3);
}
.abv-root[data-abv-mode='homeowner'] .abv-steps__label {
  font-size: var(--h-help); font-weight: 600; color: var(--h-muted);
  text-transform: none; letter-spacing: normal;
}
.abv-root[data-abv-mode='homeowner'] .abv-meter { margin-left: auto; display: flex; gap: 5px; }
.abv-root[data-abv-mode='homeowner'] .abv-meter i {
  display: block; width: 26px; height: 5px; border-radius: 999px;
  background: var(--h-rule); transition: background var(--abv-dur) var(--abv-ease);
}
.abv-root[data-abv-mode='homeowner'] .abv-meter i.is-now,
.abv-root[data-abv-mode='homeowner'] .abv-meter i.is-done { background: var(--h-accent); }

/* ---------------------------------------------------------------------------
   4. CHOICE CARDS — the main control of this tool
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='homeowner'] .abv-cards { gap: var(--h-2); }
.abv-root[data-abv-mode='homeowner'] .abv-card {
  border: 2px solid var(--h-rule); border-radius: var(--h-radius);
  background: #fff; box-shadow: none;
  transition: border-color var(--abv-dur-fast) var(--abv-ease),
              box-shadow var(--abv-dur-fast) var(--abv-ease);
}
.abv-root[data-abv-mode='homeowner'] .abv-card:hover { border-color: var(--h-accent); box-shadow: var(--h-shadow); }
.abv-root[data-abv-mode='homeowner'] .abv-card.is-on {
  border-color: var(--h-accent); background: var(--h-accent-bg);
  box-shadow: 0 0 0 3px var(--h-accent-bg);
}
.abv-root[data-abv-mode='homeowner'] .abv-card__body b {
  font-size: var(--h-ctrl); font-weight: 700; color: var(--h-ink);
}
.abv-root[data-abv-mode='homeowner'] .abv-card__body small {
  font-size: var(--h-help); color: var(--h-muted); line-height: 1.45;
}
/* The tick badge on a selected card: ORANGE ground, WHITE glyph — the signature
   selected indicator. This override used to repaint it with the primary-button
   fill, which the palette correction turned navy; a selected indicator is an
   accent, not a structural action, so the base orange rule now stands. */
.abv-root[data-abv-mode='homeowner'] .abv-card.is-on::after {
  background-color: var(--abv-orange); color: #fff;
}

/* ---------------------------------------------------------------------------
   5. VALIDATION — red, never orange
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='homeowner'] .abv-error,
.abv-root[data-abv-mode='homeowner'] [data-abv-size-error] {
  display: flex; align-items: flex-start; gap: 8px;
  margin: var(--h-1) 0 0; padding: 0; background: none; border: 0;
  font-size: var(--h-help); font-weight: 600; color: var(--h-err);
}
.abv-root[data-abv-mode='homeowner'] .abv-error::before,
.abv-root[data-abv-mode='homeowner'] [data-abv-size-error]::before {
  content: '!'; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin-top: 1px; border-radius: 50%;
  background: var(--h-err); color: #fff; font-size: 12px; font-weight: 700; line-height: 1;
}
.abv-root[data-abv-mode='homeowner'] .abv-error[hidden],
.abv-root[data-abv-mode='homeowner'] [data-abv-size-error][hidden] { display: none !important; }
.abv-root[data-abv-mode='homeowner'] .abv-field__wrap.is-invalid,
.abv-root[data-abv-mode='homeowner'] input.is-invalid {
  border-color: var(--h-err-rule); background: var(--h-err-bg);
}

/* ---------------------------------------------------------------------------
   6. THE RESULT — the reward, and the part that was weakest
------------------------------------------------------------------------- */
.abv-root[data-abv-mode='homeowner'] .abv-plan { max-width: none; }
.abv-root[data-abv-mode='homeowner'] .abv-plan__head {
  padding-bottom: var(--h-3); margin-bottom: var(--h-3);
  border-bottom: 2px solid var(--h-rule);
}
.abv-root[data-abv-mode='homeowner'] .abv-plan__title {
  font-size: var(--h-title); line-height: 1.1; letter-spacing: -0.6px;
  font-weight: 800; color: var(--h-ink); margin: var(--h-1) 0 0;
}
.abv-root[data-abv-mode='homeowner'] .abv-plan__addr b { font-size: var(--h-ctrl); color: var(--h-ink); }
.abv-root[data-abv-mode='homeowner'] .abv-plan__addr span { font-size: var(--h-help); color: var(--h-muted); }

/* THE HERO. Navy ground, the product beside it, the answer in plain words. */
.abv-root[data-abv-mode='homeowner'] .abv-rec {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: var(--h-3);
  background: var(--h-navy); color: #fff;
  border-radius: var(--h-radius); padding: var(--h-4);
  margin-bottom: var(--h-2);
}
.abv-root[data-abv-mode='homeowner'] .abv-rec .abv-eyebrow { color: rgba(255,255,255,.72); }
.abv-root[data-abv-mode='homeowner'] .abv-rec__qty {
  margin: var(--h-1) 0 0; font-size: var(--h-help); color: rgba(255,255,255,.8);
}
.abv-root[data-abv-mode='homeowner'] .abv-rec__qty b {
  font-size: var(--h-metric); font-weight: 800; color: #fff; line-height: 1;
  margin-right: 6px;
}
.abv-root[data-abv-mode='homeowner'] .abv-rec__name {
  margin: var(--h-1) 0 0; font-size: 26px; font-weight: 800; color: #fff;
  line-height: 1.18; letter-spacing: -0.4px;
}
.abv-root[data-abv-mode='homeowner'] .abv-rec__mount {
  margin: 6px 0 0; font-size: var(--h-help); color: rgba(255,255,255,.78);
}
/* The product photograph. Real asset or nothing — see abv-result.js. */
.abv-hrec__shot {
  flex: none; width: 168px; height: 168px; border-radius: var(--h-radius-sm);
  background: #fff; padding: var(--h-1);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.abv-hrec__shot img { width: 100%; height: 100%; object-fit: contain; }

/* Three numbers, big enough to read at arm's length. */
.abv-root[data-abv-mode='homeowner'] .abv-stats {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--h-2); margin-bottom: var(--h-4);
}
.abv-root[data-abv-mode='homeowner'] .abv-stat {
  background: var(--h-ground); border: 0; border-radius: var(--h-radius-sm);
  padding: var(--h-3);
}
.abv-root[data-abv-mode='homeowner'] .abv-stat > span {
  display: block; font-size: var(--h-help); font-weight: 600; color: var(--h-muted);
  text-transform: none; letter-spacing: normal;
}
.abv-root[data-abv-mode='homeowner'] .abv-stat > b {
  display: block; margin-top: 6px; font-size: var(--h-metric); font-weight: 800;
  color: var(--h-ink); line-height: 1.05; font-variant-numeric: tabular-nums;
}
.abv-root[data-abv-mode='homeowner'] .abv-stat > small {
  display: block; margin-top: 4px; font-size: var(--h-help); color: var(--h-muted);
}

/* Blocks: spacing and a hairline, not a box inside a box. */
.abv-root[data-abv-mode='homeowner'] .abv-block {
  border: 0; background: none; padding: 0;
  margin: 0 0 var(--h-4);
}
.abv-root[data-abv-mode='homeowner'] .abv-block > h4 { margin-bottom: var(--h-2); }
.abv-root[data-abv-mode='homeowner'] .abv-block p { font-size: var(--h-help); line-height: 1.65; color: var(--h-body); }

/* Alternatives are SECONDARY. Rows under a hairline, never cards competing
   with the navy hero. */
.abv-root[data-abv-mode='homeowner'] .abv-alts { display: grid; gap: 0; }
.abv-root[data-abv-mode='homeowner'] .abv-alt {
  border: 0; border-bottom: 1px solid var(--h-rule-2); border-left: 3px solid transparent;
  border-radius: 0; background: none; padding: var(--h-2) 0 var(--h-2) var(--h-2);
}
.abv-root[data-abv-mode='homeowner'] .abv-alt:last-child { border-bottom: 0; }
.abv-root[data-abv-mode='homeowner'] .abv-alt.is-below {
  border-left-color: var(--h-accent); background: var(--h-accent-bg);
}
.abv-root[data-abv-mode='homeowner'] .abv-alt b { font-size: var(--h-ctrl); color: var(--h-ink); }
.abv-root[data-abv-mode='homeowner'] .abv-alt span { font-size: var(--h-help); color: var(--h-muted); }
.abv-root[data-abv-mode='homeowner'] .abv-alt em {
  font-size: var(--h-help); font-weight: 600; text-transform: none; letter-spacing: normal;
  color: var(--h-ok);
}
.abv-root[data-abv-mode='homeowner'] .abv-alt.is-below em { color: var(--h-ink); }

.abv-root[data-abv-mode='homeowner'] .abv-details {
  border: 1px solid var(--h-rule); border-radius: var(--h-radius-sm);
  padding: var(--h-2) var(--h-3); margin-bottom: var(--h-2);
}
.abv-root[data-abv-mode='homeowner'] .abv-details summary { cursor: pointer; }

/* ---- WHAT TO DO NEXT: one primary, two secondary, one quiet ------------- */
.abv-root[data-abv-mode='homeowner'] .abv-cta {
  background: var(--h-ground); border-radius: var(--h-radius);
  padding: var(--h-4); margin-top: var(--h-4);
}
.abv-root[data-abv-mode='homeowner'] .abv-cta h4 { margin: 0 0 var(--h-1); font-size: var(--h-sub); }
.abv-root[data-abv-mode='homeowner'] .abv-cta__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--h-2);
  margin-top: var(--h-3);
}
.abv-root[data-abv-mode='homeowner'] .abv-cta__row .abv-btn { flex: 0 1 auto; min-width: 240px; }
.abv-root[data-abv-mode='homeowner'] .abv-cta__foot {
  margin-top: var(--h-3); padding-top: var(--h-2);
  border-top: 1px solid var(--h-rule);
  display: flex; align-items: center; gap: var(--h-2); flex-wrap: wrap;
}

/* ---------------------------------------------------------------------------
   7. RESPONSIVE — stack, never shrink
------------------------------------------------------------------------- */
@media (min-width: 1040px) {
  /* The result reads as two columns: the answer on the left, the supporting
     detail on the right. The wizard stays single-column on purpose. */
  .abv-hplan__cols {
    display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: var(--h-4);
  }
}
@media (max-width: 860px) {
  .abv-root[data-abv-mode='homeowner'] .abv-rec { grid-template-columns: 1fr; justify-items: start; }
  .abv-hrec__shot { width: 132px; height: 132px; order: -1; }
  .abv-root[data-abv-mode='homeowner'] .abv-stats { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
  .abv-root[data-abv-mode='homeowner'] .abv-shell { padding: var(--h-3) var(--h-2) var(--h-4); }
  .abv-root[data-abv-mode='homeowner'] .abv-cta { padding: var(--h-3); }
  .abv-root[data-abv-mode='homeowner'] .abv-cta__row .abv-btn,
  .abv-root[data-abv-mode='homeowner'] .abv-cta__row .abv-btn--ghost { flex: 1 1 100%; min-width: 0; }
  .abv-root[data-abv-mode='homeowner'] .abv-meter i { width: 18px; }
}
@media (max-width: 620px) {
  .abv-root[data-abv-mode='homeowner'] .abv-rec { padding: var(--h-3); }
  .abv-root[data-abv-mode='homeowner'] .abv-rec__name { font-size: 22px; }
}

/* ---- Phase 19: the built-yet routing step and the new-build states ------ */
.abv-root[data-abv-mode='homeowner'] .abv-cards--status {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--h-2);
}
.abv-root[data-abv-mode='homeowner'] .abv-card--status {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--h-2);
  padding: var(--h-3); text-align: left; cursor: pointer;
}
.abv-root[data-abv-mode='homeowner'] .abv-card--status .abv-card__art {
  width: 100%; max-width: 190px; color: var(--h-navy);
}
.abv-root[data-abv-mode='homeowner'] .abv-card--status .abv-card__art svg { width: 100%; height: auto; }

/* The plan panel that stands where the map would be. It has to read as a
   deliberate state, which means it needs as much presence as the map it
   replaces — not a grey box with an apology in it. */
.abv-newplan {
  display: flex; align-items: center; gap: var(--h-3);
  padding: var(--h-4); margin-bottom: var(--h-3);
  background: var(--h-ground); border-radius: var(--h-radius);
}
.abv-newplan[hidden] { display: none !important; }
.abv-newplan__art { flex: none; width: 96px; color: var(--h-navy); }
.abv-newplan__art svg { width: 100%; height: auto; }
.abv-newplan__body { min-width: 0; }
.abv-root[data-abv-mode='homeowner'] .abv-newplan__body b {
  display: block; font-size: var(--h-sub); font-weight: 700; color: var(--h-ink);
}
.abv-root[data-abv-mode='homeowner'] .abv-newplan__body p {
  margin: 6px 0 0; font-size: var(--h-help); line-height: 1.6; color: var(--h-body); max-width: 62ch;
}

/* Imagery of a plot mid-build is context, not evidence — labelled as such. */
.abv-newnote {
  margin: var(--h-2) 0 0; padding: var(--h-2) var(--h-3);
  background: rgba(57,147,223,.07); border-left: 3px solid rgba(57,147,223,.32);
  border-radius: 0 var(--h-radius-sm) var(--h-radius-sm) 0;
  font-size: var(--h-help); line-height: 1.6; color: var(--h-body);
}
.abv-newnote[hidden] { display: none !important; }

.abv-root[data-abv-mode='homeowner'] .abv-nav {
  display: flex; align-items: center; gap: var(--h-2); flex-wrap: wrap;
  margin-top: var(--h-4); padding-top: var(--h-3); border-top: 1px solid var(--h-rule);
}
.abv-root[data-abv-mode='homeowner'] .abv-nav__spacer { flex: 1 1 auto; }

@media (max-width: 700px) {
  .abv-root[data-abv-mode='homeowner'] .abv-cards--status { grid-template-columns: 1fr; }
  .abv-newplan { flex-direction: column; align-items: flex-start; padding: var(--h-3); }
  .abv-newplan__art { width: 72px; }
  .abv-root[data-abv-mode='homeowner'] .abv-nav .abv-btn { flex: 1 1 100%; }
}

/* =============================================================================
   HOMEOWNER PAGE — Phase 19
   =============================================================================
   The page around the tool. Deliberately OUTSIDE .abv-root, because it is page
   content, not calculator state — but it uses the same tokens so the seam
   between page and tool is not visible.

   Short by design. The brief asked for an introduction the homeowner passes
   through, not an article they have to get past.
   ========================================================================== */
.abvpage-intro,
.abvpage-after {
  /* HOMEOWNER page bands. 2026-08-25: grey body/helper/rule/ground retired and
     the accent moved to Breeze Home Green. NOTE - nothing emits .abvpage-* any
     more (verified by grepping every widget and JS file on 2026-08-25); the
     bands were replaced by the Elementor-native hybrid page. Corrected rather
     than deleted so reviving it cannot reintroduce four off-palette values. */
  --pg-ink: #051124; --pg-body: #051124; --pg-muted: rgba(5,17,36,.72);
  --pg-rule: rgba(5,17,36,.14); --pg-ground: #ffffff; --pg-accent: #5c9d5e;
  font-family: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
  max-width: 1140px; margin: 0 auto; padding: 0 24px;
  color: var(--pg-body); box-sizing: border-box;
}
.abvpage-intro * , .abvpage-after * { box-sizing: border-box; }

.abvpage-intro { padding-top: 56px; padding-bottom: 8px; }
.abvpage-eyebrow {
  display: block; font-size: 12px; font-weight: 700; letter-spacing: 1.6px;
  text-transform: uppercase; color: var(--pg-muted); margin-bottom: 10px;
}
.abvpage-h1 {
  margin: 0 0 12px; font-size: clamp(30px, 4vw, 44px); line-height: 1.08;
  letter-spacing: -0.9px; font-weight: 800; color: var(--pg-ink);
}
.abvpage-lead {
  margin: 0 0 32px; max-width: 62ch;
  font-size: 17px; line-height: 1.6; color: var(--pg-body);
}
/* What you'll need — three numbered items, not a wall of copy. */
.abvpage-need {
  list-style: none; margin: 0 0 20px; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px;
}
.abvpage-need li {
  display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; align-items: start;
  padding: 20px; background: var(--pg-ground); border-radius: 14px;
}
.abvpage-need__n {
  grid-row: 1 / span 2;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--pg-accent); color: #fff;   /* orange ground, white numeral */
  font-size: 15px; font-weight: 700; line-height: 1;
}
.abvpage-need b { font-size: 16px; font-weight: 700; color: var(--pg-ink); }
.abvpage-need em { font-style: normal; font-size: 14px; line-height: 1.5; color: var(--pg-muted); }
.abvpage-meta { margin: 0; font-size: 14px; color: var(--pg-muted); }

.abvpage-after {
  padding-top: 40px; padding-bottom: 72px;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 48px;
}
.abvpage-h2 {
  margin: 0 0 16px; font-size: 22px; font-weight: 800; letter-spacing: -0.3px;
  color: var(--pg-ink);
}
.abvpage-list, .abvpage-steps { margin: 0; padding: 0; list-style: none; }
.abvpage-list li {
  position: relative; padding: 10px 0 10px 30px;
  border-bottom: 1px solid var(--pg-rule);
  font-size: 15.5px; line-height: 1.5; color: var(--pg-body);
}
.abvpage-list li:last-child { border-bottom: 0; }
.abvpage-list li::before {
  content: ''; position: absolute; left: 4px; top: 18px;
  width: 9px; height: 9px; border-radius: 50%; background: var(--pg-accent);
}
.abvpage-steps { counter-reset: abvstep; }
.abvpage-steps li {
  counter-increment: abvstep;
  display: grid; grid-template-columns: auto 1fr; gap: 2px 14px; align-items: start;
  padding: 12px 0; border-bottom: 1px solid var(--pg-rule);
}
.abvpage-steps li::before {
  content: counter(abvstep); grid-row: 1 / span 2;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: #051124; color: #fff; font-size: 14px; font-weight: 700;
}
.abvpage-steps b { font-size: 16px; font-weight: 700; color: var(--pg-ink); }
.abvpage-steps span { font-size: 14px; color: var(--pg-muted); line-height: 1.5; }
.abvpage-note {
  margin: 20px 0 0; font-size: 14px; line-height: 1.6; color: var(--pg-muted);
}

@media (max-width: 900px) {
  .abvpage-need { grid-template-columns: 1fr; }
  .abvpage-after { grid-template-columns: 1fr; gap: 36px; }
}
@media (max-width: 768px) {
  .abvpage-intro { padding-top: 36px; }
  .abvpage-intro, .abvpage-after { padding-left: 16px; padding-right: 16px; }
  .abvpage-after { padding-bottom: 48px; }
}

/* ---- Phase 19: the seam between the page and the tool -------------------
   The page now carries the title, the promise and the "what you'll need".
   Left alone, the widget repeated all three: an app-bar name, an eyebrow and
   a second H1, stacked directly under the page's own. So on the welcome
   screen the tool stops introducing itself and just starts. */
.abv-root[data-abv-mode='homeowner'] .abv-bar {
  border: 0; padding: 0; margin: 0; min-height: 0;
}
.abv-root[data-abv-mode='homeowner'] .abv-bar__name { display: none; }
.abv-root[data-abv-mode='homeowner'] .abv-bar:has(.abv-bar__prop:not([hidden])) {
  padding: 0 0 var(--h-2); margin-bottom: var(--h-3);
  border-bottom: 1px solid var(--h-rule); min-height: 44px;
}

.abv-root[data-abv-mode='homeowner'] .abv-screen[data-abv-screen='welcome'] .abv-eyebrow { display: none; }

/* A start panel, not a second hero. */
.abv-root[data-abv-mode='homeowner'] .abv-welcome {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: var(--h-4);
  background: var(--h-ground); border-radius: var(--h-radius);
  padding: var(--h-4);
}
.abv-root[data-abv-mode='homeowner'] .abv-welcome .abv-q {
  font-size: var(--h-q); max-width: 20ch;
}
.abv-root[data-abv-mode='homeowner'] .abv-welcome .abv-sub { margin-bottom: var(--h-3); max-width: 46ch; }
.abv-root[data-abv-mode='homeowner'] .abv-welcome__art {
  flex: none; width: 260px; border-radius: var(--h-radius-sm); overflow: hidden;
}
.abv-root[data-abv-mode='homeowner'] .abv-welcome__art svg,
.abv-root[data-abv-mode='homeowner'] .abv-welcome__art img { width: 100%; height: auto; display: block; }
.abv-root[data-abv-mode='homeowner'] .abv-welcome__meta {
  margin: var(--h-2) 0 0; font-size: var(--h-help); color: var(--h-muted);
}

.abv-root[data-abv-mode='homeowner'] .abv-shell { padding-top: var(--h-2); }

@media (max-width: 860px) {
  .abv-root[data-abv-mode='homeowner'] .abv-welcome { grid-template-columns: 1fr; padding: var(--h-3); }
  .abv-root[data-abv-mode='homeowner'] .abv-welcome__art { width: 190px; order: -1; }
  .abv-root[data-abv-mode='homeowner'] .abv-welcome .abv-q { max-width: none; }
}

/* ---- ADDRESS SEARCH: the whole field is the tap target ------------------
   The 56px band around the address input only LOOKED tappable — the input
   itself was 42px, so the top and bottom 7px did nothing. Stretching the
   input to fill its wrapper makes the visible field and the hit area the
   same rectangle, and clears the 44px minimum on every path. */
.abv-root[data-abv-mode='homeowner'] .abv-search input {
  align-self: stretch;
  height: 100%;
  padding: 0;
  font-size: var(--h-ctrl);
  /* The theme styles bare text inputs at a higher specificity than the base
     `.abv-search input` reset, so the field drew a second grey rectangle
     inside itself. The wrapper is the field; the input carries no chrome. */
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

/* ==========================================================================
   PHASE 20 — HOMEOWNER POLISH
   Presentation only. Every rule is scoped to
   `.abv-root[data-abv-mode='homeowner']` so nothing here can reach the
   professional calculator or Elementor's global button styles.
   ========================================================================== */

/* --- 1. THE RECOMMENDED PRODUCT ------------------------------------------
   Was a hard white square on navy: the photo's own white background made a
   visible box, and the box read as a sticker rather than a product.
   No photograph in the registry has an alpha channel, so there is no cutout
   to use; `multiply` dissolves the photo's white into a soft light plate
   instead, which needs no retouching and leaves no ragged edge. */
.abv-root[data-abv-mode='homeowner'] .abv-hrec__shot {
  position: relative;
  flex: none;
  width: 208px;
  height: 188px;
  border-radius: 0;
  background: none;
  padding: 0;
  display: grid;
  place-items: center;
  overflow: visible;
}

/* The plate the product stands on: light enough for multiply to work, soft
   enough at the edges that it never reads as a second box. */
/* A pool of light, not a panel. The first attempt kept a rounded rectangle
   with a visible edge, which is the same "product in a box" problem in a
   softer form — so the gradient now fades out completely well inside its own
   bounds and no edge is ever drawn. */
.abv-root[data-abv-mode='homeowner'] .abv-hrec__stage {
  position: absolute;
  inset: -6% -8% -2%;
  border-radius: 0;
  background:
    radial-gradient(56% 48% at 50% 44%,
      #ffffff 0%,
      #f1f5fa 42%,
      rgba(241, 245, 250, .55) 66%,
      rgba(241, 245, 250, 0) 82%);
}
/* Contact shadow, so the fan sits on the plate rather than hovering. */
.abv-root[data-abv-mode='homeowner'] .abv-hrec__shot::after {
  content: '';
  position: absolute;
  left: 22%;
  right: 22%;
  bottom: 15%;
  height: 12px;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(13, 27, 51, .30) 0%, rgba(13, 27, 51, 0) 100%);
}

.abv-root[data-abv-mode='homeowner'] .abv-hrec__shot img {
  position: relative;
  z-index: 1;
  width: 92%;
  height: 92%;
  object-fit: contain;
  mix-blend-mode: multiply;
}

/* The finish is a fact about the photograph, so it is named rather than left
   for the homeowner to guess at. */
.abv-root[data-abv-mode='homeowner'] .abv-hrec__finish {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: -2px;
  transform: translateX(-50%);
  padding: 4px 12px;
  border-radius: var(--h-pill);
  background: rgba(255, 255, 255, .14);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .01em;
  white-space: nowrap;
}

@media (max-width: 720px) {
  .abv-root[data-abv-mode='homeowner'] .abv-hrec__shot { width: 168px; height: 152px; }
}

/* --- 2. PLACEMENT: ONE IDEA PER BLOCK ------------------------------------
   The aerial and the diagram are no longer a two-up comparison, so the
   side-by-side grid is retired and each gets the full measure. */
/* The Phase 20 two-block plan layout (aerial beside a schematic) is gone:
   there is no schematic any more, and the property is the whole visual. */

/* --- 3. NEW CONSTRUCTION: FORWARD, NOT PARKED ----------------------------
   The panel was flat grey with a disabled Continue beside it. It now carries
   the brand, states the outcome, and names the step it leads to. */
.abv-root[data-abv-mode='homeowner'] .abv-newplan {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: var(--h-3);
  align-items: start;
  margin-bottom: var(--h-3);
  padding: var(--h-3);
  border: 1px solid var(--h-rule);
  border-left: 4px solid var(--h-accent);
  border-radius: var(--h-radius);
  background: linear-gradient(180deg, #fff 0%, rgba(57,147,223,.05) 100%);
}
.abv-root[data-abv-mode='homeowner'] .abv-newplan__art {
  display: block;
  color: var(--h-ink);
}
.abv-root[data-abv-mode='homeowner'] .abv-newplan__art svg { width: 100%; height: auto; }
.abv-root[data-abv-mode='homeowner'] .abv-newplan__body b {
  display: block;
  margin-bottom: 6px;
  font-size: var(--h-sub);
  line-height: 1.35;
  color: var(--h-ink);
}
.abv-root[data-abv-mode='homeowner'] .abv-newplan__body p {
  margin: 0;
  font-size: var(--h-help);
  line-height: 1.6;
  color: var(--h-body);
}
/* "Next: ..." — the sentence that stops the screen feeling like a dead end. */
.abv-root[data-abv-mode='homeowner'] .abv-newplan__next {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: var(--h-2) !important;
  padding-top: var(--h-2);
  border-top: 1px solid var(--h-rule);
  color: var(--h-ink) !important;
  font-weight: 600;
}
.abv-root[data-abv-mode='homeowner'] .abv-newplan__next span {
  flex: none;
  padding: 3px 10px;
  border-radius: var(--h-pill);
  background: var(--h-ink);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}
@media (max-width: 620px) {
  .abv-root[data-abv-mode='homeowner'] .abv-newplan { grid-template-columns: 64px 1fr; gap: var(--h-2); }
}

/* The address search is no longer inside the map wrapper, so it needs its own
   layout in both places it now appears. */
.abv-root[data-abv-mode='homeowner'] .abv-search.is-standalone {
  position: static;
  max-width: none;
  margin-bottom: var(--h-2);
}
.abv-root[data-abv-mode='homeowner'] .abv-search__hint {
  margin: var(--h-1) 2px 0;
  font-size: var(--h-help);
  line-height: 1.5;
  color: var(--h-muted);
}

/* --- 4. WELCOME HERO ------------------------------------------------------ */
.abv-root[data-abv-mode='homeowner'] .abv-welcome__art {
  background: #051124;
  border-radius: var(--h-radius);
  padding: var(--h-2);
  overflow: hidden;
}
.abv-root[data-abv-mode='homeowner'] .abv-welcome__art svg,
.abv-root[data-abv-mode='homeowner'] .abv-welcome__art img {
  display: block;
  width: 100%;
  height: auto;
}

/* --- 5. "NOT SURE" AS A DESIGNED ANSWER ----------------------------------
   Was a grey hatched tile that looked like a picture which failed to load.
   Now a navy tile with a real question mark, matched across every step.
   The `--install` plate rule below carries the same weight and comes later, so
   the Not-sure tile is written with the card class as well to outrank it —
   without it the navy lost and the white question mark vanished. */
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure .abv-card__art--unsure,
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure .abv-card__photo--unsure,
.abv-root[data-abv-mode='homeowner'] .abv-card__art--unsure,
.abv-root[data-abv-mode='homeowner'] .abv-card__photo--unsure {
  display: grid;
  place-items: center;
  background: #051124;
  border: 0;
}
.abv-root[data-abv-mode='homeowner'] .abv-card__photo--unsure {
  aspect-ratio: 3 / 2;
  width: 100%;
}
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure .abv-card__art--unsure,
.abv-root[data-abv-mode='homeowner'] .abv-card__art--unsure {
  border-radius: var(--h-radius-sm);
  padding: var(--h-2) 0;
}
.abv-root[data-abv-mode='homeowner'] .abv-card__art--unsure svg,
.abv-root[data-abv-mode='homeowner'] .abv-card__photo--unsure svg {
  width: 100%;
  max-width: 118px;
  height: auto;
}
/* Selected state keeps the navy tile legible instead of tinting it orange. */
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure.is-on .abv-card__art--unsure,
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure.is-on .abv-card__photo--unsure {
  background: #051124;
}

/* --- 6. INSTALL + FAN-STYLE CARDS ---------------------------------------- */
.abv-root[data-abv-mode='homeowner'] .abv-card__art--install {
  border-radius: var(--h-radius-sm);
  background: linear-gradient(180deg, rgba(57,147,223,.05) 0%, rgba(57,147,223,.10) 100%);
  padding: var(--h-2) 0;
}
.abv-root[data-abv-mode='homeowner'] .abv-card__art--install svg { max-width: 156px; }

/* The fan-style cards carry a real photograph once the registry loads. Same
   multiply treatment, so the shot's white background disappears into the
   plate rather than sitting on it as a second rectangle. */
.abv-root[data-abv-mode='homeowner'] .abv-card__art--shot {
  min-height: 132px;
  padding: var(--h-1) 0;
}
.abv-root[data-abv-mode='homeowner'] .abv-card__art--shot img {
  display: block;
  width: auto;
  max-width: 82%;
  max-height: 124px;
  margin: 0 auto;
  mix-blend-mode: multiply;
}

/* --- 9. BUTTON POLISH ----------------------------------------------------
   The rule is unchanged — orange fill always carries white — this only adds
   room. `--h-btn-pad` keeps the two forward controls on the address step the
   same height when one of them has much longer wording. */
.abv-root[data-abv-mode='homeowner'] .abv-nav .abv-btn {
  padding-left: 32px;
  padding-right: 32px;
}
.abv-root[data-abv-mode='homeowner'] [data-abv-skip-addr] {
  white-space: normal;
  text-align: center;
  line-height: 1.3;
}

/* ==========================================================================
   PHASE 21 — HOMEOWNER ART DIRECTION CORRECTION
   Scoped to the homeowner calculator. Nothing here reaches the professional
   tool or Elementor's globals.
   ========================================================================== */

/* --- 6. COLOUR DISCIPLINE -------------------------------------------------
   The audit found 14 distinct text colours, most of them near-duplicates:
   two navies (#051124 and #051124), two greys (#6b7787 and #6f7680) and a
   warm body grey (#3e3e3e). They came from base tokens showing through
   wherever the homeowner layer had not restated them.

   Rather than chase every rule, the base tokens are re-pointed at the
   homeowner ones INSIDE the homeowner scope. One navy, one body, one grey.
   `--abv-blue-lt` (#3993D5) is the focus ring and blueprint stroke, and a
   navy ring on navy text would be far worse than an off-palette blue. */
.abv-root[data-abv-mode='homeowner'] {
  /* Navy now resolves to #051124 globally, so these three only still exist
     to collapse the GREYS. The navy aliases are harmless and kept so the
     scope stays self-describing. */
  --abv-ink-head: var(--h-ink);    /* = #051124                     */
  --abv-muted:    var(--h-muted);  /* was #6f7680 — a second grey   */
  --abv-text:     var(--h-body);   /* was #3e3e3e — a warm grey     */
  --abv-navy:     var(--h-ink);    /* = #051124                     */
}

/* The only text that still used the link blue. Navy carries the words; the
   orange marker carries the "this opens" signal. */
.abv-root[data-abv-mode='homeowner'] .abv-why summary {
  color: var(--h-ink);
  font-weight: 600;
}
.abv-root[data-abv-mode='homeowner'] .abv-why summary::marker,
.abv-root[data-abv-mode='homeowner'] .abv-why summary::-webkit-details-marker {
  color: var(--h-accent);
}

/* --- 2 + 5. "NOT SURE" AS A DRAWING --------------------------------------
   The art is now a full-bleed navy board with its own setting-out grid and
   corner ticks, so it has to fill the tile rather than sit in the middle of
   it at 118px. The question mark inside is real Poppins at weight 800. */
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure .abv-card__art--unsure,
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure .abv-card__photo--unsure,
.abv-root[data-abv-mode='homeowner'] .abv-card__art--unsure,
.abv-root[data-abv-mode='homeowner'] .abv-card__photo--unsure {
  padding: 0;
  overflow: hidden;
}
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure .abv-card__art--unsure svg,
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure .abv-card__photo--unsure svg,
.abv-root[data-abv-mode='homeowner'] .abv-card__art--unsure svg,
.abv-root[data-abv-mode='homeowner'] .abv-card__photo--unsure svg {
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  object-fit: cover;
}
/* The install-step tiles are shorter than the photo tiles; give the board a
   consistent height so the two Not-sure cards match each other. */
.abv-root[data-abv-mode='homeowner'] .abv-card--unsure .abv-card__art--unsure {
  min-height: 132px;
  border-radius: var(--h-radius-sm);
}

/* --- 3. THE PRODUCT, CLEARLY READABLE ------------------------------------
   A Jet Black fan on a navy card was losing its silhouette into the
   background: the light pool was too small and too soft, and the finish chip
   sat on top of the product in translucent white.

   Fixes: a larger, slightly brighter pool so the black body always has light
   behind it; and the finish moved OUT of the image onto its own solid line
   beneath, where it can never sit over the product. */
.abv-root[data-abv-mode='homeowner'] .abv-hrec__shot {
  width: 216px;
  height: 208px;
  grid-template-rows: 1fr auto;
}
.abv-root[data-abv-mode='homeowner'] .abv-hrec__stage {
  inset: -4% -10% 16%;
  background:
    radial-gradient(64% 58% at 50% 43%,
      #ffffff 0%,
      #f2f6fb 38%,
      rgba(242, 246, 251, .70) 56%,
      rgba(242, 246, 251, .34) 72%,
      rgba(242, 246, 251, 0) 92%);
}
.abv-root[data-abv-mode='homeowner'] .abv-hrec__shot::after {
  left: 20%;
  right: 20%;
  bottom: 26%;
  height: 14px;
  background: radial-gradient(50% 50% at 50% 50%, rgba(13, 27, 51, .34) 0%, rgba(13, 27, 51, 0) 100%);
}
.abv-root[data-abv-mode='homeowner'] .abv-hrec__shot img {
  align-self: center;
  width: 88%;
  height: 78%;
  margin-top: -6%;
}
/* The finish is a caption, not a sticker over the photograph. */
.abv-root[data-abv-mode='homeowner'] .abv-hrec__finish {
  position: static;
  transform: none;
  align-self: center;
  margin-top: 2px;
  padding: 5px 14px;
  border: 1px solid rgba(255, 255, 255, .26);
  background: rgba(255, 255, 255, .10);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .02em;
}
@media (max-width: 720px) {
  .abv-root[data-abv-mode='homeowner'] .abv-hrec__shot { width: 184px; height: 178px; }
}

/* --- 4. THE PLACEMENT DRAWING --------------------------------------------
   It is a technical illustration, so it is presented as one: a bordered
   board, generous margin, and a caption that reads as a drawing note. */
.abv-root[data-abv-mode='homeowner'] .abv-planwrap .abv-planschem {
  padding: var(--h-2) var(--h-3) var(--h-1);
  border: 1px solid var(--h-rule);
  border-radius: var(--h-radius);
  background: #fff;
}
.abv-root[data-abv-mode='homeowner'] .abv-planwrap .abv-planschem figcaption {
  margin-top: 2px;
  padding: var(--h-2) 0 var(--h-2);
  border-top: 1px solid var(--h-rule-2);
  font-size: var(--h-help);
  font-style: normal;
  color: var(--h-muted);
  text-align: center;
}

/* --- 1 + 7. ARTWORK PANELS ------------------------------------------------
   The welcome board and the choice-card art share one navy and one padding
   so the set reads as one drawing set rather than assorted icons. */
.abv-root[data-abv-mode='homeowner'] .abv-welcome__art {
  background: #051124;
  border-radius: var(--h-radius);
  padding: 0;
  overflow: hidden;
}
.abv-root[data-abv-mode='homeowner'] .abv-card--status .abv-card__art {
  background: linear-gradient(180deg, rgba(57,147,223,.05) 0%, rgba(57,147,223,.10) 100%);
  border-radius: var(--h-radius-sm);
  padding: var(--h-2);
  color: var(--h-ink);
}

/* ==========================================================================
   PHASE 24 — HOMEOWNER PLACEMENT: THE REAL PROPERTY
   The generated cutaway is gone. For an existing home the visual is the live
   Google satellite view of the confirmed address; for a new build it is a
   deliberate "Planned home" state. Scoped to the homeowner calculator.
   ========================================================================== */

/* --- THE PROPERTY VIEW ---------------------------------------------------
   Sized by ASPECT RATIO rather than a fixed height so it stays useful from
   1440 down to 390 without ever eating the phone screen. Wide and cinematic
   on desktop; closer to 4:3 on a phone, where a wide strip would show almost
   no roof — but capped so the result page still scrolls sensibly. */
.abv-root[data-abv-mode='homeowner'] .abv-propmap {
  margin-top: 0;
  margin-left: 0;
  margin-right: 0;
  margin-bottom: 24px;
  border: 1px solid var(--h-rule);
  border-radius: var(--h-radius);
  overflow: hidden;
  background: var(--h-ink);
}
.abv-root[data-abv-mode='homeowner'] .abv-propmap .abv-map {
  position: relative;
  inset: auto;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: 460px;
  background: var(--h-ink);
}

/* The address sits on a navy plate under the imagery — clearly a caption for
   the property above it, and never overlaying Google's own attribution. */
.abv-root[data-abv-mode='homeowner'] .abv-propmap figcaption {
  padding: var(--h-2) var(--h-3);
  background: var(--h-ink);
  border-top: 0;
}
.abv-root[data-abv-mode='homeowner'] .abv-propmap__addr b {
  display: block;
  font-size: var(--h-ctrl);
  font-weight: 700;
  line-height: 1.3;
  color: #fff;
}
.abv-root[data-abv-mode='homeowner'] .abv-propmap__addr span {
  display: block;
  margin-top: 2px;
  font-size: var(--h-help);
  color: rgba(255, 255, 255, .72);
}

/* --- NEW CONSTRUCTION: A DELIBERATE STATE, NOT A MISSING MAP ------------- */
.abv-root[data-abv-mode='homeowner'] .abv-planned {
  margin: 0 0 var(--h-3);
  padding: var(--h-4) var(--h-3);
  border-radius: var(--h-radius);
  background: var(--h-ink);
  color: #fff;
}
.abv-root[data-abv-mode='homeowner'] .abv-planned__eyebrow {
  display: block;
  margin-bottom: var(--h-1);
  font-size: var(--h-eyebrow);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--h-accent);
}
.abv-root[data-abv-mode='homeowner'] .abv-planned p {
  margin: 0;
  max-width: 62ch;
  font-size: var(--h-ctrl);
  line-height: 1.6;
  color: rgba(255, 255, 255, .88);
}
.abv-root[data-abv-mode='homeowner'] .abv-planned__loc {
  margin-top: var(--h-3);
  padding-top: var(--h-2);
  border-top: 1px solid rgba(255, 255, 255, .16);
}
.abv-root[data-abv-mode='homeowner'] .abv-planned__loc > span {
  display: block;
  margin-bottom: 4px;
  font-size: var(--h-eyebrow);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
}
.abv-root[data-abv-mode='homeowner'] .abv-planned__addr b {
  display: block;
  font-size: var(--h-ctrl);
  font-weight: 700;
  color: #fff;
}
.abv-root[data-abv-mode='homeowner'] .abv-planned__addr span {
  display: block;
  margin-top: 2px;
  font-size: var(--h-help);
  color: rgba(255, 255, 255, .72);
}

/* --- SUGGESTED PLACEMENT ------------------------------------------------- */
.abv-root[data-abv-mode='homeowner'] .abv-guide {
  margin-top: 24px;
}
.abv-root[data-abv-mode='homeowner'] .abv-guide h5 {
  margin: 0 0 var(--h-2);
  line-height: 1.5;
  font-size: var(--h-eyebrow);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--h-muted);
}
.abv-root[data-abv-mode='homeowner'] .abv-guide .abv-tips {
  margin: 0 0 var(--h-2);
  padding-left: 20px;
}
.abv-root[data-abv-mode='homeowner'] .abv-guide .abv-tips li {
  margin-bottom: var(--h-1);
  font-size: var(--h-ctrl);
  line-height: 1.6;
  color: var(--h-ink);
}
.abv-root[data-abv-mode='homeowner'] .abv-guide .abv-tips li::marker { color: var(--h-accent); }
.abv-root[data-abv-mode='homeowner'] .abv-guide .abv-fine {
  margin: 0;
  font-size: var(--h-help);
  line-height: 1.6;
  color: var(--h-muted);
}
.abv-root[data-abv-mode='homeowner'] .abv-planwrap .abv-plan__lead {
  margin: 0 0 var(--h-2);
  font-size: var(--h-sub);
  color: var(--h-ink);
}

/* --- RESPONSIVE ---------------------------------------------------------- */
@media (max-width: 1040px) {
  .abv-root[data-abv-mode='homeowner'] .abv-propmap .abv-map { aspect-ratio: 16 / 10; }
}
@media (max-width: 768px) {
  .abv-root[data-abv-mode='homeowner'] .abv-propmap .abv-map {
    aspect-ratio: 3 / 2;
    max-height: 340px;
  }
}
@media (max-width: 480px) {
  /* On a phone a wide strip shows almost no roof, so it squares up — but the
     cap keeps it from taking over the result. */
  .abv-root[data-abv-mode='homeowner'] .abv-propmap .abv-map {
    aspect-ratio: 4 / 3;
    max-height: 300px;
  }
  .abv-root[data-abv-mode='homeowner'] .abv-planned { padding: var(--h-3) var(--h-2); }
}

/* ==========================================================================
   PHASE 25 — ORIENTATION SWEEP
   ========================================================================== */

/* A disabled Continue now says why. It sits on the left of the nav row so it
   reads before the button on desktop, and above it once the row stacks. */
.abv-root[data-abv-mode='homeowner'] .abv-nav__why {
  margin: 0;
  align-self: center;
  font-size: var(--h-help);
  line-height: 1.45;
  color: var(--h-muted);
}
@media (max-width: 620px) {
  .abv-root[data-abv-mode='homeowner'] .abv-nav {
    flex-wrap: wrap;
    row-gap: var(--h-2);
  }
  .abv-root[data-abv-mode='homeowner'] .abv-nav__why {
    order: -1;
    flex: 1 0 100%;
    text-align: left;
  }
}

/* Native smooth scrolling is what moves the viewport between steps; honour a
   reduced-motion request at the CSS layer too, so nothing animates even if a
   scroll is triggered by something other than ABVScroll. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .abv-root * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* scroll-margin is the belt to ABVScroll's braces: anything that gets focused
   or hash-targeted keeps clear of a sticky header without any script. */
.abv-root [data-abv-screen],
.abv-root [data-abv-sec],
.abv-root .abv-q,
.abv-root .abvp-title { scroll-margin-top: 96px; }

/* ==========================================================================
   PHASE 26 — RESERVE THE CALCULATOR'S SPACE
   Both calculators render as an empty <div class="abv-root"> that JavaScript
   fills at DOMContentLoaded. Measured: the container went 0 -> 453px
   (homeowner) and 0 -> 2252px (professional) about 1.8s into the load, and
   everything below it — the page content and the footer — moved down. That is
   the whole of the measured CLS: 0.152 homeowner, 0.554 professional.

   min-height is deliberately set BELOW each measured first-render height, so
   it can only ever reduce the growth and can never cause a collapse in the
   other direction. Numbers measured 2026-08-19 at each breakpoint; if the
   first screen gets taller these stay correct, they simply reserve slightly
   less.
   ========================================================================== */
.abv-root[data-abv-mode='homeowner'] { min-height: 440px; }   /* measured 453 */
.abv-root[data-abv-mode='professional'] { min-height: 2200px; } /* measured 2252 */

@media (max-width: 1100px) {
  .abv-root[data-abv-mode='homeowner'] { min-height: 415px; }     /* measured 426 @768 */
  .abv-root[data-abv-mode='professional'] { min-height: 2850px; } /* measured 2915 @768 */
}
@media (max-width: 620px) {
  .abv-root[data-abv-mode='homeowner'] { min-height: 465px; }     /* measured 477 @430 */
  .abv-root[data-abv-mode='professional'] { min-height: 3150px; } /* measured 3201 @430 */
}
@media (max-width: 380px) {
  .abv-root[data-abv-mode='homeowner'] { min-height: 510px; }     /* measured 532 @360 */
  .abv-root[data-abv-mode='professional'] { min-height: 3330px; } /* measured 3387 @360 */
}

/* The product photograph reserves its own box, so the recommendation card does
   not reflow when the image arrives. */
.abv-root[data-abv-mode='homeowner'] .abv-hrec__shot img { aspect-ratio: 1 / 1; }
.abv-root[data-abv-mode='homeowner'] .abv-card__art--shot img { aspect-ratio: 1 / 1; }

/* ==========================================================================
   PHASE 27 — THE STICKY MOBILE NAV MUST NOT SIT ON THE LAST ANSWER
   `.abv-nav` is position:sticky; bottom:0 with an opaque white background, so
   the forward action is always reachable on a phone — which is right. But it
   is painted OVER the scroll content, and at rest it covered the bottom ~70px
   of the last choice card: on "How big is the attic?" the "I'm not sure"
   option was clipped mid-sentence, and it is a legitimate answer.

   Measured at 390x780: nav occupies y 639-780 (141px). Reserving that much
   scroll room beneath the content lets every card clear the bar instead of
   living under it. The nav keeps its own sticky behaviour untouched.
   ========================================================================== */
@media (max-width: 620px) {
  /* The clearance must sit ABOVE the nav, on the content itself. Putting it
     after the nav (which is the last child) reserved space nothing could use:
     the bar still floated over the final card. */
  .abv-root[data-abv-mode='homeowner'] .abv-screen:not([data-abv-screen='result']) .abv-split__main,
  .abv-root[data-abv-mode='homeowner'] .abv-screen:not([data-abv-screen='result']) > .abv-cards {
    padding-bottom: 150px;
  }
}

/* ==========================================================================
   PHASE 27 — MAP CONTROLS ARE JOBSITE CONTROLS
   The planning-map mode buttons (Draw outline, Edit, Clear, Place) rendered
   at 40px. Everything else in the tool clears 44px, and these are the ones
   pressed on a roof with a phone in one hand. Height only — the compact
   horizontal padding that keeps the row on one line is untouched.
   ========================================================================== */
.abv-root[data-abv-mode='professional'] .abvp-btn--mini,
.abv-root[data-abv-mode='professional'] .abv-minibtn,
.abv-root[data-abv-mode='professional'] [data-abv-plan-act],
.abv-root[data-abv-mode='professional'] [data-abv-place] {
  min-height: 44px;
}

/* ============================================================================
   REVISION 3 — HOMEOWNER UX RESET
   Six screens, was eleven. Everything below styles markup that did not exist
   before this pass; nothing here overrides an existing rule except where it is
   scoped and commented. Ordered by the stage it belongs to.
   ========================================================================= */

/* ---- shared: sub-question heading, rule between merged questions ---------- */
.abv-q--sub { font-size: clamp(19px, 2.4vw, 24px); margin-top: 0; }
.abv-hr { height: 1px; background: var(--abv-line); border: 0; margin: var(--abv-6) 0 var(--abv-5); }
.abv-note--accent { border-left: 3px solid var(--abv-orange); background: var(--abv-tint); }

/* An unknown is not an error, so it never borrows the error colour. */
.abv-link {
  display: inline-block; background: none; border: 0; padding: 0;
  font: inherit; font-size: var(--abv-small); font-weight: var(--abv-w-strong);
  color: var(--abv-navy); text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}
.abv-link:hover { color: var(--abv-ink-head); }

/* ---- STAGE 1 · the routing segmented control ----------------------------- */
.abv-seg {
  display: inline-flex; padding: 4px; gap: 4px; margin: 0 0 var(--abv-3);
  background: var(--abv-bg-soft); border: 1px solid var(--abv-line);
  border-radius: var(--abv-radius-pill);
}
.abv-seg__opt { position: relative; }
.abv-seg__opt input { position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0; }
.abv-seg__opt > span {
  display: flex; align-items: center; justify-content: center;
  padding: 11px 20px; min-height: var(--abv-tap);
  font-size: var(--abv-small); font-weight: var(--abv-w-strong);
  color: var(--abv-muted); border-radius: var(--abv-radius-pill);
  transition: background-color var(--abv-dur) var(--abv-ease), color var(--abv-dur) var(--abv-ease);
}
.abv-seg__opt.is-on > span { background: var(--abv-navy); color: #fff; }
.abv-seg__opt input:focus-visible + span { outline: 3px solid var(--abv-blue-lt); outline-offset: 2px; }
.abv-seg__why { font-size: var(--abv-small); color: var(--abv-muted); margin: 0 0 var(--abv-5); }

/* The new-construction panel is type, not a drawing.
   The drawn blueprint is gone from the MARKUP, so the two-column grid that
   used to hold it now has a single child — which landed in the 96px art column
   and wrapped the copy to one word per line at 390. Measured on staging.
   Scoped to beat the homeowner-mode rule that sets the columns. */
.abv-newplan__art { display: none; }
.abv-root[data-abv-mode="homeowner"] .abv-newplan,
.abv-root[data-abv-mode="professional"] .abv-newplan { grid-template-columns: 1fr; }
@media (max-width: 620px) {
  .abv-root[data-abv-mode="homeowner"] .abv-newplan { grid-template-columns: 1fr; }
}

/* ---- STAGE 2 · attic size, its source, its qualifiers -------------------- */
.abv-areahead { display: flex; gap: var(--abv-5); align-items: flex-start; flex-wrap: wrap; }
.abv-areahead .abv-field { flex: 1 1 260px; min-width: 0; }
.abv-field--lead .abv-field__wrap input { font-size: 22px; font-weight: var(--abv-w-strong); }
.abv-areashot { flex: 0 0 auto; margin: 0; }
.abv-areashot img {
  display: block; width: 168px; height: auto;
  border-radius: var(--abv-radius); border: 1px solid var(--abv-line);
}
.abv-areashot figcaption {
  margin-top: 6px; font-size: 11px; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: var(--abv-muted);
}
.abv-source {
  margin: var(--abv-2) 0 0; font-size: var(--abv-small); color: var(--abv-muted);
  padding-left: 14px; position: relative;
}
.abv-source::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--abv-orange);
}

/* The derived path is a disclosure, not a peer choice. */
.abv-est { margin: var(--abv-5) 0 0; border-top: 1px solid var(--abv-line); }
.abv-est > summary {
  list-style: none; cursor: pointer; padding: var(--abv-4) 0;
  font-size: var(--abv-small); font-weight: var(--abv-w-strong); color: var(--abv-ink-head);
  display: flex; align-items: center; gap: var(--abv-2);
}
.abv-est > summary::-webkit-details-marker { display: none; }
.abv-est > summary::before {
  content: "+"; flex: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--abv-bg-soft); color: var(--abv-ink-head);
  display: grid; place-items: center; font-weight: 700; line-height: 1;
}
.abv-est[open] > summary::before { content: "\2212"; }
.abv-est__body { padding: 0 0 var(--abv-5); display: grid; gap: var(--abv-5); }

.abv-qual { margin-top: var(--abv-5); }
.abv-check { display: flex; align-items: flex-start; gap: var(--abv-3); cursor: pointer; }
.abv-check input {
  flex: none; width: 22px; height: 22px; margin: 0;
  accent-color: var(--abv-navy); cursor: pointer;
}
.abv-check > span { font-size: var(--abv-body); color: var(--abv-text); }
.abv-qual .abv-note { margin-top: var(--abv-4); }

/* ---- STAGE 3 · material photography + engine colour swatches ------------- */
/* A typographic tile where no photograph exists. Designed, not a placeholder. */
.abv-card__photo--plain, .abv-card__art--plain { background: var(--abv-navy); }
.abv-plaintile {
  display: grid; place-content: center; gap: 4px; width: 100%;
  aspect-ratio: 3 / 2; text-align: center; color: #fff;
}
.abv-plaintile b { font-size: 30px; font-weight: 800; line-height: 1; color: var(--abv-orange); }
.abv-plaintile i {
  font-style: normal; font-size: 11px; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: rgba(255, 255, 255, 0.82);
}

.abv-colour { margin-top: var(--abv-6); }
.abv-sws {
  display: grid; gap: var(--abv-3);
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
}
.abv-sw {
  position: relative; display: flex; flex-direction: column; gap: 8px;
  padding: 10px; text-align: left; cursor: pointer; font: inherit; color: var(--abv-text);
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  transition: border-color var(--abv-dur) var(--abv-ease), box-shadow var(--abv-dur) var(--abv-ease);
}
.abv-sw input { position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0; }
.abv-sw:hover { border-color: var(--abv-navy); }
.abv-sw.is-on { border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange); }
.abv-sw__chip {
  display: block; height: 40px; border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgba(5, 17, 36, 0.16);
}
.abv-sw__chip--plain {
  background: var(--abv-navy); color: var(--abv-orange);
  display: grid; place-items: center; font-weight: 800; font-size: 18px;
}
.abv-sw__name { font-size: 12.5px; line-height: 1.3; color: var(--abv-ink-head); }
.abv-sw input:focus-visible ~ .abv-sw__chip { outline: 3px solid var(--abv-blue-lt); outline-offset: 2px; }
.abv-band {
  margin: var(--abv-4) 0 0; font-size: var(--abv-small); color: var(--abv-text);
  padding: var(--abv-3) var(--abv-4);
  background: var(--abv-bg-soft); border-radius: var(--abv-radius);
}

/* ---- STAGE 4 · blueprint quick-picks, identifier, sun -------------------- */
.abv-bps {
  display: grid; gap: var(--abv-3); margin: 0 0 var(--abv-5);
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
}
.abv-bp {
  display: flex; flex-direction: column; gap: 6px; padding: var(--abv-4);
  cursor: pointer; text-align: left; font: inherit; color: var(--abv-blue-lt);
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  transition: border-color var(--abv-dur) var(--abv-ease), box-shadow var(--abv-dur) var(--abv-ease);
}
.abv-bp:hover { border-color: var(--abv-navy); }
.abv-bp.is-on { border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange); }
.abv-bp__art { display: block; }
.abv-bp__art svg { display: block; width: 100%; height: auto; }
.abv-bp__meta { display: flex; align-items: baseline; gap: 6px; }
.abv-bp__meta b { font-size: 16px; font-weight: 800; color: var(--abv-ink-head); }
.abv-bp__meta i { font-style: normal; font-size: 12px; color: var(--abv-muted); }
.abv-bp__tell { font-size: 12px; line-height: 1.35; color: var(--abv-muted); }

.abv-pitch__est {
  align-self: center; font-size: 10.5px; font-weight: 700;
  letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase;
  color: var(--abv-navy); background: var(--abv-tint);
  border: 1px solid var(--abv-orange); border-radius: var(--abv-radius-pill);
  padding: 3px 9px;
}
.abv-ident {
  margin: var(--abv-5) 0 0; padding: var(--abv-5);
  background: var(--abv-bg-soft); border-radius: var(--abv-radius-lg);
}
.abv-ident > .abv-q--sub { margin-bottom: var(--abv-4); }
.abv-picks { display: grid; gap: var(--abv-2); }
.abv-pick {
  text-align: left; padding: 13px var(--abv-4); min-height: var(--abv-tap);
  font: inherit; font-size: var(--abv-small); color: var(--abv-text);
  background: #fff; border: 1px solid var(--abv-line);
  border-radius: var(--abv-radius); cursor: pointer;
  transition: border-color var(--abv-dur) var(--abv-ease), box-shadow var(--abv-dur) var(--abv-ease);
}
.abv-pick:hover { border-color: var(--abv-navy); }
.abv-pick.is-on {
  border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange);
  font-weight: var(--abv-w-strong);
}
.abv-identshot { margin: 0 0 var(--abv-3); }
.abv-identshot img {
  display: block; width: 100%; max-width: 320px; height: auto;
  border-radius: var(--abv-radius); border: 1px solid var(--abv-line);
}
.abv-identshot figcaption {
  margin-top: 6px; font-size: 11px; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: var(--abv-muted);
}
.abv-lastresort {
  margin-top: var(--abv-5); padding-top: var(--abv-4);
  border-top: 1px solid var(--abv-line);
}
.abv-lastresort .abv-fine { margin: var(--abv-2) 0 0; }

/* Sun: type and tone. No drawn sun, no drawn tree. */
.abv-sunrow { margin-top: var(--abv-2); }
.abv-suns {
  display: grid; gap: var(--abv-3);
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.abv-suntile {
  position: relative; display: block; padding: var(--abv-5) var(--abv-4);
  border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  cursor: pointer; overflow: hidden;
  transition: border-color var(--abv-dur) var(--abv-ease), box-shadow var(--abv-dur) var(--abv-ease);
}
.abv-suntile input { position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0; }
.abv-suntile:hover { border-color: var(--abv-navy); }
.abv-suntile.is-on { border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange); }
.abv-suntile--bright { background: linear-gradient(160deg, #fff6ef 0%, #ffffff 62%); }
.abv-suntile--shade { background: linear-gradient(160deg, #eef1f6 0%, #ffffff 62%); }
.abv-suntile--plain { background: #fff; }
.abv-suntile__body b { display: block; font-size: 16px; font-weight: 800; color: var(--abv-ink-head); }
.abv-suntile__body small { display: block; margin-top: 4px; font-size: 12.5px; color: var(--abv-muted); }

/* ---- STAGE 5 · placement plates ------------------------------------------ */
.abv-card__art--plate { background: var(--abv-navy); padding: 0; }
.abv-plate {
  display: grid; place-content: center; width: 100%; aspect-ratio: 16 / 10;
  padding: var(--abv-4); text-align: center;
}
.abv-plate i {
  font-style: normal; font-size: 11.5px; font-weight: 700;
  letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase;
  color: var(--abv-orange);
}
/* A photograph, once the registry supplies one, replaces the plate entirely. */
.abv-card__art--shot img { display: block; width: 100%; height: auto; }

/* ---- RESULT · the intake number, the estimated-slope disclosure ---------- */
.abv-planshot { margin: var(--abv-4) 0 0; }
.abv-planshot img {
  display: block; width: 100%; max-width: 420px; height: auto;
  border-radius: var(--abv-radius); border: 1px solid rgba(255, 255, 255, 0.18);
}
.abv-intake {
  margin: var(--abv-5) 0; padding: var(--abv-5) var(--abv-6);
  background: var(--abv-tint);
  border: 1px solid var(--abv-orange); border-left-width: 4px;
  border-radius: var(--abv-radius-lg);
}
.abv-intake .abv-eyebrow { color: var(--abv-navy); }
.abv-intake__fig { margin: 6px 0 0; display: flex; align-items: baseline; gap: 8px; }
.abv-intake__fig b {
  font-size: clamp(32px, 5vw, 44px); font-weight: 800; line-height: 1;
  color: var(--abv-ink-head); font-variant-numeric: tabular-nums;
}
.abv-intake__fig i {
  font-style: normal; font-size: 15px; font-weight: 700; color: var(--abv-ink-head);
}
.abv-intake__say { margin: var(--abv-3) 0 0; font-size: var(--abv-body); color: var(--abv-text); }
.abv-intake .abv-fine { margin: var(--abv-3) 0 0; }

.abv-estnote {
  margin: var(--abv-5) 0; padding: var(--abv-4) var(--abv-5);
  background: var(--abv-tint); border-left: 3px solid var(--abv-orange);
  border-radius: 0 var(--abv-radius) var(--abv-radius) 0;
}
.abv-estnote > b { display: block; font-size: 15px; color: var(--abv-ink-head); }
.abv-estnote > b i {
  font-style: normal; font-size: 10.5px; font-weight: 700; margin-left: 6px;
  letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase; color: var(--abv-navy);
  border: 1px solid var(--abv-orange); border-radius: var(--abv-radius-pill); padding: 2px 7px;
}
.abv-estnote > p { margin: var(--abv-2) 0 var(--abv-3); font-size: var(--abv-small); color: var(--abv-text); }

/* ---- MOBILE ------------------------------------------------------------- */
@media (max-width: 640px) {
  .abv-seg { display: flex; width: 100%; }
  .abv-seg__opt { flex: 1; }
  .abv-seg__opt > span { padding: 11px 8px; }
  .abv-areahead { flex-direction: column; }
  /* flex-basis follows the MAIN AXIS. The 260px basis above is a width in the
     desktop row; once this becomes a column it turns into a 260px HEIGHT, and
     the field padded itself out to 260px around 86px of content — 174px of dead
     space between the input and its source line. Measured at 390 on staging. */
  .abv-areahead .abv-field { flex: 0 0 auto; }
  .abv-areashot { order: -1; }
  .abv-areashot img { width: 100%; max-width: 100%; }
  /* Two-up minimum: tiles never shrink to icons. */
  .abv-sws { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .abv-bps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .abv-suns { grid-template-columns: 1fr; }
  .abv-intake { padding: var(--abv-4); }
  .abv-ident { padding: var(--abv-4); }
}
@media (max-width: 380px) {
  .abv-sws { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================================
   REVISION 3 — KIT BUTTON RESET  (found in the visual pass, 2026-08-20)
   The Elementor kit paints EVERY bare <button> in this document: background
   #EF7D48, white text, padding 32px 48px. Measured on staging — the four
   pitch quick-picks, the identifier link and its answer buttons, and the
   colour "Not sure" tile all rendered as solid orange blocks, because the
   kit's selector outranks the plain class selectors that style them.

   Everything below is scoped under .abv-root purely to win that fight. No new
   design decisions here — these are the values already declared above,
   re-asserted at a specificity the kit cannot beat.
   ========================================================================= */
.abv-root :is(.abv-bp, .abv-pick, .abv-link, .abv-sw, .abv-sw--plain) {
  -webkit-appearance: none;
  appearance: none;
  box-shadow: none;
  text-transform: none;
  letter-spacing: normal;
  font-family: inherit;
  min-height: 0;
}
.abv-root .abv-link {
  background: none; border: 0; padding: 0;
  font-size: var(--abv-small); font-weight: var(--abv-w-strong);
  color: var(--abv-navy); text-decoration: underline; text-underline-offset: 3px;
}
.abv-root .abv-link:hover { background: none; color: var(--abv-ink-head); }
.abv-root .abv-bp {
  background: #fff; color: var(--abv-blue-lt);
  border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  padding: var(--abv-4); text-align: left;
}
.abv-root .abv-bp:hover { background: #fff; border-color: var(--abv-navy); }
.abv-root .abv-bp.is-on { background: #fff; border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange); }
.abv-root .abv-pick {
  background: #fff; color: var(--abv-text);
  border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  padding: 13px var(--abv-4); min-height: var(--abv-tap); text-align: left;
  font-size: var(--abv-small);
}
.abv-root .abv-pick:hover { background: #fff; border-color: var(--abv-navy); }
.abv-root .abv-pick.is-on {
  background: #fff; border-color: var(--abv-orange);
  box-shadow: inset 0 0 0 1px var(--abv-orange); font-weight: var(--abv-w-strong);
}
.abv-root .abv-sw, .abv-root .abv-sw--plain {
  background: #fff; color: var(--abv-text);
  border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  padding: 10px; text-align: left;
}
.abv-root .abv-sw:hover, .abv-root .abv-sw--plain:hover { background: #fff; border-color: var(--abv-navy); }
.abv-root .abv-sw.is-on { background: #fff; border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange); }

/* ---- PROGRESS TREATMENT (approved palette) --------------------------------
   The stage counter was neutral grey. Progress is structural, so the label is
   NAVY, and it carries one small BREEZE ORANGE accent bar. Deliberately still a
   single progress signal — the accent marks it, it does not become a second
   progress system alongside the counter. */
.abv-root[data-abv-mode="homeowner"] .abv-steps__label,
.abv-root[data-abv-mode="professional"] .abv-steps__label,
.abv-root .abv-steps__label {
  color: var(--abv-navy);
  font-weight: var(--abv-w-strong);
  display: inline-flex; align-items: center; gap: 10px;
}
.abv-root[data-abv-mode="homeowner"] .abv-steps__label::before,
.abv-root .abv-steps__label::before {
  content: ""; flex: none; width: 18px; height: 3px; border-radius: 2px;
  background: var(--abv-orange);
}

/* ---- EYEBROW HIERARCHY (approved palette) ---------------------------------
   Two homeowner-scoped rules outranked the palette intent, so they are
   corrected here at matching specificity:

   · On the NAVY recommendation card the eyebrow is the signature Attic Breeze
     accent — BREEZE ORANGE on navy, 6.92:1.
   · On the orange-tinted intake callout it is structural — NAVY on tint,
     16.45:1. It had fallen back to the generic muted grey. */
.abv-root[data-abv-mode="homeowner"] .abv-rec .abv-eyebrow { color: var(--abv-orange); }
.abv-root[data-abv-mode="homeowner"] .abv-intake .abv-eyebrow { color: var(--abv-navy); }

/* ============================================================================
   REVISION 3 — SECOND REFINEMENT PASS
   Button language taken from The Breeze Lab (8682), mapped onto the approved
   calculator palette. Plus the pitch disclosure, the text-first placement
   rows, the banded colour picker, and the density fixes.
   ========================================================================= */

/* ---- BUTTONS · Breeze Lab design language --------------------------------
   Measured on /the-breeze-lab/:
     pill radius 999 · height 48 · padding 13px 22px · Poppins 700 13.5px
     letter-spacing 1.1px · uppercase · 1.78px solid border
     transition background-color/border-color/color 0.2s ease
     hover  translateY(-2px) + box-shadow rgba(5,17,36,.18) 0 8px 20px
     and an orange fill hovers to navy.

   COLOUR IS MAPPED, NOT COPIED. Breeze Lab has an orange filled pill; that is
   the white-on-#EF7D48 2.73:1 case already rejected, so the calculator's
   primary takes Breeze Lab's NAVY filled pill instead. Breeze Orange becomes
   the hover/selection accent — the style is theirs, the hierarchy is ours.
   -------------------------------------------------------------------------- */
.abv-root[data-abv-mode="homeowner"] .abv-btn,
.abv-root[data-abv-mode="homeowner"] .abv-btn--ghost,
.abv-root[data-abv-mode="homeowner"] .abv-btn--quiet {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--abv-font);
  font-size: 13.5px; font-weight: 700; letter-spacing: 1.1px; line-height: 1.25;
  text-transform: uppercase; text-decoration: none;
  border-radius: 999px; border: 1.78px solid transparent;
  cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease, color .2s ease,
              transform .2s ease, box-shadow .2s ease;
}
.abv-root[data-abv-mode="homeowner"] .abv-btn,
.abv-root[data-abv-mode="homeowner"] .abv-btn--ghost {
  min-height: 48px; padding: 13px 22px;
}

/* PRIMARY — navy fill, white text. Hover adds the Breeze Lab lift and an
   ORANGE border as the accent cue, so the label keeps its 18.88:1. */
.abv-root[data-abv-mode="homeowner"] .abv-btn {
  background: var(--abv-navy); color: #fff; border-color: var(--abv-navy);
}
.abv-root[data-abv-mode="homeowner"] .abv-btn:hover:not(:disabled),
.abv-root[data-abv-mode="homeowner"] .abv-btn:focus-visible:not(:disabled) {
  background: var(--abv-navy); color: #fff; border-color: var(--abv-orange);
  transform: translateY(-2px); box-shadow: 0 8px 20px rgba(5, 17, 36, .18);
}
.abv-root[data-abv-mode="homeowner"] .abv-btn:active:not(:disabled) {
  transform: translateY(0); box-shadow: none;
}
.abv-root[data-abv-mode="homeowner"] .abv-btn:disabled,
.abv-root[data-abv-mode="homeowner"] .abv-btn[aria-disabled="true"] {
  opacity: .42; transform: none; box-shadow: none; cursor: not-allowed;
}

/* SECONDARY — Breeze Lab's outline pill, filling to navy on hover. */
.abv-root[data-abv-mode="homeowner"] .abv-btn--ghost {
  background: transparent; color: var(--abv-navy); border-color: var(--abv-navy);
}
.abv-root[data-abv-mode="homeowner"] .abv-btn--ghost:hover:not(:disabled),
.abv-root[data-abv-mode="homeowner"] .abv-btn--ghost:focus-visible:not(:disabled) {
  background: var(--abv-navy); color: #fff; border-color: var(--abv-navy);
  transform: translateY(-2px); box-shadow: 0 8px 20px rgba(5, 17, 36, .18);
}

/* QUIET — Breeze Lab's text-link variant (11.5px / 1.38px / gap 8px), with the
   orange mapped to navy because orange text on white is 2.73:1. */
.abv-root[data-abv-mode="homeowner"] .abv-btn--quiet {
  background: none; border-color: transparent; padding: 8px 0; min-height: 44px;
  color: var(--abv-navy); font-size: 11.5px; letter-spacing: 1.38px;
}
.abv-root[data-abv-mode="homeowner"] .abv-btn--quiet:hover {
  background: none; color: var(--abv-navy);
  text-decoration: underline; text-underline-offset: 4px;
}

/* ---- PROPERTY IMAGE · the confirmation sits below it, never over it ------- */
.abv-root .abv-confirm {
  position: static; inset: auto; transform: none; margin: var(--abv-4) 0 0;
  display: flex; flex-wrap: wrap; gap: var(--abv-4);
  align-items: center; justify-content: space-between;
  padding: var(--abv-4) var(--abv-5);
  background: #fff; border: 1px solid var(--abv-line);
  border-left: 4px solid var(--abv-orange);
  border-radius: var(--abv-radius); box-shadow: none;
}
.abv-root .abv-confirm__text b { display: block; color: var(--abv-navy); font-size: 15px; }
.abv-root .abv-confirm__text span { font-size: var(--abv-small); color: var(--abv-muted); }
.abv-root .abv-confirm__actions { display: flex; gap: var(--abv-3); flex-wrap: wrap; }

/* ---- PITCH · quick-picks lead, fine control is a disclosure --------------- */
.abv-bps { grid-template-columns: repeat(auto-fit, minmax(164px, 1fr)); gap: var(--abv-4); }
.abv-root .abv-bp { padding: var(--abv-5) var(--abv-4); gap: 8px; }
.abv-bp__art svg { max-height: 74px; }
.abv-bp__meta b { font-size: 18px; }
.abv-bp__tell { font-size: 12.5px; white-space: normal; }

/* One concise confirmation line, replacing the old always-on technical panel. */
.abv-chosen {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: var(--abv-4) 0 0; padding: var(--abv-3) var(--abv-4);
  background: var(--abv-bg-soft); border-radius: var(--abv-radius);
  border-left: 3px solid var(--abv-orange);
}
.abv-chosen__label {
  font-size: 11px; font-weight: 700; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: var(--abv-muted);
}
.abv-chosen__val { font-size: 19px; font-weight: 800; color: var(--abv-navy); }
.abv-chosen__deg { font-size: var(--abv-small); color: var(--abv-muted); }
.abv-chosen__est {
  font-size: 10.5px; font-weight: 700; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: var(--abv-navy);
  border: 1px solid var(--abv-orange); border-radius: 999px; padding: 2px 8px;
}

/* The shared "more" disclosure used by pitch and by exact colours. */
.abv-more { margin: var(--abv-4) 0 0; border-top: 1px solid var(--abv-line); }
.abv-root .abv-more > summary {
  list-style: none; cursor: pointer; padding: var(--abv-4) 0;
  font-family: var(--abv-font); font-size: 12px; font-weight: 700;
  letter-spacing: 1.1px; text-transform: uppercase; color: var(--abv-navy);
  display: flex; align-items: center; gap: 10px;
}
.abv-root .abv-more > summary::-webkit-details-marker { display: none; }
.abv-root .abv-more > summary::before {
  content: ""; flex: none; width: 18px; height: 3px; border-radius: 2px;
  background: var(--abv-orange);
  transition: width .2s ease;
}
.abv-root .abv-more[open] > summary::before { width: 30px; }
.abv-root .abv-more > summary:hover { text-decoration: underline; text-underline-offset: 4px; }
.abv-more__body { padding: 0 0 var(--abv-5); }
.abv-more__say { font-size: var(--abv-small); color: var(--abv-muted); margin: 0 0 var(--abv-4); }
/* Inside the disclosure the old panel is plain, not a grey slab. */
.abv-root .abv-more .abv-pitch { background: transparent; padding: 0; }

/* ---- COLOUR · band tiles first, exact colours behind the disclosure ------- */
.abv-bands {
  display: grid; gap: var(--abv-3); margin: 0 0 var(--abv-3);
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
}
.abv-root .abv-bandtile {
  position: relative; display: flex; flex-direction: column; gap: 10px;
  padding: var(--abv-4); cursor: pointer; text-align: left;
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.abv-bandtile input { position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0; }
.abv-root .abv-bandtile:hover { border-color: var(--abv-navy); transform: translateY(-2px); }
.abv-root .abv-bandtile.is-on {
  border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange);
}
.abv-bandtile__strip { display: flex; gap: 4px; }
.abv-bandtile__strip i {
  display: block; flex: 1; height: 34px; border-radius: 4px;
  box-shadow: inset 0 0 0 1px rgba(5, 17, 36, .16);
}
.abv-bandtile__body b { display: block; font-size: 16px; font-weight: 800; color: var(--abv-navy); }
.abv-bandtile__body small { display: block; margin-top: 3px; font-size: 12px; line-height: 1.4; color: var(--abv-muted); }

/* "I don't know the colour" is a deliberate action on its own row. */
.abv-unsure-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--abv-3);
  margin-top: var(--abv-2); padding-top: var(--abv-3);
  border-top: 1px solid var(--abv-line);
}
.abv-unsure-row .abv-fine { margin: 0; }

/* ---- INSTALL · text-first placement rows --------------------------------- */
.abv-root .abv-card--text {
  display: block; padding: var(--abv-5); min-height: 0;
}
.abv-root .abv-card--text .abv-card__body b {
  display: block; font-size: 18px; font-weight: 800; color: var(--abv-navy);
  letter-spacing: -.2px;
}
.abv-root .abv-card--text .abv-card__body small {
  display: block; margin-top: 5px; font-size: 13.5px; line-height: 1.5; color: var(--abv-muted);
}
.abv-root .abv-card--text.is-on .abv-card__body b { color: var(--abv-navy); }
/* One column: these are rows, not a grid of thumbnails. */
.abv-cards--install { grid-template-columns: 1fr; gap: var(--abv-3); }
/* The fan-style tiles keep the product photograph, so they stay a grid. */
.abv-panel .abv-cards--install { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* ---- DENSITY · tablet material 3-up, mobile result stats 2-up ------------- */
@media (min-width: 700px) and (max-width: 1024px) {
  /* Measured at 768: 3-up gives ~228px cards — the photo stays legible and the
     title fits on one line, so 3-up it is. */
  .abv-cards--photo { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  /* Short figures pair cleanly; nothing is shrunk and nothing long is squeezed. */
  .abv-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--abv-3); }
  .abv-stats .abv-stat { min-width: 0; }
  .abv-bps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--abv-3); }
  .abv-bands { grid-template-columns: 1fr; }
  .abv-bandtile__strip i { height: 28px; }
  .abv-confirm { flex-direction: column; align-items: stretch; }
  .abv-confirm__actions .abv-btn,
  .abv-confirm__actions .abv-btn--ghost { flex: 1; }
}

/* ---- MOBILE DENSITY · band tiles ------------------------------------------
   At 390 three stacked band tiles cost ~330px and made the roof stage the
   longest in the flow. Three across keeps the real colour chips — which is what
   the homeowner recognises — and drops the name caption, whose full list is one
   tap away under "Pick my exact colour". */
@media (max-width: 640px) {
  .abv-bands { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--abv-2); }
  .abv-root .abv-bandtile { padding: var(--abv-3); gap: 7px; }
  .abv-bandtile__strip { gap: 3px; }
  .abv-bandtile__strip i { height: 30px; }
  .abv-bandtile__body b { font-size: 14px; }
  .abv-bandtile__body small { display: none; }
}

/* ---- STICKY-NAV CLEARANCE, RE-TARGETED -----------------------------------
   A pre-existing rule puts 150px of bottom padding on the last block of a
   homeowner screen so nothing hides behind the sticky Continue button. On the
   roof stage the tile grid is no longer the last block — the colour question
   follows it — so that clearance was stranded in the middle of the page as
   150px of dead space between the tiles and "How dark is the roof?". Measured
   at 390. The clearance stays wherever it is still last; here it goes. */
.abv-root[data-abv-mode="homeowner"] .abv-screen[data-abv-screen="roof"] .abv-cards--photo {
  padding-bottom: 0;
}

/* ---- MOBILE RESULT STATS · 2-up ------------------------------------------
   A homeowner-scoped rule forces these to one column all the way up to 860px,
   which left two short figures ("1,810 CFM", "1,925 CFM") stacked with a lot of
   air around them. They pair cleanly. Scoped and narrowed so it beats that rule
   without touching the 861px+ layout. Nothing is shrunk: same type, same tile
   padding — only the column count changes. */
@media (max-width: 640px) {
  .abv-root[data-abv-mode="homeowner"] .abv-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--abv-3);
  }
  .abv-root[data-abv-mode="homeowner"] .abv-stats > * { min-width: 0; }
}

/* =============================================================================
   REVISION 4 — flipped attic sizing (both calculators)
   The home size leads; the estimated attic floor area is the live, derived
   answer; "I know my attic floor area" is the manual override. Blocks that
   used to live inside the estimator disclosure now stand in the main column,
   so they carry their own rhythm here.
   ========================================================================== */
.abv-areahead { margin-bottom: var(--abv-5); }
.abv-estimate { margin: 0 0 var(--abv-4); }
/* .abv-btn--quiet sets display:inline-flex, which would defeat the [hidden]
   attribute on the back-to-estimate button. hidden must always win. */
.abv-root [hidden] { display: none !important; }
.abv-estimate .abv-btn--quiet { margin: var(--abv-2) 0 0; padding-left: 0; }

/* Professional: the two sizing panels swap; the segmented mode control is the
   existing .abv-seg. Estimate figure reads as the answer, not a suggestion. */
.abvp-grp [data-abv-mode-home], .abvp-grp [data-abv-mode-direct] { display: grid; gap: var(--abv-4, 16px); }

/* REV4: the identifier's candidate shortlist. Same blueprint tiles as the
   quick-picks; the say-line is navy structural text per the palette. */
.abv-identcands { margin: var(--abv-5) 0 0; }
.abv-identcands__say { margin: 0 0 var(--abv-2); font-size: var(--abv-body); font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-identcands .abv-bps { margin: var(--abv-4) 0; }

/* REV4: contractor-program routing (professional). The question block is a
   compact optional group in step 1; the What's-next card sits after the
   proposal actions — technical work first, program second. Orange is the
   accent (kicker), navy carries the CTA, per the approved calculator palette. */
.abv-root[data-abv-mode='professional'] .abvp-program { display: grid; gap: var(--abv-4, 16px); }
.abv-root[data-abv-mode='professional'] .abvp-next {
  margin: 22px 0 0; padding: 24px 26px;
  background: var(--p-panel, #ffffff); border: 1px solid var(--p-line, rgba(5,17,36,.14)); border-radius: 12px;
}
.abv-root[data-abv-mode='professional'] .abvp-next__kicker { color: var(--abv-orange, #EF7D48); }
.abv-root[data-abv-mode='professional'] .abvp-next__title {
  margin: 6px 0 8px; font-size: 19px; font-weight: 800; color: var(--p-ink, #051124);
}
.abv-root[data-abv-mode='professional'] .abvp-next__body {
  margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: var(--p-ink-2, #3E3E3E); max-width: 640px;
}
.abv-root[data-abv-mode='professional'] .abvp-next__row {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
}

/* REV4: company logo — manual upload primary, website lookup secondary
   (professional, step 1). */
.abv-root[data-abv-mode='professional'] .abvp-logo { margin-top: 26px; display: grid; gap: 14px; }
.abv-root[data-abv-mode='professional'] .abvp-logo .abvp-grp__note { margin-bottom: 0; }
.abv-root[data-abv-mode='professional'] .abvp-logo__primary {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.abv-root[data-abv-mode='professional'] .abvp-logo__primary .abvp-help { flex: 1 1 240px; margin: 0; }
/* The website-URL logo import was removed 2026-08-21 — its separator, input
   row and failure panel are gone with it. Uploading is the only logo path. */
.abv-root[data-abv-mode='professional'] .abvp-logo__found {
  display: flex; gap: 18px; align-items: center; flex-wrap: wrap;
  padding: 16px 18px; background: #fff; border: 1px solid var(--p-line, rgba(5,17,36,.14)); border-radius: 10px;
}
.abv-root[data-abv-mode='professional'] .abvp-logo__shot {
  flex: 0 0 auto; display: grid; place-items: center; width: 200px; min-height: 80px;
  background: #fff; border: 1px dashed var(--p-line, rgba(5,17,36,.14)); border-radius: 8px; padding: 8px;
}
.abv-root[data-abv-mode='professional'] .abvp-logo__shot img {
  max-width: 180px; max-height: 72px; width: auto; height: auto; display: block;
}
.abv-root[data-abv-mode='professional'] .abvp-logo__meta { display: grid; gap: 6px; min-width: 220px; flex: 1 1 220px; }
.abv-root[data-abv-mode='professional'] .abvp-logo__meta b { font-size: 14px; color: var(--p-ink, #051124); }
.abv-root[data-abv-mode='professional'] .abvp-logo__btns { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 4px; }

/* REV4: manufacturer roof-color library (homeowner exact-color panel). */
.abv-mfrbar { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 var(--abv-4); }
.abv-mfrpill {
  padding: 8px 14px; border: 1.5px solid var(--abv-line); border-radius: 999px;
  background: #fff; color: var(--abv-ink-head); font-family: var(--abv-font);
  font-size: 12.5px; font-weight: var(--abv-w-strong); cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease;
}
.abv-mfrpill:hover { border-color: var(--abv-navy); }
.abv-mfrpill.is-on { border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange); }

.abv-sws--library { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: var(--abv-4); }
.abv-sws__abhead {
  grid-column: 1 / -1; margin: var(--abv-3) 0 0; padding-top: var(--abv-4);
  border-top: 1px solid var(--abv-line);
  font-size: var(--abv-small); font-weight: var(--abv-w-strong); color: var(--abv-ink-head);
}
.abv-mclr {
  position: relative; display: flex; flex-direction: column; gap: 8px;
  padding: 10px; background: #fff; border: 1.5px solid var(--abv-line); border-radius: 10px;
  cursor: pointer; transition: border-color .15s ease;
}
.abv-mclr input { position: absolute; opacity: 0; pointer-events: none; }
.abv-mclr:hover { border-color: var(--abv-navy); }
.abv-mclr.is-on { border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange); }
.abv-mclr__shot img { display: block; width: 100%; height: auto; border-radius: 6px; }
.abv-mclr__meta { display: grid; gap: 2px; }
.abv-mclr__meta b { font-size: 14px; color: var(--abv-ink-head); }
.abv-mclr__meta small { font-size: 11.5px; color: var(--abv-muted); }
.abv-mclr__band { font-style: normal; font-size: 11px; font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-mclr__pending { font-style: normal; font-size: 11px; color: var(--abv-muted); }
.abv-mclr.is-pending { cursor: not-allowed; opacity: .62; }
.abv-mclr.is-pending:hover { border-color: var(--abv-line); }
.abv-attrib { margin-top: var(--abv-4); color: var(--abv-muted); max-width: 640px; }
@media (max-width: 480px) {
  .abv-sws--library { grid-template-columns: repeat(2, 1fr); }
}

/* =============================================================================
   REV4 IMAGERY — image first, color/product name second.
   Manufacturer cards and photo-backed Attic Breeze references share one card:
   real roof photo (majority of the card, 4:3 presentation window), brand/line
   small, COLOR NAME prominent, band as a small supporting label. Selected =
   Breeze Orange. Square source photos are cropped by CSS (object-fit) only —
   presentation, not file modification — and width/height attributes match the
   real files so nothing shifts while loading.
   ========================================================================== */
.abv-mclr__shot { display: block; aspect-ratio: 4 / 3; overflow: hidden; border-radius: 6px; }
.abv-mclr__shot img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; }
.abv-mclr__meta small { order: -1; }
.abv-mclr__meta b { font-size: 15.5px; letter-spacing: .1px; }
.abv-mclr--ref .abv-mclr__meta small { text-transform: uppercase; letter-spacing: .8px; font-size: 10px; }

/* Light / Medium / Dark tiles with real roof photography (shingle). The photo
   IS the tile face; the band word and the real color names sit beneath it. */
.abv-bandtile--photo { display: flex; flex-direction: column; gap: 10px; }
.abv-bandtile__shot { display: block; aspect-ratio: 8 / 3; overflow: hidden; border-radius: 8px; }
.abv-bandtile__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ==== REV4 — MANUFACTURER EXACT-COLOR PANELS (Metal / Tile + pro library) ====
   HOMEOWNER: material -> manufacturer -> profile -> color, inside the existing
   "Pick my exact color" shelf. PROFESSIONAL: the same catalog behind a denser
   pill navigation. All presentation — selection still rides the same radios. */

/* -- homeowner: manufacturer chooser cards --
   Three-class specificity + full reset: the Elementor kit (post-1333) paints
   every bare <button> as an orange 32/48 uppercase slab with nowrap text. */
.abv-mfrs { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--abv-4); }
.abv-root .abv-sws .abv-mfrchoice,
.abv-root .abv-sws .abv-profchoice,
.abv-root .abv-sws .abv-crumb__back {
  -webkit-appearance: none; appearance: none;
  display: grid; gap: 4px; min-height: 0; width: 100%; max-width: 100%;
  padding: 14px; margin: 0; text-align: left; cursor: pointer;
  font-family: var(--abv-font); font-size: 13px; font-weight: 400; line-height: 1.45;
  letter-spacing: normal; text-transform: none; text-decoration: none;
  white-space: normal; overflow-wrap: anywhere;
  color: var(--abv-ink); background: #fff;
  border: 1px solid var(--abv-line); border-radius: 10px; box-shadow: none;
}
.abv-root .abv-sws .abv-mfrchoice:hover,
.abv-root .abv-sws .abv-profchoice:hover,
.abv-root .abv-sws .abv-crumb__back:hover { background: #fff; color: var(--abv-ink); border-color: var(--abv-navy); }
.abv-mfrchoice b { font-size: 15px; color: var(--abv-ink-head); }
.abv-mfrchoice small { font-size: 12px; color: var(--abv-muted); line-height: 1.4; }
.abv-mfrchoice i { font-style: normal; font-size: 11px; font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }

/* -- homeowner: breadcrumb + notes -- */
.abv-crumb { grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.abv-crumb b { font-size: 14px; color: var(--abv-ink-head); }
.abv-root .abv-sws .abv-crumb__back {
  display: inline-flex; align-items: center; width: auto;
  padding: 6px 12px; font-size: 12.5px; font-weight: var(--abv-w-strong);
  color: var(--abv-ink-head); border-radius: 999px;
}
.abv-mfr-note { grid-column: 1 / -1; margin: 0; }
.abv-stdref-row { grid-column: 1 / -1; }

/* -- homeowner: profile chooser (photo cards where official imagery exists) -- */
.abv-profiles { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--abv-4); }
.abv-root .abv-sws .abv-profchoice { padding: 10px; }
.abv-profchoice b { font-size: 14px; color: var(--abv-ink-head); }
.abv-profchoice small { font-size: 12px; color: var(--abv-muted); }
.abv-prof__shot { display: block; aspect-ratio: 16 / 9; overflow: hidden; border-radius: 6px; }
.abv-prof__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* -- homeowner: manufacturer color card visuals --
   Approximate tone preview where official swatches are rights-pending — never
   a substitute photograph; the microlabel says exactly what it is. */
.abv-mclr__tone {
  display: flex; align-items: flex-end; aspect-ratio: 4 / 3; border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgba(5, 17, 36, .18);
}
.abv-mclr__tone i {
  font-style: normal; font-size: 9px; letter-spacing: .5px; text-transform: uppercase;
  margin: 0 0 4px 6px; padding: 1px 6px; border-radius: 999px;
  background: rgba(255, 255, 255, .85); color: var(--abv-ink-head);
}
.abv-mclr__descbox {
  display: grid; align-content: center; gap: 4px; aspect-ratio: 4 / 3; padding: 10px;
  border-radius: 6px; background: var(--abv-paper, #ffffff);
  box-shadow: inset 0 0 0 1px rgba(5, 17, 36, .10);
}
.abv-mclr__descbox b { font-size: 12px; line-height: 1.35; color: var(--abv-ink-head); font-weight: var(--abv-w-strong); }
.abv-mclr__descbox i { font-style: normal; font-size: 10.5px; color: var(--abv-muted); }
.abv-mclr__mto { font-style: normal; font-size: 10.5px; color: var(--abv-muted); }

/* -- professional: manufacturer pills + profile chips --
   Same kit-defeating reset discipline as .abvp-btn (post-1333 paints every
   bare <button> orange, uppercase, nowrap). */
.abvp-mfrbar { grid-column: 1 / -1; display: flex; gap: 6px; flex-wrap: wrap; }
.abv-root[data-abv-mode='professional'] .abvp-mfrpill {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; min-height: 0; width: auto; max-width: 100%;
  padding: 6px 12px; margin: 0; cursor: pointer;
  font: inherit; font-size: var(--p-label); font-weight: 600; line-height: 1.3;
  letter-spacing: normal; text-transform: none; white-space: normal;
  color: var(--p-ink); background: #fff; box-shadow: none;
  border: 1px solid var(--p-rule); border-radius: 999px;
}
.abv-root[data-abv-mode='professional'] .abvp-mfrpill:hover { background: #fff; color: var(--p-ink); border-color: var(--p-accent); }
.abv-root[data-abv-mode='professional'] .abvp-mfrpill.is-on { border-color: var(--p-accent); box-shadow: inset 0 0 0 1px var(--p-accent); background: var(--p-accent-bg); }
.abv-root[data-abv-mode='professional'] .abvp-mfrpill--std { color: var(--p-ink-3); }
.abvp-profbar { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.abv-root[data-abv-mode='professional'] .abvp-profpill {
  -webkit-appearance: none; appearance: none;
  display: grid; gap: 3px; min-height: 0; width: 100%; max-width: 100%;
  padding: 8px; margin: 0; text-align: left; cursor: pointer;
  font: inherit; font-size: var(--p-label); font-weight: 400; line-height: 1.35;
  letter-spacing: normal; text-transform: none; white-space: normal; overflow-wrap: anywhere;
  color: var(--p-ink); background: #fff; box-shadow: none;
  border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm);
}
.abvp-profpill img { display: block; width: 100%; height: 54px; object-fit: cover; border-radius: 4px; }
.abvp-profpill b { font-size: var(--p-label); color: var(--p-ink); }
.abvp-profpill small { font-size: var(--p-help); color: var(--p-ink-3); }
.abv-root[data-abv-mode='professional'] .abvp-profpill:hover { background: #fff; color: var(--p-ink); border-color: var(--p-accent); }
.abv-root[data-abv-mode='professional'] .abvp-profpill.is-on { border-color: var(--p-accent); box-shadow: inset 0 0 0 1px var(--p-accent); }

/* -- professional: manufacturer color card visuals -- */
.abvp-sw__photo { flex: none; width: 44px; height: 44px; border-radius: 5px; overflow: hidden; }
.abvp-sw__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.abvp-sw__chip--approx { position: relative; }
.abvp-sw__chip--none {
  background: repeating-linear-gradient(45deg, rgba(57,147,223,.16), rgba(57,147,223,.16) 4px, rgba(57,147,223,.05) 4px, rgba(57,147,223,.05) 8px);
}
.abv-root[data-abv-mode='professional'] .abvp-sw__card.is-pending { cursor: not-allowed; opacity: .6; }
.abvp-mfrnote { font-size: var(--p-help) !important; }
.abvp-attrib { font-size: 10.5px !important; color: var(--p-ink-3) !important; background: none !important; padding: 4px 0 !important; }

/* ==== REV4b — UNIFIED EXACT-COLOR LIBRARY (search + banded groups) ========
   One system for Shingle, Metal and Tile on both calculators: a search field,
   then LIGHT / MEDIUM / DARK sections of image-led cards. No brand buttons. */

/* -- homeowner: search field -- */
.abv-csearch { display: grid; gap: 6px; margin: 0 0 var(--abv-4); }
.abv-csearch__label { font-size: 13px; font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-csearch__box { position: relative; }
.abv-root .abv-csearch__box input[type='search'] {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; min-height: 46px; padding: 10px 44px 10px 14px;
  font-family: var(--abv-font); font-size: 15px; color: var(--abv-ink);
  background: #fff; border: 1.5px solid var(--abv-line); border-radius: 10px; box-shadow: none;
}
.abv-root .abv-csearch__box input[type='search']:focus { border-color: var(--abv-navy); outline: none; }
.abv-csearch__box input::-webkit-search-cancel-button { display: none; }
.abv-root .abv-csearch__clear {
  -webkit-appearance: none; appearance: none;
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 32px; height: 32px; min-height: 0; padding: 0; margin: 0;
  display: grid; place-items: center; cursor: pointer;
  font: inherit; font-size: 20px; line-height: 1; letter-spacing: 0; text-transform: none;
  color: var(--abv-muted); background: transparent; border: 0; border-radius: 50%; box-shadow: none;
}
.abv-root .abv-csearch__clear:hover { background: var(--abv-paper, #ffffff); color: var(--abv-ink-head); }
.abv-csearch__count { margin: 0; }

/* -- homeowner: band group headings inside the card grid -- */
.abv-cgroup__head {
  grid-column: 1 / -1; display: flex; align-items: baseline; gap: 8px;
  margin: 10px 0 2px; padding-top: 12px; border-top: 1px solid var(--abv-line);
}
.abv-cgroup__head:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.abv-cgroup__head b {
  font-size: 12px; font-weight: var(--abv-w-strong); letter-spacing: 1.2px;
  color: var(--abv-ink-head);
}
.abv-cgroup__head span { font-size: 11.5px; color: var(--abv-muted); letter-spacing: .3px; }
.abv-cgroup__head--pending b { color: var(--abv-muted); }
.abv-cgroup__none { grid-column: 1 / -1; margin: 0; font-size: 13.5px; color: var(--abv-muted); }

/* -- homeowner: pending-chip visual for colors with no usable imagery yet -- */
.abv-mclr__chipmiss {
  display: block; aspect-ratio: 4 / 3; border-radius: 6px;
  background: repeating-linear-gradient(45deg, rgba(57,147,223,.16), rgba(57,147,223,.16) 5px, rgba(57,147,223,.05) 5px, rgba(57,147,223,.05) 10px);
  box-shadow: inset 0 0 0 1px rgba(5, 17, 36, .08);
}

/* -- professional: search + group headings + photo card sizing -- */
.abvp-csearch { grid-column: 1 / -1; display: grid; gap: 4px; }
.abvp-csearch__box { position: relative; }
.abv-root[data-abv-mode='professional'] .abvp-csearch__box input[type='search'] {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; min-height: 40px; padding: 8px 40px 8px 12px;
  font: inherit; font-size: var(--p-control); color: var(--p-ink);
  background: #fff; border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm); box-shadow: none;
}
.abv-root[data-abv-mode='professional'] .abvp-csearch__box input[type='search']:focus {
  border-color: var(--p-accent); outline: none;
}
.abvp-csearch__box input::-webkit-search-cancel-button { display: none; }
.abv-root[data-abv-mode='professional'] .abvp-csearch__clear {
  -webkit-appearance: none; appearance: none;
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; min-height: 0; padding: 0; margin: 0;
  display: grid; place-items: center; cursor: pointer;
  font: inherit; font-size: 18px; line-height: 1; letter-spacing: 0; text-transform: none;
  color: var(--p-ink-3); background: transparent; border: 0; border-radius: 50%; box-shadow: none;
}
.abv-root[data-abv-mode='professional'] .abvp-csearch__clear:hover { background: var(--p-ground); color: var(--p-ink); }
.abvp-csearch__count { margin: 0; font-size: var(--p-help); color: var(--p-ink-3); }
.abvp-cgroups { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 6px; }
.abvp-cghead {
  grid-column: 1 / -1; display: flex; align-items: baseline; gap: 8px;
  margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--p-rule);
}
.abvp-cghead:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.abvp-cghead b { font-size: 11px; font-weight: 800; letter-spacing: 1.1px; color: var(--p-ink); }
.abvp-cghead span { font-size: var(--p-help); color: var(--p-ink-3); }
.abvp-cghead--pending b { color: var(--p-ink-3); }
@media (max-width: 560px) {
  .abvp-cgroups { grid-template-columns: repeat(auto-fill, minmax(146px, 1fr)); }
}

/* ==========================================================================
   COASTAL / AEROBREEZE RECOMMENDATION (both calculators)
   A positive product recommendation, never a warning. Navy ground with the
   Breeze Orange accent doing the signalling — the same pairing the rest of
   the calculator uses for an emphasised, good-news block.
   ====================================================================== */
.abv-root .abv-coastal {
  margin: var(--abv-5) 0; padding: 22px 24px; border-radius: var(--abv-radius);
  background: var(--abv-navy, #051124); color: #fff;
  border-left: 4px solid var(--abv-orange, #EF7D48);
}
.abv-root .abv-coastal__eyebrow { color: var(--abv-orange, #EF7D48); }
.abv-root .abv-coastal__title {
  margin: 6px 0 10px; font-size: 20px; line-height: 1.25; color: #fff;
  font-weight: var(--abv-w-strong, 600);
}
.abv-root .abv-coastal__say { margin: 0 0 10px; font-size: 15px; line-height: 1.6; color: #fff; }
.abv-root .abv-coastal__say b { color: var(--abv-orange, #EF7D48); }
.abv-root .abv-coastal .abv-fine { color: rgba(255,255,255,.82); margin: 0 0 12px; }
.abv-root .abv-coastal .abv-fine a { color: #fff; text-decoration: underline; }
/* Three-class specificity: .abv-btn--ghost paints navy-on-transparent, which
   is invisible on this navy ground. Same trap as the kit button bleed. */
.abv-root .abv-coastal .abv-coastal__cta {
  display: inline-flex; margin-top: 4px; border-color: #fff; color: #fff; background: transparent;
}
.abv-root .abv-coastal .abv-coastal__cta:hover,
.abv-root .abv-coastal .abv-coastal__cta:focus-visible {
  background: #fff; color: var(--abv-navy, #051124); border-color: #fff;
}
@media (max-width: 520px) {
  .abv-root .abv-coastal { padding: 18px; }
  .abv-root .abv-coastal__title { font-size: 18px; }
}

/* Professional — technical, on white, sitting inside the result stack. */
.abv-root[data-abv-mode='professional'] .abvp-coastal {
  border-left: 4px solid var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-coastal__say {
  margin: 0 0 14px; font-size: 14px; line-height: 1.65; color: var(--p-ink-2, #3E3E3E); max-width: 70ch;
}
.abv-root[data-abv-mode='professional'] .abvp-coastal__sched { display: grid; gap: 8px; margin-bottom: 12px; }
.abv-root[data-abv-mode='professional'] .abvp-coastal__row {
  display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
  padding: 10px 14px; background: #fff; border: 1px solid var(--p-line, rgba(5,17,36,.14)); border-radius: 8px;
}
.abv-root[data-abv-mode='professional'] .abvp-coastal__row b { font-size: 14px; color: var(--p-ink, #051124); }
.abv-root[data-abv-mode='professional'] .abvp-coastal__row code {
  font-size: 12.5px; padding: 2px 7px; background: #fff;
  border: 1px solid var(--p-line, rgba(5,17,36,.14)); border-radius: 5px; color: var(--p-ink, #051124);
}
.abv-root[data-abv-mode='professional'] .abvp-coastal__row span { font-size: 12.5px; color: var(--p-muted, #5c6470); }
.abv-root[data-abv-mode='professional'] .abvp-coastal__eng { margin: 0 0 12px; }
.abv-root[data-abv-mode='professional'] .abvp-coastal__cert {
  padding: 14px 16px; border-radius: 8px; background: #fff;
  border: 1px solid var(--p-line, rgba(5,17,36,.14)); margin-bottom: 12px;
}
.abv-root[data-abv-mode='professional'] .abvp-coastal__cert b { font-size: 13.5px; color: var(--p-ink, #051124); }
.abv-root[data-abv-mode='professional'] .abvp-coastal__cert ul { margin: 8px 0 8px 18px; padding: 0; }
.abv-root[data-abv-mode='professional'] .abvp-coastal__cert li {
  font-size: 13px; line-height: 1.6; color: var(--p-ink-2, #3E3E3E);
}
/* The withheld-approval variant reads as information, not alarm. */
.abv-root[data-abv-mode='professional'] .abvp-coastal__cert--none {
  background: #fff; border-left: 3px solid var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-coastal__links { display: flex; gap: 16px; flex-wrap: wrap; }
.abv-root[data-abv-mode='professional'] .abvp-coastal__links a {
  font-size: 12.5px; font-weight: 600; color: var(--p-ink, #051124); text-decoration: underline;
}

/* ==== REV5 — BAND-FIRST TONE ROW (professional) ==========================
   The same three close-up material photographs the homeowner band tiles use,
   at contractor density. Selecting one sets the engine's heatBand and filters
   the exact-color list below. */
.abvp-bands { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: 6px; max-width: 760px; }
.abv-root[data-abv-mode='professional'] .abvp-band__tile { position: relative; margin: 0; cursor: pointer; min-width: 0; }
.abvp-band__tile input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.abvp-band__inner {
  display: grid; gap: 0; overflow: hidden;
  border: 1px solid var(--p-rule); border-radius: var(--p-radius-sm); background: #fff;
  transition: border-color var(--abv-dur-fast) var(--abv-ease), box-shadow var(--abv-dur-fast) var(--abv-ease);
}
.abv-root .abvp-band__inner img { display: block; width: 100%; height: 46px; object-fit: cover; }
.abvp-band__inner b {
  padding: 5px 8px 2px; font-size: var(--p-label); font-weight: 700; color: var(--p-ink); line-height: 1.2;
}
.abvp-band__mult {
  padding: 0 8px 6px; font-size: var(--p-help); color: var(--p-ink-3);
  font-variant-numeric: tabular-nums;
}
.abvp-band__tile:hover .abvp-band__inner { border-color: var(--p-accent); }
.abvp-band__tile input:checked + .abvp-band__inner {
  border-color: var(--p-accent); box-shadow: inset 0 0 0 2px var(--p-accent);
}
.abvp-band__tile input:focus-visible + .abvp-band__inner { outline: 3px solid var(--p-focus); outline-offset: 2px; }

/* Homeowner: the selected exact-color card reads unmistakably in AB orange. */
.abv-root[data-abv-mode='homeowner'] .abv-mclr.is-on {
  border-color: var(--abv-orange); box-shadow: inset 0 0 0 2px var(--abv-orange);
}

/* ==== REV5b — VISUAL COMPLETION =========================================
   Every selectable color carries a visual. The manufacturer's own blend
   description and published reflectance survive as small supporting lines
   under the band, instead of standing in for a missing picture. */
.abv-mclr__desc, .abv-mclr__sr {
  display: block; font-style: normal; font-size: 10.5px; line-height: 1.35;
  color: var(--abv-muted); font-variant-numeric: tabular-nums;
}
.abv-mclr__desc {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* The "approximate tone" badge was retired 2026-08-21 — a swatch should read
   as a color, not as a disclaimer. Provenance lives in the swatch tooltip and
   in the catalog manifest. Every professional chip carries the same hairline so
   a pale color is still visible against white. */
.abv-root[data-abv-mode='professional'] .abvp-sw__chip { box-shadow: inset 0 0 0 1px rgba(5, 17, 36, .22); }

/* ==========================================================================
   PROFLOW™ FEATURE PREVIEW (professional only)
   A premium extension of Attic Breeze, not a separate product: navy ground,
   Breeze Orange accent, Poppins from the kit. No new palette.
   ====================================================================== */
.abv-root[data-abv-mode='professional'] .abvp-pf {
  margin-top: 28px; padding: 28px 30px; border-radius: 12px;
  background: var(--abv-navy, #051124); color: #fff;
  border-left: 4px solid var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__eyebrow { color: var(--abv-orange, #EF7D48); }
.abv-root[data-abv-mode='professional'] .abvp-pf__title {
  margin: 8px 0 10px; font-size: 22px; line-height: 1.2; color: #fff; font-weight: 700;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__say {
  margin: 0 0 20px; font-size: 14.5px; line-height: 1.65; color: rgba(255,255,255,.86); max-width: 68ch;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__feats {
  list-style: none; margin: 0 0 22px; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__feat {
  padding: 14px 16px; border-radius: 9px;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.14);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__feat b {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 14px; color: #fff; margin-bottom: 5px;
}
/* The old generic '.abvp-pf__feat span' rule is REMOVED. It matched the icon
   wrapper as well as the description — which is why the orange glyph rendered
   at rgba(255,255,255,.74) — and the description now carries .abvp-pf__featd. */
/* "Coming soon" must read as not-yet-available, never as an active feature. */
.abv-root[data-abv-mode='professional'] .abvp-pf__soon {
  font-size: 10px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px;
  color: var(--abv-navy, #051124); background: var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__feat.is-soon { opacity: .82; }
.abv-root[data-abv-mode='professional'] .abvp-pf__cta {
  display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__inline { margin: 0 12px 0 0; font-size: 14px; color: #fff; }
/* Three-class specificity: the ghost/quiet buttons paint navy, invisible here. */
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-btn--secondary {
  border-color: #fff; color: #fff; background: transparent;
}
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-btn--secondary:hover {
  background: #fff; color: var(--abv-navy, #051124);
}
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-btn--quiet { color: rgba(255,255,255,.82); }
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-btn--quiet:hover { color: #fff; }
.abv-root[data-abv-mode='professional'] .abvp-pf__fine {
  margin: 16px 0 0; font-size: 12px; line-height: 1.55; color: rgba(255,255,255,.6);
}
@media (max-width: 560px) {
  .abv-root[data-abv-mode='professional'] .abvp-pf { padding: 22px 18px; }
  .abv-root[data-abv-mode='professional'] .abvp-pf__title { font-size: 19px; }
  .abv-root[data-abv-mode='professional'] .abvp-pf__cta { align-items: stretch; flex-direction: column; }
}
/* The navy primary button disappears on the ProFlow navy ground. Inverting it
   (white fill, navy label) keeps the pairing inside the approved four colours
   and reads at full contrast. Orange fill is NOT used here: white on #EF7D48
   is 2.73:1 and fails AA for both normal and large text. */
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-btn--primary {
  background: #fff; color: var(--abv-navy, #051124); border-color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-btn--primary:hover,
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-btn--primary:focus-visible {
  background: var(--abv-orange, #EF7D48); color: var(--abv-navy, #051124); border-color: var(--abv-orange, #EF7D48);
}

/* ProFlow unlock flow (Phase 2). Same navy card, now interactive. */
.abv-root[data-abv-mode='professional'] .abvp-pf__form { margin: 0 0 14px; }
/* The step's OWN heading. The card title names the product; this says what
   the contractor is being asked to do right now — previously that sentence
   was the <label> for the email field, which made a screen reader announce
   the input as "Enter your work email" and left the step unnamed. */
.abv-root[data-abv-mode='professional'] .abvp-pf__steph {
  margin: 18px 0 4px; font-family: var(--abv-font);
  font-size: 17px; line-height: 1.25; font-weight: 800; letter-spacing: -0.2px; color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__stepsay {
  margin: 0 0 14px; font-size: 14px; line-height: 1.6; color: rgba(255,255,255,.82);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__label {
  display: block; margin-bottom: 8px; font-size: 12px; font-weight: 700;
  letter-spacing: 1px; text-transform: uppercase; color: rgba(255,255,255,.86);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__row {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__input {
  flex: 1 1 240px; min-width: 0; height: 46px;
  background: #fff; border: 1.5px solid rgba(255,255,255,.3); color: var(--abv-navy, #051124);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__input--code {
  flex: 0 0 150px; letter-spacing: 5px; font-weight: 700; text-align: center;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__msg {
  margin: 12px 0 0; font-size: 13px; line-height: 1.55; color: rgba(255,255,255,.86);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__msg.is-warn { color: #FFD9C7; }
.abv-root[data-abv-mode='professional'] .abvp-pf__msg.is-ok { color: #BFE3C9; }
.abv-root[data-abv-mode='professional'] .abvp-pf__verified { margin-bottom: 18px; }
.abv-root[data-abv-mode='professional'] .abvp-pf__badge {
  display: inline-block; margin: 0 0 8px; padding: 5px 12px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  background: var(--abv-orange, #EF7D48); color: var(--abv-navy, #051124);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__cta--quiet { margin-top: 4px; }

/* ProFlow Phase 3: locked previews + member workspace + resource lists. */
.abv-root[data-abv-mode='professional'] .abvp-lock {
  padding: 26px 28px; border-radius: 12px; background: #fff;
  border: 1px solid var(--p-line, rgba(5,17,36,.14)); border-left: 4px solid var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-lock__eyebrow { color: var(--abv-orange, #EF7D48); }
.abv-root[data-abv-mode='professional'] .abvp-lock__title {
  margin: 8px 0 8px; font-size: 20px; color: var(--p-ink, #051124); font-weight: 700;
}
.abv-root[data-abv-mode='professional'] .abvp-lock__say {
  margin: 0 0 12px; font-size: 14px; line-height: 1.6; color: var(--p-ink-2, #3E3E3E); max-width: 68ch;
}
.abv-root[data-abv-mode='professional'] .abvp-lock__list {
  margin: 0 0 18px; padding: 0 0 0 20px; columns: 2; column-gap: 28px;
}
.abv-root[data-abv-mode='professional'] .abvp-lock__list li {
  font-size: 13.5px; line-height: 1.9; color: var(--p-ink-2, #3E3E3E);
}
.abv-root[data-abv-mode='professional'] .abvp-lock__fine { margin: 12px 0 0; }
.abv-root[data-abv-mode='professional'] .abvp-pf__ws {
  margin-top: 20px; padding-top: 18px; border-top: 1px solid rgba(255,255,255,.16);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__wsh {
  margin: 0 0 10px; font-size: 13px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase; color: rgba(255,255,255,.9);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__soonline {
  margin: 0; font-size: 13px; line-height: 1.6; color: rgba(255,255,255,.72);
}
.abv-root[data-abv-mode='professional'] .abvp-res { display: grid; gap: 16px; }
.abv-root[data-abv-mode='professional'] .abvp-res__title {
  margin: 0 0 6px; font-size: 12px; font-weight: 700; letter-spacing: .8px;
  text-transform: uppercase; color: var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-res__list { margin: 0; padding: 0 0 0 18px; }
.abv-root[data-abv-mode='professional'] .abvp-res__list li {
  font-size: 13.5px; line-height: 1.8; color: rgba(255,255,255,.86);
}
.abv-root[data-abv-mode='professional'] .abvp-res__list a { color: #fff; text-decoration: underline; }
.abv-root[data-abv-mode='professional'] .abvp-res__meta {
  margin-left: 8px; font-size: 11.5px; color: rgba(255,255,255,.6);
}
.abv-root[data-abv-mode='professional'] .abvp-res__note {
  padding: 12px 14px; border-radius: 8px; background: rgba(255,255,255,.07);
  border-left: 3px solid var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-res__note p {
  margin: 0; font-size: 12.5px; line-height: 1.6; color: rgba(255,255,255,.82);
}
@media (max-width: 560px) {
  .abv-root[data-abv-mode='professional'] .abvp-lock { padding: 20px 18px; }
  .abv-root[data-abv-mode='professional'] .abvp-lock__list { columns: 1; }
}
/* Touch targets: the small button variant measured 45px inside the ProFlow
   card and the locked previews. Both are primary contractor actions on a
   phone, so they are floored at 48px. */
.abv-root[data-abv-mode='professional'] .abvp-pf .abv-btn,
.abv-root[data-abv-mode='professional'] .abvp-pf button.abvp-btn,
.abv-root[data-abv-mode='professional'] .abvp-lock .abv-btn,
.abv-root[data-abv-mode='professional'] .abvp-lock button.abvp-btn {
  min-height: 48px;
}
/* The relocated logo block sits inside the ProFlow card, so its own dark-on-
   white styling needs the navy ground treatment rather than a second design. */
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot { margin-top: 12px; }
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-logo { margin-top: 0; }
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-grp__title,
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-f__label,
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-logo__or { color: rgba(255,255,255,.9); }
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-help,
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-grp__note { color: rgba(255,255,255,.7); }
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-logo__or::before,
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-logo__or::after { background: rgba(255,255,255,.22); }
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-logo__found,
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-logo__fail {
  background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.18);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-logo__meta b,
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-logo__fail b { color: #fff; }
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-btn--secondary {
  border-color: #fff; color: #fff; background: transparent;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__logoslot .abvp-btn--quiet { color: rgba(255,255,255,.82); }

/* ProFlow programme routing cards (professional step 1). Restrained: one card
   at a time, one loud button, never a wall of orange. */
.abv-root[data-abv-mode='professional'] .abvp-route { margin: 16px 0 4px; }
.abv-root[data-abv-mode='professional'] .abvp-route__card {
  padding: 22px 24px; border-radius: 12px; background: #fff;
  border: 1px solid var(--p-line, rgba(5,17,36,.14)); border-left: 4px solid var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-unlock,
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-verified {
  background: var(--abv-navy, #051124); border-color: var(--abv-navy, #051124);
  border-left-color: var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-route__eyebrow { color: var(--abv-orange, #EF7D48); }
.abv-root[data-abv-mode='professional'] .abvp-route__title {
  margin: 8px 0 10px; font-size: 19px; line-height: 1.3; font-weight: 700; color: var(--p-ink, #051124);
}
.abv-root[data-abv-mode='professional'] .abvp-route__say {
  margin: 0 0 12px; font-size: 14px; line-height: 1.6; color: var(--p-ink-2, #3E3E3E); max-width: 66ch;
}
.abv-root[data-abv-mode='professional'] .abvp-route__list { margin: 0 0 16px; padding: 0 0 0 18px; }
.abv-root[data-abv-mode='professional'] .abvp-route__list li {
  font-size: 13.5px; line-height: 1.75; color: var(--p-ink-2, #3E3E3E);
}
.abv-root[data-abv-mode='professional'] .abvp-route__cta {
  display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
}
.abv-root[data-abv-mode='professional'] .abvp-route__card .abv-btn { min-height: 48px; }
.abv-root[data-abv-mode='professional'] .abvp-route__fine { margin: 14px 0 0; }
.abv-root[data-abv-mode='professional'] .abvp-route__fine a { color: var(--p-ink, #051124); text-decoration: underline; }
/* Navy variants invert their type and buttons, staying inside the four colours. */
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-unlock .abvp-route__title,
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-verified .abvp-route__title { color: #fff; }
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-unlock .abvp-route__say,
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-verified .abvp-route__say { color: rgba(255,255,255,.86); }
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-unlock .abvp-route__list li { color: rgba(255,255,255,.82); }
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-unlock .abvp-btn--primary,
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-verified .abvp-btn--primary {
  background: #fff; color: var(--abv-navy, #051124); border-color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-unlock .abvp-btn--quiet,
.abv-root[data-abv-mode='professional'] .abvp-route__card.is-verified .abvp-btn--quiet { color: rgba(255,255,255,.82); }
@media (max-width: 560px) {
  .abv-root[data-abv-mode='professional'] .abvp-route__card { padding: 18px 16px; }
  .abv-root[data-abv-mode='professional'] .abvp-route__title { font-size: 17px; }
  .abv-root[data-abv-mode='professional'] .abvp-route__cta { flex-direction: column; align-items: stretch; }
}

/* ==========================================================================
   PROFLOW WORKSPACE — the premium job plan.
   Attic Breeze first: navy ground, Poppins, Breeze Orange for the section
   numbers, Light Blue for the drafting rules. No new palette, no dashboard.
   ====================================================================== */
.abv-root[data-abv-mode='professional'] .abvp-sec--flow { padding: 0; border: 0; background: none; }
.abv-root[data-abv-mode='professional'] .abvf {
  border-radius: 14px; overflow: hidden;
  background-color: #051124;
  /* A restrained drafting grid, not a texture. */
  background-image:
    linear-gradient(rgba(57,147,223,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(57,147,223,.07) 1px, transparent 1px);
  background-size: 48px 48px, 48px 48px;
}
.abv-root[data-abv-mode='professional'] .abvf-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 20px;
  flex-wrap: wrap; padding: 30px 32px 24px;
  border-bottom: 1px solid rgba(57,147,223,.28);
}
.abv-root[data-abv-mode='professional'] .abvf-eyebrow { color: #EF7D48; }
.abv-root[data-abv-mode='professional'] .abvf-title {
  margin: 8px 0 6px; font-size: 28px; line-height: 1.15; font-weight: 800; color: #fff;
  letter-spacing: -.3px;
}
.abv-root[data-abv-mode='professional'] .abvf-addr { margin: 0; font-size: 13.5px; color: rgba(255,255,255,.78); }
.abv-root[data-abv-mode='professional'] .abvf-addr b { color: #fff; }
.abv-root[data-abv-mode='professional'] .abvf-addr span { margin-left: 8px; }
.abv-root[data-abv-mode='professional'] .abvf-verified {
  padding: 7px 14px; border-radius: 999px; font-size: 11px; font-weight: 700;
  letter-spacing: 1px; text-transform: uppercase; white-space: nowrap;
  color: #051124; background: #EF7D48;
}
.abv-root[data-abv-mode='professional'] .abvf-coastal {
  display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
  padding: 14px 32px; background: rgba(57,147,223,.12);
  border-bottom: 1px solid rgba(57,147,223,.28);
}
.abv-root[data-abv-mode='professional'] .abvf-coastal b {
  color: #EF7D48; font-size: 12px; letter-spacing: 1px; text-transform: uppercase;
}
.abv-root[data-abv-mode='professional'] .abvf-coastal span { font-size: 13.5px; color: rgba(255,255,255,.86); }

.abv-root[data-abv-mode='professional'] .abvf-sec {
  padding: 26px 32px; border-bottom: 1px solid rgba(57,147,223,.18);
}
.abv-root[data-abv-mode='professional'] .abvf-sec:last-child { border-bottom: 0; }
.abv-root[data-abv-mode='professional'] .abvf-sec.is-key { background: rgba(255,255,255,.04); }
.abv-root[data-abv-mode='professional'] .abvf-sec__head {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 16px;
}
.abv-root[data-abv-mode='professional'] .abvf-sec__n {
  font-size: 12px; font-weight: 800; letter-spacing: 1.4px;
  color: #EF7D48; font-variant-numeric: tabular-nums;
}
.abv-root[data-abv-mode='professional'] .abvf-sec__title {
  margin: 0; font-size: 17px; font-weight: 700; color: #fff; letter-spacing: -.1px;
}
.abv-root[data-abv-mode='professional'] .abvf-sec__note {
  margin: 0; flex: 1 1 100%; font-size: 12.5px; color: rgba(255,255,255,.6);
}
.abv-root[data-abv-mode='professional'] .abvf-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px 24px;
}
.abv-root[data-abv-mode='professional'] .abvf-fact span {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: .9px;
  text-transform: uppercase; color: rgba(255,255,255,.55); margin-bottom: 3px;
}
.abv-root[data-abv-mode='professional'] .abvf-fact b { font-size: 15px; color: #fff; font-weight: 600; }
.abv-root[data-abv-mode='professional'] .abvf-lead {
  margin: 0 0 16px; font-size: 22px; font-weight: 800; color: #fff; letter-spacing: -.2px;
}
.abv-root[data-abv-mode='professional'] .abvf-lead--sm {
  margin: 0 0 14px; font-size: 14px; line-height: 1.6; color: rgba(255,255,255,.82);
}
.abv-root[data-abv-mode='professional'] .abvf-list { margin: 0; padding-left: 18px; }
.abv-root[data-abv-mode='professional'] .abvf-list li {
  font-size: 13.5px; line-height: 1.8; color: rgba(255,255,255,.86);
}
.abv-root[data-abv-mode='professional'] .abvf-list b { color: #fff; }
.abv-root[data-abv-mode='professional'] .abvf-sched { display: grid; gap: 10px; }
.abv-root[data-abv-mode='professional'] .abvf-sched__row {
  display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
  padding: 12px 16px; border-radius: 9px;
  background: rgba(255,255,255,.05); border: 1px solid rgba(57,147,223,.22);
}
.abv-root[data-abv-mode='professional'] .abvf-sched__row b { font-size: 14px; color: #fff; }
.abv-root[data-abv-mode='professional'] .abvf-sched__row code {
  font-size: 12.5px; padding: 2px 8px; border-radius: 5px; color: #fff;
  background: rgba(57,147,223,.18); border: 1px solid rgba(57,147,223,.34);
}
.abv-root[data-abv-mode='professional'] .abvf-sched__row span { font-size: 12.5px; color: rgba(255,255,255,.7); }
.abv-root[data-abv-mode='professional'] .abvf-soon {
  display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap;
  padding: 18px 20px; border-radius: 10px;
  background: rgba(255,255,255,.04); border: 1px dashed rgba(57,147,223,.4);
}
.abv-root[data-abv-mode='professional'] .abvf-soon__badge {
  padding: 4px 10px; border-radius: 999px; font-size: 10.5px; font-weight: 700;
  letter-spacing: 1px; text-transform: uppercase; color: #051124; background: #EF7D48;
}
.abv-root[data-abv-mode='professional'] .abvf-soon p {
  margin: 0; flex: 1 1 240px; font-size: 13.5px; line-height: 1.6; color: rgba(255,255,255,.72);
}
.abv-root[data-abv-mode='professional'] .abvf-muted { font-size: 12.5px; color: rgba(255,255,255,.62); }
.abv-root[data-abv-mode='professional'] .abvf-actions {
  display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin-top: 16px;
}
.abv-root[data-abv-mode='professional'] .abvf-actions .abv-btn {
  min-height: 48px; background: #fff; color: #051124; border-color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvf-actions .abv-btn:hover {
  background: #EF7D48; border-color: #EF7D48; color: #051124;
}
/* The analysis and the logo are MOVED in; they keep their own markup and get
   the navy treatment here rather than a second design being written for them. */
.abv-root[data-abv-mode='professional'] .abvf .abvp-logo { margin-top: 0; }
.abv-root[data-abv-mode='professional'] .abvf .abvp-grp__title,
.abv-root[data-abv-mode='professional'] .abvf .abvp-f__label,
.abv-root[data-abv-mode='professional'] .abvf .abvp-logo__or,
.abv-root[data-abv-mode='professional'] .abvf .abvp-vent b,
.abv-root[data-abv-mode='professional'] .abvf .abvp-block__title { color: rgba(255,255,255,.92); }
.abv-root[data-abv-mode='professional'] .abvf .abvp-help,
.abv-root[data-abv-mode='professional'] .abvf .abvp-sec__note { color: rgba(255,255,255,.68); }
.abv-root[data-abv-mode='professional'] .abvf .abvp-logo__or::before,
.abv-root[data-abv-mode='professional'] .abvf .abvp-logo__or::after { background: rgba(57,147,223,.35); }
.abv-root[data-abv-mode='professional'] .abvf .abvp-logo__found,
.abv-root[data-abv-mode='professional'] .abvf .abvp-logo__fail {
  background: rgba(255,255,255,.06); border-color: rgba(57,147,223,.28);
}
.abv-root[data-abv-mode='professional'] .abvf .abvp-logo__meta b,
.abv-root[data-abv-mode='professional'] .abvf .abvp-logo__fail b { color: #fff; }
.abv-root[data-abv-mode='professional'] .abvf .abvp-btn--secondary {
  border-color: #fff; color: #fff; background: transparent;
}
.abv-root[data-abv-mode='professional'] .abvf .abvp-btn--quiet { color: rgba(255,255,255,.82); }
.abv-root[data-abv-mode='professional'] .abvf .abvp-res { display: grid; gap: 16px; }
.abv-root[data-abv-mode='professional'] .abvf .abvp-res__title { color: #EF7D48; }
.abv-root[data-abv-mode='professional'] .abvf .abvp-res__list li { color: rgba(255,255,255,.86); }
.abv-root[data-abv-mode='professional'] .abvf .abvp-res__list a { color: #fff; text-decoration: underline; }
.abv-root[data-abv-mode='professional'] .abvf .abvp-res__note {
  background: rgba(57,147,223,.12); border-left-color: #EF7D48;
}
.abv-root[data-abv-mode='professional'] .abvf .abvp-res__note p { color: rgba(255,255,255,.84); }
@media (max-width: 640px) {
  .abv-root[data-abv-mode='professional'] .abvf-head { padding: 22px 18px 18px; }
  .abv-root[data-abv-mode='professional'] .abvf-title { font-size: 22px; }
  .abv-root[data-abv-mode='professional'] .abvf-sec { padding: 20px 18px; }
  .abv-root[data-abv-mode='professional'] .abvf-coastal { padding: 12px 18px; }
  .abv-root[data-abv-mode='professional'] .abvf-facts { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px 16px; }
  .abv-root[data-abv-mode='professional'] .abvf-lead { font-size: 18px; }
  .abv-root[data-abv-mode='professional'] .abvf-actions { flex-direction: column; align-items: stretch; }
}

/* =============================================================================
   ASYNC STATE + THE PAYOFF MOMENTS
   =============================================================================
   Three products, three completions, one grammar:

       BreezeMatch      MATCHED
       Ventilation Cal. SIZED
       ProFlow          UNLOCKED

   Each is a small tick badge and a line of type, never a celebration. The
   whole sequence is under half a second and every step is a Web Animations API
   call, NOT requestAnimationFrame — rAF is starved in both browsers on this
   site (established on the Breeze Lab build), so a rAF-driven reveal silently
   never runs and the badge just pops in.

   prefers-reduced-motion is honoured by jumping to the end state, never by
   leaving an element mid-animation.
   ========================================================================== */

/* ---- 1. BUSY + DONE ON ANY CALCULATOR BUTTON ---------------------------- */
/* A working button must never look dead. `.is-busy` keeps the button at full
   contrast — a 45%-opacity "disabled" look during a 900ms request reads as
   broken, not busy — and swaps in a spinner sized off the type. */
.abv-root .abvp-btn.is-busy,
.abv-root .abv-btn.is-busy {
  cursor: progress; opacity: 1;
}
.abv-root .abvp-btn.is-busy::before,
.abv-root .abv-btn.is-busy::before {
  content: ''; flex: none;
  width: 1em; height: 1em; margin-right: 2px;
  border: 2px solid currentColor; border-top-color: transparent;
  border-radius: 50%;
  animation: abv-spin .7s linear infinite;
}
@keyframes abv-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .abv-root .abvp-btn.is-busy::before,
  .abv-root .abv-btn.is-busy::before { animation-duration: 2.4s; }
}
/* The success state a verify button holds for ~500ms before the panel changes,
   so the click is acknowledged where the finger was. Navy ground + white tick:
   no orange fill ever carries a label. */
.abv-root .abvp-btn.is-done,
.abv-root .abv-btn.is-done {
  background: var(--abv-navy, #051124) !important;
  border-color: var(--abv-orange, #EF7D48) !important;
  color: #fff !important;
}
.abv-root .abvp-btn.is-done::before,
.abv-root .abv-btn.is-done::before {
  content: '\2713'; font-weight: 700; margin-right: 4px;
}

/* ---- 2. THE TICK BADGE — shared by all three products ------------------- */
.abv-root .abv-payoff {
  display: inline-flex; align-items: center; gap: 9px;
  margin: 0 0 10px; padding: 7px 15px 7px 11px;
  border-radius: 999px;
  background: rgba(239,125,72,.12);
  border: 1px solid rgba(239,125,72,.42);
  font-family: var(--abv-font);
  font-size: 11.5px; font-weight: 700; letter-spacing: 1.1px; text-transform: uppercase;
  color: #a8481c;               /* accent-ink: 5.83:1 on white. The accent
                                   itself is 2.73:1 and would fail as text. */
}
/* On a navy ground the same badge inverts — the accent becomes legible as
   type at 6.92:1, which is why orange text is allowed here and nowhere on
   white. */
.abv-root .abvf .abv-payoff,
.abv-root .abvp-route__card.is-unlock .abv-payoff,
.abv-root .abvp-route__card.is-verified .abv-payoff,
.abv-root .abvp-pf .abv-payoff {
  background: rgba(239,125,72,.16);
  border-color: rgba(239,125,72,.55);
  color: var(--abv-orange, #EF7D48);
}
.abv-root .abv-payoff__tick {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  background: var(--abv-orange, #EF7D48); color: #fff;
  font-size: 11px; line-height: 1; font-weight: 700;
}
/* The tick draws itself: scale from 0 with a short overshoot. WAAPI drives
   this via .animate() in JS; the class is the reduced-motion fallback. */
.abv-root .abv-payoff__tick svg { width: 11px; height: 11px; display: block; }
.abv-root .abv-payoff__tick svg path {
  stroke: #fff; stroke-width: 2.6; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ---- 3. THE PROFLOW UNLOCK SEQUENCE ------------------------------------ */
/* Staged reveal, 150-400ms per step, driven from JS with WAAPI. These rules
   only supply the START state; JS animates to the end state and clears the
   class. If JS never runs, nothing is left invisible — see .abv-fx-in below,
   which resolves to the visible state when the stylesheet alone applies. */
.abv-root .abv-fx-in { opacity: 1; }
.abv-root .abv-fx-in[data-abv-fx='pending'] { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .abv-root .abv-fx-in[data-abv-fx='pending'] { opacity: 1; }
}

/* The orange sweep that completes across the verify panel. A 2px rule, not a
   progress bar — it reads as a drafting line finishing, which is the ProFlow
   idea rather than a download. */
.abv-root .abvp-pf__sweep {
  position: relative; height: 2px; margin: 16px 0 14px;
  background: rgba(255,255,255,.14); border-radius: 2px; overflow: hidden;
}
.abv-root .abvp-pf__sweep i {
  position: absolute; inset: 0 auto 0 0; width: 0;
  background: var(--abv-orange, #EF7D48);
  border-radius: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .abv-root .abvp-pf__sweep i { width: 100%; }
}

/* The blueprint ground fading in behind the unlocked workspace. Light Blue at
   low alpha on navy — the same 48px drafting grid the workspace already uses,
   introduced rather than simply present. */
.abv-root .abvf[data-abv-fx='pending'] { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .abv-root .abvf[data-abv-fx='pending'] { opacity: 1; }
}

/* The unlocked headline pair inside the card. */
.abv-root .abvp-pf__unlocked { margin: 4px 0 2px; }
.abv-root .abvp-pf__unlockedh {
  margin: 0 0 6px;
  font-family: var(--abv-font); font-size: 23px; line-height: 1.18;
  font-weight: 800; letter-spacing: -0.3px; color: #fff;
}
.abv-root .abvp-pf__unlockedsay {
  margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: rgba(255,255,255,.86);
}
@media (max-width: 640px) {
  .abv-root .abvp-pf__unlockedh { font-size: 20px; }
  .abv-root .abv-payoff { font-size: 11px; letter-spacing: .9px; }
}

/* The free professional result's completion line. Sits ABOVE the navy hero,
   on the page ground, so the first thing read after a calculation is that the
   calculation is finished — not a product name and not an upgrade offer. */
.abv-root[data-abv-mode='professional'] .abvp-sized { margin: 0 0 18px; }
.abv-root[data-abv-mode='professional'] .abvp-sized__h {
  margin: 4px 0 0; font-family: var(--abv-font);
  font-size: 28px; line-height: 1.14; font-weight: 800; letter-spacing: -0.5px;
  color: var(--p-ink, #051124);
}
@media (max-width: 640px) {
  .abv-root[data-abv-mode='professional'] .abvp-sized__h { font-size: 23px; }
}

/* =============================================================================
   THE CHOICE CHIP — the calculator's answer control, both calculators
   =============================================================================
   WHAT WAS WRONG. Every segmented control carried BOTH classes, `.abv-seg`
   (the homeowner pill wrapper) and `.abvp-seg` (the professional shared-border
   grid), and neither treatment ever completed:

     · `.abv-seg` won the grey pill wrapper and the 999px radius, because it is
       declared later in this file
     · `.abvp-seg` won a cramped 44px inner span
     · `.abvp-seg`'s `grid-template-columns: repeat(3, 1fr)` never applied at
       all, because `.abv-seg`'s `inline-flex` overrode the `grid` it needs
     · no label carries `.abv-seg__opt`, which is the class the polished
       48px segment styling was actually written against
     · and the selected state was `::before { content: '✓\00a0' }`, which is
       what produced the cramped "✓No" inside a 35px-wide target

   Measured before: "Yes / No" was a 91px control with 42px and 35px segments.

   WHAT IT IS NOW. Not a split pill — a ROW OF INDEPENDENT CHIPS. Each option
   is its own white card with room to breathe, the grey tray is gone entirely,
   and the group reads as a set of branded buttons rather than a browser
   segmented control.

   TWO DELIBERATE DEPARTURES FROM THE CTA PILLS, both reasoned:

   1. SOFT 12px RADIUS, NOT THE 999px PILL. Pills are for ACTIONS; these are
      ANSWERS. Keeping the two shapes distinct is what stops a four-word answer
      from looking like a call to action, and a pill around "Estimate from home
      size" reads as a button you press rather than a choice you make.

   2. SENTENCE CASE, NOT TRACKED CAPS. Uppercase destroys the internal case
      change in the product wordmarks — "GableBreeze only" would render
      "GABLEBREEZE ONLY", which is not how the mark is written. The brand
      standard also reserves uppercase for button labels and short eyebrows,
      and a multi-word answer is neither.

   A hover LIFT is used here even though the site's CTA rule explicitly kills
   it (`:hover,:focus { transform:none }`). That rule governs the marketing
   CTAs; these are application controls where the 1px rise is the thing that
   makes an answer feel pressable. Both are honoured, in their own scopes.
   ========================================================================== */
.abv-root {
  --ab-chip-h:       56px;   /* comfortably past the 48px floor */
  --ab-chip-pad-y:   15px;
  --ab-chip-pad-x:   22px;
  --ab-chip-radius:  12px;
  --ab-chip-bw:       2px;
  --ab-chip-gap:     12px;
  --ab-chip-size:    15px;
  --ab-chip-dur:      .18s;
}

/* ---- THE GROUP -------------------------------------------------------- */
/* The grey tray is removed on BOTH calculators: no background, no border, no
   padding. The chips are the control now. */
.abv-root .abv-seg {
  display: flex; flex-wrap: wrap; align-items: stretch;
  gap: var(--ab-chip-gap);
  margin: 10px 0 var(--abv-5);
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  overflow: visible;          /* the tick badge overhangs the corner */
}

/* Each option. `position: relative` anchors the tick badge; `flex: 0 1 auto`
   keeps short answers compact instead of stretching "Yes" across the row. */
.abv-root .abv-seg > label,
.abv-root .abv-seg .abv-seg__opt {
  position: relative;
  display: flex;
  flex: 0 1 auto;
  min-width: 116px;
  max-width: 100%;
  margin: 0;
  grid-template-columns: none;   /* retire the declaration that never won */
}

/* ---- THE CHIP -------------------------------------------------------- */
.abv-root .abv-seg > label > span,
.abv-root .abv-seg .abv-seg__opt > span {
  position: relative;
  display: flex; flex: 1 1 auto;
  align-items: center; justify-content: center; text-align: center;
  min-height: var(--ab-chip-h);
  padding: var(--ab-chip-pad-y) var(--ab-chip-pad-x);
  font-family: var(--abv-font);
  font-size: var(--ab-chip-size); font-weight: 600; line-height: 1.35;
  letter-spacing: normal; text-transform: none;
  /* Break on WORDS. `anywhere` was splitting "Ventilation" mid-word. */
  white-space: normal; overflow-wrap: break-word; hyphens: none;
  color: var(--abv-navy, #051124);
  background: #fff;
  border: var(--ab-chip-bw) solid #dde2e8;
  border-radius: var(--ab-chip-radius);
  box-shadow: 0 1px 2px rgba(5, 17, 36, .04);
  cursor: pointer;
  transition: border-color var(--ab-chip-dur) var(--abv-ease),
              background-color var(--ab-chip-dur) var(--abv-ease),
              color var(--ab-chip-dur) var(--abv-ease),
              box-shadow var(--ab-chip-dur) var(--abv-ease),
              transform var(--ab-chip-dur) var(--abv-ease);
}

/* The radio stays in the accessibility tree and keeps driving state — it is
   moved out of sight, never `display:none`, so it remains focusable and the
   label/radiogroup semantics are untouched. */
.abv-root .abv-seg > label > input,
.abv-root .abv-seg .abv-seg__opt > input {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  margin: 0; padding: 0;
  opacity: 0; appearance: none; -webkit-appearance: none;
  cursor: pointer;
}

/* ---- HOVER: the orange accent arrives as an edge and a ring ----------- */
.abv-root .abv-seg > label > input:not(:checked):hover + span,
.abv-root .abv-seg .abv-seg__opt > input:not(:checked):hover + span {
  background: #fff;                 /* explicit: no tint may creep back in */
  border-color: var(--abv-orange, #EF7D48);
  box-shadow: 0 3px 10px rgba(5, 17, 36, .07),
              0 0 0 3px rgba(239, 125, 72, .16);
  transform: translateY(-1px);
}

/* ---- SELECTED: navy chip, white label, orange tick ------------------- */
/* Orange is the accent on the badge, never a fill behind the label — the
   brand rule, and 2.73:1 is why. Navy + white is 18.88:1. */
.abv-root .abv-seg > label > input:checked + span,
.abv-root .abv-seg .abv-seg__opt > input:checked + span {
  background: var(--abv-navy, #051124);
  border-color: var(--abv-navy, #051124);
  color: #fff;
  box-shadow: 0 3px 12px rgba(5, 17, 36, .16);
}
.abv-root .abv-seg > label > input:checked:hover + span,
.abv-root .abv-seg .abv-seg__opt > input:checked:hover + span {
  border-color: var(--abv-orange, #EF7D48);
  transform: translateY(-1px);
}
/* The tick. A badge on the corner rather than a glyph jammed in front of the
   label, so the selected state does not depend on colour alone and does not
   steal width from the text. */
.abv-root .abv-seg > label > input:checked + span::after,
.abv-root .abv-seg .abv-seg__opt > input:checked + span::after {
  content: '\2713';
  position: absolute; top: -9px; right: -9px;
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--abv-orange, #EF7D48); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 1;
  box-shadow: 0 0 0 2px #fff;
}
/* The old cramped inline tick, retired. */
.abv-root .abv-seg > label > input:checked + span::before,
.abv-root .abvp-seg input:checked + span::before { content: none; }

/* ---- FOCUS: blue, independent of hover ------------------------------- */
/* Blue #346AC1 is 5.27:1; the site's orange focus ring is 2.73:1 and fails the
   3:1 non-text floor. And now that hover IS an orange gesture, an orange ring
   would be indistinguishable from it. */
.abv-root .abv-seg > label > input:focus-visible + span,
.abv-root .abv-seg .abv-seg__opt > input:focus-visible + span {
  outline: 3px solid var(--abv-blue-lit, #346AC1);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .abv-root .abv-seg > label > input:hover + span,
  .abv-root .abv-seg .abv-seg__opt > input:hover + span { transform: none; }
}

/* ---- The question block gets room around it -------------------------- */
/* The controls sat flush against their label and against the next question.
   This is the "breathing room" half of the fix — the geometry alone does not
   make a form feel guided. */
.abv-root[data-abv-mode='professional'] .abvp-program .abvp-f { margin-bottom: var(--p-3); }
.abv-root[data-abv-mode='professional'] .abvp-f__label { margin-bottom: 2px; }
.abv-root .abv-seg__why { margin-top: -10px; }

/* ---- MOBILE: full-width, equal, stacked or two-up -------------------- */
@media (max-width: 600px) {
  .abv-root .abv-seg { gap: 10px; }
  /* Short answers stay side by side; longer ones take the full row. Both keep
     the 56px height and the 12px gutter, so nothing reads as crowded. */
  .abv-root .abv-seg > label,
  .abv-root .abv-seg .abv-seg__opt { flex: 1 1 132px; min-width: 132px; }
  .abv-root .abv-seg > label > span,
  .abv-root .abv-seg .abv-seg__opt > span {
    padding-left: 14px; padding-right: 14px;
  }
}

/* =============================================================================
   THE PAGER — "Load more colors", both calculators
   =============================================================================
   A SECONDARY action. It sits under a grid of swatches and must not compete
   with Continue or Calculate, so it takes the outline treatment: white ground,
   navy label, navy edge. Hover fills navy and brings the orange in as a ring,
   which is the same gesture the choice chips use.

   Shape here IS the pill, unlike the chips — this one is an action.
   ========================================================================== */
.abv-root .abv-pager {
  grid-column: 1 / -1;              /* the swatch hosts are grids */
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 8px 16px;
  margin: 20px 0 6px; padding-top: 18px;
  border-top: 1px solid var(--abv-hairline, #e3e5e8);
  text-align: center;
}
/* Secondary by design: small, quiet, and it does not shout the total. */
.abv-root .abv-pager__count {
  order: 2; flex: 1 1 100%;
  margin: 0;
  font-family: var(--abv-font);
  font-size: 12.5px; font-weight: 500; letter-spacing: .2px;
  color: var(--abv-muted, #6f7680);
}
.abv-root .abv-pager__acts {
  order: 1; flex: 0 1 auto;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px;
}
.abv-root .abv-pager__btn {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 13px 26px;
  font-family: var(--abv-font);
  font-size: 13px; font-weight: 700; line-height: 1.2;
  letter-spacing: 1px; text-transform: uppercase;
  color: var(--abv-navy, #051124);
  background: #fff;
  border: 2px solid var(--abv-navy, #051124);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color .2s var(--abv-ease), color .2s var(--abv-ease),
              border-color .2s var(--abv-ease), box-shadow .2s var(--abv-ease),
              transform .2s var(--abv-ease);
}
.abv-root .abv-pager__btn:hover {
  background: var(--abv-navy, #051124); color: #fff;
  border-color: var(--abv-orange, #EF7D48);
  box-shadow: 0 3px 12px rgba(5, 17, 36, .14),
              0 0 0 3px rgba(239, 125, 72, .16);
  transform: translateY(-1px);
}
.abv-root .abv-pager__btn:active { transform: translateY(0); }
.abv-root .abv-pager__btn:focus-visible {
  outline: 3px solid var(--abv-blue-lit, #346AC1); outline-offset: 3px;
}
/* "Show fewer" is the utility tier — quieter than the load action beside it. */
.abv-root .abv-pager__btn--quiet {
  border-color: var(--abv-line, #cacbcc);
  color: var(--abv-muted, #6f7680);
  letter-spacing: .6px;
  padding-left: 20px; padding-right: 20px;
}
.abv-root .abv-pager__btn--quiet:hover {
  background: #fff; color: var(--abv-navy, #051124);
  border-color: var(--abv-navy, #051124);
  box-shadow: 0 2px 8px rgba(5, 17, 36, .08);
}
@media (prefers-reduced-motion: reduce) {
  .abv-root .abv-pager__btn:hover { transform: none; }
}
@media (max-width: 600px) {
  /* Full width on a phone — this is the one control on the screen a thumb is
     actually reaching for after scrolling a grid of swatches. */
  .abv-root .abv-pager__acts { flex: 1 1 100%; }
  .abv-root .abv-pager__btn { flex: 1 1 100%; padding-left: 18px; padding-right: 18px; }
}

/* =============================================================================
   THE DE-GRAY COMPENSATION LAYER + THE PREMIUM STEP TREATMENT
   =============================================================================
   Retiring the grey at the token level removed every grey fill in one move, but
   three kinds of element were relying on that fill as their ONLY separation and
   would now be white on white. Each gets a real treatment instead of a tint:

     1. small pills and badges  -> a navy hairline, so they read as objects
     2. disabled fields         -> white ground, dimmed, hatched-free
     3. section headers         -> a proper branded header, not a bar

   Nothing here reintroduces a grey. Separation is a navy hairline, spacing, or
   type weight — the three things the brief asked for in grey's place.
   ========================================================================== */

/* ---- 1. PILLS AND BADGES THAT LOST THEIR FILL ------------------------- */
/* SKU chips, tag pills and the status pill were a grey lozenge with no border.
   White-on-white erases them, so they become white with a navy hairline —
   which reads as more deliberate than the grey lozenge ever did. */
.abv-root[data-abv-mode='professional'] .abvp-sched__sku,
.abv-root[data-abv-mode='professional'] .abvp-status {
  border: 1px solid var(--p-rule);
  background: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-alt__tags > em {
  border: 1px solid var(--p-rule);
  background: #fff;
}
/* The semantic tags keep their meaning colour — those were never grey. */
.abv-root[data-abv-mode='professional'] .abvp-alt__tags > em.is-good {
  border-color: var(--p-ok-rule);
}
.abv-root[data-abv-mode='professional'] .abvp-alt__tags > em.is-warn {
  border-color: var(--p-accent-rule);
}

/* ---- 2. DISABLED FIELDS ---------------------------------------------- */
/* A disabled input used to be recognisable BECAUSE it was grey. White would
   make it look editable, which is worse than ugly — it is misleading. It keeps
   the white ground and says "disabled" with a dashed navy edge and dimmed ink,
   which does not depend on a fill at all. */
.abv-root[data-abv-mode='professional'] .abvp-f__ctrl:disabled,
.abv-root[data-abv-mode='homeowner'] .abv-f__ctrl:disabled {
  background: #fff;
  border-style: dashed;
  border-color: var(--p-rule);
  color: var(--p-ink-3);
  cursor: not-allowed;
}

/* ---- 3. THE SECTION HEADER — the big one ----------------------------- */
/* This was the grey bar in the brief's screenshot: a full-width #f4f6f8 strip
   across the top of every step, which is exactly what made the calculator read
   as an admin form.

   It is now a branded header on white:

     ORANGE KICKER   the step count, uppercase and tracked
     Navy title      bold, the loudest thing in the block
     Muted note      one line, smaller, lighter navy
     Orange rule     a progress indicator that fills as the flow advances

   The progress rule is real, not decorative: abv-pro.js passes the step index
   and the total as custom properties, so the orange segment is proportional to
   how far through the six steps the contractor actually is. */
.abv-root[data-abv-mode='professional'] .abvp-sec {
  background: #fff;
  border: 1px solid var(--p-rule);
  /* Very restrained: a 1px contact shadow and a wide soft navy lift. No grey. */
  box-shadow: 0 1px 2px rgba(5, 17, 36, .04), 0 10px 30px rgba(5, 17, 36, .05);
}
.abv-root[data-abv-mode='professional'] .abvp-sec__head {
  position: relative;
  display: block;                    /* was a flex row with the badge inline */
  background: #fff;
  padding: 26px 28px 20px;
  border-bottom: 1px solid var(--p-rule-2);
}
/* The step count becomes the kicker: orange, uppercase, tracked — the site's
   own eyebrow treatment, which is its most recognisable type detail. */
.abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-step {
  display: flex; align-items: baseline; gap: 6px;
  margin: 0 0 8px;
  font-family: var(--abv-font);
  font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
  color: var(--abv-orange, #EF7D48);
}
/* The number was a filled navy circle. Now it is simply the first word of the
   kicker — no badge, no chip, nothing to misalign. */
.abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-step__n {
  display: inline; width: auto; height: auto;
  min-width: 0; padding: 0; margin: 0;
  background: none; border: 0; border-radius: 0;
  color: inherit; font: inherit;
}
.abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-step__n::before { content: 'Step '; }
.abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-step__of {
  color: rgba(5, 17, 36, .45); font-weight: 600; letter-spacing: 1.4px;
}
.abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-sec__title {
  margin: 0;
  font-size: 25px; line-height: 1.16; font-weight: 800; letter-spacing: -0.5px;
  color: var(--abv-navy, #051124);
}
.abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-sec__note {
  margin: 7px 0 0;
  font-size: 14px; line-height: 1.6; color: rgba(5, 17, 36, .58);
  max-width: 74ch;
}
/* THE ORANGE PROGRESS RULE. Sits on the header's bottom edge and covers the
   fraction of it the contractor has completed. --abv-step-i / --abv-step-n are
   written onto the element by abv-pro.js; without them the rule simply does not
   paint, so a missing value can never render a wrong progress state. */
.abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-step[style*='--abv-step-i']::after {
  content: '';
  position: absolute; left: 0; bottom: -1px; height: 3px;
  width: calc(var(--abv-step-i) / var(--abv-step-n) * 100%);
  background: var(--abv-orange, #EF7D48);
  border-radius: 0 3px 3px 0;
  transition: width .32s var(--abv-ease);
}
/* An aside in the header (the material/tone summary) keeps its place without a
   flex row to sit in. */
.abv-root[data-abv-mode='professional'] .abvp-sec__head > *:not(.abvp-step):not(.abvp-sec__heading) {
  margin-top: 12px;
}

/* ---- 4. THE HOMEOWNER STAGE HEADER ---------------------------------- */
/* BreezeMatch's "Stage 1 of 5" gets the same orange kicker so the two products
   read as one family, at the homeowner's larger, softer scale. */
.abv-root[data-abv-mode='homeowner'] .abv-stage,
.abv-root[data-abv-mode='homeowner'] .abv-eyebrow {
  color: var(--abv-orange, #EF7D48);
  font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
}
.abv-root[data-abv-mode='homeowner'] .abv-q {
  color: var(--abv-navy, #051124);
}

/* ---- 5. ANY REMAINING PANEL THAT READ AS A GREY BLOCK --------------- */
/* These were `background: var(--p-ground)` blocks — inset panels, metric
   strips, the search box, the summary rail. All white now, so each gets the
   navy hairline that makes it a panel rather than a void. */
.abv-root[data-abv-mode='professional'] .abvp-panel,
.abv-root[data-abv-mode='professional'] .abvp-inset,
.abv-root[data-abv-mode='professional'] .abvp-csearch__box,
.abv-root[data-abv-mode='homeowner'] .abv-panel,
.abv-root[data-abv-mode='homeowner'] .abv-csearch__box {
  background: #fff;
  border: 1px solid var(--p-rule, rgba(5, 17, 36, .14));
}

/* Section dividers: a navy hairline, never a filled band. */
.abv-root .abvp-rule,
.abv-root .abv-rule { background: var(--abv-hairline); height: 1px; border: 0; }

/* ---- 6. MOBILE ------------------------------------------------------ */
@media (max-width: 600px) {
  .abv-root[data-abv-mode='professional'] .abvp-sec__head { padding: 20px 18px 16px; }
  .abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-sec__title { font-size: 21px; }
  .abv-root[data-abv-mode='professional'] .abvp-sec__head .abvp-step { letter-spacing: 1.6px; }
}

/* BreezeMatch's stage label becomes the same orange kicker the professional
   step header uses. It was 14px/700 navy sentence case, which read as a label;
   the two products should announce their position in the flow identically. */
.abv-root[data-abv-mode='homeowner'] .abv-steps__label {
  font-family: var(--abv-font);
  font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
  color: var(--abv-orange, #EF7D48);
}

/* The tertiary link inside a route card measured 46px. It is a real tap target
   in the middle of a conversion moment, so it takes the 48px floor like every
   other control — inline-flex so the min-height actually applies to a link. */
.abv-root[data-abv-mode='professional'] .abvp-route__card .abvp-btn--quiet,
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-btn--quiet {
  display: inline-flex; align-items: center;
  min-height: 48px;
}

/* =============================================================================
   THE PROFLOW UNLOCK BLOCK — icon cards, tighter hierarchy
   =============================================================================
   The block was a dark box holding six paragraphs. The information was right;
   the presentation asked a contractor to READ a pitch rather than SCAN one.

   The structure it now follows, top to bottom:

     PRO ADVANTAGE EXCLUSIVE   orange kicker
     Unlock ProFlow            the headline, and only while it is selling
     one short line            what it is, in a sentence
     six icon cards            what you get, one line each
     the unlock zone           its own panel — the thing you DO
     Explore Pro Advantage     the path for everyone who cannot unlock

   The icon sits ABOVE the title, not beside it. The grid runs three across on
   desktop, and a left-hand icon takes the width the title needs — which forces
   exactly the two-line wrapping this pass exists to remove.
   ========================================================================== */

/* ---- HEADLINE + INTRO ------------------------------------------------- */
.abv-root[data-abv-mode='professional'] .abvp-pf__title {
  margin: 6px 0 8px;
  font-size: 27px; line-height: 1.14; font-weight: 800; letter-spacing: -0.5px;
  color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__say {
  margin: 0 0 22px;
  font-size: 15px; line-height: 1.6; color: rgba(255, 255, 255, .82);
  max-width: 56ch;              /* was 68ch — a shorter measure reads faster */
}

/* ---- THE ICON CARDS -------------------------------------------------- */
.abv-root[data-abv-mode='professional'] .abvp-pf__feats {
  list-style: none; margin: 0 0 26px; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
  gap: 12px;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__feat {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 0;
  padding: 18px 18px 20px;
  border-radius: 12px;
  /* Barely-there white lift on the navy, with a hairline. Not a grey card. */
  background: rgba(255, 255, 255, .045);
  border: 1px solid rgba(255, 255, 255, .12);
  transition: background-color .2s var(--abv-ease), border-color .2s var(--abv-ease),
              transform .2s var(--abv-ease);
}
/* The whole card reacts, so the grid feels like a set of objects rather than a
   block of text. Restrained: an accent edge and 1px, nothing more. */
.abv-root[data-abv-mode='professional'] .abvp-pf__feat:hover {
  background: rgba(255, 255, 255, .07);
  border-color: rgba(239, 125, 72, .55);
  transform: translateY(-1px);
}
@media (prefers-reduced-motion: reduce) {
  .abv-root[data-abv-mode='professional'] .abvp-pf__feat:hover { transform: none; }
}

/* The icon plate. The brand's signature icon treatment is a navy circle with an
   orange glyph; on a navy ground that circle disappears, so the same idea is
   inverted — an orange-tinted plate carrying an orange glyph. */
.abv-root[data-abv-mode='professional'] .abvp-pf__icowrap {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; margin: 0 0 13px;
  border-radius: 10px;
  background: rgba(239, 125, 72, .14);
  border: 1px solid rgba(239, 125, 72, .3);
  color: var(--abv-orange, #EF7D48);
  flex: none;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__ico {
  width: 19px; height: 19px; display: block;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__feat b {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 5px;
  font-size: 14.5px; font-weight: 700; line-height: 1.25; color: #fff;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__featd {
  display: block;
  font-size: 12.8px; line-height: 1.5; color: rgba(255, 255, 255, .7);
}
/* "Soon" — one word now, and quiet. It marks a feature that is not here yet;
   it should not be the loudest thing in the grid, which a full orange
   "COMING SOON" lozenge was. */
.abv-root[data-abv-mode='professional'] .abvp-pf__soon {
  font-size: 9.5px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase;
  padding: 3px 7px; border-radius: 999px;
  color: var(--abv-orange, #EF7D48);
  background: rgba(239, 125, 72, .14);
  border: 1px solid rgba(239, 125, 72, .38);
}
/* The unavailable card is dimmed and does not invite a hover it cannot honour. */
.abv-root[data-abv-mode='professional'] .abvp-pf__feat.is-soon { opacity: .72; }
.abv-root[data-abv-mode='professional'] .abvp-pf__feat.is-soon:hover {
  background: rgba(255, 255, 255, .045);
  border-color: rgba(255, 255, 255, .12);
  transform: none;
}

/* ---- THE UNLOCK ZONE ------------------------------------------------- */
/* Its own panel, separated by a rule and a slightly stronger ground, so the
   action reads as the next move rather than as more of the pitch. */
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone {
  margin: 0 0 18px; padding: 22px 22px 18px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .16);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone .abvp-pf__steph {
  margin: 0 0 3px; font-size: 18px;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone .abvp-pf__stepsay {
  margin: 0 0 16px;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone .abvp-pf__form:last-child { margin-bottom: 0; }
/* The field: taller, white, and the label above it in the same tracked caps the
   rest of the calculator uses. */
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone .abvp-pf__input {
  height: 52px; border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, .34);
  font-size: 15px;
}
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone .abvp-pf__input:focus-visible {
  outline: 3px solid var(--abv-blue-lt, #3993D5); outline-offset: 2px;
}
/* The send button is the loudest control in the block: white on navy is the
   strongest pairing available here, and 18.88:1. */
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone .abvp-btn--primary {
  min-height: 52px; padding-left: 28px; padding-right: 28px;
}

/* ---- THE NON-MEMBER PATH -------------------------------------------- */
/* Was a bare ghost button with no lead-in, which made it read as a second
   equal option. One short question turns it into an answer for the people it
   is actually for. */
.abv-root[data-abv-mode='professional'] .abvp-pf__cta--quiet {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, .12);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__notmember {
  margin: 0; font-size: 13.5px; color: rgba(255, 255, 255, .72);
}

/* ---- MOBILE --------------------------------------------------------- */
@media (max-width: 600px) {
  .abv-root[data-abv-mode='professional'] .abvp-pf__title { font-size: 23px; }
  .abv-root[data-abv-mode='professional'] .abvp-pf__say { font-size: 14.5px; margin-bottom: 18px; }
  /* One column. Two 196px cards in a 356px content width leaves no room for the
     icon plate and a readable line. */
  .abv-root[data-abv-mode='professional'] .abvp-pf__feats {
    grid-template-columns: 1fr; gap: 10px; margin-bottom: 20px;
  }
  /* Icon moves BESIDE the title once each card owns a full row — it reclaims
     the vertical space six stacked cards would otherwise cost. */
  .abv-root[data-abv-mode='professional'] .abvp-pf__feat {
    display: grid; grid-template-columns: auto 1fr; gap: 0 14px;
    align-items: center; padding: 14px 16px;
  }
  .abv-root[data-abv-mode='professional'] .abvp-pf__icowrap {
    grid-row: 1 / span 2; margin: 0; width: 40px; height: 40px;
  }
  .abv-root[data-abv-mode='professional'] .abvp-pf__feat b { margin-bottom: 2px; }
  .abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone { padding: 18px 16px 16px; }
  .abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone .abvp-btn--primary { width: 100%; }
  .abv-root[data-abv-mode='professional'] .abvp-pf__cta--quiet .abvp-btn { width: 100%; }
}

/* ---- PROFLOW GRID + CONTROL OVERRIDES -------------------------------------
   Three fixes that specificity, not intent, got wrong first time:

   1. auto-fit/minmax(196px) resolved to FIVE columns at 1109px, so the six
      cards laid out 5 + 1 and the last one sat alone. An explicit 3-up gives
      two clean rows of three, which is what six items want.
   2. The icon plate's colour is set here, past the generic span rule that was
      overriding it.
   3. `.abvp-pf button.abvp-btn` carries an element qualifier and out-specified
      the 52px unlock button, holding it at the 48px floor.
--------------------------------------------------------------------------- */
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-pf__feats {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-pf__icowrap {
  color: var(--abv-orange, #EF7D48);
}
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone button.abvp-btn--primary {
  min-height: 52px;
}
/* Two-up on tablet, one-up on phone — never a lone card on its own row. */
@media (max-width: 900px) {
  .abv-root[data-abv-mode='professional'] .abvp-pf .abvp-pf__feats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .abv-root[data-abv-mode='professional'] .abvp-pf .abvp-pf__feats {
    grid-template-columns: 1fr;
  }
}

/* =============================================================================
   THE SHARED CONTENT RAIL  @ab-rail-20260824
   =============================================================================
   The hero establishes a left content edge. Below it, each calculator centred
   itself in its own max-width box, so the eye travelling down the page hit a
   different left edge every time. Measured at a 1425px content width:

       hero text (eyebrow + H1)     left  74
       homeowner stage heading      left 307      <- 233px adrift
       professional intro heading   left 117      <-  43px adrift
       professional step title      left 146      <-  72px adrift

   THE RAIL IS DERIVED, NOT GUESSED. Three numbers come straight off the hero
   container on both pages and are the only values anyone should ever edit:

       --ab-rail-max      1600px   the hero .e-con-inner max-width
       --ab-rail-gutter     32px   the hero container's side padding
       --ab-rail-inset      42px   hero inner padding (10) + copy column (32)

   --ab-rail then reproduces exactly what Elementor does to place that text:
   centre a 1600px box, but never closer than 32px to the edge, then step in by
   the inset.

   READ THE CAP AT A WIDE VIEWPORT. At 1440 the inner measures 1361px, but that
   is the container CONSTRAINING it (1425 - 64), not its max-width. Taking that
   number as the cap put the rail 119px off at 1920. The real values are
   max-width:1600px on .e-con-inner and padding-left:42px on the copy column. Percentages resolve against the calculator's own full-width
   parent, so this is scrollbar-safe in a way 100vw is not.

   ALIGNMENT, NOT WIDTH. Each calculator keeps its own max-width — the
   homeowner questionnaire stays a narrow reading measure, the professional
   workspace stays wide. Only the left edge is shared.

   DESKTOP ONLY (>=1025px). Below that both calculators keep their existing
   centred, padded, full-width behaviour untouched.
   ========================================================================== */
.abv-root {
  --ab-rail-max:    1600px;
  --ab-rail-gutter:   32px;
  --ab-rail-inset:    42px;
  --ab-rail: calc(
    max(var(--ab-rail-gutter), (100% - var(--ab-rail-max)) / 2) + var(--ab-rail-inset)
  );
}

@media (min-width: 1025px) {
  /* ---- HOMEOWNER ------------------------------------------------------
     The shell's own 24px side padding is dropped here rather than subtracted
     from the margin: the rail then lands on the shell's CONTENT edge with no
     arithmetic to keep in sync, so the stage label and question sit exactly on
     the hero's 74px. The shell keeps its 860px reading measure and simply
     ends earlier on the right — deliberate, per the brief. */
  .abv-root[data-abv-mode='homeowner'] .abv-shell {
    margin-left: var(--ab-rail);
    margin-right: auto;
    padding-left: 0;
    padding-right: 0;
  }

  /* ---- PROFESSIONAL ---------------------------------------------------
     Same treatment on the workspace wrapper. Its 1240px max-width is kept, so
     at 1425 it runs 74 -> 1314 and at 1920 it runs 321 -> 1561 — inside the
     hero's own right edge at both, which is why no right-hand cap is needed. */
  .abv-root[data-abv-mode='professional'] .abv-pro,
  .abv-root[data-abv-mode='professional'] .abvp {
    margin-left: var(--ab-rail);
    margin-right: auto;
    padding-left: 0;
    padding-right: 0;
  }

  /* Every later section — result, plan, proposal, the ProFlow workspace —
     lives inside those two wrappers, so it inherits the rail. Nothing below is
     positioned independently, which is what keeps the alignment from drifting
     between stages. */
}

/* =============================================================================
   "PICK MY EXACT COLOR" — the shared disclosure  @ab-exact-20260824
   =============================================================================
   Light / Medium / Dark IS the engine input, so it is a complete answer. The
   manufacturer library is refinement, and it is now closed by default on both
   calculators. Previously the homeowner side force-opened it the moment a tone
   was picked, which is what made this one step run several screens deep.

   ONE implementation: both calculators use a native <details class="abv-exact">.
   Native gives keyboard operation, correct expanded/collapsed semantics, and
   open state that survives a repaint — none of which a div-and-button pair does
   without extra code. The styling below removes every trace of the default
   look, so it reads as an Attic Breeze control rather than a browser widget.

   No grey anywhere: white ground, navy type, navy hairline, orange chevron.
   ========================================================================== */

/* The optional framing, above the control. Small, plain, and it makes clear
   the user can simply continue. */
.abv-root .abv-exact__opt {
  margin: var(--abv-5) 0 8px;
  font-family: var(--abv-font);
  font-size: 13.5px; line-height: 1.5;
  color: rgba(5, 17, 36, .58);
}

.abv-root details.abv-exact {
  margin: 0 0 var(--abv-5);
  background: #fff;
  border: 1px solid var(--p-rule, rgba(5, 17, 36, .14));
  border-radius: 12px;
  overflow: hidden;
}
/* The summary row. 56px so the tap target clears 48 with room to spare. */
.abv-root details.abv-exact > summary {
  display: flex; align-items: center; gap: 12px;
  min-height: 56px; padding: 14px 18px;
  cursor: pointer;
  list-style: none;                 /* Firefox marker */
  border-top: 0;                    /* .abv-more adds one; not wanted here */
  font-family: var(--abv-font);
  transition: background-color .18s var(--abv-ease);
}
.abv-root details.abv-exact > summary::-webkit-details-marker { display: none; }
.abv-root details.abv-exact > summary::marker { content: ''; }
.abv-root details.abv-exact > summary:hover { background: rgba(57, 147, 223, .05); }
.abv-root details.abv-exact > summary:focus-visible {
  outline: 3px solid var(--abv-blue-lit, #346AC1); outline-offset: -3px;
}
.abv-root .abv-exact__label {
  font-size: 13px; font-weight: 700; letter-spacing: 1.1px; text-transform: uppercase;
  color: var(--abv-navy, #051124);
  flex: none;
}
/* The retained selection. Sits between the label and the chevron and truncates
   rather than wrapping the row onto two lines. */
.abv-root .abv-exact__sel {
  flex: 1 1 auto; min-width: 0;
  font-size: 13px; font-weight: 600; line-height: 1.3;
  color: var(--abv-orange, #EF7D48);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.abv-root .abv-exact__sel::before { content: '\2713\00a0'; font-weight: 700; }
/* The chevron. A rotating box, so there is no icon font and no SVG to load. */
.abv-root .abv-exact__chev {
  flex: none; margin-left: auto;
  width: 10px; height: 10px;
  border-right: 2px solid var(--abv-orange, #EF7D48);
  border-bottom: 2px solid var(--abv-orange, #EF7D48);
  transform: rotate(45deg) translateY(-2px);
  transition: transform .22s var(--abv-ease);
}
.abv-root details.abv-exact[open] > summary .abv-exact__chev {
  transform: rotate(-135deg) translateY(-2px);
}
/* When a selection is shown the label must not be pushed off; the selection is
   the flexible one and already truncates, so nothing else needs to give. */
.abv-root .abv-exact__sel:not([hidden]) ~ .abv-exact__chev { margin-left: 0; }

.abv-root .abv-exact__body,
.abv-root details.abv-exact > .abv-more__body {
  padding: 4px 18px 20px;
  border-top: 1px solid var(--abv-hairline, rgba(5, 17, 36, .09));
}
@media (prefers-reduced-motion: reduce) {
  .abv-root .abv-exact__chev { transition: none; }
}
@media (max-width: 600px) {
  .abv-root details.abv-exact > summary { padding: 14px 14px; gap: 10px; }
  .abv-root .abv-exact__label { font-size: 12px; letter-spacing: .9px; }
  /* On a phone the selection gets its own line rather than a 60px ellipsis. */
  .abv-root details.abv-exact > summary { flex-wrap: wrap; }
  .abv-root .abv-exact__sel { flex: 1 1 100%; order: 3; white-space: normal; }
  .abv-root .abv-exact__chev { margin-left: auto; }
  .abv-root .abv-exact__body { padding: 4px 14px 18px; }
}

/* ============================================================================
   REVISION 7 · "WHICH ATTIC FAN DO I NEED?" — GUIDED ROOF-SLOPE STAGE
   Homeowner only. The professional calculator's pitch control is an `abvp-`
   scoped <select> and shares no selector with anything below.

   The stage now reads: four questions, one at a time -> four roof pictures ->
   sun. Everything technical that used to sit above the questions is gone from
   the markup; its rules (.abv-pitch*, .abv-chosen*, .abv-lastresort,
   .abv-identshot*, .abv-ident) are left in the sheet unchanged because
   .abv-more is SHARED with the exact-colour disclosure in abv-roof.js and
   pulling the block apart risks that. They now match nothing.

   Two things the kit forces on us, re-asserted here at .abv-root specificity:
   the Elementor kit paints every bare <button> orange (kit-1333), and
   .abv-root [hidden] is already !important, so [hidden] beats every display
   value below without a per-element rule.
   ========================================================================= */

/* The lead-in is two lines, not two paragraphs with a 32px hole between. */
.abv-screen[data-abv-screen="slope"] > .abv-sub { margin-bottom: var(--abv-2); }
.abv-screen[data-abv-screen="slope"] > .abv-sub--run { margin-bottom: var(--abv-6); }

/* ---- the guided questionnaire -------------------------------------------- */
.abv-wiz {
  margin: 0 0 var(--abv-5); padding: var(--abv-5);
  background: #fff; border: 1px solid var(--abv-line);
  border-radius: var(--abv-radius-lg);
}
.abv-wiz__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--abv-4); margin: 0 0 var(--abv-4);
}
.abv-wiz__count {
  font-size: 11px; font-weight: 700; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: var(--abv-muted);
}
.abv-wiz__rail { display: flex; align-items: center; gap: 6px; margin: 0; padding: 0; list-style: none; }
.abv-wiz__rail > li::marker { content: none; }
.abv-wiz__dot {
  display: grid; place-items: center; width: 24px; height: 24px;
  border-radius: var(--abv-radius-pill); font-size: 11px; font-weight: 800;
  color: var(--abv-muted); background: #fff; border: 1px solid var(--abv-line);
  transition: background var(--abv-dur) var(--abv-ease),
              border-color var(--abv-dur) var(--abv-ease),
              color var(--abv-dur) var(--abv-ease);
}
.abv-wiz__dot.is-done { background: var(--abv-navy); border-color: var(--abv-navy); color: #fff; }
.abv-wiz__dot.is-now {
  background: #fff; color: var(--abv-navy);
  border-color: var(--abv-orange); box-shadow: inset 0 0 0 1px var(--abv-orange);
}

/* ONE question on screen. The legend is the question, so it carries h3 weight
   rather than the small bold a <legend> normally gets. */
.abv-wizq { border: 0; margin: 0; padding: 0; min-width: 0; }
.abv-wizq > legend {
  display: block; float: none; width: 100%; padding: 0 0 var(--abv-2);
  font-size: var(--abv-h3); line-height: var(--abv-h3-lh); letter-spacing: var(--abv-h3-ls);
  font-weight: var(--abv-w-head); color: var(--abv-ink-head);
}
.abv-wizq__help {
  margin: 0 0 var(--abv-4); max-width: 52ch;
  font-size: var(--abv-small); line-height: 1.55; color: var(--abv-muted);
}

/* The answer buttons keep the house pick treatment and gain a resolve mark. */
.abv-root .abv-wizq .abv-pick {
  display: flex; align-items: center; justify-content: space-between; gap: var(--abv-3);
}
.abv-root .abv-pick > span { flex: 1 1 auto; }
.abv-pick__check, .abv-bp__check {
  flex: none; display: grid; place-items: center; width: 22px; height: 22px;
  border-radius: var(--abv-radius-pill); font-style: normal;
  background: var(--abv-orange); color: var(--abv-navy);
  opacity: 0; transform: scale(.55);
  transition: opacity var(--abv-dur) var(--abv-ease), transform var(--abv-dur) var(--abv-ease);
}
.abv-root .abv-pick.is-on .abv-pick__check,
.abv-root .abv-bp.is-on .abv-bp__check { opacity: 1; transform: none; }

/* ---- answered questions stay editable ------------------------------------ */
.abv-wizrecap { list-style: none; display: grid; gap: 2px; margin: 0 0 var(--abv-4); padding: 0; }
.abv-wizrecap > li::marker { content: none; }
.abv-root .abv-wizrecap__row {
  -webkit-appearance: none; appearance: none;
  display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--abv-2) var(--abv-3);
  width: 100%; padding: 9px var(--abv-3) 9px var(--abv-3); min-height: 0;
  font: inherit; font-size: var(--abv-small); text-align: left;
  text-transform: none; letter-spacing: normal;
  color: var(--abv-text); background: #fff;
  border: 0; border-left: 2px solid var(--abv-line); border-radius: 0;
  box-shadow: none; cursor: pointer;
  transition: background var(--abv-dur) var(--abv-ease), border-color var(--abv-dur) var(--abv-ease);
}
.abv-root .abv-wizrecap__row:hover {
  background: rgba(5, 17, 36, .04); border-left-color: var(--abv-orange);
}
.abv-wizrecap__q {
  flex: 0 0 auto; min-width: 9.5em;
  font-size: 11px; font-weight: 700; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: var(--abv-muted);
}
.abv-wizrecap__a { flex: 1 1 12em; font-weight: var(--abv-w-strong); color: var(--abv-ink-head); }
.abv-wizrecap__edit {
  flex: 0 0 auto; font-size: 11px; font-weight: 700; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: var(--abv-blue-lit);
  text-decoration: underline; text-underline-offset: 3px;
}

/* ---- "got it — here are the closest matches" ------------------------------ */
.abv-matches__flash {
  display: flex; align-items: center; gap: 10px; margin: 0 0 var(--abv-3);
  font-size: 11px; font-weight: 700; letter-spacing: var(--abv-eyebrow-ls);
  text-transform: uppercase; color: var(--abv-navy);
}
.abv-matches__flash::before {
  content: ""; flex: none; width: 18px; height: 3px;
  border-radius: 2px; background: var(--abv-orange);
}
.abv-matches > .abv-q--sub { margin: 0 0 var(--abv-2); }
.abv-matches > .abv-sub { margin-bottom: var(--abv-5); }
.abv-matches .abv-fine { margin: 0; }

/* ---- the four roof profiles ----------------------------------------------
   Four across on desktop; the shell's 860px measure gives ~194px cards, which
   is the drawing's natural size. Two-up from 880 down, which covers 768, 430
   and 390 — a 2x2 grid compares better than a scroller because all four
   silhouettes stay on screen together, which is the whole point of them. */
.abv-matches .abv-bps {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--abv-3); margin: 0 0 var(--abv-4);
}
.abv-root .abv-matches .abv-bp {
  position: relative; display: flex; flex-direction: column; gap: 0;
  padding: var(--abv-4) var(--abv-4) var(--abv-5);
  background: #fff; border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  transition: border-color var(--abv-dur) var(--abv-ease),
              box-shadow var(--abv-dur) var(--abv-ease),
              transform var(--abv-dur) var(--abv-ease);
}
.abv-root .abv-matches .abv-bp:hover { border-color: var(--abv-navy); transform: translateY(-2px); }
.abv-root .abv-matches .abv-bp.is-on {
  background: #fff; border-color: var(--abv-orange);
  box-shadow: inset 0 0 0 2px var(--abv-orange); transform: none;
}
.abv-matches .abv-bp__art { display: block; margin: 0 0 var(--abv-3); }
.abv-matches .abv-bp__art svg { display: block; width: 100%; height: auto; max-height: none; }
.abv-bp__name {
  font-size: 16px; font-weight: 800; line-height: 1.25; color: var(--abv-ink-head);
}
.abv-matches .abv-bp__tell {
  margin-top: 4px; font-size: 12.5px; line-height: 1.4; color: var(--abv-muted);
}
/* The exact pitch is supporting text. It is here because a homeowner who DOES
   know their pitch should be able to confirm the card — never as the headline. */
.abv-bp__pitch {
  margin-top: 10px; font-size: 11px; font-weight: 700;
  letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase; color: var(--abv-blue);
}
.abv-bp__check { position: absolute; top: 10px; right: 10px; }

@media (max-width: 880px) {
  .abv-matches .abv-bps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--abv-3); }
}
@media (max-width: 620px) {
  .abv-wiz { padding: var(--abv-4); }
  .abv-wiz__head { flex-wrap: wrap; gap: var(--abv-2) var(--abv-3); }
  .abv-root .abv-matches .abv-bp { padding: var(--abv-3) var(--abv-3) var(--abv-4); }
  .abv-matches .abv-bp__art { margin-bottom: var(--abv-2); }
  .abv-bp__name { font-size: 15px; }
  .abv-matches .abv-bp__tell { font-size: 12px; }
  .abv-wizrecap__q { min-width: 0; }
}

/* Sun follows the profile, so it starts hidden and is revealed by
   ABVSun.syncSunVisible(). Its top rule closes the previous question. */
.abv-sunrow .abv-hr { margin-top: var(--abv-5); }

/* ---- the stray box around every stage heading ------------------------------
   Pre-existing, found while shooting this stage. App.go() focuses the stage
   heading (tabindex="-1") so a screen reader announces the new step; the UA
   answers with its own 1px focus ring, which paints a box around the question
   on EVERY stage of both calculators. Suppressed on that element only — a
   tabindex="-1" heading is never reached by keyboard tabbing, so no real focus
   indicator is lost, and the announcement still happens. */
.abv-root .abv-q[tabindex="-1"]:focus,
.abv-root .abv-plan__title[tabindex="-1"]:focus { outline: none; }

/* The profile frame is now sized to the shortlist (see abv-pitch.js), so the
   drawing fills its tile instead of floating under empty sky. Give it room. */
.abv-matches .abv-bp__art { min-height: 0; }
.abv-matches .abv-bp__art svg { max-width: 100%; }

/* The card is picture + name + pitch. The name gets a little more air now that
   the second descriptive line is gone (see abv-pitch.js on why it went). */
.abv-matches .abv-bp__name { margin-top: 2px; }
.abv-matches .abv-bp__pitch { margin-top: 6px; }

/* =============================================================================
   THE FREE RESULT — PROFLOW PRODUCT SEPARATION
   =============================================================================
   The public Ventilation Calculator now ends at the answer. Three new blocks:

     .abvp-core   the recommendation card — product, tier, quantity, mount,
                  SKU and the product photograph, on the navy hero
     .abvp-free   the two actions the free contractor has, and the routing
                  card + restart that used to live in the proposal section
     .abvp-pf__cta--lead   the conversion block's own Unlock / Learn pair,
                  above the folded-away verification form

   Everything premium keeps its existing rules and is simply never shown
   outside the ProFlow workspace.
   ========================================================================== */

.abv-root[data-abv-mode='professional'] .abvp-sized__say {
  margin: 6px 0 0; font-size: var(--p-help); color: var(--p-ink-3);
}

/* ---- the recommendation card -------------------------------------------- */
/* Photograph and specification side by side on the navy ground. Explicit
   columns, never auto-fit: there are exactly two children and auto-fit would
   collapse them at an arbitrary width. */

.abv-root[data-abv-mode='professional'] .abvp-core__grid {
  display: grid; grid-template-columns: 1fr; gap: var(--p-3);
  margin: 0 0 var(--p-3);
}

.abv-root[data-abv-mode='professional'] .abvp-core__grid.has-shot { grid-template-columns: 168px minmax(0, 1fr); align-items: start; }

.abv-root[data-abv-mode='professional'] .abvp-core__shot {
  display: grid; place-items: center;
  aspect-ratio: 1 / 1; padding: 12px;
  background: #fff; border-radius: var(--abv-radius-lg, 14px);
}

.abv-root[data-abv-mode='professional'] .abvp-core__shot img { width: 100%; height: 100%; object-fit: contain; }

.abv-root[data-abv-mode='professional'] .abvp-core__spec { min-width: 0; }

/* The key/value rows are written for white surfaces. On the hero they need the
   inverse ink, and the hairline has to be white at low alpha or it vanishes. */

.abv-root[data-abv-mode='professional'] .abvp-core__spec .abvp-row { border-bottom-color: rgba(255,255,255,.18); }

.abv-root[data-abv-mode='professional'] .abvp-core__spec .abvp-row:last-child { border-bottom: 0; }

.abv-root[data-abv-mode='professional'] .abvp-core__spec .abvp-row__k { color: rgba(255,255,255,.76); }

.abv-root[data-abv-mode='professional'] .abvp-core__spec .abvp-row__v,

.abv-root[data-abv-mode='professional'] .abvp-core__spec .abvp-row__v b { color: #fff; }

.abv-root[data-abv-mode='professional'] .abvp-core__spec .abvp-row__v small { color: rgba(255,255,255,.72); }
/* The SKU is the thing that gets typed into an order, so it is set in the
   monospaced-feeling way the schedule already uses rather than as prose. */

.abv-root[data-abv-mode='professional'] .abvp-core__spec .abvp-row:nth-last-child(1) .abvp-row__v b { letter-spacing: .4px; }

@media (max-width: 720px) {
  
.abv-root[data-abv-mode='professional'] .abvp-core__grid.has-shot { grid-template-columns: 1fr; }
  
.abv-root[data-abv-mode='professional'] .abvp-core__shot { aspect-ratio: 16 / 9; max-width: 240px; }
}

/* ---- the two free actions ------------------------------------------------ */
/* Not equals. The summary is the finished free product and carries the primary
   treatment; ProFlow is the next level and takes the outline. */

.abv-root[data-abv-mode='professional'] .abvp-free {
  margin: var(--p-4) 0 0; padding: var(--p-3) 0 0;
  border-top: 1px solid var(--p-rule);
}

.abv-root[data-abv-mode='professional'] .abvp-free__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--p-2);
}

.abv-root[data-abv-mode='professional'] .abvp-free__fine { margin: var(--p-2) 0 0; max-width: 62ch; }

.abv-root[data-abv-mode='professional'] .abvp-free__foot { margin-top: var(--p-3); }

@media (max-width: 560px) {
  
.abv-root[data-abv-mode='professional'] .abvp-free__row { flex-direction: column; align-items: stretch; }
  
.abv-root[data-abv-mode='professional'] .abvp-free__row > .abvp-btn { width: 100%; }
}

/* ---- the conversion block ------------------------------------------------ */
/* The card leads with why, so its own Unlock/Learn pair sits directly under
   the four benefits and above the folded verification form. */

.abv-root[data-abv-mode='professional'] .abvp-pf__cta--lead {
  margin-top: var(--p-3);
  padding-top: var(--p-2);
  border-top: 1px solid rgba(255,255,255,.16);
}

.abv-root[data-abv-mode='professional'] .abvp-pf__say--sm {
  font-size: var(--p-help); color: rgba(255,255,255,.82); max-width: 64ch;
}
/* The unlock zone is revealed in place. Give it a moment of its own so it does
   not read as having been there all along. */

.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone[hidden] { display: none; }

.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone:not([hidden]) {
  animation: abvp-pf-open .28s cubic-bezier(.22,.61,.36,1) both;
}
@keyframes abvp-pf-open {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  
.abv-root[data-abv-mode='professional'] .abvp-pf__unlockzone:not([hidden]) { animation: none; }
}

/* ---- the ProFlow workspace gained three adopted tools -------------------- */
/* Each borrowed node arrives carrying its own section chrome, which would
   double the framing inside a ProFlow section that already has a header and a
   body. Strip the outer shell on the adopted copies only. */

.abv-root[data-abv-mode='professional'] .abvf-sec__body > [data-abv-alt-stage],

.abv-root[data-abv-mode='professional'] .abvf-sec__body > [data-abv-vent-stage],

.abv-root[data-abv-mode='professional'] .abvf-sec__body > [data-abv-acts-host] { padding: 0; }

.abv-root[data-abv-mode='professional'] .abvf-sec__body > [data-abv-plan-block] { margin: 0; }
/* The planning surface is the one adopted tool with a fixed-height canvas. It
   has to keep its own height inside the workspace or the aerial collapses. */

.abv-root[data-abv-mode='professional'] .abvf-sec__body > [data-abv-plan-block] .abvp-plan__canvas { min-height: 360px; }
@media (max-width: 720px) {
  
.abv-root[data-abv-mode='professional'] .abvf-sec__body > [data-abv-plan-block] .abvp-plan__canvas { min-height: 260px; }
}
/* Adopted content sits on the workspace's navy drafting ground, so anything
   that assumed a white page needs the inverse ink. */

.abv-root[data-abv-mode='professional'] .abvf-sec__body .abvp-acts__fine,

.abv-root[data-abv-mode='professional'] .abvf-sec__body .abvp-sec__note { color: rgba(255,255,255,.74); }

.abv-root[data-abv-mode='professional'] .abvf-actions .abvp-acts__row { margin: 0; }

/* The card is picture + name + pitch. The name gets a little more air now that
   the second descriptive line is gone (see abv-pitch.js on why it went). */
.abv-matches .abv-bp__name { margin-top: 2px; }
.abv-matches .abv-bp__pitch { margin-top: 6px; }

/* ---- FOUR benefits, not six -------------------------------------------
   The conversion block was written for a six-item feature list and pinned to
   `repeat(3, minmax(0,1fr))` so six cards could never lay out 5+1. Four items
   in a three-column grid orphans the fourth, which is the same defect in a
   different shape. Four across on a wide card, 2x2 in the middle, one column
   on a phone.

   These carry the `.abvp-pf` qualifier deliberately: the existing 600px rule
   is written against the bare `.abvp-pf__feats`, so a lower-specificity
   override would lose to the pinned three-column rule inside the media query
   and phones would keep three columns. */
.abv-root[data-abv-mode='professional'] .abvp-pf .abvp-pf__feats {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1000px) {
  .abv-root[data-abv-mode='professional'] .abvp-pf .abvp-pf__feats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .abv-root[data-abv-mode='professional'] .abvp-pf .abvp-pf__feats {
    grid-template-columns: 1fr;
  }
}

/* =============================================================================
   THE ADOPTED TOOLS SIT ON A WHITE PLATE
   =============================================================================
   Navy is the PLAN. White is the TOOL. Four interactive blocks are borrowed
   whole from the free calculator into the ProFlow workspace — the alternates,
   the ventilation analysis, the planning surface and the report controls — and
   every one of them was designed, and contrast-checked, against white.

   Measured before writing this: 53 text nodes in the workspace were below
   3.2:1 on the navy ground. Re-tokenising --p-ink inside .abvf fixed those and
   broke 34 others that sit on their own light sub-panels (inputs, #fdf1ea
   advisories, the map-state card). A plate fixes both sets at once and cannot
   miss a selector, which a per-rule inversion demonstrably did.
   ========================================================================== */

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot {
  background: #fff;
  border: 1px solid rgba(57,147,223,.30);
  border-radius: 14px;
  padding: 22px 22px 24px;
  color: var(--p-ink);
}

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot:empty { display: none; }
@media (max-width: 640px) {
  
.abv-root[data-abv-mode='professional'] .abvf .abvf-plate,
  
.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot { padding: 16px 14px 18px; border-radius: 12px; }
}

/* ---- and the navy inversion is undone inside the plate -------------------
   Every original declaration these rules overrode was already token-based, so
   the restore is the same token reference rather than a hard-coded colour —
   change a token later and the plate follows it. One class deeper than the
   inversion block, which is what makes it win. */

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-grp__title,

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-f__label,

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-block__title,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-grp__title,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-f__label,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-logo__meta b,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-logo__fail b { color: var(--p-ink); }


.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-help,

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-sec__note,

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-btn--quiet,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-help,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-logo__or { color: var(--p-ink-3); }


.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-vent b { color: var(--p-ink); }


.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-logo__or::before,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-logo__or::after { background: var(--p-rule); }

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-logo__found,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-logo__fail {
  background: #fff; border-color: var(--p-line, rgba(5,17,36,.14));
}

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-btn--secondary,

.abv-root[data-abv-mode='professional'] .abvf .abvf-logoslot .abvp-btn--secondary {
  background: #fff; color: var(--p-navy); border-color: var(--p-rule);
}
/* .abvf-actions paints its buttons white so they read on navy. The report
   controls now sit on a white plate, where a white button is invisible. */

.abv-root[data-abv-mode='professional'] .abvf .abvf-actions.abvf-plate .abv-btn,

.abv-root[data-abv-mode='professional'] .abvf .abvf-actions .abvf-plate .abv-btn {
  background: var(--p-navy); color: #fff; border-color: var(--p-navy);
}

.abv-root[data-abv-mode='professional'] .abvf .abvf-actions.abvf-plate .abv-btn:hover,

.abv-root[data-abv-mode='professional'] .abvf .abvf-actions .abvf-plate .abv-btn:hover {
  background: #EF7D48; border-color: #EF7D48; color: #051124;
}

.abv-root[data-abv-mode='professional'] .abvf .abvf-actions .abvf-plate .abvp-btn--secondary {
  background: #fff; color: var(--p-navy); border-color: var(--p-rule);
}

/* The plate carries its own frame, so the tool must not draw a second one. */

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate > .abvp-plan { margin: 0; }

.abv-root[data-abv-mode='professional'] .abvf .abvf-plate .abvp-sec__head { display: none; }

/* ---- ROOF BAND TILES · exact-colour picker ON HOLD (2026-08-25) ----------
   The mobile rule further up dropped the band-tile name caption because "the
   full list is one tap away under Pick my exact colour". That picker now sits
   behind ABV_WP.features.exactColor and is not rendered, so this caption is the
   only place the example names appear — and it is the point of the card. Stack
   the three tiles instead: the vertical cost is a fraction of the exact-colour
   section that no longer sits below them. */
@media (max-width: 640px) {
  .abv-bands { grid-template-columns: 1fr; }
  .abv-bandtile__body small { display: block; }
  .abvp-bands { grid-template-columns: 1fr; }
}
/* The professional's tone tile gains the same quiet example line, matching the
   multiplier line it sits beside. */
.abvp-band__eg {
  padding: 0 8px 6px; font-size: var(--p-help); color: var(--p-ink-3); line-height: 1.35;
}

/* =========================================================================
   THE ATTIC BREEZE ROOF COLOR REFERENCE — 2026-08-26
   Shared by the homeowner stage and the professional form. No gray card
   surfaces, no muddy orange, no underlines. Selected state is the orange
   border plus a warm tint plus an explicit check, so it never depends on
   color alone.
   ====================================================================== */


/* Breeze Orange, darkened for TEXT use. #EF7D48 measures 2.73:1 on white and
   2.38:1 on the orange tint — both below AA for a small uppercase label. This
   is the accent at 68%, which clears 4.5:1 on both grounds (5.40 and 4.70) and
   reads as the same color. Same precedent the brand sets for sage text. */
:root, .abv-root { --abv-accent-text: #a35531; }

/* The collapsed row. The hint sits under the label rather than beside it, so
   it never competes with the control name for the first line. */
.abv-exact__hint {
  display: block; margin-top: 2px;
  font-size: 12px; line-height: 1.35; font-weight: 400;
  color: var(--abv-muted);
}
.abv-root .abv-exact summary { text-decoration: none; }

/* The one explanatory note, shown once when the panel opens — never per card.
   White ground with an orange rule: a gray panel here would fight the cards,
   which are the only thing in this panel that should carry color. */
.abv-refnote {
  margin: 0 0 var(--abv-4); padding: var(--abv-3) var(--abv-4);
  border-left: 3px solid var(--abv-orange);
  background: var(--abv-tint);
  border-radius: 0 var(--abv-radius) var(--abv-radius) 0;
  font-size: 13px; line-height: 1.5; color: var(--abv-text);
}
.abv-refnote__eyebrow {
  display: block; margin-bottom: 3px;
  font-size: var(--abv-eyebrow-size); font-weight: var(--abv-w-strong);
  letter-spacing: var(--abv-eyebrow-ls); text-transform: uppercase;
  color: var(--abv-accent-text);
}

/* THE GRID. auto-fit with a floor rather than a fixed column count, so a
   material with two references does not stretch them across the full width.
   A bare 1fr track resolves to min-content and would squeeze the names. */
.abv-refs {
  display: grid; gap: var(--abv-3);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

/* ONE CARD. Image-led: a real roofing surface, the name under it, nothing
   else. The whole label is the hit target, so it is far past 48px in both
   directions at every breakpoint. */
.abv-root .abv-ref {
  position: relative; display: block; cursor: pointer;
  background: #fff;
  border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  overflow: hidden;
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.abv-ref input {
  position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0;
  /* Sized to the card rather than collapsed, so keyboard focus lands on
     something with real geometry. */
  width: 100%; height: 100%;
}
.abv-root .abv-ref:hover { border-color: var(--abv-navy); transform: translateY(-2px); }
.abv-ref input:focus-visible ~ .abv-ref__shot {
  outline: 3px solid var(--abv-blue-lt); outline-offset: -3px;
}

.abv-ref__shot {
  position: relative; display: block; overflow: hidden;
  /* The derivatives are all 3:2, so the box is declared rather than inferred
     — no reflow when a lazy image lands. */
  aspect-ratio: 3 / 2; background: var(--abv-line);
}
.abv-ref__shot img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}

/* The check. Present only when selected, and it is a SHAPE as well as a
   color, so the selected state survives a monochrome display. */
.abv-ref__tick {
  position: absolute; top: 8px; right: 8px;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--abv-orange);
  box-shadow: 0 1px 4px rgba(5, 17, 36, .35);
  opacity: 0; transform: scale(.6);
  transition: opacity .18s ease, transform .18s ease;
}
.abv-ref__tick::after {
  content: ''; position: absolute; left: 7px; top: 7px;
  width: 9px; height: 5px;
  border-left: 2.5px solid #fff; border-bottom: 2.5px solid #fff;
  transform: rotate(-45deg);
}
.abv-ref.is-on .abv-ref__tick { opacity: 1; transform: scale(1); }

.abv-ref__name {
  display: block; padding: 9px var(--abv-3) 10px;
  font-size: 14px; font-weight: 700; line-height: 1.25;
  color: var(--abv-navy);
  /* Two-word names wrap rather than clip; a fixed height would truncate
     "Continental Seville". */
  word-break: normal; overflow-wrap: break-word;
}

/* SELECTED. Orange border, warm tint behind the NAME only — tinting the whole
   card would sit a wash over the roofing color the customer is judging. */
.abv-root .abv-ref.is-on {
  border-color: var(--abv-orange);
  box-shadow: inset 0 0 0 1px var(--abv-orange);
}
.abv-root .abv-ref.is-on .abv-ref__name {
  background: var(--abv-tint); color: var(--abv-navy);
}

.abv-refs__foot {
  margin: var(--abv-3) 0 0; font-size: 12px; line-height: 1.45;
  color: var(--abv-muted);
}

@media (max-width: 640px) {
  /* Two across is comfortable at 390: the card lands ~166px, which holds
     "Continental Seville" on two lines without squeezing. */
  .abv-refs { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--abv-2); }
  .abv-ref__name { padding: 8px 10px 9px; font-size: 13px; }
  .abv-ref__tick { width: 22px; height: 22px; }
  .abv-ref__tick::after { left: 6px; top: 6px; }
}

/* =========================================================================
   HOMEOWNER RESULT — YOUR ROOF + RECOMMENDED FINISH
   ====================================================================== */
.abv-roofmatch {
  display: grid; gap: var(--abv-4);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  margin: 0 0 var(--abv-6); padding: var(--abv-5);
  background: #fff;
  border: 1px solid var(--abv-line); border-radius: var(--abv-radius);
  border-left: 3px solid var(--abv-orange);
}
.abv-roofmatch .abv-eyebrow { color: var(--abv-accent-text); }
.abv-roofmatch__spec { display: flex; flex-wrap: wrap; gap: 6px 10px; margin: 6px 0 0; }
.abv-roofmatch__spec b,
.abv-roofmatch__spec span {
  font-size: 15px; font-weight: 700; color: var(--abv-navy);
}
/* A dot separator drawn rather than typed, so it never gets read out. */
.abv-roofmatch__spec span::before {
  content: ''; display: inline-block; vertical-align: middle;
  width: 4px; height: 4px; margin-right: 9px; border-radius: 50%;
  background: var(--abv-line);
}
.abv-roofmatch__name { display: flex; align-items: center; gap: 9px; margin: 6px 0 0; }
.abv-roofmatch__name b { font-size: 19px; font-weight: 800; color: var(--abv-navy); }
.abv-roofmatch__chip {
  display: block; flex: 0 0 auto; width: 20px; height: 20px; border-radius: 5px;
  box-shadow: inset 0 0 0 1px rgba(5, 17, 36, .22);
}
.abv-roofmatch__why { margin: 5px 0 0; color: var(--abv-muted); }

/* =========================================================================
   PROFESSIONAL — the finish suggestion in the design form
   ====================================================================== */
.abvp-f--ref { grid-column: 1 / -1; }

.abvp-fsug {
  margin: var(--p-2, 10px) 0 0; padding: 10px 12px;
  background: #fff;
  border: 1px solid var(--p-line, #dde2e8); border-left: 3px solid var(--abv-orange);
  border-radius: 0 6px 6px 0;
}
.abvp-fsug__eyebrow {
  display: block; margin-bottom: 4px;
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--abv-accent-text);
}
.abvp-fsug__row { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.abvp-fsug__row b { font-size: 15px; font-weight: 700; color: var(--p-ink, #051124); }
.abvp-fsug__chip {
  display: block; flex: 0 0 auto; width: 18px; height: 18px; border-radius: 4px;
  box-shadow: inset 0 0 0 1px rgba(5, 17, 36, .22);
}
/* NAVY, not orange. Orange is 3.0:1 on white, so small white text on an
   orange button fails AA — the accent stays on the rule and the eyebrow. */
.abvp-fsug__use {
  margin-left: auto; padding: 7px 13px; min-height: 34px;
  font: inherit; font-size: 13px; font-weight: 700; line-height: 1;
  color: #fff; background: var(--abv-navy, #051124);
  border: 0; border-radius: 6px; cursor: pointer;
  transition: box-shadow .18s ease, background .18s ease;
}
.abvp-fsug__use:hover { box-shadow: inset 0 0 0 2px var(--abv-orange); }
.abvp-fsug__use:focus-visible { outline: 3px solid var(--abv-blue-lt, #3993D5); outline-offset: 2px; }
.abvp-fsug__on {
  margin-left: auto; font-size: 12px; font-weight: 700;
  color: var(--p-ink-3, #6b7787);
}
.abvp-fsug__why {
  display: block; margin-top: 5px; font-style: normal;
  font-size: 12px; line-height: 1.45; color: var(--p-ink-3, #6b7787);
}

/* Pro result — one line stating what the reference suggests. */
.abvp-refnote {
  display: flex; align-items: flex-start; gap: 8px;
  margin: var(--p-3, 14px) 0 0; padding: 9px 12px;
  background: #fff; border: 1px solid var(--p-line, #dde2e8);
  border-left: 3px solid var(--abv-orange); border-radius: 0 6px 6px 0;
  font-size: 13px; line-height: 1.5; color: var(--p-ink-2, #33404f);
}
.abvp-refnote b { color: var(--p-ink, #051124); }
.abvp-refnote__chip {
  flex: 0 0 auto; display: block; width: 16px; height: 16px; margin-top: 2px;
  border-radius: 4px; box-shadow: inset 0 0 0 1px rgba(5, 17, 36, .22);
}

@media (prefers-reduced-motion: reduce) {
  .abv-root .abv-ref,
  .abv-ref__tick { transition: none; }
  .abv-root .abv-ref:hover { transform: none; }
}

/* =============================================================================
   PROFLOW SEAM  -  the free calculator's ending becomes a ProFlow transition
   =============================================================================
   Inside an unlocked session the result page no longer closes the product: it
   hands off to the job plan rendered directly below it. The furniture that used
   to sit here - conversion CTA, Pro Advantage What's-next card, start another
   project - is not styled away, it is not built (abv-pro-result.js branches on
   the session). What is left needs a seam that reads as continuation.
   ========================================================================== */

/* THE FIRST PAINT ALREADY KNOWS. JavaScript hides the programme block the
   moment the session resolves, but that resolve is a fetch, and one frame of
   "Is this your first Attic Breeze installation?" would still reach a member.
   The body class is decided in PHP from the same signed cookie, so the first
   painted frame is correct and nothing has to be corrected. */
body.abv-pf-member .abv-root[data-abv-mode="professional"] [data-abv-program],
body.abv-pf-member .abv-root[data-abv-mode="professional"] [data-abv-program-rule],
.abv-root[data-abv-mode="professional"] [data-abv-program][hidden],
.abv-root[data-abv-mode="professional"] [data-abv-program-rule][hidden] {
  display: none !important;
}

.abv-root[data-abv-mode="professional"] .abvp-free--flow {
  margin: var(--p-4) 0 0; padding: 0; border-top: 0;
}

/* THE HANDOFF. Navy, because it belongs to the plan below it rather than to
   the white result above it - the eye reads it as the top of the next thing. */
.abv-root[data-abv-mode="professional"] .abvp-hand {
  padding: 22px 24px; border-radius: 14px;
  background: linear-gradient(180deg, #051124 0%, #071a33 100%);
  box-shadow: inset 0 0 0 1px rgba(57, 147, 223, .28);
}
.abv-root[data-abv-mode="professional"] .abvp-hand__kicker { color: #EF7D48; }
.abv-root[data-abv-mode="professional"] .abvp-hand__say {
  margin: 8px 0 0; max-width: 66ch;
  font-size: 14.5px; line-height: 1.6; color: rgba(255, 255, 255, .82);
}
.abv-root[data-abv-mode="professional"] .abvp-hand__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--p-2); margin-top: 18px;
}
/* The quiet button sits on navy here, so it must not inherit the ink colour
   the quiet button uses on the white plates. */
.abv-root[data-abv-mode="professional"] .abvp-hand .abvp-btn--quiet {
  color: rgba(255, 255, 255, .82);
}
.abv-root[data-abv-mode="professional"] .abvp-hand .abvp-btn--quiet:hover,
.abv-root[data-abv-mode="professional"] .abvp-hand .abvp-btn--quiet:focus-visible {
  color: #fff;
}
.abv-root[data-abv-mode="professional"] .abvp-hand .abvp-acts__status {
  color: rgba(255, 255, 255, .82);
}

/* WORKSPACE HEADER UTILITY. Sign out and start-over are account-level, so they
   are deliberately the quietest thing in the header rather than buttons in the
   middle of the job. */
.abv-root[data-abv-mode="professional"] .abvf-head__util {
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
}
.abv-root[data-abv-mode="professional"] .abvf-util {
  display: flex; align-items: center; gap: 16px;
}
.abv-root[data-abv-mode="professional"] .abvf-util__btn {
  appearance: none; -webkit-appearance: none; background: none; border: 0;
  padding: 0; margin: 0; font: inherit; font-size: 12.5px; font-weight: 600;
  line-height: 1.4; letter-spacing: 0; text-transform: none; cursor: pointer;
  color: rgba(255, 255, 255, .62); text-decoration: none; border-radius: 4px;
}
.abv-root[data-abv-mode="professional"] .abvf-util__btn:hover,
.abv-root[data-abv-mode="professional"] .abvf-util__btn:focus-visible {
  color: #fff; text-decoration: underline; text-underline-offset: 3px;
}
.abv-root[data-abv-mode="professional"] .abvf-util__btn:focus-visible {
  outline: 2px solid #3993DF; outline-offset: 3px;
}

@media (max-width: 860px) {
  .abv-root[data-abv-mode="professional"] .abvf-head__util { align-items: flex-start; }
  .abv-root[data-abv-mode="professional"] .abvp-hand { padding: 18px 16px; }
  .abv-root[data-abv-mode="professional"] .abvp-hand__row { flex-direction: column; align-items: stretch; }
  .abv-root[data-abv-mode="professional"] .abvp-hand__row > .abvp-btn { width: 100%; }
}


/* =======================================================================
   ABV-R2 — THE ATTIC VENTILATION RESULTS BLOCK                2026-08-31
   =======================================================================
   Presentation only. Every figure inside this block is written by
   ABVResult.headlineResults() from the live engine result on each render —
   there is no number in this stylesheet and nothing here can pin one.

   Scoped to .abv-root so it cannot reach page furniture, and built out of
   the existing tokens rather than literal colours, which is what makes the
   same markup read green on the homeowner page (abv-hlook.css flips
   --abv-accent) without needing a second rule set.
   ----------------------------------------------------------------------- */
.abv-root .abv-r2__intro {
  margin: 10px 0 0;
  max-width: 34em;
  font-size: 17px;
  line-height: 1.55;
  color: var(--abv-text);
}

/* THE THREE NUMBERS. One column on a phone, three from 900px: the figures
   are the point of this screen, and three of them side by side at 375px
   would shrink each to something nobody reads aloud to an installer. */
.abv-root .abv-r2__nums {
  list-style: none;
  margin: var(--abv-5) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  counter-reset: none;
}
@media (min-width: 900px) {
  .abv-root .abv-r2__nums { grid-template-columns: repeat(3, 1fr); gap: 18px; }
}

.abv-root .abv-r2__num {
  position: relative;
  margin: 0;
  padding: 30px 22px 24px;
  background: var(--abv-bg);
  border: 1px solid var(--abv-line);
  /* The accent rule across the top is what makes the three cards read as one
     answer in three parts rather than three unrelated statistics. */
  border-top: 3px solid var(--abv-accent);
  border-radius: var(--abv-radius-lg);
  box-shadow: var(--abv-shadow-sm);
  min-width: 0;
}

/* The step marker sits ON the accent rule, half in and half out, which is the
   same device the page's own numbered progressions use. */
.abv-root .abv-r2__step {
  position: absolute;
  top: -15px;
  left: 20px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--abv-navy);
  color: #fff;
  font-size: 14px;
  font-weight: var(--abv-w-head);
  line-height: 1;
}

/* THE FIGURE. Fluid, because 2,400 and 1,699 are four characters wide and a
   fixed 54px overflows a 375px card once the unit sits beside it. */
.abv-root .abv-r2__fig {
  margin: 0;
  display: block;
}
.abv-root .abv-r2__fig > b {
  display: block;
  font-size: clamp(40px, 9vw, 56px);
  line-height: 1.02;
  font-weight: var(--abv-w-head);
  color: var(--abv-navy);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.abv-root .abv-r2__fig > span {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  font-weight: var(--abv-w-strong);
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--abv-navy);
}

.abv-root .abv-r2__lbl {
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--abv-hairline);
  font-size: 14px;
  font-weight: var(--abv-w-strong);
  line-height: 1.4;
  color: var(--abv-accent-text, var(--abv-navy));
}

.abv-root .abv-r2__say {
  margin: 8px 0 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--abv-muted);
}

/* WHY BOTH NUMBERS MATTER. A tinted plate rather than a fourth card, so the
   reader can see at a glance that it explains the three above it instead of
   adding a fourth thing to remember. */
.abv-root .abv-r2__why {
  margin: var(--abv-5) 0 0;
  padding: 22px 24px;
  background: var(--abv-plate);
  border: 1px solid var(--abv-hairline);
  border-left: 3px solid var(--abv-accent);
  border-radius: var(--abv-radius-lg);
}
.abv-root .abv-r2__why > .abv-eyebrow { display: block; margin: 0; }
.abv-root .abv-r2__eq {
  margin: 10px 0 0;
  font-size: clamp(19px, 4.4vw, 24px);
  line-height: 1.3;
  font-weight: var(--abv-w-head);
  color: var(--abv-navy);
}
.abv-root .abv-r2__eq > i {
  font-style: normal;
  color: var(--abv-accent-text, var(--abv-accent));
  padding: 0 2px;
}
.abv-root .abv-r2__whysay {
  margin: 10px 0 0;
  max-width: 62ch;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--abv-text);
}

@media (max-width: 480px) {
  .abv-root .abv-r2__num { padding: 28px 18px 20px; }
  .abv-root .abv-r2__why { padding: 20px 18px; }
}


/* ------------------------------------------------------------------------
   ABV-R2b - THE RESULT HEADER SITS ON NAVY               2026-08-31
   ------------------------------------------------------------------------
   Two things found by measuring the rendered header rather than reading the
   markup:

   1. `.abv-eyebrow` in .abv-plan__head is NOT a text style. abv-hcx-calc.css
      turns it into the Attic Breeze wordmark - `text-indent: -9999px` plus a
      background mark - at (0,6,1), with its own note about why the white mark
      is safe on this navy panel. That is a brand decision, so it is left
      alone and the eyebrow the results document asks for is a second line
      under it rather than a fight over the same element.

   2. The header is navy. The new intro line inherited #051124 and was
      rendering navy on navy: present, correctly sized, and invisible.
   ------------------------------------------------------------------------ */
.abv-root .abv-plan__head .abv-r2__eyebrow {
  display: block;
  margin: 0 0 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .70);
}
.abv-root .abv-plan__head .abv-r2__intro {
  color: rgba(255, 255, 255, .88);
  max-width: 46em;
}


/* ------------------------------------------------------------------------
   ABV-MAP-MOBILE - the address step on a phone            2026-08-31
   ------------------------------------------------------------------------
   Third of the three changes behind the map-scroll fix. The other two are
   in JS: abv-map.js hands a one-finger drag back to the PAGE on a coarse
   pointer (Google's own `cooperative` mode), and abv-app.js scrolls the
   confirmation into view the moment an address is picked.

   This one is arithmetic. Measured on a 375 x 812 phone before the change:

     map wrapper   min-height 380  ->  map ends at y 709
     confirm bar   starts at 726 (it is already a normal block BELOW the map,
                   not an overlay - that was fixed in an earlier pass)
     "Yes, that's it"           at y 979, i.e. 167px BELOW the fold

   So the homeowner had to scroll past the map to answer the question the map
   had just asked - and while a one-finger drag still belonged to the map,
   that scroll did not happen. 290px keeps the roof clearly readable at this
   width (the tile still fills 333 x 290 at zoom 20) and pulls the whole
   confirmation up by 90px.
   ------------------------------------------------------------------------ */
@media (max-width: 480px) {
  .abv-root .abv-mapwrap { min-height: 290px; }
}
