/* ====================================================================
   Delta Air — shared site chrome
   Header, navigation, logo, promo banner and buttons for every page.
   Linked AFTER each page's own <style>, so these values win and the
   chrome cannot drift between pages. Edit here, not per page.
   ==================================================================== */
:root{
  --logo:url("/img/logo-v2.webp");
}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;font-family:"Montserrat","Montserrat Fallback",sans-serif;font-weight:700;font-size:.97rem;padding:.85rem 1.5rem;border-radius:10px;border:2px solid transparent;text-decoration:none;cursor:pointer;transition:transform .12s ease,box-shadow .12s ease,background .2s}
.btn--hot{background:linear-gradient(100deg,#F47B20,#D32017);color:#fff;box-shadow:0 6px 18px rgba(211,32,23,.26)}
.btn--hot:hover{transform:translateY(-2px)}
.btn--cool{background:linear-gradient(100deg,var(--blue-800),var(--blue-600));color:#fff;box-shadow:0 6px 18px rgba(18,60,143,.24)}
.btn--cool:hover{transform:translateY(-2px)}
.btn--ghost{background:transparent;border-color:var(--line);color:var(--ink)}
.btn--ghost:hover{border-color:var(--blue-600);color:var(--blue-800)}
/* Header */
.giveaway-carousel{color:#fff;transition:background .5s ease;position:sticky;top:72px;z-index:49}
.giveaway-carousel[data-scheme="orange"]{background:linear-gradient(100deg,var(--red-600),var(--orange-500))}
.giveaway-carousel[data-scheme="blue"]{background:linear-gradient(100deg,var(--blue-900),var(--blue-600))}
.giveaway-carousel__inner{display:flex;align-items:center;justify-content:center;gap:1.4rem;flex-wrap:nowrap;padding:.5rem 22px;text-align:center;min-height:0}
.giveaway-carousel__viewport{flex:1 1 auto;min-width:0;overflow:hidden}
/* Continuous right-to-left marquee: one long strip of all the messages,
   rendered twice so the animation can loop without a visible seam. */
.giveaway-carousel__marquee{display:flex;width:max-content;will-change:transform;animation:giveawayMarquee 16s linear infinite}
.giveaway-carousel:hover .giveaway-carousel__marquee{animation-play-state:paused}
.giveaway-carousel__strip{
  display:inline-flex;align-items:center;flex:0 0 auto;white-space:nowrap;
  font-family:"Montserrat","Montserrat Fallback",sans-serif;font-weight:600;font-size:.98rem;line-height:1;
}
/* 800 against 600 reads as a size jump in Montserrat, so the emphasis is
   kept to a single step and the strip stays visually even. */
.giveaway-carousel__strip{font-weight:700}
.giveaway-carousel__strip b{font-weight:700}
.giveaway-carousel__sep{display:inline-block;width:4.5rem}
@media(prefers-reduced-motion:reduce){.giveaway-carousel__marquee{animation:none}}
.giveaway-carousel__cta{font-family:"Montserrat","Montserrat Fallback",sans-serif;font-weight:800;font-size:.9rem;color:var(--red-600);background:#fff;text-decoration:none;white-space:nowrap;flex:0 0 auto;padding:.42rem 1.05rem;border-radius:999px;box-shadow:0 3px 10px rgba(0,0,0,.22);transition:transform .15s ease,box-shadow .15s ease;animation:ctaFlash 1.6s ease-in-out infinite}
@media(prefers-reduced-motion:reduce){.giveaway-carousel__cta{animation:none}}
.giveaway-carousel__cta:hover{transform:translateY(-1px);box-shadow:0 5px 14px rgba(0,0,0,.28)}
/* When the bar turns blue (hero in heating mode) the white pill blends in,
   so the button flips to orange for contrast. */
.giveaway-carousel[data-scheme="blue"] .giveaway-carousel__cta{background:linear-gradient(100deg,#F47B20,#D32017);color:#fff}
.giveaway-carousel.is-hidden{display:none}
@media(max-width:640px){
  .giveaway-carousel__inner{padding-top:.42rem;padding-bottom:.42rem;padding-left:10px;padding-right:22px;gap:.6rem}
  .giveaway-carousel__strip{font-size:.8rem}
  .giveaway-carousel__cta{font-size:.8rem;padding:.38rem .75rem}
}
@media(max-width:360px){
  .giveaway-carousel__strip{font-size:.72rem}
  .giveaway-carousel__cta{font-size:.72rem;padding:.34rem .65rem}
}
@media(max-width:330px){
  .giveaway-carousel__inner{gap:.4rem}
  .giveaway-carousel__strip{font-size:.66rem}
  .giveaway-carousel__cta{font-size:.66rem;padding:.3rem .55rem}
}
.header{position:sticky;top:0;z-index:50;background:rgba(255,255,255,.95);backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
/* a little breathing room under the logo on laptop/desktop */
.header__bar{display:flex;align-items:center;gap:1.4rem;padding:.5rem 22px .4rem;max-width:var(--wrap);margin:0 auto}
.brand{display:flex;align-items:center;text-decoration:none;flex:0 0 auto}
.brand__logo{display:block;width:135px;height:63px;background:var(--logo) left center/contain no-repeat}
/* The nav had 1.5rem gaps and no wrap guard, so once it outgrew the bar every
   label broke mid-word ("Standard / Installation"). Tighter gaps that ease
   off on narrower desktops, and labels that never split. */
.nav{display:flex;gap:clamp(.7rem,1.4vw,1.5rem);margin-left:auto}
.nav > a,.nav__drop-btn,.nav__install{white-space:nowrap}
/* The header CTA was wrapping to two lines once the bar got tight. */
.header .btn--hot{white-space:nowrap}
.nav a{font-weight:500;font-size:.96rem;color:var(--ink);text-decoration:none;padding:.3rem 0;border-bottom:2px solid transparent}
.nav a:hover{border-bottom-color:var(--orange-500)}
.nav__drop{position:relative;pointer-events:none}
.nav__panel-back{display:none}
.nav__drop > *{pointer-events:auto}
.nav__drop-btn{display:inline-flex;align-items:center;gap:.3rem;font-family:inherit;font-weight:500;font-size:.96rem;line-height:1.65;color:var(--ink);background:none;border:none;border-bottom:2px solid transparent;padding:.3rem 0;cursor:pointer}
.nav__drop-btn:hover{border-bottom-color:var(--orange-500)}
.nav__chev{width:14px;height:14px;transition:transform .2s ease;flex:0 0 auto}
.nav__drop.is-open .nav__chev{transform:rotate(180deg)}
.nav__panel{
  position:absolute;top:calc(100% + 14px);left:50%;transform:translateX(-50%) translateY(-6px);
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 16px 34px rgba(3,12,36,.16);padding:.5rem;min-width:230px;
  display:flex;flex-direction:column;gap:.1rem;
  opacity:0;pointer-events:none;transition:opacity .18s ease,transform .18s ease;z-index:60;
}
.nav__drop.is-open .nav__panel{opacity:1;pointer-events:auto;transform:translateX(-50%) translateY(0)}
.nav__panel a{padding:.55rem .7rem;border-radius:8px;font-size:.92rem;color:var(--ink);text-decoration:none;border-bottom:none!important;font-weight:500}
.nav__panel a:hover{background:var(--surface-2);color:var(--blue-600)}
.header__cta{display:flex;align-items:center;gap:.85rem}
.header__cta .btn{padding:.4rem .95rem;font-size:.85rem}
.header__call{display:grid;place-items:center;width:34px;height:34px;border-radius:50%;border:2px solid var(--line);color:var(--blue-800);text-decoration:none;transition:background .18s,border-color .18s,color .18s;flex:0 0 auto;animation:callFlash 2s ease-in-out infinite}
@media(prefers-reduced-motion:reduce){.header__call{animation:none}}
.header__call:hover{background:var(--blue-800);border-color:var(--blue-800);color:#fff;animation:none}
.header__call svg{width:16px;height:16px;fill:currentColor}
.burger{display:none;background:none;border:1px solid var(--line);border-radius:8px;padding:.45rem .7rem;font-size:1.1rem;cursor:pointer}
@media(max-width:1119px){
  /* On mobile the Solutions item opens a slide-in submenu rather than an
     accordion, so point the chevron right (">") instead of down. */
  .nav__chev{transform:rotate(-90deg)}
  .nav__drop.is-open .nav__chev{transform:rotate(-90deg)}
  .nav{
    display:flex;order:3;width:100%;flex-direction:column;align-items:center;gap:0;
    max-height:0;opacity:0;overflow:hidden;
    transition:max-height .45s cubic-bezier(.4,0,.2,1),opacity .3s ease,padding-bottom .45s ease;
    padding-bottom:0;
  }
  /* Overlay the open menu rather than letting it expand the sticky header.
     Expanding in-flow grew the header ~250px, which pushed page content down
     and shifted the visitor's scroll position whenever they opened the menu
     part-way down the page. */
  .nav.is-open{
    max-height:calc(100vh - 100%);opacity:1;padding-bottom:.5rem;
    position:absolute;left:0;right:0;top:100%;
    background:rgba(255,255,255,.98);backdrop-filter:blur(10px);
    border-bottom:1px solid var(--line);
    box-shadow:0 18px 32px rgba(3,14,40,.16);
    overflow-y:auto;z-index:55;
  }
  .nav > a, .nav > .nav__drop{
    width:100%;text-align:center;padding:.7rem 0;border-bottom:1px solid var(--line);
    opacity:0;transform:translateY(-16px);
  }
  .nav.is-open > a, .nav.is-open > .nav__drop{animation:navDrop .36s cubic-bezier(.2,.8,.2,1) forwards}
  .nav.is-open > *:nth-child(1){animation-delay:0.04s}
  .nav.is-open > *:nth-child(2){animation-delay:0.08s}
  .nav.is-open > *:nth-child(3){animation-delay:0.12s}
  .nav.is-open > *:nth-child(4){animation-delay:0.16s}
  .nav.is-open > *:nth-child(5){animation-delay:0.20s}
  .nav.is-open > *:nth-child(6){animation-delay:0.24s}
  .nav.is-open > *:nth-child(7){animation-delay:0.28s}
  .nav.is-open > *:nth-child(8){animation-delay:0.32s}
  .nav.is-open > *:nth-child(9){animation-delay:0.36s}
  .nav.is-open > *:nth-child(10){animation-delay:0.40s}
  .nav__drop-btn{width:100%;justify-content:center;padding:.7rem 0}
  .nav > .nav__drop{border-bottom:none;padding:0;position:static}
  .nav__drop .nav__drop-btn{border-bottom:1px solid var(--line)}
  .nav__panel{
    position:static;transform:none!important;box-shadow:none;border:none;border-radius:0;
    background:var(--surface-2);min-width:0;padding:0;
    max-height:0;opacity:1;overflow:hidden;transition:max-height .4s ease;
  }
  .nav__drop.is-open .nav__panel{max-height:400px}
  .nav__panel a{text-align:center;border-radius:0;padding:.65rem 0;border-bottom:1px solid var(--line)!important}
  .nav__panel-back{display:none;width:100%;align-items:center;justify-content:center;gap:.4rem;background:none;border:none;border-bottom:1px solid var(--line);padding:.75rem 0;font-family:inherit;font-weight:700;font-size:.92rem;color:var(--blue-600);cursor:pointer}
  .nav__panel-back svg{width:16px;height:16px}
  /* Mobile drill-down: tapping "Solutions" replaces the main menu with the
     full Solutions submenu (plus the Back button above), rather than an
     inline accordion — tap Back to return to the main menu. */
  .nav.submenu-active > a, .nav.submenu-active > .nav__drop > .nav__drop-btn{display:none!important}
  .nav.submenu-active .nav__panel{
    display:flex!important;flex-direction:column;max-height:none!important;overflow:visible!important;
    position:static!important;width:100%;opacity:1!important;pointer-events:auto!important;
  }
  .nav.submenu-active .nav__panel a{display:block;width:100%}
  .nav.submenu-active .nav__panel-back{display:flex}
  @keyframes navDrop{
    from{opacity:0;transform:translateY(-16px)}
    to{opacity:1;transform:translateY(0)}
  }
  .header__bar{flex-wrap:wrap;gap:.7rem}
  .header__cta{margin-left:auto}
  .header__cta .btn{display:none}
  .burger{display:block;margin-left:.2rem}
  .brand__logo{width:106px;height:50px}
}
.hero .btn--ghost{border-color:rgba(255,255,255,.5);color:#fff}
.hero .btn--ghost:hover{border-color:#fff;background:rgba(255,255,255,.1)}
.hero .btn--hot{transition:background .4s ease,transform .12s ease,box-shadow .12s ease}
/* Hero CTAs always contrast against whichever background is showing —
   orange buttons on the blue (cooling) background, blue buttons on the
   orange (heating) background — instead of blending into it. */
.hero[data-mode="heating"] .hero__actions .btn--hot{background:linear-gradient(100deg,var(--blue-800),var(--blue-600));box-shadow:0 6px 18px rgba(18,60,143,.35)}
.hero[data-mode="heating"] .hero__actions .btn--ghost{border-color:rgba(111,200,255,.75)}
.hero[data-mode="heating"] .hero__actions .btn--ghost:hover{border-color:#fff;background:rgba(111,200,255,.15)}
.hero[data-mode="cooling"] .hero__actions .btn--hot{background:linear-gradient(100deg,#F47B20,#D32017);box-shadow:0 6px 18px rgba(211,32,23,.35)}
.hero[data-mode="cooling"] .hero__actions .btn--ghost{border-color:rgba(255,178,110,.8)}
.hero[data-mode="cooling"] .hero__actions .btn--ghost:hover{border-color:#fff;background:rgba(255,178,110,.15)}
@media(max-width:700px){
  .hpunit__air{display:block;width:380px;height:150px;top:calc(100% - 8px);--travel:82px;--depth:165px}
  .hpunit__air{width:340px;margin-left:-170px;height:150px;--travel:80px}
  .hero__inner{padding:1.4rem 0 2.4rem;gap:1.6rem}
  .hero h1{font-size:clamp(1.85rem,7.4vw,2.35rem)}
  .hpunit{margin-bottom:.8rem}
  /* Legacy sizing from the original toggle design — scoped so it no longer
     overrides the room-temperature +/- buttons, which set their own size. */
  .toggle button:not(.toggle__step){width:34px;height:32px}
  .toggle__brand{width:26px;height:21px}
  .hero__sub{font-size:1rem;margin:.75rem 0 1.15rem}
  .hero__actions{gap:.6rem}
  .hero__actions .btn{flex:1 1 100%;padding:.8rem 1.2rem}
  .hero__marks{margin-top:1.4rem;padding-top:.8rem}
  .hero__marks span{font-size:.82rem;padding-right:.7rem;margin-right:.7rem}
  .hero__stars{font-size:.92rem}
}
/* Brand carousel — now sits under the hero on a light background */
.brandstrip--light{background:var(--surface-2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.brandstrip__wrap{display:flex;align-items:center;gap:1.2rem;padding:1rem 22px}
.brandstrip__label{flex:0 0 auto;font-family:"Montserrat","Montserrat Fallback";font-weight:700;font-size:.78rem;color:var(--muted);white-space:nowrap}
.brandstrip__viewport{flex:1 1 auto;min-width:0;overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.brandstrip__track{display:flex;width:max-content;animation:marquee 20s linear infinite;will-change:transform}
.brandstrip__set{display:flex;align-items:center;gap:.9rem;padding-right:.9rem;margin:0;list-style:none}
.brandstrip__set li{font-family:"Montserrat","Montserrat Fallback";font-weight:700;font-size:.9rem;color:var(--blue-800);white-space:nowrap;background:#fff;border:1px solid var(--line);border-radius:999px;padding:.42rem 1.1rem}
.brandstrip--light:hover .brandstrip__track{animation-play-state:paused}
@media(max-width:700px){
  .brandstrip__wrap{flex-direction:column;align-items:stretch;gap:.45rem;padding:.7rem 22px}
  .brandstrip__set li{font-size:.85rem;padding:.32rem .9rem}
  .brandstrip__track{animation-duration:15s}
}
.offer .btn{margin-top:auto}
.calc-promo .btn--hot{flex:0 0 auto}
@media(max-width:720px){
  .calc-promo{padding:2.2rem 0}
  .calc-promo__inner{text-align:center;justify-content:center}
  .calc-promo__text{min-width:100%}
  .calc-promo .btn--hot{width:100%}
}
@media(max-width:720px){.avail__inner{text-align:center;justify-content:center}.avail .btn{width:100%}}
/* Brands */
.brands{display:flex;flex-wrap:wrap;gap:.8rem;align-items:center}
.brands span{border:1px solid var(--line);background:#fff;border-radius:8px;padding:.75rem 1.4rem;font-family:"Montserrat","Montserrat Fallback";font-weight:700;color:var(--blue-900)}
@media(prefers-reduced-motion:reduce){
  *{animation-duration:.001s !important;transition-duration:.001s !important}
  .hero__air path{animation:none !important;stroke-dasharray:none;stroke-dashoffset:0;opacity:.3}
  .toggle__dot,.ring,.hero__wave,.hpunit__air i{animation:none !important}
  .hpunit__flap{transition:none}
  .hpunit__flap{transform:rotateX(-70deg)}
  .toggle__dot{opacity:1}
  .meet__flow path{animation:none !important;stroke-dasharray:none;stroke-dashoffset:0;opacity:.3}
  .brandstrip__track{animation:none !important;flex-wrap:wrap;width:auto}
  .brandstrip__set{flex-wrap:wrap}
  .brandstrip__set[aria-hidden="true"]{display:none}
  html{scroll-behavior:auto;scroll-padding-top:90px}
  .nav{transition:none}
  .nav a{animation:none !important;opacity:1;transform:none}
}
@media(max-width:680px){
  .sol__cards--2,.sol__cards--3,.sol__products{grid-template-columns:1fr}
  .sol__cta .btn{flex:1 1 100%}
}
/* Countdown pill — always visible, sitting beside the sliding carousel. */
.giveaway-carousel__clock{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:.25rem;
  font-family:"Barlow","Barlow Fallback",monospace;font-weight:700;font-size:.76rem;
  color:#fff;background:rgba(0,0,0,.2);
  border:1px solid rgba(255,255,255,.3);border-radius:999px;
  padding:.2rem .55rem;white-space:nowrap;letter-spacing:.01em;
}
@media(max-width:780px){.giveaway-carousel__clock{font-size:.66rem;padding:.16rem .4rem}}
@media(max-width:520px){.giveaway-carousel__clock{font-size:.6rem;padding:.14rem .32rem;gap:.15rem}}
@media(max-width:400px){.giveaway-carousel__clock{font-size:.55rem;padding:.12rem .28rem}}
html[data-theme="dark"] .header{background:rgba(11,18,32,.92);border-bottom-color:var(--line)}
html[data-theme="dark"] .burger{color:var(--ink);border-color:var(--line)}
html[data-theme="dark"] .header__call{border-color:var(--line);color:#9CC6FF}
html[data-theme="dark"] .hero__card,
html[data-theme="dark"] .offer,
html[data-theme="dark"] .form,
html[data-theme="dark"] .revs__arrow,
html[data-theme="dark"] .brands span,
html[data-theme="dark"] .cards span{background:#121D31;border-color:var(--line);color:var(--ink)}
html[data-theme="dark"] .nav__panel{background:var(--surface-2);border-color:var(--line);box-shadow:0 18px 38px rgba(0,0,0,.55)}
html[data-theme="dark"] .nav__panel a{color:var(--ink)}
html[data-theme="dark"] .nav__panel-back{color:#9CC6FF;border-bottom-color:var(--line)}
html[data-theme="dark"] .nav.is-open{background:var(--surface-2);border-bottom-color:var(--line);box-shadow:0 18px 32px rgba(0,0,0,.55)}
/* the submenu fills the panel, so drop the strip of nav padding that
   otherwise shows as a mismatched band under the last item */
html[data-theme="dark"] .nav.submenu-active{padding-bottom:0}
.nav.submenu-active{padding-bottom:0}
html[data-theme="dark"] .nav > a,
html[data-theme="dark"] .nav > .nav__drop{border-bottom-color:var(--line)}
html[data-theme="dark"] .nav a,
html[data-theme="dark"] .nav__drop-btn{color:var(--ink)}
@media (prefers-color-scheme: light){
  html:not([data-theme="dark"]) .giveaway-carousel__cta{background:#fff;color:var(--red-600);box-shadow:0 3px 10px rgba(0,0,0,.22)}
}
/* Orange CTA buttons keep white text in dark mode. Most are <a> tags, so
   they were inheriting the dark-mode link colour and rendering pale blue
   on orange, which read poorly and looked off-brand. */
html[data-theme="dark"] .btn--hot,
html:not([data-theme="light"]) .btn--hot,
html[data-theme="dark"] a.btn--hot,
html:not([data-theme="light"]) a.btn--hot{color:#fff}
/* Match the card grid so the button lines up with a card column:
   3 columns above 900px, 2 from 681-900px, full width below. */
.sol__cta--wide .btn{width:calc((100% - 2.4rem) / 3);max-width:none;justify-content:center}
@media(max-width:900px){
  .sol__cta--wide .btn{width:calc((100% - 1.2rem) / 2)}
}
@media(max-width:680px){
  .sol__cta--wide .btn{width:100%}
}
/* Banner typography — the strip, countdown and CTA were running at three
   different sizes across two fonts, which read as inconsistent. Aligned to
   one family and size; the clock keeps tabular figures so the seconds
   don't jitter as they tick. */
.giveaway-carousel__clock{
  font-family:"Montserrat","Montserrat Fallback",sans-serif!important;
  font-size:.86rem!important;font-weight:700!important;
  font-variant-numeric:tabular-nums;
}
.giveaway-carousel__cta{font-size:.86rem;font-weight:700}
/* One size for the whole line — mixing sizes inside a single sentence
   read as a mistake rather than emphasis. */
.giveaway-carousel__strip{font-size:.8rem;font-weight:700}
.giveaway-carousel__strip b{font-size:inherit;font-weight:700}
@media(max-width:780px){
  .giveaway-carousel__clock{font-size:.66rem!important}
  .giveaway-carousel__cta{font-size:.72rem}
  .giveaway-carousel__strip{font-size:.7rem}
  .giveaway-carousel__strip b{font-size:inherit}
}
@media(max-width:520px){
  .giveaway-carousel__clock{font-size:.6rem!important}
  .giveaway-carousel__cta{font-size:.64rem}
  .giveaway-carousel__strip{font-size:.64rem}
  .giveaway-carousel__strip b{font-size:inherit}
}
/* "Install app" sits in the menu rather than the header bar — browsers bury
   their own install prompt, and the header had no room for another button.
   Hidden until the browser confirms the page is actually installable. */
.nav__install{display:none!important;align-items:center;gap:.4rem;color:var(--blue-600)!important;font-weight:700}
/* Desktop shows it only in the mobile menu now: the header bar ran out of
   room once "Standard Installation" joined the nav, and every item was
   wrapping mid-label. Phones and tablets keep it. */
.nav__install.is-ready{display:none!important}
@media(max-width:1119px){.nav__install.is-ready{display:block!important;width:100%;text-align:center}}
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) .nav__install{color:#9CC6FF!important}}
@media(max-width:400px){
  .giveaway-carousel__inner{gap:.38rem;padding-left:10px;padding-right:22px}
  .giveaway-carousel__clock{font-size:.58rem!important;padding:.1rem .3rem!important}
  .giveaway-carousel__cta{font-size:.62rem;padding:.26rem .5rem}
  .giveaway-carousel__strip{font-size:.72rem}
}
/* iOS Safari was substituting a different face for part of the line, so the
   two halves rendered at visibly different sizes. Pin the family, size and
   weight on the bold element and disable Safari's text auto-sizing, which
   also inflates runs of text independently. */
/* the strip keeps its own responsive size; children inherit it exactly */
.giveaway-carousel__strip{
  font-family:"Montserrat","Montserrat Fallback","Helvetica Neue",Arial,sans-serif!important;
  font-weight:700!important;
  -webkit-text-size-adjust:100%!important;
  text-size-adjust:100%!important;
}
.giveaway-carousel__strip b,
.giveaway-carousel__strip span{
  font-family:inherit!important;
  font-size:inherit!important;
  font-weight:inherit!important;
  font-style:normal!important;
}
/* phone icon is mobile-only — marker */

/* Same fixed geometry as the subpages so the bar is identical everywhere. */
.giveaway-carousel .giveaway-carousel__inner{min-height:36px}
.giveaway-carousel .giveaway-carousel__cta{
  padding:.42rem 1.05rem!important;line-height:1.45!important;min-height:0!important;
  display:inline-flex!important;align-items:center!important;border-radius:999px!important;
}
.giveaway-carousel .giveaway-carousel__clock{
  padding:.2rem .55rem!important;line-height:1.45!important;min-height:0!important;
}
/* Final: one fixed height for the bar and its controls on every page. */
.giveaway-carousel .giveaway-carousel__inner{height:38px;min-height:38px;max-height:38px;align-items:center;overflow:hidden}
.giveaway-carousel .giveaway-carousel__cta{height:30px!important;padding:0 1rem!important}
.giveaway-carousel .giveaway-carousel__clock{height:24px!important;padding:0 .55rem!important}
@media(max-width:560px){
  .giveaway-carousel .giveaway-carousel__cta{height:26px!important;padding:0 .7rem!important}
  .giveaway-carousel .giveaway-carousel__clock{height:22px!important;padding:0 .4rem!important}
}


/* ===== Mobile menu open/close =======================================
   The menu was switching between position:static (closed) and
   position:absolute (open). Position cannot animate, so the panel
   snapped into place while its height tried to ease — which read as a
   jerky close. Keep it absolutely positioned in both states and animate
   only transform and opacity, which the compositor can do smoothly. */
@media(max-width:1119px){
  .nav{
    position:absolute!important;
    left:0;right:0;top:100%;
    display:flex!important;
    flex-direction:column;align-items:center;
    max-height:none!important;
    padding-bottom:.5rem;
    background:rgba(255,255,255,.98);
    border-bottom:1px solid var(--line);
    box-shadow:0 18px 32px rgba(3,14,40,.16);
    z-index:55;
    opacity:0;
    visibility:hidden;
    transform:translateY(-8px);
    transition:opacity .26s ease, transform .26s cubic-bezier(.4,0,.2,1), visibility 0s linear .26s;
  }
  .nav.is-open{
    opacity:1;
    visibility:visible;
    transform:translateY(0);
    transition:opacity .26s ease, transform .26s cubic-bezier(.4,0,.2,1), visibility 0s;
  }
  @media (prefers-color-scheme: dark){
html:not([data-theme="light"]) /* !important because the homepage still carries an inline .nav.is-open
       rule with a light background that would otherwise win. */
    .nav, html:not([data-theme="light"]) .nav.is-open{background:var(--surface-2)!important;border-bottom-color:var(--line)!important}
html:not([data-theme="light"]) .nav a, html:not([data-theme="light"]) .nav__drop-btn{color:var(--ink)!important}
  }
  @media (prefers-reduced-motion: reduce){
    .nav{transition:none}
  }
}


/* ===== Nav alignment ================================================
   Some pages left .nav a at line-height:normal while the Solutions
   button inherited 1.65, so the words sat at different heights even
   though the boxes lined up. Pin both to the same value. */
.nav a,
.nav__drop-btn{line-height:1.65!important;display:inline-flex;align-items:center}
.nav__drop-btn{padding-top:.3rem;padding-bottom:.3rem}


/* ===== Hero card alignment (laptop and up) ==========================
   The "No cost, no obligation" card started ~107px below the AC unit,
   leaving an awkward gap beside it. Align the tops so the two columns
   begin together. */
/* The hero is two columns from 901px up, not 981px — the old breakpoint
   left the card sitting below the AC unit between those widths. */
/* The card starts level with the AC unit and finishes level with the two
   hero buttons — matching the visible content on the left rather than the
   full column, which ran past them. Height is set in JS (see below) because
   the left column's height depends on how the copy wraps. */
@media(min-width:901px){
  .hero__inner{align-items:start}
  .hero__card{margin-top:0;display:flex;flex-direction:column}
  .hero__card ul{flex:1 1 auto}
}


/* ===== About page body copy =========================================
   Paragraphs were rendering in three different colours (deep blue, ink
   and muted) depending on which rule won. Body copy uses the site's
   muted grey; headings use ink — the same pairing as every other page. */
.about-story h2,
.why-us__head h2,
.why-us__card h3{color:var(--ink)!important}
.about-story p,
.why-us__head p,
.why-us__card p,
.about-lede,
.stat-item span{color:var(--muted)!important}
.stat-item b{color:var(--blue-800)!important}
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) .about-story h2, html:not([data-theme="light"]) .why-us__head h2, html:not([data-theme="light"]) .why-us__card h3{color:var(--ink)!important}
html:not([data-theme="light"]) .about-story p, html:not([data-theme="light"]) .why-us__head p, html:not([data-theme="light"]) .why-us__card p, html:not([data-theme="light"]) .stat-item span{color:var(--muted)!important}
html:not([data-theme="light"]) .stat-item b{color:#9CC6FF!important}
}

/* ===== Header in dark mode =========================================
   The header kept its white background while the rest of the page went
   dark, which left a bright band across the top and a hard black seam
   where it met the promo bar. */
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) .header{
    background:rgba(11,18,32,.95)!important;
    border-bottom-color:var(--line)!important;
  }
html:not([data-theme="light"]) .header__bar{background:transparent!important}
html:not([data-theme="light"]) .burger{border-color:var(--line)!important;color:var(--ink)!important;background:transparent!important}
html:not([data-theme="light"]) .header__call{border-color:var(--line)!important;color:#9CC6FF!important}
html:not([data-theme="light"]) .header__call:hover{background:var(--blue-600)!important;border-color:var(--blue-600)!important;color:#fff!important}
html:not([data-theme="light"]) .nav a, html:not([data-theme="light"]) .nav__drop-btn{color:var(--ink)!important}
html:not([data-theme="light"]) body{background:var(--surface)}
}

/* "Local experts" block was centred internally but the block itself sat
   left of the page — it has a max-width with no auto margins. */
@media(min-width:901px){
  .about{margin-left:auto!important;margin-right:auto!important;text-align:center}
  .about .brands,.about .cards{justify-content:center}
}

/* "Comfort now. Pay your way." sat as a left-aligned two-column block while
   the sections around it are centred. Centre it to match. */
@media(min-width:901px){
  .finance{
    grid-template-columns:1fr!important;
    justify-items:center;text-align:center;
    max-width:70ch;margin-left:auto!important;margin-right:auto!important;
    gap:1.6rem!important;
  }
  .finance .cards{justify-content:center}
  .finance .btn{justify-self:center}
}

/* The promo bar's sticky offset (72px) was larger than the header's actual
   height on tablet and mobile (65px), leaving a strip of page showing
   between the two as you scroll. Match the offset to the real height. */

/* Solutions heading and lede sat left while the card grid spans the full
   width — centre them so the block reads as one centred section. */
@media(min-width:901px){
  #solutions .head{text-align:center;max-width:70ch;margin-left:auto;margin-right:auto}
  #solutions .head .lede{margin-left:auto;margin-right:auto}
  #solutions .sol__cta{justify-content:center}
}

/* Brand pills kept a white background in dark mode while the text went
   light, leaving white-on-white. Give them the dark surface instead. */
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) .brands span, html:not([data-theme="light"]) .brands-row span, html:not([data-theme="light"]) .cards span, html:not([data-theme="light"]) .about-brands span, html:not([data-theme="light"]) .why-us .brands span{
    background:var(--surface-2)!important;
    border-color:var(--line)!important;
    color:var(--ink)!important;
  }
}

/* The CTA carried a red-tinted glow behind an orange gradient, which read as
   a second colour bleeding out around the edges rather than as a shadow.
   A neutral shadow gives the same lift without the colour halo. */
.btn--hot{
  box-shadow:0 4px 14px rgba(15,26,46,.22)!important;
}
.btn--hot:hover{
  box-shadow:0 6px 18px rgba(15,26,46,.28)!important;
}

/* Seven cards in a three-column grid leaves the last one stranded on the
   left of its own row. Centre it when it's alone. */
@media(min-width:901px){
  .sol__cards--3 > .sol__link:last-child:nth-child(3n+1){grid-column:2}
}
@media(min-width:681px) and (max-width:900px){
  /* two columns at this size — an odd last card ends up alone again */
  .sol__cards--3 > .sol__link:last-child:nth-child(2n+1){grid-column:1 / -1;max-width:calc(50% - .6rem);justify-self:center}
}

/* Brand gradient restored (orange into red). The red *glow* behind the
   button is what was removed — the shadow is neutral, with a subtle inner
   highlight so the button still reads as embossed. */
.btn--hot{
  background:linear-gradient(100deg,#F47B20,#D32017)!important;
  box-shadow:0 4px 14px rgba(15,26,46,.24),
             inset 0 1px 0 rgba(255,255,255,.28)!important;
}
.btn--hot:hover{
  background:linear-gradient(100deg,#F58B2E,#E0311F)!important;
  box-shadow:0 6px 18px rgba(15,26,46,.30),
             inset 0 1px 0 rgba(255,255,255,.34)!important;
}

/* Section headings sat left while the content below them is centred —
   centre the Specials heading and its lede to match. */
#offers .head{text-align:center;max-width:70ch;margin-left:auto;margin-right:auto}
#offers .head .lede{margin-left:auto;margin-right:auto}

/* Gradient stays within the orange family — the previous orange-to-red ramp
   left a visibly red edge that read as a second colour. */
.btn--hot,
a.btn--hot,
button.btn--hot,
.header .btn--hot,
.hero__actions .btn--hot{
  background-image:linear-gradient(100deg,#F47B20,#D32017)!important;
  background-color:#EA6A1A!important;
  box-shadow:0 4px 14px rgba(15,26,46,.22)!important;
}
.btn--hot:hover{
  background-image:linear-gradient(100deg,#F98A2E,#E03226)!important;
}

/* Ratings and trust marks now sit below both hero columns, centred, rather
   than tucked under the left column only. */
.hero__marks{grid-column:1 / -1;justify-self:center;text-align:center;width:100%;max-width:860px}
.hero__marks .hero__stars{justify-content:center}
.hero__marks-row{justify-content:center}

/* The button carries a 2px transparent border. With background-clip at its
   default (border-box) the solid fill paints under that border and shows as
   a darker strip down the left edge. Clip to the padding box and drop the
   solid colour so only the gradient renders. */
/* No border at all, rather than a transparent one. A transparent border with
   padding-box clipping showed the page through it as a white ring; with
   border-box clipping it showed the fill as a dark strip. Removing it avoids
   both. */
.btn--hot,
a.btn--hot,
button.btn--hot{
  border:0!important;
  background-color:transparent!important;
  background-clip:border-box!important;
}

/* Reviews heading and its Google link sit centred over the review cards. */
.head--centred{text-align:center;max-width:70ch;margin-left:auto;margin-right:auto}
.revs__link--centred{text-align:center}

/* The reviews carousel has a max-width but no auto margins, so it sat left
   under a centred heading. Centre the block and its text. */
.revs{margin-left:auto!important;margin-right:auto!important}
.rev{border-left:0;border-top:4px solid var(--orange-500);padding:1rem 1.2rem 0;text-align:center}
.rev__who,.rev__meta{text-align:center}

/* Carousel controls centre with the reviews they belong to. */
.revs__nav{justify-content:center;padding-left:0!important}

/* Lift the ratings/trust marks clear of the decorative wave at the foot of
   the hero — they were overlapping it, especially on mobile. */
.hero__marks{margin-top:1.4rem!important;margin-bottom:clamp(10px,1.5vw,20px)}
@media(max-width:900px){
  .hero__marks{margin-top:1rem!important;margin-bottom:clamp(58px,13vw,86px)}
}

/* Sticky header + promo bar, hardened.
   position:sticky silently fails if any ancestor has overflow other than
   visible, or if html/body are height-constrained — both of which have bitten
   this site already. Pin the chain explicitly so it holds on every browser. */
/* No overflow on html/body: any value other than visible can silently
   disable position:sticky for descendants in some browsers. */
html,body{overflow:visible;min-height:100%;height:auto}
body{position:relative}
main,.app-wrap,.app{overflow:visible!important}
.header{position:sticky!important;top:0!important;z-index:60!important}
.giveaway-carousel{position:sticky!important;z-index:59!important}
@supports (position:-webkit-sticky){
  .header{position:-webkit-sticky!important;top:0!important}
  .giveaway-carousel{position:-webkit-sticky!important}
}

/* Dark mode: the intro paragraph in the narrow wrap kept a deep-blue colour
   that is unreadable on a dark background. Covered in shared.css, duplicated
   here so it still holds if that file is unavailable. */
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) .wrap--narrow p, html:not([data-theme="light"]) .about-story p, html:not([data-theme="light"]) .why-us__head p, html:not([data-theme="light"]) .why-card p, html:not([data-theme="light"]) .why-us__card p{color:var(--muted)!important}
html:not([data-theme="light"]) .wrap--narrow h2, html:not([data-theme="light"]) .about-story h2, html:not([data-theme="light"]) .why-card h3, html:not([data-theme="light"]) .why-us__card h3{color:var(--ink)!important}
}

/* Below ~380px the hero column was rendering wider than the screen, so both
   the AC unit and the heading overflowed. Keep the column inside the
   viewport and let the heading scale with it. */
@media(max-width:380px){
  .hero__inner,.hero__inner > *{max-width:100%;min-width:0}
  .hpunit-mount,.hpunit{max-width:100%}
  
}



/* The scrolling marquee is ~1638px wide by design; it must be clipped by its
   viewport. On solutions/calculator it was escaping, which made the whole
   page horizontally scrollable — that sideways scroll is what made the
   sticky header appear to drift away. */
#giveawayCarousel{overflow:hidden!important;max-width:100vw}
#giveawayCarousel .giveaway-carousel__viewport{overflow:hidden!important;min-width:0}
#giveawayCarousel .wrap{overflow:hidden}

/* The visually-hidden file input was positioned past the right edge, which
   made the whole page horizontally scrollable on phones — and that sideways
   scroll is what made the sticky header look like it drifted off. Hide it
   without giving it any layout width. */
.filedrop__input{
  position:absolute!important;
  width:1px!important;height:1px!important;
  left:0!important;top:0!important;right:auto!important;
  opacity:0!important;pointer-events:none!important;
  overflow:hidden!important;
}

/* The decorative hero wave is drawn slightly wider than the viewport so its
   curve reaches the edges; clip it so it can't create a horizontal scroll. */
.hero__wave{overflow:hidden;max-width:100%}
.hero__wave svg{max-width:100%;display:block}

/* Final guard: the hero section itself clips anything that overhangs, so no
   decorative element can make the page scroll sideways on small phones. */
.hero{overflow-x:clip}
@supports not (overflow:clip){ .hero{overflow-x:hidden} }

/* --- Tablet and mobile refinements ------------------------------------ */

/* 2. "View all solutions" was left-aligned on tablet while the cards above
      it are centred. */
@media(max-width:900px){
  .sol__cta--wide{justify-content:center}
  .sol__cta--wide .btn{margin-left:auto;margin-right:auto}
}

/* 5. On tablet the AC unit used only about half of its column, leaving a
      large empty gap to its right. Let it use the space. */
@media(min-width:641px) and (max-width:900px){
  /* use the full column width, but keep the unit's proportions so it doesn't
     become a tall empty box */
  .hpunit-mount{max-width:100%!important;width:100%!important}
  .hpunit{max-width:100%!important;width:100%!important;aspect-ratio:2.85/1;min-height:0}
}

/* 6. The hero heading sat too close to the paragraph beneath it on phones. */
@media(max-width:640px){
  .hero h1{margin-bottom:1.15rem!important}
  .hero h1 + p,.hero .lede{margin-top:.25rem!important}
}

/* Show the full hint wherever it fits — the shortened variants were kicking
   in earlier than necessary on phones. */
@media(max-width:820px){
  .hpunit__hint-full{display:inline!important}
  .hpunit__hint-mid,.hpunit__hint-short{display:none!important}
}
@media(max-width:345px){
  .hpunit__hint-full{display:none!important}
  .hpunit__hint-mid{display:inline!important}
}

/* The "new version available" bar had dark text on a dark panel in dark mode. */

/* The quote form card kept a white background on About while its labels
   switched to the dark-mode light colour, so the headings vanished. */
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) #contact .form{background:#121D31!important;border-color:var(--line)!important}
html:not([data-theme="light"]) #contact .form label, html:not([data-theme="light"]) #contact .field label{color:var(--ink)!important}
html:not([data-theme="light"]) #contact .form input, html:not([data-theme="light"]) #contact .form select, html:not([data-theme="light"]) #contact .form textarea{
    background:#0D1626!important;border-color:var(--line)!important;color:var(--ink)!important;
  }
html:not([data-theme="light"]) #contact .form input::placeholder, html:not([data-theme="light"]) #contact .form textarea::placeholder{color:var(--muted)!important}
html:not([data-theme="light"]) #contact .form__fine, html:not([data-theme="light"]) #contact .form small{color:var(--muted)!important}
html:not([data-theme="light"]) #contact .filedrop{border-color:var(--line)!important}
html:not([data-theme="light"]) #contact .filedrop__text{color:var(--ink)!important}
html:not([data-theme="light"]) #contact .filedrop__hint{color:var(--muted)!important}
html:not([data-theme="light"]) #contact h2{color:var(--ink)!important}
html:not([data-theme="light"]) #contact .lede, html:not([data-theme="light"]) #contact p{color:var(--muted)!important}
}

/* Update banner: a light panel with dark text in BOTH colour schemes. The
   previous dark-mode treatment wasn't winning, leaving near-white text on a
   white panel. Fixing the colours outright avoids the conflict. */
.update-bar,
#updateBar{
  background:#F4F8FC!important;
  border:1px solid #D7E0EC!important;
  color:#0F1A2E!important;
  box-shadow:0 8px 28px rgba(3,14,40,.28)!important;
}
.update-bar span,
#updateBar span{color:#0F1A2E!important;font-weight:600}
.update-bar button,
#updateBar button{
  background:linear-gradient(100deg,#F47B20,#D32017)!important;
  color:#fff!important;border:0!important;font-weight:800!important;
}

@media(max-width:560px){
  .update-bar span,#updateBar span{font-size:.9rem}
  .update-bar,#updateBar{gap:.6rem;padding:.7rem .8rem}
}

/* When the AC unit is switched off the airflow spacing disappears with it,
   collapsing the gap to the heading. Hold a minimum gap either way. */
.hero .hpunit-mount{margin-bottom:clamp(1.6rem,2.6vw,2.4rem)}
@media(max-width:640px){
  .hero .hpunit-mount{margin-bottom:clamp(1.4rem,4vw,2rem)}
}

/* The wave was stretched to fill a tall box (background-size:100% 100%),
   which distorted its shape and made it read as too deep. Keep its natural
   proportions, and use the original cool wave in both heating and cooling
   modes rather than swapping the artwork. */
.hero__wave{
  height:clamp(70px,9vw,130px)!important;
  background-size:100% auto!important;
  background-position:bottom center!important;
  background-repeat:no-repeat!important;
}
.hero[data-mode="cooling"] .hero__wave,
.hero[data-mode="heating"] .hero__wave{background-image:var(--wave-cool)!important}

/* Trim the hero's bottom padding on desktop — with the shorter wave there was
   a large empty band between the ratings and the curve. */
/* Scoped to the homepage hero only. The calculator page has its own element
   using the same .hero class name, but with a CTA button sitting at the bottom
   of the section: stripping the bottom padding there dropped the button behind
   the wave above 901px, which is why it looked cut off on laptop and fine on
   a phone. Class-name collision between pages, same as .nav previously. */
@media(min-width:901px){
  .hero:not(.hero--standalone){padding-bottom:0!important}
  .hero:not(.hero--standalone) .hero__marks{margin-bottom:0!important}
}

/* Brand wave — transparent PNG so it reads correctly on any background,
   and always the same artwork regardless of heating/cooling mode. */
.hero__wave,
.hero[data-mode="cooling"] .hero__wave,
.hero[data-mode="heating"] .hero__wave{
  background-image:url("img/hero-wave.webp")!important;
  background-size:100% auto!important;
  background-position:bottom center!important;
  background-repeat:no-repeat!important;
  height:clamp(64px,8vw,120px)!important;
}

/* ===== THEME OVERRIDE: manual dark mode ===== */
html[data-theme="dark"] .nav__install{color:#9CC6FF!important}
html[data-theme="dark"] /* !important because the homepage still carries an inline .nav.is-open
       rule with a light background that would otherwise win. */
    .nav, html[data-theme="dark"] .nav.is-open{background:var(--surface-2)!important;border-bottom-color:var(--line)!important}
html[data-theme="dark"] .nav a, html[data-theme="dark"] .nav__drop-btn{color:var(--ink)!important}
html[data-theme="dark"] .about-story h2, html[data-theme="dark"] .why-us__head h2, html[data-theme="dark"] .why-us__card h3{color:var(--ink)!important}
html[data-theme="dark"] .about-story p, html[data-theme="dark"] .why-us__head p, html[data-theme="dark"] .why-us__card p, html[data-theme="dark"] .stat-item span{color:var(--muted)!important}
html[data-theme="dark"] .stat-item b{color:#9CC6FF!important}
html[data-theme="dark"] .header{
    background:rgba(11,18,32,.95)!important;
    border-bottom-color:var(--line)!important;
  }
html[data-theme="dark"] .header__bar{background:transparent!important}
html[data-theme="dark"] .burger{border-color:var(--line)!important;color:var(--ink)!important;background:transparent!important}
html[data-theme="dark"] .header__call{border-color:var(--line)!important;color:#9CC6FF!important}
html[data-theme="dark"] .header__call:hover{background:var(--blue-600)!important;border-color:var(--blue-600)!important;color:#fff!important}
html[data-theme="dark"] .nav a, html[data-theme="dark"] .nav__drop-btn{color:var(--ink)!important}
html[data-theme="dark"] body{background:var(--surface)}
html[data-theme="dark"] .brands span, html[data-theme="dark"] .brands-row span, html[data-theme="dark"] .cards span, html[data-theme="dark"] .about-brands span, html[data-theme="dark"] .why-us .brands span{
    background:var(--surface-2)!important;
    border-color:var(--line)!important;
    color:var(--ink)!important;
  }
html[data-theme="dark"] .wrap--narrow p, html[data-theme="dark"] .about-story p, html[data-theme="dark"] .why-us__head p, html[data-theme="dark"] .why-card p, html[data-theme="dark"] .why-us__card p{color:var(--muted)!important}
html[data-theme="dark"] .wrap--narrow h2, html[data-theme="dark"] .about-story h2, html[data-theme="dark"] .why-card h3, html[data-theme="dark"] .why-us__card h3{color:var(--ink)!important}
html[data-theme="dark"] #contact .form{background:#121D31!important;border-color:var(--line)!important}
html[data-theme="dark"] #contact .form label, html[data-theme="dark"] #contact .field label{color:var(--ink)!important}
html[data-theme="dark"] #contact .form input, html[data-theme="dark"] #contact .form select, html[data-theme="dark"] #contact .form textarea{
    background:#0D1626!important;border-color:var(--line)!important;color:var(--ink)!important;
  }
html[data-theme="dark"] #contact .form input::placeholder, html[data-theme="dark"] #contact .form textarea::placeholder{color:var(--muted)!important}
html[data-theme="dark"] #contact .form__fine, html[data-theme="dark"] #contact .form small{color:var(--muted)!important}
html[data-theme="dark"] #contact .filedrop{border-color:var(--line)!important}
html[data-theme="dark"] #contact .filedrop__text{color:var(--ink)!important}
html[data-theme="dark"] #contact .filedrop__hint{color:var(--muted)!important}
html[data-theme="dark"] #contact h2{color:var(--ink)!important}
html[data-theme="dark"] #contact .lede, html[data-theme="dark"] #contact p{color:var(--muted)!important}

/* Light / dark toggle in the header */
.themetoggle{
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;flex:0 0 auto;
  background:transparent;border:1px solid var(--line);border-radius:10px;
  color:var(--ink);cursor:pointer;padding:0;margin-left:.15rem;
  transition:background .18s,border-color .18s;
}
.themetoggle:hover{background:rgba(26,95,203,.08);border-color:var(--blue-600)}
.themetoggle svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7}
.themetoggle__moon{display:none;fill:currentColor;stroke:none}
/* show the moon when dark is active, the sun when light is */
html[data-theme="dark"] .themetoggle__sun{display:none}
html[data-theme="dark"] .themetoggle__moon{display:block}
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]):not([data-theme="light"]) .themetoggle__sun{display:none}
html:not([data-theme="light"]):not([data-theme="light"]) .themetoggle__moon{display:block}
}
html[data-theme="light"] .themetoggle__sun{display:block}
html[data-theme="light"] .themetoggle__moon{display:none}
@media(max-width:1119px){ .themetoggle{width:36px;height:36px} }

/* Explicit light-mode surface so toggling back from dark restores the
   background rather than leaving it transparent. */
html[data-theme="light"] body{background:var(--surface,#F4F8FC)!important;color:var(--ink,#0F1A2E)!important}
html[data-theme="light"]{color-scheme:light}
html[data-theme="dark"]{color-scheme:dark}

/* The mobile menu's item dividers were leaking onto the desktop nav in dark
   mode — they belong only to the stacked mobile menu. */
@media(min-width:1120px){
  .header .nav > a,
  .header .nav > .nav__drop,
  html[data-theme="dark"] .header .nav > a,
  html[data-theme="dark"] .header .nav > .nav__drop{
    border-bottom:0!important;
  }
}

/* The mobile menu panel's own background/border/shadow were showing on the
   desktop nav in dark mode. They belong to the stacked menu only. */
@media(min-width:1120px){
  .header .nav,
  html[data-theme="dark"] .header .nav,
  html:not([data-theme="light"]) .header .nav{
    background:transparent!important;
    border:0!important;
    box-shadow:none!important;
    position:static!important;
    visibility:visible!important;
    opacity:1!important;
    transform:none!important;
  }
}

/* The finance section was only centred from 901px up, so on phones the
   heading, card list and button stayed left-aligned. */
@media(max-width:900px){
  .finance{justify-items:center;text-align:center}
  .finance .cards{justify-content:center}
  .finance .btn{margin-left:auto;margin-right:auto;display:inline-flex}
}

/* "Local experts" block was only centred from 901px up, so the copy, brand
   pills and "Read more about us" link stayed left on tablet and mobile. */
@media(max-width:900px){
  .about{margin-left:auto!important;margin-right:auto!important;text-align:center}
  .about .brands,.about .cards{justify-content:center}
  .about a,.about .reveal{text-align:center}
  .about .reveal a{display:inline-block}
}

/* Success confirmation sits directly under the Send button, where the eye
   already is after clicking, rather than above the form where it can be
   scrolled out of view. */
.form__ok{margin-top:1rem;margin-bottom:0}
.form__ok.is-visible{
  display:block;
  animation:okPop .35s ease-out;
  scroll-margin-top:120px;
}
@keyframes okPop{ from{opacity:0;transform:translateY(-6px)} to{opacity:1;transform:none} }

/* The wave box was given a fixed height shorter than the artwork needs at
   that width, so the bottom of the curve was sliced off on tablet and laptop
   (fine on mobile, where the numbers happened to line up). Let the box follow
   the artwork's own 1400x198 proportions so the whole curve always shows. */
.hero__wave,
.hero[data-mode="cooling"] .hero__wave,
.hero[data-mode="heating"] .hero__wave{
  /* aspect-ratio tied height to width with no ceiling, so wide screens grew a
     204px wave that towered over the trust marks. background-size:100% 100%
     stretches the artwork to whatever box it is given rather than cropping it,
     so the curve stays whole at any height -- which means the height can be
     capped. Fluid with a ceiling: ~55px on a phone, ~100px on a wide laptop. */
  height:clamp(40px,4.4vw,70px)!important;
  background-size:100% 100%!important;
  background-position:bottom center!important;
}


/* The hero went two-column from 901px, but at 901-1023px that leaves the
   left column narrower than a phone screen and the AC unit ends up cramped.
   Stay single-column until there is genuinely room for two. */
@media(max-width:1023px){
  .hero__inner{grid-template-columns:1fr;gap:2rem}
  .hero__sub{min-height:0}
  /* Fill the single column, as it already did at 900px and below, so the
     unit doesn't suddenly shrink to 403px in a 950px-wide column. The
     aspect cap that applies at 641-900px is extended here too, otherwise
     the unit stretches to a thin 3.2 ratio. */
  .hpunit-mount{max-width:100%!important;width:100%!important}
  .hpunit{aspect-ratio:2.85/1}
}

/* ===== Hero hint: sized by the unit, not the viewport =====
   The unit's width does not track the viewport — it is 856px wide at a
   900px viewport but only 390px at 1440px, where the hero splits into two
   columns. Viewport-keyed font sizes therefore produced a 14.4px hint on a
   390px unit at laptop and a 9.6px hint on a 316px unit at phone: the same
   element looking materially different at near-identical unit widths.
   Sizing against the unit's own inline size keeps the hint's proportion and
   position constant at every resolution, tested or not, and removes the need
   for the three text-length variants. */

.hpunit__hint{
  font-size:clamp(.5rem,3.2cqw,1rem)!important;
  margin:1.5cqi 0 0!important;
  gap:1cqi!important;
}
.hpunit__hint svg{
  width:clamp(8px,2.6cqw,15px)!important;
  height:clamp(8px,2.6cqw,15px)!important;
}
/* Hint length follows the unit's own width, not the viewport. The badge sits
   in the bottom-left corner and the hint is centred, so on a narrow unit the
   full sentence runs into the badge. These replace an unconditional override
   that forced the full text on at every width, defeating the three lengths. */
.hpunit__hint-full{display:inline!important}
.hpunit__hint-mid,.hpunit__hint-short{display:none!important}
@container mount (max-width:340px){
  .hpunit__hint-full{display:none!important}
  .hpunit__hint-mid{display:inline!important}
  .hpunit__hint-short{display:none!important}
}
@container mount (max-width:268px){
  .hpunit__hint-full,.hpunit__hint-mid{display:none!important}
  .hpunit__hint-short{display:inline!important}
}

/* ===== Hero controls: compacted by the unit's width, not the viewport =====
   The compact control rules were keyed to viewport (<=640px, 641-980px), but
   the unit is ~390px wide at 1024-1440px where the hero splits into two
   columns. Above 980px no compact rule applied at all, so full desktop
   controls were forced into a phone-width box and wrapped onto four lines,
   colliding with the Daikin badge. Keying to the unit's own inline size makes
   the controls fit at any resolution, including ones never explicitly tested. */
@container mount (max-width:660px){
  .toggle__row{flex-wrap:nowrap!important;gap:.3rem!important}
  .toggle__stat{min-width:0!important;padding:4px 8px!important}
  .toggle__stat i{font-size:.56rem!important}
  .toggle__stat b{font-size:1rem!important}
  .toggle__power,.toggle__mode{min-width:0!important;padding:5px 7px!important}
  .toggle__step{width:19px!important;height:19px!important;font-size:.78rem!important}
  .toggle__temp-ctrl{gap:.25rem!important}
}
@container mount (max-width:430px){
  .hpunit .toggle{padding:4px!important;gap:.3rem!important}
  .toggle__stat{padding:3px 6px!important;gap:2px!important;height:44px!important}
  .toggle__stat i{font-size:.52rem!important}
  .toggle__stat b{font-size:.86rem!important}
  .toggle__step{width:17px!important;height:17px!important;min-width:17px!important;min-height:17px!important;font-size:.66rem!important}
  .toggle__temp-ctrl{gap:.22rem!important}
  .toggle__power,.toggle__mode{padding:3px 6px!important;gap:2px!important;height:44px!important}
  .toggle__power svg,.toggle__mode svg{width:17px!important;height:17px!important}
  .toggle__power em,.toggle__mode em{font-size:.54rem!important}
  .toggle__div{height:24px!important}
  .hpunit__logo{width:60px!important}
}

/* Room for the hint inside the unit, keyed to the unit's own width. The
   container sits on .hpunit-mount rather than .hpunit so the unit's own
   padding can respond — an element cannot be styled by its own container. */
@container mount (max-width:470px){
  .hpunit{padding-bottom:16%!important;min-height:128px!important}
}
@container mount (max-width:430px){
  .hpunit__vent{bottom:20px!important}
  .hpunit__logo{bottom:42px!important}
}

/* The mount was shrink-to-fit (inline-block), so it could not act as a size
   container. Giving it a definite width — the column it sits in — makes its
   size come from its parent rather than its contents; the unit's own
   width:min(100%,600px) still caps how wide it draws. */
.hpunit-mount{display:block!important;width:100%!important;container:mount/inline-size}
/* The hint is sized against the UNIT, not the mount: the unit is letterboxed
   narrower than its mount wherever the aspect ratio binds, so mount-keyed
   sizing drifted (4.0% of the unit at laptop vs 3.2% at phone). */
.hpunit{container:unit/inline-size}

/* ===== Section rhythm at same-colour boundaries =====
   .section pads clamp(54px,7.5vw,96px) top AND bottom, so every boundary
   stacks both: ~170px of gap. Where the background changes (tint -> plain,
   navy -> tint) the colour break reads as the divider and the space looks
   intentional. Between two UNTINTED sections there is no break, so the same
   gap reads as a void -- which is what happens above "What customers say".
   Halve the top padding only in that case: keyed to the actual condition
   (same background) rather than patched per-section, so it holds wherever
   the pattern occurs. */
.section:not(.section--tint) + .section:not(.section--tint),
.section:not(.section--tint) + .meet{
  padding-top:clamp(27px,3.75vw,48px)
}

/* ===== Reviews carousel nav on very narrow screens =====
   The row is flex/nowrap: 16 dots need ~269px, plus two 38px arrows and the
   gaps = ~377px, against 276px available at 320px wide. The arrows were being
   squashed to 21px and the dots still pushed ~11px past the viewport, which
   was the last horizontal overflow on the homepage. Let the row wrap and keep
   the arrows at their intended size; scales with however many reviews load. */
.revs__nav{justify-content:center}
.revs__arrow{flex:0 0 auto}
.revs__dots{min-width:0}

/* Under 480px the arrows + 16 dots need ~377px against ~276px available, so
   the row used to squash the arrows and push past the viewport. Wrapping it
   split the control into three stacked rows, which reads worse than the
   overflow did. Scaling the dots down instead keeps arrows, dots and active
   pill on one line: 16 dots now need ~163px, inside the ~168px available. */
@media(max-width:480px){
  .revs__nav{gap:.6rem}
  .revs__dots{gap:3px}
  .revs__dots button{width:6px;height:6px}
  .revs__dots button[aria-current="true"]{width:18px;border-radius:3px}
}

/* The unit fills its column up to a cap, and CSS owns its width -- nothing
   scripts it. Without the cap a single-column layout stretched the unit to
   906px at a 950px viewport; with aspect-ratio 2.85/1 that made a 318px-tall
   slab around ~100px of controls, and the heading fitted to it grew to match.
   The cap keeps the unit near the size it has in the two-column layout. */
.hpunit{width:100%!important;max-width:620px!important;margin-left:0;margin-right:auto}

/* .hpunit.is-fitted used display:flex purely to let the toggle span the unit.
   But flex collapsed the absolutely positioned .hpunit__logo and .hpunit__vent
   to 0x0 -- the Daikin badge and the grille vanished on any screen wide enough
   to apply is-fitted, leaving the bottom half of the unit blank. The toggle is
   itself inline-flex and already carries width:100%, so block layout spreads it
   exactly the same while the badge and grille render again. */
.hpunit.is-fitted{display:block!important}

/* ===== Constant clearance between the trust marks and the wave =====
   .hero__inner's bottom padding is fluid (38px at 390 -> 187px at 1440) while
   the wave's height is capped, so the gap between the "5-star rated" row and
   the top of the wave drifted from 56px to 124px across the range. Deriving
   the padding from the wave's own height keeps that gap identical at every
   width: never overlapping, never a growing void. */
.hero__marks{margin-bottom:0!important}
.hero__inner{padding-bottom:calc(clamp(40px,4.4vw,70px) + 28px)!important}

/* ===== Trust marks on phones =====
   The four marks are separated by border-right, cleared only on :last-child.
   Once the row wraps, whichever mark ends each visual line keeps its border,
   so every line finished with a divider pointing at nothing. The row also ran
   at 17px against the 14.7px rating line directly above it.
   Below 640px: drop the borders, lay the marks out as a centred 2x2 grid and
   match the type to the rating line. Above that the row still fits on one
   line, so the original separators are kept. */
@media(max-width:640px){
  .hero__marks-row{
    display:grid;
    grid-template-columns:repeat(2,auto);
    justify-content:center;
    column-gap:1.1rem;
    row-gap:.5rem;
  }
  .hero__marks-row span{
    font-size:.86rem;
    border-right:0!important;
    padding-right:0!important;
    margin-right:0!important;
    text-align:center;
  }
}

/* ===== Update banner sizing =====
   The pill is fixed with left:16/right:16, so it stretched the full width
   while its content (label + button, ~296px) sat flex-start -- leaving a band
   of empty white to the right of the Refresh button. Size it to its content
   and centre it within the same band, so it reads as a pill rather than a
   half-filled bar. */
#updateBar, .update-bar{
  width:max-content;
  max-width:calc(100vw - 32px);
  margin-left:auto;
  margin-right:auto;
  justify-content:center;
}

/* ===== Wave must reach both page edges =====
   .hero__wave is left:-2%/width:104% (an overhang to hide the artwork's soft
   edges), but a later rule caps it with max-width:100%. The width clamped back
   to 100% while the -2% shift stayed, so the wave sat 2% off-screen on the left
   and stopped 2% short of the right edge -- 8px at 393, 26px at 1280.
   background-size:100% 100% stretches the artwork to whatever box it is given,
   so the overhang buys nothing: pin it flush to both edges instead. */
.hero__wave{
  left:0!important;
  right:0!important;
  width:100%!important;
  max-width:100%!important;
}

/* iOS Safari auto-inflates text runs independently of the CSS; this makes the
   declared sizes authoritative on iPhone. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}

/* ===== Installation: what's included vs what good looks like =====
   Two parallel lists rather than two prose cards. The content is a
   specification on one side and a quality checklist on the other, so it is
   set as lists with the quantities (4m, 3m) carrying weight -- those are the
   numbers a customer compares between quotes. The caveat sits below both
   because it governs both, not just the inclusions. */
.installpair{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));
  gap:clamp(1.6rem,4vw,3.2rem);
  align-items:start;
}
.installpair__col h3{
  margin:0 0 .6rem;
  font-family:"Montserrat","Montserrat Fallback",sans-serif;
  font-weight:800;
  font-size:1.16rem;
  line-height:1.25;
  color:var(--ink,#0F1A2E);
  padding-bottom:.7rem;
  border-bottom:2px solid var(--orange-500,#F2790A);
}
.installpair__intro{
  margin:.9rem 0 .8rem;
  font-size:.97rem;
  line-height:1.65;
  color:var(--muted,#5A6579);
}
.installpair__spec{list-style:none;margin:0;padding:0}
.installpair__spec li{
  display:flex;
  gap:.6rem;
  align-items:flex-start;
  padding:.5rem 0;
  font-size:.97rem;
  line-height:1.5;
  color:var(--ink,#0F1A2E);
  border-bottom:1px solid var(--line,#E2E8F1);
}
.installpair__spec li:last-child{border-bottom:0}
.installpair__spec .tick{color:var(--orange-500,#F2790A);font-weight:800;flex:none;line-height:1.5}
.installpair__spec b{font-weight:700}
/* Embossed plate, matching the diagram's write-up card. The leading edge and
   the tint follow the hero unit's mode — blue on COOL, orange on HEAT — via
   data-hero-mode mirrored onto <html> by setMode(). Pages without the hero
   unit (the calculator) fall back to the brand blue default below. */
.installpair__caveat{
  --caveat-edge:#123C8F;
  --caveat-text:#123C8F;
  --caveat-top:#FFFFFF;
  --caveat-bot:#F2F7FD;
  margin:clamp(1.6rem,3vw,2.2rem) 0 0;
  padding:1.05rem 1.25rem;
  background:linear-gradient(180deg,var(--caveat-top) 0%,var(--caveat-bot) 100%);
  border:1px solid rgba(15,26,46,.10);
  border-left:3px solid var(--caveat-edge);
  border-radius:14px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 -1px 0 rgba(15,26,46,.05),
    0 1px 2px rgba(15,26,46,.07),
    0 6px 18px rgba(15,26,46,.10);
  transition:border-left-color .4s ease,background .4s ease;
  font-size:.95rem;
  line-height:1.65;
  color:var(--muted,#5A6579);
}
html[data-hero-mode="cooling"] .installpair__caveat{
  --caveat-edge:#123C8F;--caveat-text:#123C8F;--caveat-bot:#F2F7FD}
html[data-hero-mode="heating"] .installpair__caveat{
  --caveat-edge:#F2790A;--caveat-text:#A64E08;--caveat-bot:#FDF6EF}

/* The opening phrase carries the mode colour. The edge bar can use the vivid
   orange, but text cannot -- #F2790A on white is 2.9:1. #A64E08 is 5.40:1. */
.installpair__lead{font-weight:700;color:var(--caveat-text);transition:color .4s ease}
@media (prefers-reduced-motion:reduce){.installpair__lead{transition:none}}
@media (prefers-reduced-motion:reduce){
  .installpair__caveat{transition:none}
}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .installpair__col h3{color:#F2F6FB}
  html:not([data-theme="light"]) .installpair__spec li{
    color:rgba(255,255,255,.88);border-bottom-color:rgba(255,255,255,.12)}
  html:not([data-theme="light"]) .installpair__intro,
  html:not([data-theme="light"]) .installpair__caveat{color:rgba(255,255,255,.75)}
  html:not([data-theme="light"]) .installpair__caveat{
    --caveat-top:#16233A;--caveat-bot:#101A2C;
    border-color:rgba(255,255,255,.10);
    border-left-color:var(--caveat-edge);
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.07),
      inset 0 -1px 0 rgba(0,0,0,.35),
      0 2px 4px rgba(0,0,0,.35),
      0 8px 22px rgba(0,0,0,.45)}
  html:not([data-theme="light"])[data-hero-mode="cooling"] .installpair__caveat{--caveat-edge:#7FB0FF;--caveat-text:#7FB0FF}
  html:not([data-theme="light"])[data-hero-mode="heating"] .installpair__caveat{--caveat-edge:#FF9A5A;--caveat-text:#FFA24D}
  html:not([data-theme="light"]) .installpair__caveat{--caveat-edge:#7FB0FF;--caveat-text:#7FB0FF}
}
html[data-theme="dark"] .installpair__col h3{color:#F2F6FB}
html[data-theme="dark"] .installpair__spec li{
  color:rgba(255,255,255,.88);border-bottom-color:rgba(255,255,255,.12)}
html[data-theme="dark"] .installpair__intro,
html[data-theme="dark"] .installpair__caveat{color:rgba(255,255,255,.75)}
html[data-theme="dark"] .installpair__caveat{
  --caveat-top:#16233A;--caveat-bot:#101A2C;
  --caveat-edge:#7FB0FF;
  --caveat-text:#7FB0FF;
  border-color:rgba(255,255,255,.10);
  border-left-color:var(--caveat-edge);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),
    inset 0 -1px 0 rgba(0,0,0,.35),
    0 2px 4px rgba(0,0,0,.35),
    0 8px 22px rgba(0,0,0,.45)}
html[data-theme="dark"][data-hero-mode="heating"] .installpair__caveat{--caveat-edge:#FF9A5A;--caveat-text:#FFA24D}

/* ===== Standard install, drawn =====
   Most people don't know what "back-to-back" means, and it is the single thing
   that decides whether a quote is simple or complicated. A cross-section says
   it faster than the paragraph did, and gives the 4m/3m figures something to
   attach to. Line art rather than illustration: this is a spec, not decor. */
.installdiag{margin:0 0 clamp(1.8rem,4vw,2.6rem);text-align:center}
.installdiag svg{
  width:100%;
  max-width:860px;
  height:auto;
  display:block;
  margin:0 auto;
  overflow:visible;
}
.installdiag figcaption{
  margin-top:.9rem;
  font-size:.92rem;
  line-height:1.55;
  color:var(--muted,#5A6579);
  max-width:56ch;
  margin-inline:auto;
}
.idg-ground{stroke:var(--line,#E2E8F1);stroke-width:2}
.idg-wall{fill:var(--line,#E2E8F1);opacity:.65}
.idg-unit{fill:var(--card,#fff);stroke:var(--blue-800,#123C8F);stroke-width:2.5}
.idg-vent{stroke:var(--blue-800,#123C8F);stroke-width:2;opacity:.45}
.idg-air{fill:none;stroke:var(--blue-400,#4FB2EE);stroke-width:2.5;stroke-linecap:round;opacity:.8}
.idg-pipe{fill:none;stroke:var(--blue-600,#1A5FCB);stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round}
.idg-trunk{fill:var(--blue-600,#1A5FCB);opacity:.16}
.idg-drain{fill:none;stroke:var(--blue-400,#4FB2EE);stroke-width:2.2;stroke-dasharray:6 5;stroke-linecap:round}
.idg-fan{fill:none;stroke:var(--blue-800,#123C8F);stroke-width:2;opacity:.5}
.idg-fanblade{fill:none;stroke:var(--blue-600,#1A5FCB);stroke-width:2.5;stroke-linecap:round}
.idg-dim line{stroke:var(--orange-500,#F2790A);stroke-width:1.8}
.idg-dim text{fill:var(--orange-600,#D9660A);font-family:"Montserrat","Montserrat Fallback",sans-serif;font-weight:700;font-size:15px}
.idg-call line{stroke:var(--muted,#5A6579);stroke-width:1.4;opacity:.55}
.idg-call text{fill:var(--muted,#5A6579);font-family:"Barlow","Barlow Fallback",sans-serif;font-size:15px}
.idg-side{fill:var(--muted,#5A6579);font-family:"Barlow","Barlow Fallback",sans-serif;font-size:14px;letter-spacing:.04em;opacity:.8}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .installdiag figcaption{color:rgba(255,255,255,.72)}
  html:not([data-theme="light"]) .idg-ground{stroke:rgba(255,255,255,.22)}
  html:not([data-theme="light"]) .idg-wall{fill:rgba(255,255,255,.14);opacity:1}
  html:not([data-theme="light"]) .idg-unit{fill:#0F1A2E;stroke:#9CC6FF}
  html:not([data-theme="light"]) .idg-vent{stroke:#9CC6FF}
  html:not([data-theme="light"]) .idg-pipe,
  html:not([data-theme="light"]) .idg-fanblade{stroke:#9CC6FF}
  html:not([data-theme="light"]) .idg-trunk{fill:#9CC6FF;opacity:.2}
  html:not([data-theme="light"]) .idg-fan{stroke:#9CC6FF;opacity:.45}
  html:not([data-theme="light"]) .idg-dim text{fill:#FFAE63}
  html:not([data-theme="light"]) .idg-dim line{stroke:#FF9A5A}
  html:not([data-theme="light"]) .idg-call line{stroke:rgba(255,255,255,.4)}
  html:not([data-theme="light"]) .idg-call text,
  html:not([data-theme="light"]) .idg-side{fill:rgba(255,255,255,.72)}
}
html[data-theme="dark"] .installdiag figcaption{color:rgba(255,255,255,.72)}
html[data-theme="dark"] .idg-ground{stroke:rgba(255,255,255,.22)}
html[data-theme="dark"] .idg-wall{fill:rgba(255,255,255,.14);opacity:1}
html[data-theme="dark"] .idg-unit{fill:#0F1A2E;stroke:#9CC6FF}
html[data-theme="dark"] .idg-vent{stroke:#9CC6FF}
html[data-theme="dark"] .idg-pipe,
html[data-theme="dark"] .idg-fanblade{stroke:#9CC6FF}
html[data-theme="dark"] .idg-trunk{fill:#9CC6FF;opacity:.2}
html[data-theme="dark"] .idg-fan{stroke:#9CC6FF;opacity:.45}
html[data-theme="dark"] .idg-dim text{fill:#FFAE63}
html[data-theme="dark"] .idg-dim line{stroke:#FF9A5A}
html[data-theme="dark"] .idg-call line{stroke:rgba(255,255,255,.4)}
html[data-theme="dark"] .idg-call text,
html[data-theme="dark"] .idg-side{fill:rgba(255,255,255,.72)}

/* The list rows were display:flex, so every text node between the tick and the
   <b> became its own flex item -- "Up to | 4 metres | of pipework" rendered as
   three columns. Block rows with an inline tick let the text wrap normally. */
.installpair__spec li{display:block;padding-left:2.05rem;position:relative}
.installpair__spec li .tick{position:absolute;left:.55rem;top:.5rem}

/* The diagram is drawn on a 900-unit canvas; squeezed into a 350px phone the
   labels fall below 6px. Hold a legible minimum and let the figure scroll
   sideways within itself rather than shrinking the type into illegibility. */

/* ===== Interactive install diagram =====
   Static callout labels crowded the drawing and were unreadable on a phone.
   The labels now live in a panel below, revealed on hover, focus or tap, so
   the drawing stays clean and every part gets a full sentence instead of two
   words. Keyboard-reachable; the panel is aria-live so it is announced. */
.installdiag{margin:0 0 clamp(1.8rem,4vw,2.6rem)}
.installdiag svg{width:100%;max-width:860px;height:auto;display:block;margin:0 auto}
.idg-hit{fill:transparent;stroke:none}
.idg-hot{cursor:pointer;outline:none}
.idg-hot .idg-unit,.idg-hot .idg-pipe,.idg-hot .idg-trunk,
.idg-hot .idg-drain,.idg-hot .idg-fan,.idg-hot .idg-fanblade,
.idg-hot .idg-air,.idg-hot .idg-vent,.idg-hot .idg-dim{
  transition:opacity .18s ease, stroke-width .18s ease;
}
/* dim the parts you are not looking at, rather than glowing the one you are */
.installdiag.is-picked .idg-hot{opacity:.32}
.installdiag.is-picked .idg-hot.is-on{opacity:1}
.idg-hot.is-on .idg-pipe{stroke-width:5}
.idg-hot.is-on .idg-unit{stroke-width:3.5}
.idg-hot:focus-visible .idg-hit{
  stroke:var(--orange-500,#F2790A);stroke-width:2.5;stroke-dasharray:5 4;fill:none}
.installdiag__hint{
  margin:.7rem auto 0;text-align:center;font-size:.86rem;
  color:var(--muted,#5A6579);opacity:.85}
.installdiag__panel{
  margin:.9rem auto 0;max-width:640px;
  /* embossed: a raised plate rather than a flat card — soft top highlight,
     grounded drop shadow, and the orange rule down the leading edge */
  background:linear-gradient(180deg,#FFFFFF 0%,#F7FAFD 100%);
  border:1px solid rgba(15,26,46,.10);
  border-left:3px solid var(--orange-500,#F2790A);
  border-radius:14px;
  padding:1.05rem 1.25rem;
  min-height:118px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 -1px 0 rgba(15,26,46,.05),
    0 1px 2px rgba(15,26,46,.07),
    0 6px 18px rgba(15,26,46,.10);
}
.installdiag__panel{text-align:left}
.installdiag__panel h4{
  margin:0 0 .4rem;font-family:"Montserrat","Montserrat Fallback",sans-serif;font-weight:800;
  font-size:1rem;line-height:1.3;color:var(--ink,#0F1A2E)}
.installdiag__panel p{margin:0;font-size:.95rem;line-height:1.6;color:var(--muted,#5A6579)}
@media(prefers-reduced-motion:reduce){
  .installdiag .idg-hot *{transition:none}
}
@media(max-width:700px){
  .installdiag svg{min-width:0}
  .installdiag__panel{min-height:150px}
}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .installdiag__panel{
    background:linear-gradient(180deg,#16233A 0%,#101A2C 100%);
    border-color:rgba(255,255,255,.10);
    border-left-color:#FF9A5A;
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.07),
      inset 0 -1px 0 rgba(0,0,0,.35),
      0 2px 4px rgba(0,0,0,.35),
      0 8px 22px rgba(0,0,0,.45)}
  html:not([data-theme="light"]) .installdiag__panel h4{color:#F2F6FB}
  html:not([data-theme="light"]) .installdiag__panel p,
  html:not([data-theme="light"]) .installdiag__hint{color:rgba(255,255,255,.75)}
}
html[data-theme="dark"] .installdiag__panel{
  background:linear-gradient(180deg,#16233A 0%,#101A2C 100%);
  border-color:rgba(255,255,255,.10);
  border-left-color:#FF9A5A;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),
    inset 0 -1px 0 rgba(0,0,0,.35),
    0 2px 4px rgba(0,0,0,.35),
    0 8px 22px rgba(0,0,0,.45)}
html[data-theme="dark"] .installdiag__panel h4{color:#F2F6FB}
html[data-theme="dark"] .installdiag__panel p,
html[data-theme="dark"] .installdiag__hint{color:rgba(255,255,255,.75)}

/* ===== Diagram animation =====
   Two layers, kept separate so they don't fight each other:
   1. A one-off build-in when the figure scrolls into view, animating the
      CHILDREN of each hotspot group. The hover dimming animates the GROUP's
      opacity, so the two compose instead of overriding one another.
   2. Continuous motion on the fan and airflow, which is what makes the thing
      read as a working system rather than a drawing.
   All of it is off under prefers-reduced-motion. */
/* Hidden only once the script has confirmed it is running (.js-anim). Without
   JS, or if the script throws, the diagram renders fully rather than staying
   invisible behind an animation that will never start. */
.installdiag.js-anim svg .idg-hot > *,
.installdiag.js-anim svg .idg-wall,
.installdiag.js-anim svg .idg-ground,
.installdiag.js-anim svg .idg-side{opacity:0}
.installdiag.is-ready svg .idg-hot > *,
.installdiag.is-ready svg .idg-wall,
.installdiag.is-ready svg .idg-ground,
.installdiag.is-ready svg .idg-side{
  animation:idgIn .5s ease-out forwards;
}
@keyframes idgIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* build order: structure, then indoor unit, pipe run, trunking, drain, outdoor */
.installdiag.is-ready svg .idg-ground{animation-delay:0s}
.installdiag.is-ready svg .idg-wall{animation-delay:.08s}
.installdiag.is-ready svg .idg-side{animation-delay:.16s}
.installdiag.is-ready svg .idg-hot[data-part="indoor"] > *{animation-delay:.24s}
.installdiag.is-ready svg .idg-hot[data-part="pipe"] > *{animation-delay:.42s}
.installdiag.is-ready svg .idg-hot[data-part="trunk"] > *{animation-delay:.62s}
.installdiag.is-ready svg .idg-hot[data-part="drain"] > *{animation-delay:.78s}
.installdiag.is-ready svg .idg-hot[data-part="outdoor"] > *{animation-delay:.9s}

/* the pipe draws itself along its length rather than just fading in */
.installdiag.is-ready svg .idg-pipe{
  stroke-dasharray:420;
  stroke-dashoffset:420;
  animation:idgIn .3s ease-out .42s forwards, idgDraw 1s ease-out .42s forwards;
}
@keyframes idgDraw{to{stroke-dashoffset:0}}

/* continuous: the fan turns, the air moves */
.installdiag.is-ready svg .idg-fanblade{
  transform-box:view-box;transform-origin:557px 295px;
  animation:idgIn .4s ease-out .9s forwards, idgSpin 3.2s linear 1.3s infinite;
}
@keyframes idgSpin{to{transform:rotate(360deg)}}
/* Airflow only once the system is actually running. The arcs used to puff from
   the moment the drawing built itself, which said the unit was blowing air
   before it had been mounted. They now wait for the commissioning stage and
   stay on from then, because the system has been left running. */
/* These selectors carry .idg-hot deliberately. The build-in rule
   ".installdiag.is-ready svg .idg-hot > *" runs idgIn forwards, which lands on
   opacity:1, so a plainer .idg-air selector loses the specificity fight and the
   arcs stay visible however hard you hide them. */
.installdiag.js-anim svg .idg-hot > .idg-air{animation:none;opacity:0}
.installdiag.is-ready.is-running svg .idg-hot > .idg-air{
  animation:idgIn .4s ease-out forwards, idgPuff 3s ease-in-out .9s infinite;
}
.installdiag.is-ready.is-running svg .idg-hot > .idg-air:nth-of-type(2){animation-delay:.36s,1.35s}
@media(prefers-reduced-motion:reduce){
  .installdiag.is-ready.is-running svg .idg-hot > .idg-air{opacity:.8;animation:none}
}
@keyframes idgPuff{
  0%,100%{opacity:.35;transform:translateX(0)}
  45%{opacity:.9;transform:translateX(14px)}
}
/* condensate creeping down the drain line */
.installdiag.is-ready svg .idg-drain{
  animation:idgIn .4s ease-out .78s forwards, idgDrip 4s linear 1.4s infinite;
}
@keyframes idgDrip{to{stroke-dashoffset:-44}}

@media(prefers-reduced-motion:reduce){
  /* Must match the .js-anim specificity that hides these, or the override
     loses and the diagram renders empty for anyone who reduces motion. */
  .installdiag.js-anim svg .idg-hot > *,
  .installdiag.js-anim svg .idg-wall,
  .installdiag.js-anim svg .idg-ground,
  .installdiag.js-anim svg .idg-side{opacity:1!important}
  .installdiag svg *{animation:none!important;stroke-dashoffset:0!important}
}

/* ===== Walkthrough: stages, badges, controls ===== */
.installdiag__step{
  margin:0 0 .3rem;font-family:"Montserrat","Montserrat Fallback",sans-serif;font-weight:700;
  font-size:.76rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--orange-600,#D9660A)}
.installdiag__why{
  margin:.6rem 0 0;padding-top:.6rem;border-top:1px dashed var(--line,#E2E8F1);
  font-size:.9rem;line-height:1.55;color:var(--muted,#5A6579);font-style:italic}
.installdiag__why::before{content:"Why it matters: ";font-style:normal;font-weight:700;color:var(--ink,#0F1A2E)}
.installdiag__nav{
  display:flex;align-items:center;justify-content:center;gap:.9rem;
  margin:.9rem auto 0;max-width:640px;flex-wrap:wrap}
.installdiag__btn{
  appearance:none;border:1px solid var(--line,#E2E8F1);background:var(--card,#fff);
  color:var(--ink,#0F1A2E);font-family:"Montserrat","Montserrat Fallback",sans-serif;font-weight:700;
  font-size:.88rem;padding:.55rem 1rem;border-radius:999px;cursor:pointer;
  transition:background .18s ease,border-color .18s ease,opacity .18s ease}
.installdiag__btn:hover:not(:disabled){border-color:var(--orange-500,#F2790A)}
.installdiag__btn:disabled{opacity:.4;cursor:default}
.installdiag__btn:focus-visible{outline:2px solid var(--orange-500,#F2790A);outline-offset:2px}
.installdiag__dots{display:flex;gap:.45rem}
.installdiag__dot{
  width:9px;height:9px;border-radius:50%;background:var(--line,#E2E8F1);
  cursor:pointer;transition:background .18s ease,width .18s ease}
.installdiag__dot.is-on{background:var(--orange-500,#F2790A);width:22px;border-radius:5px}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .installdiag__step{color:#FFAE63}
  html:not([data-theme="light"]) .installdiag__why{
    color:rgba(255,255,255,.72);border-top-color:rgba(255,255,255,.18)}
  html:not([data-theme="light"]) .installdiag__why::before{color:#F2F6FB}
  html:not([data-theme="light"]) .installdiag__btn{
    background:var(--surface-2,#111B2C);border-color:rgba(255,255,255,.18);color:#F2F6FB}
  html:not([data-theme="light"]) .installdiag__dot{background:rgba(255,255,255,.22)}
}
html[data-theme="dark"] .installdiag__step{color:#FFAE63}
html[data-theme="dark"] .installdiag__why{
  color:rgba(255,255,255,.72);border-top-color:rgba(255,255,255,.18)}
html[data-theme="dark"] .installdiag__why::before{color:#F2F6FB}
html[data-theme="dark"] .installdiag__btn{
  background:var(--surface-2,#111B2C);border-color:rgba(255,255,255,.18);color:#F2F6FB}
html[data-theme="dark"] .installdiag__dot{background:rgba(255,255,255,.22)}
/* ===== The installer =====
   Parked off-stage until a walkthrough stage is chosen, then walks to the part
   being described. Parts already fitted stay solid, parts still to come are
   ghosted, so the drawing reads as a job in progress. */
.idg-worker{opacity:0;transform:translate(300px,330px);transition:transform .55s cubic-bezier(.4,0,.2,1),opacity .3s ease}
.idg-worker.is-active{opacity:1}
.idg-ladder{opacity:0;transition:opacity .3s ease}
.idg-ladder line{stroke:var(--muted,#5A6579);stroke-width:3;stroke-linecap:round;opacity:.55}
.idg-worker.on-ladder .idg-ladder{opacity:1}
.idg-worker.on-ladder .idg-person{transform:translateY(-54px);transition:transform .45s ease}
.idg-person{transition:transform .45s ease}
/* the working arm keeps busy while the stage is shown */
.idg-worker.is-active .idg-arm{
  transform-box:fill-box;transform-origin:0% 100%;
  animation:idgWork 1.1s ease-in-out infinite}
@keyframes idgWork{0%,100%{transform:rotate(0deg)}50%{transform:rotate(-16deg)}}
/* build progress */
.installdiag.is-picked .idg-hot.is-done{opacity:1}
.installdiag.is-picked .idg-hot.is-pending{opacity:.12}
.installdiag.is-picked .idg-hot.is-pending @media(prefers-reduced-motion:reduce){
  .idg-worker,.idg-person,.idg-ladder{transition:none}
  .idg-worker.is-active .idg-arm{animation:none}
}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .idg-torso{fill:#4A7FD4}
  html:not([data-theme="light"]) .idg-limb{stroke:#4A7FD4}
  html:not([data-theme="light"]) .idg-head{stroke:#4A7FD4}
  html:not([data-theme="light"]) .idg-ladder line{stroke:rgba(255,255,255,.55)}
}
html[data-theme="dark"] .idg-torso{fill:#4A7FD4}
html[data-theme="dark"] .idg-limb{stroke:#4A7FD4}
html[data-theme="dark"] .idg-head{stroke:#4A7FD4}
html[data-theme="dark"] .idg-ladder line{stroke:rgba(255,255,255,.55)}

/* ===== Installer detail: kit, tools per stage ===== */
.idg-boot{fill:#1E2A3D}
.idg-leg{stroke:#2B3A52;stroke-width:9;stroke-linecap:round;fill:none}
.idg-torso{fill:var(--blue-800,#123C8F)}
.idg-vest{fill:#FFD24A;opacity:.95}
.idg-belt{fill:#5A4630}
.idg-pouch{fill:#6E573B}
.idg-limb{stroke:var(--blue-800,#123C8F);stroke-width:7;stroke-linecap:round;fill:none}
.idg-glove{fill:#E8A33D}
.idg-head{fill:#F0C39B;stroke:#D9A377;stroke-width:1.2}
.idg-ear{fill:none;stroke:#D9A377;stroke-width:1.6}
.idg-hat{fill:var(--orange-500,#F2790A)}
/* tools: only the one for the current stage is drawn */
.idg-tool{display:none;fill:#2B3A52}
.idg-bit{stroke:#8B97A8;stroke-width:3;stroke-linecap:round;fill:none}
.idg-pipecoil{fill:none;stroke:#9CC6FF;stroke-width:4;stroke-linecap:round}
.idg-jaw{fill:#2B3A52}
.idg-tool--gauge circle{fill:#fff;stroke:#2B3A52;stroke-width:3}
.idg-worker[data-tool="drill"]    .idg-tool--drill,
.idg-worker[data-tool="pipe"]     .idg-tool--pipe,
.idg-worker[data-tool="driver"]   .idg-tool--driver,
.idg-worker[data-tool="spanner"]  .idg-tool--spanner,
.idg-worker[data-tool="gauge"]    .idg-tool--gauge{display:block}
/* the whole arm works, tool included */
.idg-worker.is-active .idg-arm{
  transform-box:fill-box;transform-origin:0% 100%;
  animation:idgWork 1.1s ease-in-out infinite}
@media(prefers-reduced-motion:reduce){ .idg-worker.is-active .idg-arm{animation:none} }
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .idg-torso{fill:#2F63B8}
  html:not([data-theme="light"]) .idg-limb{stroke:#2F63B8}
  html:not([data-theme="light"]) .idg-leg{stroke:#3B4C68}
}
html[data-theme="dark"] .idg-torso{fill:#2F63B8}
html[data-theme="dark"] .idg-limb{stroke:#2F63B8}
html[data-theme="dark"] .idg-leg{stroke:#3B4C68}

/* ===== Installer detail ===== */
.idg-boot{fill:#1B2433}
.idg-leg{stroke:#2C3E5C;stroke-width:8;stroke-linecap:round;fill:none}
.idg-torso{fill:var(--blue-800,#123C8F)}
.idg-vest{fill:#FFD84D;opacity:.95}
.idg-belt{fill:#6B4A2B}
.idg-pouch{fill:#8A5F35}
.idg-glove{fill:#1B2433}
.idg-head{fill:#F0C49B;stroke:#D9A87A;stroke-width:1.2}
.idg-ear{fill:none;stroke:#D9A87A;stroke-width:1.6}
.idg-hat{fill:var(--orange-500,#F2790A)}
.idg-limb{stroke:var(--blue-800,#123C8F);stroke-width:7;stroke-linecap:round;fill:none}
/* tools: only the one for the current stage is shown */
.idg-tool{display:none;fill:#3A4657}
.idg-bit{stroke:#8E9AAC;stroke-width:3.5;stroke-linecap:round;fill:none}
.idg-pipecoil{fill:none;stroke:#9AA7B8;stroke-width:4;stroke-linecap:round}
.idg-jaw{fill:#8E9AAC}
.idg-worker[data-tool="drill"]    .idg-tool--drill,
.idg-worker[data-tool="pipe"]     .idg-tool--pipe,
.idg-worker[data-tool="driver"]   .idg-tool--driver,
.idg-worker[data-tool="spanner"]  .idg-tool--spanner,
.idg-worker[data-tool="gauge"]    .idg-tool--gauge{display:block}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .idg-torso{fill:#2E5FA8}
  html:not([data-theme="light"]) .idg-limb{stroke:#2E5FA8}
}
html[data-theme="dark"] .idg-torso{fill:#2E5FA8}
html[data-theme="dark"] .idg-limb{stroke:#2E5FA8}

/* Delta Air mark on the installer's overalls */
.idg-brandmark path{fill:url(#idgBrand)}
.idg-brandmark__notch{fill:var(--blue-800,#123C8F)!important}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .idg-brandmark__notch{fill:#2E5FA8!important}
}
html[data-theme="dark"] .idg-brandmark__notch{fill:#2E5FA8!important}

/* ===== The van =====
   Arrives from off-canvas, parks while the job runs, then drives off. The
   scene was widened to 1075 units so the van has somewhere to stand without
   sitting on top of the outdoor unit. */
.idg-van{transform:translateX(230px);opacity:0;transition:transform 1.4s cubic-bezier(.3,0,.2,1),opacity .4s ease}
.idg-van.is-here{transform:translateX(0);opacity:1}
.idg-van.is-gone{transform:translateX(230px);opacity:0}
.idg-van__shell{fill:#F4F7FB;stroke:var(--blue-800,#123C8F);stroke-width:2.5}
.idg-van__glass{fill:#CFE2F6;stroke:var(--blue-800,#123C8F);stroke-width:2}
.idg-van__stripe{fill:var(--orange-500,#F2790A);opacity:.9}
.idg-van__mark path{fill:url(#idgBrand)}
.idg-van__wheel circle{fill:#1B2433}
.idg-van__hub{fill:#8E9AAC}
@media(prefers-reduced-motion:reduce){ .idg-van{transition:none} }
/* The van keeps its livery in dark mode. It is a branded vehicle, not part of
   the page furniture, so it is the same colour whatever the theme. */
/* ===== Smooth stage changes =====
   The group opacity (which drives the done/pending dimming) had no transition,
   so parts popped between states while the installer glided. Everything that
   changes on a stage switch now eases over the same ~.5s. */
.idg-hot{transition:opacity .5s ease}
.idg-hot .idg-worker{transition:transform .8s cubic-bezier(.45,.05,.2,1),opacity .4s ease}
.idg-worker .idg-tool{transition:opacity .25s ease}
/* panel copy cross-fades rather than snapping */
.installdiag__panel{transition:opacity .22s ease}
.installdiag__panel.is-swapping{opacity:0}
@media(prefers-reduced-motion:reduce){
  .idg-hot,.idg-worker,.installdiag__panel{transition:none}
}


/* Real logo on the van, on a white decal so it reads in both colour schemes */
.idg-van__decal{fill:#fff;stroke:rgba(15,26,46,.14);stroke-width:1}

/* ===== Stage colours, taken from the logo =====
   1 dark blue · 2 light blue · 3 white · 4 orange · 5 light orange.
   One variable drives the rail thumb, the panel's leading rule and the stage
   label, so each stage reads as its own colour without repeating values. */
.installdiag[data-stage="1"]{--stage:#123C8F;--stage-ink:#FFFFFF;--stage-edge:#123C8F}
.installdiag[data-stage="2"]{--stage:#4FB2EE;--stage-ink:#0B2C6B;--stage-edge:#4FB2EE}
.installdiag[data-stage="3"]{--stage:#FFFFFF;--stage-ink:#0F1A2E;--stage-edge:#C9D6E5}
.installdiag[data-stage="4"]{--stage:#F2790A;--stage-ink:#2B1400;--stage-edge:#F2790A}
.installdiag[data-stage="5"]{--stage:#FFB877;--stage-ink:#6B3A05;--stage-edge:#FFB877}


/* the write-up plate picks up the same colour on its leading edge and label */
.installdiag__panel{
  border-left-color:var(--stage-edge,var(--orange-500,#F2790A));
  transition:opacity .22s ease, border-left-color .45s ease;
}
.installdiag__step{color:var(--stage-label,var(--orange-600,#D9660A));transition:color .45s ease}
.installdiag[data-stage="1"]{--stage-label:#123C8F}
.installdiag[data-stage="2"]{--stage-label:#1E7FC0}
.installdiag[data-stage="3"]{--stage-label:#5A6579}
.installdiag[data-stage="4"]{--stage-label:#D9660A}
.installdiag[data-stage="5"]{--stage-label:#B5702A}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .installdiag[data-stage="1"]{--stage:#2E6FD4;--stage-ink:#fff;--stage-label:#7FB0FF}
  html:not([data-theme="light"]) .installdiag[data-stage="3"]{--stage:#E8EEF6;--stage-ink:#0F1A2E;--stage-label:#C3CEDC}
  html:not([data-theme="light"]) .installdiag[data-stage="5"]{--stage-label:#FFC08A}
}
html[data-theme="dark"] .installdiag[data-stage="1"]{--stage:#2E6FD4;--stage-ink:#fff;--stage-label:#7FB0FF}
html[data-theme="dark"] .installdiag[data-stage="3"]{--stage:#E8EEF6;--stage-ink:#0F1A2E;--stage-label:#C3CEDC}
html[data-theme="dark"] .installdiag[data-stage="5"]{--stage-label:#FFC08A}

/* Stage label in the brand colours ==================================
   The label is meant to take its colour from --stage-label, but that
   declaration was not reaching the element and every stage rendered in the
   muted grey. These name the figure and the label together, so the colour is
   applied directly rather than through an inherited custom property.
   Colours are the five from the logo, darkened only where needed to clear
   4.5:1 on the card. */
.installdiag[data-stage="1"] .installdiag__step{color:#123C8F}
.installdiag[data-stage="2"] .installdiag__step{color:#1A6FA8}
.installdiag[data-stage="3"] .installdiag__step{color:#5A6579}
.installdiag[data-stage="4"] .installdiag__step{color:#A64E08}
.installdiag[data-stage="5"] .installdiag__step{color:#9C6024}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]) .installdiag[data-stage="1"] .installdiag__step{color:#7FB0FF}
  html:not([data-theme="light"]) .installdiag[data-stage="2"] .installdiag__step{color:#79C6F5}
  html:not([data-theme="light"]) .installdiag[data-stage="3"] .installdiag__step{color:#C3CEDC}
  html:not([data-theme="light"]) .installdiag[data-stage="4"] .installdiag__step{color:#FFA24D}
  html:not([data-theme="light"]) .installdiag[data-stage="5"] .installdiag__step{color:#FFC08A}
}
html[data-theme="dark"] .installdiag[data-stage="1"] .installdiag__step{color:#7FB0FF}
html[data-theme="dark"] .installdiag[data-stage="2"] .installdiag__step{color:#79C6F5}
html[data-theme="dark"] .installdiag[data-stage="3"] .installdiag__step{color:#C3CEDC}
html[data-theme="dark"] .installdiag[data-stage="4"] .installdiag__step{color:#FFA24D}
html[data-theme="dark"] .installdiag[data-stage="5"] .installdiag__step{color:#FFC08A}

/* Handover pose: the tool arm gives way to a thumbs up */
.idg-thumbsup{display:none}
.idg-worker.is-done .idg-thumbsup{display:block}
.idg-worker.is-done .idg-arm{display:none;animation:none}

/* Van scaled from its ground-right corner so the logo is legible; it still
   parks well clear of the outdoor unit. */
.idg-van{transform-box:view-box;transform-origin:1026px 322px}
.idg-van.is-here{transform:translateX(0) scale(1.3)}
.idg-van.is-gone{transform:translateX(230px) scale(1.3)}

/* Climbing into the cab: fade and shrink towards the door rather than blink out */
/* One state for "he is inside the cab", played forwards when he climbs in and
   backwards when he gets out, so arriving and leaving mirror each other.
   The .is-active on the selector is deliberate: he is active and in the cab at
   the same time, and without it the plain .is-active opacity rule wins on
   source order and he never fades. */
.idg-worker.is-invan,
.idg-worker.is-active.is-invan{
  opacity:0;
  transform-origin:center bottom;
}
.idg-worker.is-invan .idg-person{transform:translateY(6px) scale(.86)}


/* The walkthrough is a tall section already — the generic .section padding
   (54px phone / 96px desktop) left a large empty band above the heading and
   below the caveat. Duplicated inline on both pages so downloaded copies
   still render; keep the three copies in step. */
.installsection{padding:clamp(2rem,4vw,3.5rem) 0}



/* Anchor jumps landed the heading behind the sticky header + giveaway banner
   (104px on phones, 124px at desktop). Offset the scroll target so the heading
   clears the stack instead of hiding under it. */
.installsection{scroll-margin-top:120px}
@media(min-width:1024px){.installsection{scroll-margin-top:140px}}

/* Giveaway winner lightbox — opens the winner announcement photo when the
   header strip (or its button) is clicked. */
#giveawayCarousel{cursor:pointer}
.winner-lightbox{position:fixed;inset:0;z-index:9999;display:none;align-items:center;justify-content:center;padding:24px}
.winner-lightbox.is-open{display:flex}
.winner-lightbox__scrim{position:absolute;inset:0;background:rgba(6,10,26,.86)}
.winner-lightbox__box{position:relative;max-width:min(92vw,480px);width:100%}
.winner-lightbox__box img{display:block;width:100%;height:auto;max-height:88vh;object-fit:contain;border-radius:18px;box-shadow:0 30px 80px rgba(0,0,0,.6)}
.winner-lightbox__close{position:absolute;top:-14px;right:-14px;width:40px;height:40px;border-radius:50%;border:2px solid #fff;background:#0B2466;color:#fff;font-size:22px;line-height:1;cursor:pointer;box-shadow:0 6px 16px rgba(0,0,0,.4)}
.winner-lightbox__close:hover{background:#123C8F}

/* Desktop menu: logo on the left, "Get a free quote" on the right, and the menu links centred
   between them (on the middle of the screen) */
@media (min-width:1120px){
  html body .header .header__bar{display:grid!important;grid-template-columns:1fr auto 1fr;column-gap:1.4rem}
  html body .header .header__bar > .brand{justify-self:start}
  html body .header .header__bar > .nav{margin-left:0!important;margin-right:0!important;justify-self:center}
  html body .header .header__bar > .header__cta{justify-self:end;margin-left:0!important}
}
/* Solutions sits level with the other menu links (owner, 19 Oct 2026): its 2px hover underline is a bottom border
   the plain links do not have, which centred its text 1px higher; a matching clear top border evens it out. */
@media(min-width:1120px){html body .header .nav .nav__drop-btn{border-top:2px solid transparent;padding-top:calc(.3rem - 1px);padding-bottom:calc(.3rem - 1px)}}
