/* ATTIC BREEZE - HOMEOWNER VENTILATION CALCULATOR, CALCULATOR UX (round 4)
 * /homeowners/ventilation-calculator/  (page 8863)              2026-08-26
 *
 * Owns four things and nothing else:
 *   1. the calculator's shell, measure and step-to-step alignment
 *   2. the bottom navigation row, and the Previous pill in it
 *   3. the five roof-slope cards, their 3+2 desktop grid and their touch rail
 *   4. the How It Looks series links, as pill buttons
 *
 * SCOPE. Every selector names `body.ab-hcx` AND `.elementor-9063`. The `.abv-*`
 * classes below belong to the plugin app and are shared with the PROFESSIONAL
 * calculator on 8864 and ProFlow on 8897 - an unscoped `.abv-nav` rule would
 * restyle both. Nothing here may reach them.
 *
 * PALETTE. Attic Navy #051124, Breeze Home Green #5C9D5E, White, Sky #3993D5.
 * No orange, no grey. Where a boundary is needed it is navy at low alpha on
 * white, which belongs to the two colours already in play rather than
 * introducing a third.
 *
 * LOAD ORDER. Printed after abv-app.css, abv-ui.css, abv-hlook.css,
 * abv-hcalc.css and abv-hux.css, so it overrides all five by source order.
 * ==========================================================================  *
 * PAGE:    /homeowners/ventilation-calculator/  (WordPress page 8863)
 * NEEDS:   loaded by novamira-sandbox/ab-hoc-calcux.php (priority 102); styles the plugin app's own markup; supplies --abhc-logo from PHP
 * FLAG:    update_option('abv_hcalcux_enabled','0') switches this layer off.
 * DOCS:    wp-content/plugins/attic-breeze-ventilation/docs/homeowner-calculator-page.md
*/

body.ab-hcx .elementor-9063 .abv-root {
  --abvq-measure: 640px;   /* the readable measure for a question heading */
  --abvq-rule:    rgba(5, 17, 36, .10);
  --abvq-green:   #5C9D5E;
  --abvq-navy:    #051124;
  --abvq-sky:     #3993D5;
  --abvq-ease:    cubic-bezier(.2, .7, .3, 1);
}


/* ==========================================================================
   1. ONE STATIONARY SHELL
   ==========================================================================
   Measured across all six steps before changing anything, at 1440:

     property  h2 32-892 (860)   sub 32-542   answers -
     attic     h2 32-792 (760)   sub 32-542   answers 32-458
     roof      h2 32-892 (860)   sub 32-542   answers 32-892
     slope     h2 32-892 (860)   sub 32-542   answers 32-892
     install   h2 32-892 (860)   sub 32-542   answers 32-892
     result    pane 32-1172 (1140)

   So the LEFT edge was already honest - every step starts at 32 - and the
   sideways movement people notice is the heading's WRAP WIDTH changing: 860 on
   four steps and 760 on the attic step, because that one sits inside
   `.abv-split__main`. 860px of 28px Poppins is also about 95 characters, well
   past a comfortable measure for a question.

   One token fixes both: cap the heading at 640px on every step. The heading
   then wraps identically from step to step, the answer area keeps the full
   860 where cards want it, and `.abv-sub`'s existing 510px reading measure is
   left exactly as it was.
   ========================================================================== */
body.ab-hcx .elementor-9063 .abv-root .abv-q {
  max-width: var(--abvq-measure);
}
/* The result screen is the one pane that is deliberately wider than the
   questions (1140 against 860) because it is a plan and not a question. Its
   title is not a question either, so it keeps its own measure. */
body.ab-hcx .elementor-9063 .abv-root .abv-plan__title {
  max-width: none;
}


/* ==========================================================================
   2. THE BOTTOM NAVIGATION, AND PREVIOUS
   ==========================================================================
   THE APP ALREADY HAD A BACK CONTROL AND IT WAS INVISIBLE. abv-steps.js puts a
   chevron `button[data-abv-back]` inside `.abv-steps` on every step - and
   abv-hcalc.css hides `.abv-steps` on this page, because the two-mode layout
   replaced the in-app step bar with its own "Your home / Stage 1 of 5" toolbar.
   Measured: the back button computed `display:inline-flex` at 0x0. So this page
   shipped with no way back at all, and the fix is not new navigation - it is
   putting a visible, labelled control on the wiring that already exists.

   abv-hcx-calc.js injects `button.abhc-prev[data-abv-back]` as the first child
   of `.abv-nav`. Because it carries that attribute, the app's own delegated
   handler (`root` -> `go(state.step - 1)`) runs unchanged: no duplicated step
   logic, no second source of truth for the current step, and the browser
   history entries the app pushes are untouched.

   `.abv-nav__why` is lifted onto its own line above the buttons. It is the
   "here is why Continue is disabled" line, and once there is a control on the
   left it has nowhere to sit without crowding one of them. */
body.ab-hcx .elementor-9063 .abv-root .abv-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin-block-start: 36px;
  padding-block-start: 24px;
  border-top: 1px solid var(--abvq-rule);
}
body.ab-hcx .elementor-9063 .abv-root .abv-nav__why {
  flex: 1 0 100%;
  order: -1;
  margin: 0;
}
body.ab-hcx .elementor-9063 .abv-root .abv-nav__spacer { flex: 1 1 auto; }

/* ---- the Previous pill ---------------------------------------------------
   The secondary half of the page's CTA pair: same 999px pill, same 48px
   target, same 13.5px/700 uppercase Poppins as Continue - white ground, navy
   text, navy outline. Continue stays the only filled button on the screen, so
   which one moves the homeowner forward is never in question.

   NO GREY, including on hover. A navy tint on white would read as grey, so
   hover deepens the OUTLINE and lifts the button instead of filling it. */
body.ab-hcx .elementor-9063 .abv-root .abhc-prev {
  order: 0;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 48px;
  margin: 0;
  padding: 13px 26px;
  border: 2px solid rgba(5, 17, 36, .28);
  border-radius: 999px;
  background: #FFFFFF;
  color: var(--abvq-navy);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  white-space: normal;
  overflow-wrap: break-word;
  min-width: 0;
  cursor: pointer;
  transition: border-color .22s var(--abvq-ease), transform .22s var(--abvq-ease),
              box-shadow .22s var(--abvq-ease);
}
body.ab-hcx .elementor-9063 .abv-root .abhc-prev svg {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
}
@media (hover: hover) and (pointer: fine) {
  body.ab-hcx .elementor-9063 .abv-root .abhc-prev:hover {
    border-color: var(--abvq-navy);
    background: #FFFFFF;
    color: var(--abvq-navy);
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(5, 17, 36, .14);
  }
  body.ab-hcx .elementor-9063 .abv-root .abhc-prev:active { transform: translateY(0); }
}
body.ab-hcx .elementor-9063 .abv-root .abhc-prev:focus-visible {
  outline: 3px solid var(--abvq-sky);
  outline-offset: 2px;
  border-radius: 999px;             /* or a page-wide focus rule squares the ends */
}

/* ---- the same control on the result screen -------------------------------
   The result's foot row is a quiet one: "Start a new plan" is an 11.5px text
   button because it throws every answer away. "Change an answer" is the
   opposite intention and gets to look like a real control - a full 48px pill -
   so the recoverable action is the more inviting of the two. The row is a flex
   row and gains a wrap so the fine print can drop under them on a phone. */
body.ab-hcx .elementor-9063 .abv-root .abv-cta__foot {
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
}
body.ab-hcx .elementor-9063 .abv-root .abhc-prev--foot {
  margin-inline-end: 4px;
}


/* ==========================================================================
   3. ONE ANSWER-CARD RADIUS
   ==========================================================================
   The answer cards were 6px while every content card on the page around them
   is 14px, which is what made the calculator read as a different component
   dropped into the page. 12px: clearly the same family, still visibly a
   control rather than a piece of content.
   ========================================================================== */
body.ab-hcx .elementor-9063 .abv-root .abv-card,
body.ab-hcx .elementor-9063 .abv-root .abv-bk,
body.ab-hcx .elementor-9063 .abv-root .abv-pick {
  border-radius: 12px;
}


/* ==========================================================================
   4. THE FIVE ROOF-SLOPE CARDS
   ==========================================================================
   THREE ACROSS, NOT FIVE, and the reason is arithmetic. The shell is capped at
   860px at every width from 1025 up, so five cards with 18px gaps would be
   159px each - narrower than the four they replace (203px) and too narrow for
   a drawing, a name, a line of description and a pitch. Three gives 274px,
   which is wider than the old four, and the trailing two centre themselves.

   The alternative was letting this one step break out of the 860 measure so
   five would fit. That is exactly the sideways jump between steps this round
   is meant to remove, so the grid gave way instead of the shell.

   flex rather than grid, because `justify-content: center` on a wrapped flex
   row centres the trailing two for free; a 3-column grid would leave them
   hanging on the left with a gap where the third would be. */
@media (min-width: 1025px) {
  body.ab-hcx .elementor-9063 .abv-root .abv-bks {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 18px;
    grid-template-columns: none;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-bks > .abv-bk {
    flex: 0 1 calc((100% - 36px) / 3);
    min-width: 0;
  }
}

/* ---- the touch rail, 1024 and down --------------------------------------
   The same interaction as every other card set on this page, for the same
   reason: five cards stacked is a very long step, and a 2-column grid leaves
   an orphan on the third row. One card at a time with the next one peeking,
   native scroll-snap, no library and no autoplay.

   A SWIPE MUST NOT SELECT. Each card IS a button and the app selects on click,
   so a finger that starts on a card and drags would commit a pitch the
   homeowner was only scrolling past. abv-hcx-calc.js guards that in the
   capture phase - the pointer-movement and rail-scroll test the page's other
   rails already use. */
@media (max-width: 1024px) {
  body.ab-hcx .elementor-9063 .abv-root .abv-bks {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 0;
    grid-template-columns: none;
    align-items: stretch;
    overflow-x: auto;
    overflow-y: visible;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;   /* or the swipe hijacks browser Back */
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding-block: 4px 10px;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-bks::-webkit-scrollbar { display: none; }
  body.ab-hcx .elementor-9063 .abv-root .abv-bks > .abv-bk {
    flex: 0 0 min(78%, 300px);
    width: min(78%, 300px);
    min-width: 0;
    margin-inline-end: 4%;
    scroll-snap-align: center;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-bks > .abv-bk:last-child {
    margin-inline-end: 0;
  }
}

/* ---- the selected state -------------------------------------------------
   Never colour alone: the green edge and the green tint say "this one", and
   the tick that was already in the markup carries the same message for anyone
   who cannot use the colour. The tint is Breeze Home Green at 7% - a green
   wash, not the grey a navy tint would read as. */
body.ab-hcx .elementor-9063 .abv-root .abv-bk.is-on {
  border-color: var(--abvq-green);
  background: rgba(92, 157, 94, .07);
  box-shadow: inset 0 0 0 1px var(--abvq-green);
}
body.ab-hcx .elementor-9063 .abv-root .abv-bk.is-on .abv-bk__name {
  color: var(--abvq-navy);
  font-weight: 700;
}
body.ab-hcx .elementor-9063 .abv-root .abv-bk:focus-visible {
  outline: 3px solid var(--abvq-sky);
  outline-offset: -3px;             /* inset: an outset ring is clipped by the rail */
}
/* The pitch is the one thing on the card that must stay legible whatever the
   name says, so it holds its own weight rather than fading with the helper. */
body.ab-hcx .elementor-9063 .abv-root .abv-bk__pitch {
  font-weight: 700;
  letter-spacing: .4px;
}


/* ==========================================================================
   5. MOBILE: GUTTERS AND VERTICAL ECONOMY
   ==========================================================================
   Measured at 390 before: the band contributes a 20px gutter and `.abv-shell`
   added 16px of its own, so the content ran 36 -> 354 and every card, field
   and button was inset 36px on a 390px screen. Zeroing the shell's inline
   padding hands the full 20px gutter back and nothing else moves - the hero's
   copy follows automatically, because abv-hcalc.js's Calc.align() measures the
   shell's LIVE padding rather than assuming a number.

   The vertical trim is the same argument. The question sat 368px down an 844px
   viewport on first paint; the pane itself has no top margin, so the space was
   in the band and the shell rather than in the question, and that is where it
   comes off. */
@media (max-width: 767px) {
  body.ab-hcx .elementor-9063 .abv-shell { padding-inline: 0; padding-block-start: 8px; }
  body.ab-hcx .elementor-9063 .abhx-calc > .e-con-inner { padding-block-start: 20px; }

  body.ab-hcx .elementor-9063 .abv-root .abv-nav {
    margin-block-start: 28px;
    padding-block-start: 20px;
    /* STRETCH, not centre. "See my ventilation plan" wraps to two lines in its
       half and runs 79px tall; centred beside a 48px Previous the row reads as
       two buttons at different heights that happen to be adjacent. Stretched,
       they are one control pair. */
    align-items: stretch;
  }
  /* PREVIOUS AND CONTINUE SPLIT THE ROW IN HALF, and the halves are what make
     it work at every phone width.

     The app stretches Continue to 100% on a phone - correct when it was the
     only control on the row, and the thing that pushed Previous onto a line of
     its own the moment there were two. Sizing them to content instead got
     three of the four steps onto one row and failed on the fourth: install's
     label is "See my recommendation", 248px wide, and 138 + 16 + 248 does not
     fit in 350px of content. Equal halves fit by construction whatever a label
     says - a long one wraps to two lines inside its own half and both keep a
     48px+ target - so there is one layout for all four steps instead of three
     tidy ones and an exception.

     The spacer goes: with both buttons flexing there is nothing left to push. */
  body.ab-hcx .elementor-9063 .abv-root .abhc-prev {
    padding: 13px 14px;
    letter-spacing: .9px;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-nav__spacer { display: none; }
  body.ab-hcx .elementor-9063 .abv-root .abhc-prev,
  body.ab-hcx .elementor-9063 .abv-root .abv-nav .abv-btn {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
    padding-inline: 14px;
    text-align: center;
  }
}
/* Below 360 the pair genuinely stops fitting. Stacking full-width is the
   clean fallback rather than shrinking two buttons until neither is usable -
   Continue first, because it is the primary action. */
@media (max-width: 359px) {
  body.ab-hcx .elementor-9063 .abv-root .abv-nav__spacer { display: none; }
  body.ab-hcx .elementor-9063 .abv-root .abhc-prev,
  body.ab-hcx .elementor-9063 .abv-root .abv-nav .abv-btn {
    flex: 1 0 100%;
    width: 100%;
  }
  body.ab-hcx .elementor-9063 .abv-root .abhc-prev { order: 2; }
  body.ab-hcx .elementor-9063 .abv-root .abv-nav .abv-btn { order: 1; }
}


/* ==========================================================================
   6. HOW IT LOOKS: THE SERIES LINKS BECOME PILL BUTTONS
   ==========================================================================
   Round 3 styled these as quiet green text links, on the argument that the
   card's job is the picture and the name. They are the only way off the card
   and onto the product, so they get to look like it: the page's own 999px
   pill, green fill, white text.

   HOVER GOES TO NAVY rather than to a darker green. Green-to-green reads as a
   state change on the same button; green-to-navy reads as "this is the thing
   that leaves the page", and white on Attic Navy is 17:1 against the 3.26:1 of
   white on Breeze Home Green - the strongest contrast on the page.

   The destinations were verified against the install rather than assumed:
     GableBreeze -> /gablebreeze-series/   page 7347, published
     AeroBreeze  -> /aerobreeze-series/    page 7338, published
     UltraBreeze -> /ultrabreeze-series/   page 7295, published
   No Rank Math redirect touches any of the three, and those are the only three
   `*-series` pages on the site. Ordinary navigation, no modal.
   ========================================================================== */
body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link {
  margin-block-start: 4px;
}
body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button,
body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button:visited {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 13px 24px;
  border: 2px solid #5C9D5E;
  border-radius: 999px;
  background: #5C9D5E;
  color: #FFFFFF;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  white-space: normal;            /* two lines on a phone card, never clipped */
  overflow-wrap: break-word;
  box-shadow: none;
  transition: background-color .22s var(--abhu-ease, ease), border-color .22s var(--abhu-ease, ease),
              transform .22s var(--abhu-ease, ease), box-shadow .22s var(--abhu-ease, ease);
}
@media (hover: hover) and (pointer: fine) {
  body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button:hover {
    background: #051124;
    border-color: #051124;
    color: #FFFFFF;
    text-decoration: none;
    transform: translateY(-1px);
    box-shadow: 0 8px 22px rgba(5, 17, 36, .26);
  }
  body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button:active {
    transform: translateY(0);
  }
}
body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button:focus,
body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button:focus-visible {
  background: #051124;
  border-color: #051124;
  color: #FFFFFF;
  text-decoration: none;
}
body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button:focus-visible {
  outline: 3px solid #3993D5;
  outline-offset: 3px;
  border-radius: 999px;
}


/* ==========================================================================
   7. REDUCED MOTION
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  body.ab-hcx .elementor-9063 .abv-root .abhc-prev,
  body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button {
    transition: none;
  }
  body.ab-hcx .elementor-9063 .abv-root .abhc-prev:hover,
  body.ab-hcx .elementor-9063 .abhc-flip .abhc-look__link .elementor-button:hover {
    transform: none;
  }
}


/* ==========================================================================
   8. NO HORIZONTAL OVERFLOW
   ==========================================================================
   The slope rail is the only thing inside the calculator that scrolls sideways
   on purpose. Its children are min-width:0 flex items inside a shell that is
   already inside `.elementor-9063 { overflow-x: clip }`. */
body.ab-hcx .elementor-9063 .abv-root .abv-bks { max-width: 100%; }
body.ab-hcx .elementor-9063 .abv-root .abv-bk { max-width: 100%; }


/* ==========================================================================
   9. ROUND 5 - THE LOW-SLOPE SECOND STEP, AND THE SPLIT RESULT CARD
   ==========================================================================
   Additive. Nothing above was rewritten.
   ========================================================================== */

/* ---- 9.1 six cards, two rows of three -----------------------------------
   Five cards centred left three / two. Six make two clean rows of three at the
   same 275px card width, so the flex rule needs no change - only the note. */

/* ---- 9.2 THE THREE LOW-SLOPE ANSWERS -----------------------------------
   Revealed under the cards when "Flat or very low" is tapped. It is a SECOND
   STEP, not a second question: it inherits the card language (same radius,
   same green selected edge, same tick) at a smaller scale, so it reads as the
   inside of the card above rather than a new stage.

   The silhouettes are drawn to THEIR OWN scale - the steepest of the three
   (3/12) sets the frame. Sharing the six cards' 12/12 frame would draw Flat,
   2/12 and 3/12 as three identical flat lines, which is the one thing this
   step exists to distinguish. */
body.ab-hcx .elementor-9063 .abv-root .abv-lowrow {
  margin-block-start: 16px;
  padding: 18px 20px 20px;
  border: 1px solid rgba(92, 157, 94, .38);
  border-radius: 12px;
  background: rgba(92, 157, 94, .05);
}
body.ab-hcx .elementor-9063 .abv-root .abv-lowrow__q {
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 700;
  color: var(--abvq-navy);
}
body.ab-hcx .elementor-9063 .abv-root .abv-lows {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
body.ab-hcx .elementor-9063 .abv-root .abv-low {
  position: relative;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  min-height: 48px;
  margin: 0;
  padding: 12px 14px 14px;
  border: 1px solid rgba(5, 17, 36, .16);
  border-radius: 12px;
  background: #FFFFFF;
  /* kit-1333 styles a bare <button> uppercase, nowrap, with tracking and its
     own padding - the same trap the scenario cards' overlay button hit. */
  font: inherit;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  cursor: pointer;
  transition: border-color .2s var(--abvq-ease), background-color .2s var(--abvq-ease);
}
body.ab-hcx .elementor-9063 .abv-root .abv-low__art {
  display: block;
  width: 100%;
  margin-block-end: 6px;
}
body.ab-hcx .elementor-9063 .abv-root .abv-low__art svg { width: 100%; height: auto; display: block; }
body.ab-hcx .elementor-9063 .abv-root .abv-low__name {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--abvq-navy);
}
body.ab-hcx .elementor-9063 .abv-root .abv-low__say {
  font-size: 13px;
  line-height: 1.4;
  color: rgba(5, 17, 36, .74);
}
body.ab-hcx .elementor-9063 .abv-root .abv-low__pitch {
  margin-block-start: 4px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--abvq-green);
}
body.ab-hcx .elementor-9063 .abv-root .abv-low .abv-bk__check {
  position: absolute;
  top: 10px;
  right: 10px;
  opacity: 0;
  color: #FFFFFF;
  background: var(--abvq-green);
  border-radius: 50%;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
}
body.ab-hcx .elementor-9063 .abv-root .abv-low.is-on {
  border-color: var(--abvq-green);
  background: rgba(92, 157, 94, .09);
  box-shadow: inset 0 0 0 1px var(--abvq-green);
}
body.ab-hcx .elementor-9063 .abv-root .abv-low.is-on .abv-bk__check { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  body.ab-hcx .elementor-9063 .abv-root .abv-low:hover { border-color: var(--abvq-green); }
}
body.ab-hcx .elementor-9063 .abv-root .abv-low:focus-visible {
  outline: 3px solid var(--abvq-sky);
  outline-offset: -3px;
}
/* An expanded two-step card keeps a green edge while its answers are open, so
   the card and the panel below it read as one control. */
body.ab-hcx .elementor-9063 .abv-root .abv-bk--two.is-open {
  border-color: var(--abvq-green);
}

/* Phones: art beside the words, one per row. Three 110px columns cannot hold
   "You can just see it slope" without breaking every line. */
@media (max-width: 767px) {
  body.ab-hcx .elementor-9063 .abv-root .abv-lows { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  body.ab-hcx .elementor-9063 .abv-root .abv-low {
    display: grid;
    grid-template-columns: 86px minmax(0, 1fr);
    grid-template-areas: 'art name' 'art say' 'art pitch';
    align-items: center;
    column-gap: 14px;
    padding: 10px 12px;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-low__art   { grid-area: art; margin: 0; }
  body.ab-hcx .elementor-9063 .abv-root .abv-low__name  { grid-area: name; }
  body.ab-hcx .elementor-9063 .abv-root .abv-low__say   { grid-area: say; }
  body.ab-hcx .elementor-9063 .abv-root .abv-low__pitch { grid-area: pitch; margin: 0; }
  body.ab-hcx .elementor-9063 .abv-root .abv-lowrow { padding: 14px 14px 16px; }
}


/* ==========================================================================
   9.3 THE RESULT: GUTTERS
   ==========================================================================
   Measured before: the result pane runs 32 -> 1172 (1140 wide) while every
   question pane is 32 -> 892 (860), because the result deliberately breaks the
   shell's measure. What it did NOT have was any inset of its own, so the
   status pill, the ATTIC BREEZE eyebrow and "Your recommendation" all began
   hard on the container's own edge with the plan card below them starting at
   the same place - correct alignment, no breathing room.

   The fix is one inset on the plan, which keeps the heading block and the card
   on ONE left edge (that alignment was right) and moves both in off the edge.
   ========================================================================== */
body.ab-hcx .elementor-9063 .abv-root .abv-plan {
  box-sizing: border-box;
  padding: 8px 28px 4px;
}
@media (max-width: 1024px) {
  body.ab-hcx .elementor-9063 .abv-root .abv-plan { padding-inline: 20px; }
}
@media (max-width: 767px) {
  /* The shell already gives 20px at this width (section 5), so the plan adds
     nothing more - 40px of inset on a 390px screen is a squeezed card, not a
     generous one. */
  body.ab-hcx .elementor-9063 .abv-root .abv-plan { padding-inline: 0; }
}


/* ==========================================================================
   9.4 THE RECOMMENDATION CARD, AS ONE SPLIT COMPONENT
   ==========================================================================
   Was: a navy card with the fan floating in a soft white radial "stage" -
   `.abv-hrec__stage` - which read as a glow pasted onto the card. Now: ONE
   rounded component divided into two zones, navy information and a white
   product panel, with a single outer radius and a green edge.

   THE GLOW IS REMOVED, NOT HIDDEN. `.abv-hrec__stage` is a real element in
   abv-result.js's markup; it keeps its place in the DOM (that file is not
   edited) and is given no paint, so nothing is left half-drawn behind the fan.

   The product photography is shot on white with no alpha, which is exactly why
   a white panel is the honest ground for it: the photo's own white edge
   disappears into the panel instead of needing a plate to hide it.
   ========================================================================== */
body.ab-hcx .elementor-9063 .abv-root .abv-rec {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: 0;
  overflow: hidden;                 /* the split cannot escape the radius */
  border: 2px solid rgba(92, 157, 94, .55);
  border-radius: 18px;
  box-shadow: 0 18px 44px rgba(5, 17, 36, .26);
}
/* ~66% navy / ~34% white. The navy side carries every word, so it takes the
   measure; the white side only has to hold a product at a readable size. */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__txt {
  flex: 1 1 66%;
  min-width: 0;
  box-sizing: border-box;
  padding: 30px 32px 32px;
}
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot {
  flex: 0 1 34%;
  min-width: 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px 22px;
  background: #FFFFFF;
  /* No radius of its own: the outer card's `overflow:hidden` rounds the two
     corners it shares and leaves the inner edge straight, which is what makes
     this one component and not a card on a card. */
  border-radius: 0;
}
/* THE GLOW. */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__stage {
  display: none;
}
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot img {
  display: block;
  width: 100%;
  max-width: 190px;
  height: auto;
  margin: 0;
  mix-blend-mode: normal;           /* the plate is gone; so is multiplying */
  filter: none;
}
/* The finish pill, sitting in the white panel rather than floating over navy. */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__finish {
  position: static;
  display: inline-flex;
  align-items: center;
  padding: 7px 14px;
  border: 1px solid rgba(5, 17, 36, .18);
  border-radius: 999px;
  background: #FFFFFF;
  color: var(--abvq-navy);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .8px;
  text-transform: uppercase;
  box-shadow: none;
}

/* ---- the navy side's hierarchy ---------------------------------------- */
body.ab-hcx .elementor-9063 .abv-root .abv-rec .abv-rec__name {
  /* NO CLAMP AND NO ELLIPSIS. A mixed recommendation names two products and
     both names have to be readable - this is the on-screen twin of the PDF
     rule. It wraps; it never shortens. */
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: break-word;
  max-width: none;
  -webkit-line-clamp: none;
}

/* ---- mixed recommendations -------------------------------------------- *
 * abv-hcx-calc.js rebuilds the white panel as one item per product family
 * when the plan names more than one, because a single UltraBreeze photograph
 * beside "1 x UltraBreeze + 1 x GableBreeze" tells the homeowner the two fans
 * are the same product. Restrained: a labelled photo, a thin rule between.
 * ---------------------------------------------------------------------- */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot.abhc-shot--multi {
  gap: 0;
  padding: 18px 16px;
}
body.ab-hcx .elementor-9063 .abv-root .abhc-shot__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 10px 0;
}
body.ab-hcx .elementor-9063 .abv-root .abhc-shot__item + .abhc-shot__item {
  border-top: 1px solid rgba(5, 17, 36, .12);
}
body.ab-hcx .elementor-9063 .abv-root .abhc-shot__item img { max-width: 132px; }
body.ab-hcx .elementor-9063 .abv-root .abhc-shot__fam {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--abvq-green);
  text-align: center;
}
body.ab-hcx .elementor-9063 .abv-root .abhc-shot__qty {
  font-size: 12px;
  font-weight: 700;
  color: var(--abvq-navy);
  text-align: center;
}

/* ---- mobile: stack the two zones inside ONE component ----------------- */
@media (max-width: 767px) {
  body.ab-hcx .elementor-9063 .abv-root .abv-rec {
    flex-direction: column;
    border-radius: 16px;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-hrec__txt {
    flex: 0 0 auto;
    padding: 22px 20px 24px;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot {
    flex: 0 0 auto;
    width: 100%;
    padding: 20px 18px;
  }
  /* Two products side by side on a phone rather than stacked: the panel is
     wide and short here, which is the opposite of the desktop column. */
  body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot.abhc-shot--multi {
    flex-direction: row;
    align-items: stretch;
    gap: 0;
  }
  body.ab-hcx .elementor-9063 .abv-root .abhc-shot__item { width: 50%; padding: 4px 8px; }
  body.ab-hcx .elementor-9063 .abv-root .abhc-shot__item + .abhc-shot__item {
    border-top: 0;
    border-left: 1px solid rgba(5, 17, 36, .12);
  }
  body.ab-hcx .elementor-9063 .abv-root .abhc-shot__item img { max-width: 120px; }
}

@media (prefers-reduced-motion: reduce) {
  body.ab-hcx .elementor-9063 .abv-root .abv-low { transition: none; }
}


/* ==========================================================================
   9.5 THE LAST ORANGE ON THE RESULT SCREEN
   ==========================================================================
   Found by sweeping every computed colour on the RESULT pane specifically -
   earlier sweeps walked the six panes but caught this one before it had a
   rendered plan to draw. `.abv-payoff` is the "RECOMMENDATION READY" pill, and
   it was #EF7D48 at 12% ground and 42% border: the calculator app's accent,
   which the 2026-08-25 sage repaint flipped everywhere it was var-driven and
   missed here because these two are literals.

   Repainted to Breeze Home Green at the same alphas, page-scoped. The pill's
   own text and tick already resolve through the flipped token, which is why
   only the ground and the edge were still warm.
   ========================================================================== */
body.ab-hcx .elementor-9063 .abv-root .abv-payoff {
  background: rgba(92, 157, 94, .12);
  border-color: rgba(92, 157, 94, .42);
}


/* ==========================================================================
   10. THE RESULT SCREEN, FINISHED   (production pass, 2026-08-26)
   ==========================================================================
   Section 9.4 made the recommendation a split card, but three things from the
   app's own homeowner styling survived underneath it and together they are
   the "white clip-art pasted on navy" look:

     1. `.abv-rec` kept its 40px padding, so the white panel was a rectangle
        floating INSIDE the navy card instead of being one half OF it.
        Measured at 880: 41px of navy to its right, 67px below it.
     2. `.abv-hrec__shot` carries a fixed `width`/`height` in abv-app.css
        (168px, 132px, 184x178 on a phone). A flex item with a definite
        height does not stretch, whatever the parent's align-items says -
        which is why the panel could never reach the card's full height.
     3. The photograph is `mix-blend-mode: multiply` at 92% of a box smaller
        than itself, over a radial-gradient plate (`.abv-hrec__stage`, inset
        -4% -10% 16%, i.e. deliberately bleeding outside its container) with a
        radial "contact shadow" on `::after` beneath it. 9.4 hid the plate;
        the blend mode, the shadow and the clipping stayed, so the fan was
        cropped top and bottom against a white band.

   All three are undone here rather than layered over: ONE rounded container,
   one border, one radius, divided navy | white, the product on a solid white
   ground that runs corner to corner on its side of the card.
   ========================================================================== */

/* ---- 10.1 THE HEADER BLOCK, AND ONE LEFT LINE ---------------------------
   `.abv-plan__head` is a navy panel (abv-hlook.css) that had no padding of
   its own - `padding: 0 0 24px` - so the status pill sat on its top edge and
   every line of type began on its left edge. That is the "pushed against the
   container edge" in the brief.

   The numbers are chosen so the header and the card share ONE left line
   rather than merely both being flush: the head is padded 36px inside a panel
   that starts at the plan's content edge, and the card's navy half is padded
   34px inside a 2px border starting at that same edge. 36 = 2 + 34.
   Measured at 1440: pill, logo, title and product name all begin at x=244. */
body.ab-hcx .elementor-9063 .abv-root .abv-plan__head {
  padding: 32px 36px 34px;
  border-radius: 18px;
  border-bottom: 0;
  margin-bottom: 18px;
}
body.ab-hcx .elementor-9063 .abv-root .abv-plan__head .abv-payoff { margin: 0 0 22px; }
body.ab-hcx .elementor-9063 .abv-root .abv-plan__head .abv-plan__title { margin: 0; }
body.ab-hcx .elementor-9063 .abv-root .abv-plan__head .abv-plan__addr { margin: 12px 0 0; }

/* ---- 10.2 THE REAL LOGO, ON NAVY ---------------------------------------
   The header said ATTIC BREEZE in letterspaced type. It now shows the
   approved white lockup - the same attachment the site header uses - passed
   in as `--abhc-logo` by ab-hoc-calcux.php and hardcoded nowhere.

   IT IS A BACKGROUND ON THE EXISTING SPAN, not a new <img>: abv-result.js
   prints that span and this project does not edit the app's markup, and the
   span keeps its text (moved out of view) so a screen reader still hears
   "Attic Breeze" with no alt attribute to get wrong.

   GATED ON `body.ab-hcx-logo`, which PHP adds only when it has actually
   resolved an attachment - so a missing asset degrades to the plain text
   label that shipped before, never to an invisible gap.

   CONTRAST: the rule is scoped to `.abv-plan__head`, which is the navy panel.
   The white mark is never painted onto a white ground. */
body.ab-hcx.ab-hcx-logo .elementor-9063 .abv-root .abv-plan__head .abv-eyebrow {
  display: block;
  width: 168px;
  height: 26px;
  margin: 0 0 14px;
  background-image: var(--abhc-logo);
  background-repeat: no-repeat;
  background-position: left center;
  background-size: contain;
  text-indent: -9999px;      /* the label stays in the a11y tree */
  overflow: hidden;
  white-space: nowrap;
}

/* ---- 10.3 ONE CARD, TWO HALVES -----------------------------------------
   The padding moves OFF the card and ON to each half. That is the whole
   trick: with the card padded, any child is a floating box; with the halves
   padded, the halves ARE the card. `overflow:hidden` on the outer container
   (section 9.4) rounds both, so there is one radius and one border round the
   pair and the navy/white seam is a straight line. */
body.ab-hcx .elementor-9063 .abv-root .abv-rec {
  padding: 0;
  margin-bottom: 24px;
  align-items: stretch;
}
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__txt {
  flex: 1 1 62%;
  padding: 34px 34px 36px;
}
/* THE WHITE HALF. No fixed size, no radius, no shadow - it is a region of the
   card. `align-self:stretch` AND `height:auto` are both required, because
   abv-app.css states a height in pixels and a definite height defeats
   stretching on its own. */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot {
  flex: 0 0 38%;
  align-self: stretch;
  width: auto;
  height: auto;
  min-height: 220px;
  /* NAVY FIRST, ALWAYS. abv-app.css gives this panel `order: -1` inside a
     media query that reaches well past the phone, which put the photograph
     on the LEFT between 768 and 900 and above the words below that - both
     the reverse of the reading order this screen wants: what you need, then
     what it looks like. Stated once here so no breakpoint has to remember. */
  order: 0;
  padding: 30px 28px;
  gap: 12px;
  background: #FFFFFF;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}
/* THE PLATE AND ITS SHADOW, removed rather than covered: the gradient stage
   is display:none and the radial contact shadow on ::after has no content, so
   nothing is left half-drawn beneath the fan. */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__stage { display: none; }
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot::after { content: none; }

/* THE PHOTOGRAPH. Shot on white with no alpha, which is exactly why a solid
   white ground is the honest presentation: the photo's own edge disappears
   into the panel and there is nothing to disguise. No blend mode, no filter,
   no negative margin, no percentage box it can overflow and be clipped by. */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot img {
  position: static;
  z-index: auto;
  display: block;
  /* SIZED WITH `width`, NOT `max-width`. Something upstream sets
     `max-width: 100%` on images with more weight than this rule has -
     measured: the computed value stayed 100% and the fan filled the panel
     edge to edge. `min()` states the same intent as a width, which that rule
     cannot touch, and still never exceeds the panel. */
  width: min(100%, 220px);
  max-width: 100%;
  height: auto;
  max-height: 240px;
  margin: 0 auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  mix-blend-mode: normal;
  filter: none;
  transform: none;
}

/* The finish is a caption now, not a chip: a bordered white pill on a white
   panel is a box drawn for no reason, and the word is the information. */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__finish {
  position: static;
  align-self: center;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  /* SOLID NAVY, NOT A NAVY TINT. `rgba(5,17,36,.62)` over white computes to
     #646A76 - a blue-grey - and this page's palette has no grey in it. The
     caption is kept quiet by size and weight instead of by fading the ink. */
  color: #051124;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
}

/* ---- 10.4 MIXED RECOMMENDATIONS ---------------------------------------
   Same white half, one item per product family, still no plates. */
body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot.abhc-shot--multi {
  gap: 0;
  padding: 22px 24px;
  justify-content: center;
}
body.ab-hcx .elementor-9063 .abv-root .abhc-shot__item img {
  width: min(100%, 148px);
  max-height: 160px;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  mix-blend-mode: normal;
  filter: none;
}

/* ---- 10.5 MOBILE: STACKED, STILL ONE CARD ------------------------------ */
@media (max-width: 767px) {
  body.ab-hcx.ab-hcx-logo .elementor-9063 .abv-root .abv-plan__head .abv-eyebrow {
    width: 148px;
    height: 23px;
    margin-bottom: 12px;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-plan__head {
    padding: 24px 22px 26px;
    border-radius: 16px;
    margin-bottom: 14px;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-plan__head .abv-payoff { margin-bottom: 18px; }
  body.ab-hcx .elementor-9063 .abv-root .abv-hrec__txt { padding: 24px 20px 26px; }
  body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot {
    flex: 0 0 auto;
    width: 100%;
    align-self: auto;
    min-height: 0;
    padding: 26px 20px 24px;
    /* NAVY FIRST, WHITE SECOND. abv-app.css gives the product panel
       `order: -1` on a phone, which put the photograph above the words -
       the reverse of the reading order this screen wants: what you need,
       then what it looks like. */
    order: 0;
  }
  body.ab-hcx .elementor-9063 .abv-root .abv-hrec__shot img { width: min(100%, 190px); max-height: 200px; }
  body.ab-hcx .elementor-9063 .abv-root .abhc-shot__item img { width: min(100%, 124px); max-height: 132px; }
}
