/* Raydn DNA layer, svc661.
   One design system across all 97 indexed pages.
   Structure comes from the company-first homepage: left aligned, roman serif display,
   one primary action, generous rhythm, boxed icon chips, lifting cards.
   Colour comes from the approved brand palette, which the homepage had drifted off.
   Loaded last on every page. Amber #f5a524. No red. */

:root{
  /* one canonical set, every legacy prefix points here */
  --rr-navy:#081127;
  --rr-navy-2:#0d1b2e;
  --rr-card:#121b2c;
  --rr-card-2:#0f1727;
  --rr-line:#26364f;
  --rr-line-2:#33456180;
  --rr-amber:#f5a524;
  --rr-amber-hi:#f7b23a;
  --rr-amber-ink:#f0a300;
  --rr-ink:#f4f6fb;
  --rr-ink-2:#c7d0dd;
  --rr-ink-3:#8a94a6;
  --rr-on-amber:#111f30;

  --rr-serif:"Source Serif Pro",Georgia,"Times New Roman",serif;
  --rr-sans:"Satoshi",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;

  --rr-r:14px;      /* cards */
  --rr-r-btn:6px;   /* actions */
  --rr-r-chip:10px; /* icon chips */
  --rr-pad-sec:88px;
  --rr-wrap:1180px;
}

/* ---- 1. one body typeface, no Inter and no Arial leak ---- */
body,input,select,textarea,button{font-family:var(--rr-sans)}

/* ---- 2. roman serif display, one scale, one tracking ---- */
h1,h2,
.section-title,
[class*="hero"] h1,[class*="hero"] h2,
[class*="__title"]:is(h1,h2),
.cc__hero-title,.ledc__h1,.asv-h1,.asv-h2{
  font-family:var(--rr-serif);
  font-weight:500;
  font-style:normal;
  letter-spacing:-.035em;
  line-height:1.1;
  text-wrap:balance;
  color:var(--rr-ink);
}
h1,[class*="hero"] h1,.cc__hero-title,.asv-h1{font-size:clamp(36px,5.2vw,48px)}
h2,.section-title,.asv-h2{font-size:clamp(28px,3.4vw,48px)}

/* amber emphasis inside a headline stays amber, stops being italic */
h1 i,h2 i,h1 em,h2 em,.asv-h1 i,.section-title i,
h1 span[class*="amber"],h2 span[class*="amber"]{
  font-style:normal;color:var(--rr-amber-ink);font-weight:inherit;
}

/* section headings in dense UI stay sans: footers, nav, small cards */
footer h2,footer h3,nav h2,nav h3,
.footer__col-title,.rr-accordion__title,.flag-card__title,
.fee-block__title,.step-flow__title,.services-range-item__title,
.town-lead-card__title,.mobile-cta-bar *{
  font-family:var(--rr-sans);letter-spacing:normal;
}

/* ---- 3. body copy, one size and one measure ---- */
p,li{color:var(--rr-ink-2)}
main p:not([class*="note"]):not([class*="fine"]):not([class*="legal"]){
  font-size:18px;line-height:1.65;
}
main p:not([class]){max-width:56ch}
[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"]){
  font-size:18px;line-height:1.55;color:var(--rr-ink);max-width:48ch;
}

/* ---- 4. eyebrows, one treatment ---- */
[class*="eyebrow"]{
  font-family:var(--rr-sans);font-size:16px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--rr-amber-hi);
  margin:0 0 16px;
}

/* ---- 5. heroes left aligned, like the homepage ---- */
[class*="hero"]:not([class*="rh-"]){text-align:left}
.cc__hero-inner,.hero__inner,.rdn-hero__inner,.town-hero__inner,
.asv-hero,.ledc__hero,[class*="hero__content"]{
  text-align:left;margin-inline:0 auto;
}
[class*="hero"] h1{max-width:20ch}
[class*="hero"] [class*="lede"],[class*="hero"] [class*="__sub"]:not([class*="__submit"]),
[class*="hero"] [class*="intro"]{max-width:46ch;margin-inline:0}
[class*="hero"] [class*="chips"],[class*="hero"] [class*="__ctas"],
[class*="hero"] [class*="actions"]{justify-content:flex-start}

/* ---- 6. one action shape ---- */
.btn,.ledc__btn,.cc__hero-btn,[class*="__submit"],
[class*="-btn"]:not([class*="mobile-cta"]):not([class*="rh-dot"]){
  border-radius:var(--rr-r-btn);
  min-height:52px;
  font-family:var(--rr-sans);
  font-weight:750;
  letter-spacing:-.005em;
  transition:transform .18s ease,background-color .18s ease,border-color .18s ease;
}
.btn--primary,.btn--lg,.ledc__btn:not(.ledc__btn--ghost),.cc__hero-btn{
  background:var(--rr-amber);color:var(--rr-on-amber);border:1px solid var(--rr-amber);
}
.btn--primary:hover,.btn--lg:hover,.cc__hero-btn:hover{
  background:var(--rr-amber-hi);transform:translateY(-1px);
}
.btn--ghost,.ledc__btn--ghost{
  background:transparent;color:var(--rr-ink);border:1px solid var(--rr-line);
}
.btn--ghost:hover,.ledc__btn--ghost:hover{border-color:var(--rr-amber);color:var(--rr-ink)}

/* ---- 7. one card shape, and the homepage lift ---- */
[class*="card"]:not([class*="__title"]):not([class*="__sub"]):not([class*="text"]),
.flag-card,.fee-block,.town-lead-card,.services-range-item,.asv-card{
  border-radius:var(--rr-r);
}
.flag-card,.services-range-item,.town-lead-card,[class*="-card"]:not(a):not([class*="__"]){
  transition:border-color .2s ease,transform .2s ease;
}
a:hover>.flag-card,a:hover>.services-range-item,
.flag-card:hover,.services-range-item:hover{
  border-color:var(--rr-amber);transform:translateY(-3px);
}

/* ---- 8. boxed amber icon chips, the homepage signature ---- */
[class*="icon-chip"],[class*="__icon"]:has(svg),.rh-lane .rh-icon{
  border-radius:var(--rr-r-chip);
}

/* ---- 9. one focus ring ---- */
a:focus-visible,button:focus-visible,summary:focus-visible,
input:focus-visible,select:focus-visible,textarea:focus-visible,
[tabindex]:focus-visible{
  outline:3px solid var(--rr-amber);outline-offset:4px;border-radius:2px;
}

/* ---- 10. section rhythm ---- */
main>section,main>div>section{scroll-margin-top:96px}

/* ---- 11. reveal on scroll, opt in only once JS confirms support ---- */
html.rr-dna-js .rr-reveal{opacity:0;transform:translateY(14px)}
html.rr-dna-js .rr-reveal.rr-in{
  opacity:1;transform:none;
  transition:opacity .55s cubic-bezier(.22,.61,.36,1),transform .55s cubic-bezier(.22,.61,.36,1);
}
@media(prefers-reduced-motion:reduce){
  html.rr-dna-js .rr-reveal{opacity:1;transform:none;transition:none}
  .btn,[class*="-card"]{transition:none!important}
}

/* ---- 12. thin amber read progress, top of every page ---- */
.rr-progress{
  position:fixed;top:0;left:0;height:2px;width:0;z-index:2147483000;
  background:linear-gradient(90deg,var(--rr-amber-ink),var(--rr-amber-hi));
  pointer-events:none;will-change:width;
}
@media(prefers-reduced-motion:reduce){.rr-progress{display:none}}

/* ---- 13. homepage back onto the approved palette ---- */
#page-home .rh-home{background:var(--rr-navy);font-family:var(--rr-sans)}
#page-home .rh-home h1,#page-home .rh-home h2,#page-home .rh-home h3{color:var(--rr-ink)}
#page-home .rh-home p,#page-home .rh-hero-owner span span{color:var(--rr-ink-2)}
#page-home .rh-home .rh-intro{color:var(--rr-ink)}
#page-home .rh-home .rh-eyebrow,#page-home .rh-menu-label,
#page-home .rh-menu-inner>a b,#page-home .rh-menu-inner>a svg,
#page-home .rh-expand,#page-home .rh-menu-inner .rh-menu-contact{color:var(--rr-amber-hi)}
#page-home .rh-home .rh-button{
  background:var(--rr-amber);color:var(--rr-on-amber);border-radius:var(--rr-r-btn);
}
#page-home .rh-home .rh-button:hover{background:var(--rr-amber-hi);transform:translateY(-1px)}
#page-home .rh-home .rh-link,#page-home .rh-proof-links small,
#page-home .rh-gallery-side a{color:var(--rr-amber-hi)}
#page-home .rh-lane{background:var(--rr-card);border-color:var(--rr-line);border-radius:var(--rr-r)}
#page-home .rh-lane:hover{border-color:var(--rr-amber)}
#page-home .rh-lane-photo:after{background:linear-gradient(transparent,var(--rr-card))}
#page-home .rh-lane .rh-icon{border-color:#8a6a2e;background:var(--rr-card-2);border-radius:var(--rr-r-chip)}
#page-home .rh-home .rh-about,#page-home .rh-home .rh-next{background:var(--rr-navy-2);border-color:var(--rr-line)}
#page-home .rh-job-links a{background:var(--rr-card);border-radius:var(--rr-r-btn)}
#page-home .rh-menu-inner>a svg{border-color:#6b5730;background:var(--rr-card)}
#page-home #nav-mobile.rh-menu{background:var(--rr-navy)}
#page-home .rh-hero:after{
  background:linear-gradient(90deg,rgba(8,17,39,.94),rgba(8,17,39,.63) 50%,rgba(8,17,39,.08)),
             linear-gradient(0deg,var(--rr-navy),transparent 35%);
}
#page-home .rh-home a:focus-visible,#page-home .rh-home button:focus-visible,
#page-home .rh-home summary:focus-visible,#page-home .rh-home input:focus-visible{
  outline-color:var(--rr-amber);
}
#page-home .is-carousel .rh-lane.is-current{border-color:var(--rr-amber)}
#page-home .rh-dot[aria-current=true]:before{background:var(--rr-amber)}
#page-home .rh-compare-control input{accent-color:var(--rr-amber)}
#page-home .rh-hero-owner img{border-color:var(--rr-amber)}
@media(max-width:600px){
  #page-home .rh-hero:after{
    background:linear-gradient(0deg,var(--rr-navy) 1%,rgba(8,17,39,.91) 35%,rgba(8,17,39,.58) 70%,rgba(8,17,39,.12));
  }
}

/* ---------------------------------------------------------------------------
   14. ONE MENU, EVERY PAGE. Unscoped from the homepage, on the approved
   palette. Replaces the tabbed interior mega menu.
   --------------------------------------------------------------------------- */
#nav-mobile.rh-menu{
  position:fixed!important;
  top:var(--rr-nav-h,65px)!important;left:0!important;right:0!important;bottom:0!important;
  z-index:190!important;
  background:var(--rr-navy,#081127)!important;
  overflow-y:auto!important;-webkit-overflow-scrolling:touch;
  padding-top:0!important;
  border-top:1px solid var(--rr-line,#26364f);
}
#nav-mobile.rh-menu{display:none!important}
#nav-mobile.rh-menu.open,#nav-mobile.rh-menu.is-open{display:block!important}
#nav-mobile .rh-menu-inner{
  padding:8px 24px calc(64px + env(safe-area-inset-bottom,0px));
  max-width:600px;margin:0 auto;
}
#nav-mobile .rh-menu-label{
  font-family:'Satoshi',system-ui,sans-serif;
  font-size:16px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--rr-amber,#f5a524);
  margin:32px 0 4px;padding-bottom:0;
}
#nav-mobile .rh-menu-label:first-child{margin-top:16px}
#nav-mobile .rh-menu-inner>a{
  display:flex;align-items:center;gap:16px;
  padding:16px 0;min-height:44px;
  color:var(--rr-ink,#f4f6fb);text-decoration:none;
  font-family:'Satoshi',system-ui,sans-serif;
  font-size:18px;font-weight:650;line-height:1.3;
  border-bottom:1px solid var(--rr-line,#26364f);
  transition:color .18s ease;
}
#nav-mobile .rh-menu-inner>a small{
  display:block;font-size:16px;font-weight:450;line-height:1.45;
  color:var(--rr-ink-3,#8a94a6);margin-top:4px;
}
#nav-mobile .rh-menu-inner>a svg{
  width:20px;height:20px;flex-shrink:0;
  color:var(--rr-amber,#f5a524);
  padding:12px;box-sizing:content-box;
  border:1px solid rgba(245,165,36,.28);border-radius:10px;
  background:var(--rr-card,#121b2c);
}
#nav-mobile .rh-menu-inner>a b{
  margin-left:auto;color:var(--rr-amber,#f5a524);
  font-weight:400;font-size:18px;line-height:1;
}
#nav-mobile .rh-menu-inner>a:hover,#nav-mobile .rh-menu-inner>a:focus-visible{color:var(--rr-amber,#f5a524)}
#nav-mobile .rh-menu-secondary{
  display:grid;grid-template-columns:1fr 1fr;gap:0 20px;
  padding-top:4px;border-bottom:0;
}#nav-mobile .rh-menu-secondary:where(:not(.rv-senior,.rv-senior *)){gap:0 16px}
#nav-mobile .rh-menu-secondary a{
  display:flex;align-items:center;min-height:46px;
  padding:6px 0;border-bottom:1px solid var(--rr-line,#26364f);
  color:var(--rr-ink-2,#c7d0dd);text-decoration:none;
  font-family:'Satoshi',system-ui,sans-serif;
  font-size:16px;font-weight:550;line-height:1.3;
}#nav-mobile .rh-menu-secondary a:where(:not(.rv-senior,.rv-senior *)){padding:8px 0}
#nav-mobile .rh-menu-secondary a:hover{color:var(--rr-amber,#f5a524)}
#nav-mobile a.rh-menu-contact{
  display:flex;align-items:center;justify-content:center;
  margin-top:32px;min-height:52px;border-radius:6px;
  background:var(--rr-amber,#f5a524);color:var(--rr-on-amber,#111f30)!important;
  font-family:'Satoshi',system-ui,sans-serif;
  font-size:18px;font-weight:750;letter-spacing:-.01em;
  text-decoration:none;border-bottom:0;
}
#nav-mobile a.rh-menu-contact svg{display:none}
@media(min-width:900px){#nav-mobile .rh-menu-secondary{grid-template-columns:1fr 1fr 1fr}}

/* 15. De-italicise the amber emphasis inside display headings. Beats
      .rdn-hero__title em and friends. */
#nav-mobile .rh-menu-label,
[class*="hero"] h1 em,[class*="hero"] h1 i,[class*="hero"] h2 em,
[class*="Hero"] h1 em,h1[class] em,h1[class] i,h2[class] em,h2[class] i,
.section-title em,.section-title i{font-style:normal!important}

/* ---------------------------------------------------------------------------
   16. ONE RADIUS SCALE. Five values sitewide: 6 actions, 10 icon chips,
   14 cards, 50% circles, 9999px pills. Kills the 8, 12 and 16 strays.
   --------------------------------------------------------------------------- */
:root{--rr-r-action:6px;--rr-r-chip:10px;--rr-r-card:14px;--rr-r-pill:9999px}
.card,.flag-card,[class*="__card"],[class*="-card"]:not([class*="pill"]),
.panel,[class*="__panel"],.tile,[class*="__tile"],
[class*="__box"],[class*="__quote"],[class*="__note"],[class*="__callout"]{
  border-radius:var(--rr-r-card)!important;
}
.btn,button.btn,a.btn,input[type=submit],
[class*="__btn"],[class*="-btn"]{border-radius:var(--rr-r-action)!important}
.btn--pill,[class*="pill"],[class*="chip"]:not([class*="icon"]){border-radius:var(--rr-r-pill)!important}
[class*="icon-box"],[class*="__icon"],[class*="-icon"]{border-radius:var(--rr-r-chip)!important}
[class*="avatar"],[class*="__dot"],[class*="-dot"]{border-radius:50%!important}
input:not([type=submit]):not([type=checkbox]):not([type=radio]),select,textarea{
  border-radius:var(--rr-r-action)!important;
}

/* ---------------------------------------------------------------------------
   17. STRAY MOP UP. Counted holdouts after pass 2.
   --------------------------------------------------------------------------- */
[class*="rdncta"],[class*="rdncta"] p,[class*="rdncta"] a,
[class*="rdncta"] span,[class*="rdncta"] small,[class*="rdncta"] strong{
  font-family:'Satoshi',system-ui,-apple-system,sans-serif!important;
}
.rdncta--boxed,.rdncta{border-radius:var(--rr-r-card,14px)!important}
.nav__logo-img{border-radius:var(--rr-r-action,6px)!important}
.nav__dropdown-trigger,.nav__dd-all{border-radius:var(--rr-r-action,6px)!important}
.nav__dd a,.nav__dropdown a,[class*="nav__dd"] a{border-radius:var(--rr-r-action,6px)!important}

/* ---------------------------------------------------------------------------
   18. HERO LEFT EDGE. The centred heroes left auto side margins on their
   eyebrows and body copy, so children landed on two different left edges
   once the hero went left aligned. One edge now.
   --------------------------------------------------------------------------- */
[class*="hero"] [class*="__eyebrow"],[class*="hero"] [class*="-eyebrow"],
[class*="hero"] > p,[class*="hero"] [class*="__sub"]:not([class*="__submit"]),[class*="hero"] [class*="__lede"],
[class*="hero"] [class*="__inner"] > p,[class*="hero"] [class*="__copy"],
[class*="hero"] h1,[class*="hero"] h2,
[class*="hero"] [class*="__chips"],[class*="hero"] [class*="__actions"],
[class*="hero"] [class*="__cta"],[class*="hero"] [class*="__trust"]{
  margin-left:0!important;margin-right:auto!important;
}

/* 18b. price and proof cards inside a left aligned hero follow the same edge */
[class*="hero"] .res-price,[class*="hero"] [class*="__price"],
[class*="hero"] [class*="__proof"]{margin-left:0!important;margin-right:auto!important}
[class*="hero"] .res-price,[class*="hero"] .res-price *{text-align:left!important}

/* ---------------------------------------------------------------------------
   19. accessibility gate, svc661b. one action colour, one target floor.
   The submit buttons were inheriting lede ink off the [class*="__sub"] match,
   which put off white on amber at 1.88. Amber always carries navy text.
   --------------------------------------------------------------------------- */
[class*="__submit"]{color:var(--rr-on-amber,#081127)}

/* every inline link that is a real action clears the 24px target floor */
a[href^="tel:"],a[href^="mailto:"],a.rdn-cite,
a[href*="maps.app.goo.gl"],a[href*="google.com/maps"]{
  display:inline-block!important;min-height:24px;line-height:24px;
}

/* economics readout captions sat between 4.04 and 4.48 on the dark cards.
   One step lighter on the same neutral clears AA on every one of them. */
.eos-src,.eos-src a,
.eos-out__k,.eos-out__s,.eos-rate__k,.eos-rate__s,
.eos-note,.eos-field__hint{color:#a7b1c2}

/* the meter label is navy by design so it reads on the amber fill, but at 0%
   there is no fill and it sat on the dark track at 1.37. Its own chip fixes
   both states. */
.eos-meter__txt{
  color:#f4f6fb;background:rgba(8,17,39,.86);
  padding:0 8px;border-radius:999px;
}

/* ---------------------------------------------------------------------------
   20. light surfaces, svc661b. Two blocks carried dark theme ink onto a white
   card. Verified with axe core: 1.08 and 1.55 against #ffffff.
   --------------------------------------------------------------------------- */
.rr-billproof__inner .rr-billproof__title{color:var(--rr-navy,#0d1b2e)}
body.rdn-light aside.sources,body.rdn-light aside.sources p{color:#4a5463}

/* ---------------------------------------------------------------------------
   21. inline links inside body text carry an underline, not colour alone.
   WCAG 1.4.1. Buttons, chips and nav keep their own treatment.
   --------------------------------------------------------------------------- */
main p > a:not([class*="btn"]):not([class*="chip"]):not([class*="cta"]),
main li > a:not([class*="btn"]):not([class*="chip"]):not([class*="cta"]):not([class*="nav"]),
main dd > a:not([class*="btn"]){text-decoration:underline;text-underline-offset:2px}

/* ---------------------------------------------------------------------------
   svc662. Hero proof line and service area line.
   Two facts the audit found missing from the first screen: the counted Google
   rating (74 reviews, read from Google's own API) and the towns Raydn covers.
   Wording of the area line is copied from the footer so the site says one
   thing in both places. Sizes are 15px and 14px, not 13px, so this does not
   add to the small caption problem the typography pass is closing.
   --------------------------------------------------------------------------- */
#page-home .rh-home .rh-proof,
.rh-proof{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;
  margin:24px 0 0;font-weight:600;color:#ecf0f3}
/* phone-paths-svc655.css sets #page-home #main-content.rh-home p to 18px with
   !important, which would make this proof line the same size as the intro above
   it and flatten the hierarchy. Matched at equal specificity, one step smaller. */
#page-home #main-content.rh-home p.rh-proof{font-size:16px!important;line-height:1.4!important}
#page-home #main-content.rh-home p.rh-area{font-size:16px!important;line-height:1.5!important}
.rh-proof__stars{color:#f7b23a;letter-spacing:1px;font-size:16px}
.rh-proof__link{display:inline-flex;align-items:center;gap:.3rem;min-height:24px;
  color:inherit;text-decoration:underline;text-decoration-color:rgba(247,178,58,.6);
  text-decoration-thickness:1px;text-underline-offset:4px}.rh-proof__link:where(:not(.rv-senior,.rv-senior *)){gap:4px}
.rh-proof__link strong{color:#fff;font-weight:800}
.rh-proof__link:hover,.rh-proof__link:focus-visible{text-decoration-color:#f7b23a;
  text-decoration-thickness:2px}

#page-home .rh-home .rh-area,
.rh-area{margin:12px 0 0;font-size:16px;font-weight:500;
  line-height:1.5;color:#c7d0dd;max-width:46ch}
.rh-area--inline{color:#8a94a6}
.cc-trust-strip__area{font-weight:500!important;color:#c7d0dd!important}
/* Pinned: interior pages have several !important 16px and 17px caption rules,
   and the area line was landing at 17px, one step ABOVE the 16px lede it sits
   under. Doubled class beats them without an id. */
p.rh-area.rh-area{font-size:16px!important;line-height:1.5!important}
p.rh-proof.rh-proof{font-size:16px!important;line-height:1.4!important}

/* ---------------------------------------------------------------------------
   svc662. Phone edge padding for content sitting directly inside
   .ledc__section. That class carries padding-block only, no padding-inline,
   so any text placed as a direct child renders hard against the phone edge.
   Counted: 16 pages use .ledc__section, 13 place their content inside a
   wrapper and are unaffected. 3 do not: small-jobs (16 flush elements, the
   whole page), electrical-repairs-edmonton (1) and electrical-services (1).
   Scoped to the direct children on purpose. Padding the section itself would
   double up on the wrappers in the other 13 and narrow the LED cluster.
   Every selector gets the SAME padding so the left edge stays one line.
   --------------------------------------------------------------------------- */
.ledc__section > h1,.ledc__section > h2,.ledc__section > h3,
.ledc__section > p,.ledc__section > ul,.ledc__section > ol,
.ledc__section > dl,.ledc__section > figure{padding-inline:clamp(1rem,5vw,3rem)}
/* Unclassed prose has no max-width of its own and would run the full 1280. */
.ledc__section > p:not([class]),.ledc__section > ul:not([class]),
.ledc__section > ol:not([class]){max-width:76ch}
/* The eyebrow carries its own padding declaration, so it needs the same
   specificity trick or it stays alone against the phone edge. */
.ledc__section > p.hero__eyebrow.hero__eyebrow{padding-inline:clamp(1rem,5vw,3rem)}
/* .town-lead-form__minutes is centred, which is right inside a centred form
   card and wrong in a left aligned hero. Scoped so the town page forms keep
   their centring. */
.ledc__section > p.town-lead-form__minutes{text-align:left}

/* ---------------------------------------------------------------------------
   svc663. Smallest rendered text. The audit recorded "13px captions on 9 of
   10 pages" and that description was wrong: the 13px text was not captions at
   all. Counted by walking text nodes at 390px across 10 pages, every node
   under 13.6px was one of three things. 36 of them, 4 per page on 9 pages,
   were .rh-menu-label, the amber uppercase section headings inside the mobile
   menu (Find your service, More services, Work out your numbers, Raydn). The
   homepage already rendered them at 16px because phone-paths-svc655.css pins
   them with !important, so the same label was 16px on one page and 13px on the
   other 9. That inconsistency was the real defect. Now 15px everywhere.
   The homepage rule carries !important at 1 id plus 1 class, so it needs 2 ids
   plus 1 class to beat it.
   --------------------------------------------------------------------------- */
#page-home #nav-mobile .rh-menu-label{font-size:16px!important;line-height:1.4!important}
/* A currency symbol at 10.2px beside a large figure. 13px still reads as a
   prefix without competing with the number. */
.rdn-result__unit{font-size:16px}

/* ---------------------------------------------------------------------------
   svc663. MEASURE. The rubric wants 45 to 75 characters per line and puts an
   explicit ceiling at 85. Measured at 1280 with a canvas text metric, not
   estimated: .rh-note on index ran 128 characters on an 825px box, and
   unclassed prose ran 85 to 96 characters on 616 and 672px boxes, worst case
   27 nodes on economics-of-solar at 94.
   The cause is the ch unit. ch is the width of the "0" glyph, and Satoshi's
   zero is much wider than its average lowercase letter, so a max-width set in
   ch renders roughly 1.35x the characters it says. 30em measures 71 to 73 real
   characters at both 16px and 17px, which lands inside the range.
   Phone is unaffected: at 390px the prose box is already about 350px, well
   under the cap, so this only changes desktop.
   --------------------------------------------------------------------------- */
#main-content p:not([class]),
#main-content li:not([class]),
#main-content dd:not([class]){max-width:30em}
.rh-note{max-width:30em}
/* The three stragglers, each a different cause, measured not guessed.
   1. .rh-note kept 825px because a higher specificity rule sets it. Needs the
      doubled class to win without an id.
   2. The .rr-svc-invite lede carries style="max-width:40rem" INLINE in the
      markup on solar and residential-electrical, and an inline declaration
      beats every stylesheet, so this is the one place !important is the correct
      tool rather than a shortcut. 40rem is 640px and rendered 89 characters.
   3. Some pages have <main> with no #main-content id, so the rule above missed
      their unclassed prose. Covered by element selector here. */
.rh-note.rh-note{max-width:30em}
.rr-svc-invite p{max-width:30em!important}
main p:not([class]),main li:not([class]),main dd:not([class]){max-width:30em}
/* The winner was #page-home .rh-home .rh-note{max-width:75ch} in
   company-home-svc652.css, 1 id + 2 classes, which my doubled class could not
   beat. Worth recording WHY it was wrong: whoever wrote 75ch meant 75
   characters. It renders 128. That is the whole ch-unit trap in one
   declaration. Same specificity, later sheet, so this wins on cascade order. */
#page-home .rh-home .rh-note{max-width:30em}
/* svc663 HEADER HEIGHT. my-own-bill.html rendered a 75px mobile header where the
   other 94 pages render 65px, because that page loads bundle-ab177b3065.css in
   slot 1 instead of raydn.css, so a different .header rule wins the cascade.
   Root cause is the CSS delivery split (79 distinct bundle filenames sitewide,
   every sheet linked twice). That is a real structural problem and it is NOT
   fixed here. This only normalises the symptom: the logo rendered 42x42 there
   and 40x40 everywhere else, which pushed the nav 10px taller. */
@media (max-width:720px){
  /* !important because the winning declaration lives in a per page bundle that
     outranks this sheet on my-own-bill and privacy. Same situation as the
     inline max-width earlier: the competing rule cannot be reached by
     specificity from a sheet loaded last, so this is the correct tool. */
  header#site-header .nav__logo-img{width:40px!important;height:40px!important}
}
/* The last straggler, scoped. my-own-bill (body.mob-page) let .nav__actions
   (57px) drive its nav to 74px and its header to 75px, where the other 94 pages
   render 65px. A first attempt set .nav height sitewide and moved all 95 pages
   from 65px to 57px, because the nav is border-box so the 8px padding sits
   inside the declared height. Reverted. This targets only the page that is
   wrong, and sets the nav to the 64px the majority actually computes. */
@media (max-width:720px){
  body.mob-page header#site-header .nav{height:64px}
}
/* svc663 HOMEPAGE LOGO TAGLINE. Giving index.html the canonical header exposed a
   truncation: i.nav__logo-slogan-txt needs 174px and was allotted 150px, so the
   tagline rendered "Electrical, solar a..." with an ellipsis. Cause is index's
   own CTA label, "Send a work request", which is about 24px wider than the
   "See my payback" label the other 88 pages carry. The CTA is his copy and his
   call, so the logo is told to hold its width and the nav link row absorbs the
   24px instead. */
#page-home header#site-header .nav__logo{flex:0 0 auto!important}
#page-home header#site-header .nav__logo-slogan-txt{max-width:none;overflow:visible}
/* svc663 CONTRAST, real WCAG failures found by axe core 4.10.2 on pages that
   were NOT in the earlier 10 page audit sample. All five are pre existing and
   none were caused by this pass. They are gate G4 failures, so the earlier
   claim that no gate was binding rested on a sample that missed them.

   my-own-bill.html: .receipt and .honesty are deliberately light sections,
   background #fafafa and #ffffff, section colour navy, with 40 and 35 navy
   children each. Four elements were left off white #f4f6fb, giving 1.03 and
   1.08 contrast, which is invisible text, not merely low contrast. They are
   strays against their own siblings, so they are corrected to the navy their
   section already uses rather than darkening the section. */
.receipt .receipt__title,
.receipt .receipt__lede,
.honesty .honesty__h,
.honesty .honesty__intro{color:#0d1b2e}
/* The amber emphasis word in .honesty__h measured 2.11 on white. Large bold
   text still needs 3:1, and no amber in the brand set reaches that on white
   without going brown, so the emphasis is carried by the existing italic and
   the colour matches the heading. Amber stays the accent on dark backgrounds. */
.honesty .honesty__h em{color:#0d1b2e}
/* panel-upgrade-edmonton.html: off white on amber at 1.88. This is the same
   shape as the logged ONE LESSON, white on the amber fill. Navy on #f5a524
   measures about 8.5:1. */
.rr-testimonials__quote-cta__sub{color:#0d1b2e!important}
/* #8a94a6 on #2d2e2d measured 4.45 where normal text needs 4.5. A genuine near
   miss rather than a design error. Moved to the palette grey that clears it. */
.rdx-out__k,.rdx-out__note{color:#c7d0dd}

/* svc663 CONTRAST, the 21 real failures. Method note, because the first count
   here was wrong and the correction matters more than the fix. An axe core run
   across all 96 pages at 390 and 1280 reported 242 failing nodes on 26 pages.
   Re running it after scrolling every page to fire the scroll reveals, and then
   forcing any element still under opacity 1 to opaque, dropped that to 21 real
   nodes on 6 pages. The other 113 at 390 were reveal wrappers sitting at
   opacity 0 when axe sampled them, so axe blended the text into its own
   background and reported 1.01. Correct count, wrong interpretation. Only the
   21 below are defects.

   Root cause of 16 of the 21: commercial-solar-calculator.html and
   gallery.html carry body.rdn-light, the light theme, but several elements kept
   the dark theme off white, giving 1.01 and 1.08 on white, which is invisible
   text rather than low contrast. Fixed at the theme so any future light page
   inherits it. */
body.rdn-light .lead-card__title,
body.rdn-light .lead-card__sub,
body.rdn-light .section__title,
body.rdn-light .section-title{color:#0d1b2e!important}
body.rdn-light .sources p,
body.rdn-light .sources p strong{color:#4a5161!important}
/* Amber on white measures 1.84 at eyebrow size. No amber in the brand set
   reaches 4.5:1 on white without turning brown, so on light sections the
   eyebrow carries its hierarchy through uppercase, tracking and weight instead
   of colour. Amber stays the accent on navy, where it is compliant. */
body.rdn-light .section__eyebrow{color:#0d1b2e!important}
/* Page specific class, exists only on ev-calculator.html. */
.evx-edu__h{color:#0d1b2e!important}
/* Grey on dark panels measured 4.09 and 4.15 where normal text needs 4.5.
   Genuine near misses. Moved to the palette grey that clears them. */
.rdx-cap,.rdx-out__k,.rdx-out__note{color:#c7d0dd!important}
/* our-mission.html only: the phone button rendered navy text on a navy panel
   at 1.1. Everywhere else this button sits on amber, where navy is correct, so
   this is scoped to the page rather than changed sitewide. */
body.pg-mission .btn--phone{color:#f4f6fb!important}

/* svc663 the two real findings from the definitive sweep. Method matters here.
   The same axe core run gave three different answers depending on how the page
   was prepared. 242 nodes on a plain load, because scroll reveal wrappers sit at
   opacity 0 and axe blends the text into its own background and reports 1.01.
   21 nodes after scrolling to fire the reveals, which still missed wrappers
   whose observer never triggered. A different 11 when visibility was also
   forced, because that un hid the mega menu and the footer band and invented
   failures that no visitor can see. The admissible preparation suppresses
   animation and opacity only, and leaves visibility alone. On that basis, all 96
   pages at 390 and 1280 produce exactly one contrast failure and ten list
   semantics failures, both below.

   gallery.html is a body.rdn-light page, so the footer contact band renders on
   white while this span kept the off white used on the dark footer. 1.55. */
/* First attempt set this span to a dark grey, which cleared the white case and
   broke the dark one, because the band is dark at 390 and loses its background
   at 1280 on light theme pages, where it then falls through to the white body.
   No single colour clears 4.5:1 against both white and near black. The band was
   always meant to be dark, so the background is restored at every width on light
   theme pages and the text goes back to off white. */
body.rdn-light .footer-contact-band{background:#0a1624!important}
body.rdn-light .footer-contact-band__or span{color:#c7d0dd!important}

/* BLOCK 10, svc666. The menu button was off screen on every phone.
   .nav is a nowrap flex row and every child was a fixed width: logo block 203px,
   phone pill 156px, burger 44px, plus two 8px gaps. That is 419px of content in
   the 351px available at 390, so the last child, the burger, was pushed out and
   clipped by the nav's own overflow rule. Measured, not guessed: #nav-burger sat
   at x 446 to 490 at 390 and x 441 to 485 at 360.
   The fix takes the 147px wordmark out of the flow below 768px. The logo mark still
   links home and still carries the accessible name, because the text is moved off
   screen the screen reader way rather than hidden with display none. Full phone
   number and the menu button both stay. New arithmetic at 360: 56 + 8 + 148 + 8 + 44
   = 264 in 324 available. */
@media (max-width:767px){
  .nav__logo-text{
    position:absolute!important;width:1px!important;height:1px!important;
    padding:0!important;margin:-1px!important;overflow:hidden!important;
    clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important;
  }
  .nav{flex-wrap:nowrap!important}
  .nav__logo{flex:0 0 auto!important;min-width:0!important}
  .nav__actions{flex:0 1 auto!important;min-width:0!important}
  #nav-burger{flex:0 0 auto!important;margin-left:auto!important}
}

/* BLOCK 11, svc666. Two tap to call controls sat side by side in the nav on phones:
   the outlined pill showing the number, 156x57, and an icon only amber circle, 44x44,
   both pointing at the same tel: link. Once the burger came back on screen they were
   both visible at once. The pill stays, because a readable phone number is worth more
   than an icon on a trade site, and the circle is retired below 768. That also returns
   52px of headroom to the row. */
@media (max-width:767px){
  .nav .nav__mobile-call{display:none!important}
}

/* BLOCK 12, svc666. review.html uses its own header and its tap to call control measured
   44x24, which is under the 44px minimum target size in WCAG 2.2 AA 2.5.8. It was the only
   header control on the whole site still under size. Made a proper 44x44 target without
   changing where it sits or how it looks. */
.lr-nav__tel{
  min-height:44px!important;min-width:44px!important;
  display:inline-flex!important;align-items:center!important;justify-content:center!important;
}

/* BLOCK 13, svc669. The equipment explainer on solar.html. Panels are the part
   every quote lists and the electronics are the part that decides the 25 year
   experience, so this section gives the three real topologies equal, honest
   framing instead of a spec dump. Built on the existing rr- tokens so it reads
   as part of the same system, not a bolted on widget. Mobile first at 390. */
.eqp{max-width:900px;margin:0 auto}
.eqp-spec{background:linear-gradient(180deg,var(--rr-card),var(--rr-card-2));border:1px solid var(--rr-line);
  border-radius:var(--rr-r-card);padding:24px 16px;margin:0 0 24px}
.eqp-spec__lead{font-family:var(--rr-sans);font-size:16px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--rr-amber);margin:0 0 16px;font-weight:600}
.eqp-spec__grid{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:14px 12px}.eqp-spec__grid:where(:not(.rv-senior,.rv-senior *)){gap:12px 12px}
.eqp-spec__grid li{display:flex;flex-direction:column;gap:3px}.eqp-spec__grid li:where(:not(.rv-senior,.rv-senior *)){gap:4px}
.eqp-spec__n{font-family:var(--rr-serif);font-size:22px;line-height:1.05;color:var(--rr-ink);font-weight:600}
.eqp-spec__k{font-family:var(--rr-sans);font-size:16px;line-height:1.35;color:var(--rr-ink-3)}
.eqp-spec__note{font-family:var(--rr-sans);font-size:16px;line-height:1.5;color:var(--rr-ink-3);
  margin:16px 0 0;padding-top:16px;border-top:1px solid var(--rr-line-2)}
.eqp-tabs{display:grid;grid-template-columns:1fr;gap:8px;margin:0 0 16px}
.eqp-tab{min-height:56px;min-width:44px;display:flex;flex-direction:column;justify-content:center;
  align-items:center;gap:2px;padding:8px 12px;background:var(--rr-card);border:1px solid var(--rr-line);
  border-radius:var(--rr-r-chip);color:var(--rr-ink-2);font-family:var(--rr-sans);font-size:16px;
  font-weight:600;line-height:1.2;text-align:center;cursor:pointer;
  transition:border-color .25s var(--rr-ease-lux),background .25s var(--rr-ease-lux),color .25s var(--rr-ease-lux)}.eqp-tab:where(:not(.rv-senior,.rv-senior *)){gap:4px}
.eqp-tab__s{font-size:16px;font-weight:500;color:var(--rr-ink-3);letter-spacing:.02em}
.eqp-tab:hover{border-color:var(--rr-amber)}
.eqp-tab.is-on{background:var(--rr-amber);border-color:var(--rr-amber);color:var(--rr-on-amber)}
.eqp-tab.is-on .eqp-tab__s{color:var(--rr-on-amber);opacity:.78}
.eqp-tab:focus-visible{outline:2px solid var(--rr-amber);outline-offset:2px}
.eqp-panel{background:var(--rr-card-2);border:1px solid var(--rr-line);border-radius:var(--rr-r-card);padding:16px 16px}
.eqp-panel[hidden]{display:none}
.eqp-flow{display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin:0 0 16px;padding-bottom:16px;
  border-bottom:1px solid var(--rr-line-2)}.eqp-flow:where(:not(.rv-senior,.rv-senior *)){gap:8px}
.eqp-flow__b{font-family:var(--rr-sans);font-size:16px;font-weight:600;line-height:1.25;color:var(--rr-ink-2);
  background:var(--rr-navy-2);border:1px solid var(--rr-line);border-radius:var(--rr-r-chip);padding:8px 8px}
.eqp-flow__b--hi{background:rgba(245,165,36,.13);border-color:var(--rr-amber);color:var(--rr-ink)}
.eqp-flow__a{width:13px;height:1px;background:var(--rr-ink-3);position:relative;flex:0 0 auto}
.eqp-flow__a::after{content:"";position:absolute;right:0;top:-2.5px;border-left:5px solid var(--rr-ink-3);
  border-top:3px solid transparent;border-bottom:3px solid transparent}
.eqp-pts{list-style:none;margin:0;padding:0;display:grid;gap:15px}.eqp-pts:where(:not(.rv-senior,.rv-senior *)){gap:16px}
.eqp-pts li{display:grid;gap:3px;padding-left:15px;position:relative}.eqp-pts li:where(:not(.rv-senior,.rv-senior *)){gap:4px}
.eqp-pts li::before{content:"";position:absolute;left:0;top:7px;width:6px;height:6px;border-radius:50%;
  background:var(--rr-amber)}
.eqp-pts__t{font-family:var(--rr-sans);font-size:16px;font-weight:600;line-height:1.3;color:var(--rr-ink)}
.eqp-pts__d{font-family:var(--rr-sans);font-size:16px;line-height:1.55;color:var(--rr-ink-3)}
.eqp-note{font-family:var(--rr-sans);font-size:16px;line-height:1.55;color:var(--rr-ink-2);
  margin:16px 0 0;padding-top:16px;border-top:1px solid var(--rr-line-2)}
.eqp-pair{margin:24px 0 0;background:linear-gradient(180deg,rgba(245,165,36,.07),transparent);
  border:1px solid var(--rr-line);border-left:3px solid var(--rr-amber);
  border-radius:var(--rr-r-card);padding:16px 16px}
.eqp-pair__t{font-family:var(--rr-serif);font-size:18px;line-height:1.3;color:var(--rr-ink);
  font-weight:600;margin:0 0 12px}
.eqp-pair__d{font-family:var(--rr-sans);font-size:16px;line-height:1.6;color:var(--rr-ink-2);margin:0 0 16px}
.eqp-pair__m{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,1fr);gap:10px}.eqp-pair__m:where(:not(.rv-senior,.rv-senior *)){gap:8px}
.eqp-pair__m li{display:flex;flex-direction:column;gap:2px;text-align:center;background:var(--rr-navy-2);
  border:1px solid var(--rr-line);border-radius:var(--rr-r-chip);padding:12px 6px}.eqp-pair__m li:where(:not(.rv-senior,.rv-senior *)){gap:4px}
.eqp-pair__n{font-family:var(--rr-serif);font-size:18px;color:var(--rr-amber);font-weight:600;line-height:1.1}
.eqp-pair__k{font-family:var(--rr-sans);font-size:16px;line-height:1.3;color:var(--rr-ink-3)}
.eqp-cta{margin:24px 0 0;text-align:center}
@media (min-width:640px){
  .eqp-spec{padding:24px 24px}
  .eqp-spec__grid{grid-template-columns:repeat(4,1fr)}
  .eqp-spec__n{font-size:28px}
  .eqp-panel{padding:24px 24px}
  .eqp-pts{grid-template-columns:repeat(3,1fr);gap:20px}.eqp-pts:where(:not(.rv-senior,.rv-senior *)){gap:16px}
  .eqp-tabs{grid-template-columns:repeat(3,1fr)}
  .eqp-pair{padding:24px 24px}
  .eqp-pair__t{font-size:22px}
  .eqp-flow__b{font-size:16px;padding:8px 12px}
}
@media (prefers-reduced-motion:reduce){.eqp-tab{transition:none}}
.eqp-steps{list-style:none;margin:0 0 16px;padding:0;display:grid;gap:12px;counter-reset:none}
.eqp-steps li{display:flex;gap:11px;align-items:flex-start}.eqp-steps li:where(:not(.rv-senior,.rv-senior *)){gap:12px}
.eqp-steps__n{flex:0 0 auto;width:24px;height:24px;border-radius:50%;background:var(--rr-amber);
  color:var(--rr-on-amber);font-family:var(--rr-sans);font-size:16px;font-weight:700;
  display:flex;align-items:center;justify-content:center;margin-top:0px}
.eqp-steps__b{display:grid;gap:2px}.eqp-steps__b:where(:not(.rv-senior,.rv-senior *)){gap:4px}
.eqp-steps__t{font-family:var(--rr-sans);font-size:16px;font-weight:600;line-height:1.3;color:var(--rr-ink)}
.eqp-steps__d{font-family:var(--rr-sans);font-size:16px;line-height:1.5;color:var(--rr-ink-3)}
.eqp-pair__ask{font-family:var(--rr-sans);font-size:16px;line-height:1.55;color:var(--rr-ink-2);
  margin:0 0 16px;padding:12px 12px;background:var(--rr-navy-2);border-radius:var(--rr-r-chip);
  border-left:2px solid var(--rr-amber)}

/* svc675 forms first: tighten the lead form section on the two paid pages whose
   form was measured below the fold at 390x844. Padding only, no copy removed. */
@media (max-width: 767px){
  .rdn-foldtight{ padding-top:16px !important; padding-bottom:24px !important; }
  .rdn-foldtight > h2,
  .rdn-foldtight .town-lead-card__title{ margin-top:0 !important; margin-bottom:6px !important; }.rdn-foldtight > h2:where(:not(.rv-senior,.rv-senior *)),.rdn-foldtight .town-lead-card__title:where(:not(.rv-senior,.rv-senior *)){margin-bottom:4px !important}
  .rdn-foldtight .section-desc,
  .rdn-foldtight .town-lead-card__sub{ margin-top:0 !important; margin-bottom:8px !important; }
  .rdn-foldtight .town-lead-card{ padding-top:16px !important; }
  .rdn-foldtight .town-lead-card__terms{ margin-top:16px; }
  .rdn-foldtight .town-lead-card__terms .town-lead-card__sub{ margin-bottom:6px !important; }.rdn-foldtight .town-lead-card__terms .town-lead-card__sub:where(:not(.rv-senior,.rv-senior *)){margin-bottom:4px !important}
}/* svc675 forms first: tighten the lead form section on the two paid pages whose
   form was measured below the fold at 390x844. Padding only:where(:not(.rv-senior,.rv-senior *)),no copy removed. */
@media (max-width: 767px):where(:not(.rv-senior,.rv-senior *)){margin-bottom:4px !important;margin-bottom:4px !important}

/* svc675 forms first, second pass: tighten the HERO on the two paid pages that
   carry a full lead form instead of a one field hero form. Padding and margin
   only. No copy removed, no field added, desktop untouched. */
@media (max-width: 767px){
  .rdn-foldhero{ padding-top:16px !important; padding-bottom:12px !important; }
  .rdn-foldhero .hero__eyebrow,
  .rdn-foldhero .ledc__eyebrow{ margin:0 0 6px !important; }.rdn-foldhero .hero__eyebrow:where(:not(.rv-senior,.rv-senior *)),.rdn-foldhero .ledc__eyebrow:where(:not(.rv-senior,.rv-senior *)){margin:0 0 4px !important}
  .rdn-foldhero h1,
  .rdn-foldhero .ledc__h2{ margin:0 0 8px !important; }
  .rdn-foldhero .section-desc,
  .rdn-foldhero .ledc__lede{ margin:0 0 12px !important; }
  .rdn-foldhero .rh-proof,
  .rdn-foldhero .rdn-hero-rating,
  .rdn-foldhero .town-lead-form__minutes{ margin:0 0 8px !important; }
  .rdn-foldhero .rh-area{ margin:0 !important; }
  .rdn-foldhero .ledc__wrap{ padding-top:0 !important; padding-bottom:0 !important; }
}/* svc675 forms first:where(:not(.rv-senior,.rv-senior *)),second pass: tighten the HERO on the two paid pages that
   carry a full lead form instead of a one field hero form. Padding and margin
   only. No copy removed:where(:not(.rv-senior,.rv-senior *)),no field added:where(:not(.rv-senior,.rv-senior *)),desktop untouched. */
@media (max-width: 767px):where(:not(.rv-senior,.rv-senior *)){margin:0 0 4px !important}
@media (max-width: 767px){
  /* svc675: the geo eyebrow is two lines of uppercase town names. Tighter leading
     only, same words, same towns. */
  .rdn-foldhero .ledc__eyebrow{ line-height:1.25 !important; }
}

/* svc675: #small-jobs-form and #small-jobs-anchor-form render full bleed at 390px,
   so their NAME label sits flush against the screen edge while every other element
   on the page is inset. Pre-existing, confirmed against a control copy of the page
   before the svc675 move. The equivalent form on electrical-repairs sits at 49px
   because it is wrapped in a padded card. This matches the other two. */
#small-jobs-form, #small-jobs-anchor-form{
  padding-left: clamp(16px, 4.2vw, 28px);
  padding-right: clamp(16px, 4.2vw, 28px);
  box-sizing: border-box;
}

/* ===========================================================================
   BLOCK svc701. LIGHT SURFACES. One cause, four invisible elements.

   The DNA layer sets dark theme ink on every heading, lede, intro and __sub
   with no exclusion for light sections:

     [class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])
       { color: var(--rr-ink) }          -- #f4f6fb, off white
     h1,h2,.section-title,[class*="__title"]:is(h1,h2),...
       { color: var(--rr-ink) }

   Most of the site is navy so that is right almost everywhere. On a cream or
   white section it paints off white text on an off white background. Measured
   in a browser on the live site:

     /solar            .saft__sub          1.01:1 on #fdf6ea cream
     /my-own-bill      .anatomy__title     1.01:1 on #f5f7fa
     /my-own-bill      .btn--secondary     1.04:1  (see the button note below)
     /economics-of-solar .eos-fin__seg--intro 1.61:1 on a green gradient

   The old guard, .section--cream>.container>p, only matched direct p children
   of .container, so anything nested escaped it. This block guards the surface
   instead of the element, so a new element dropped into a light section
   inherits the right ink without another patch.
   =========================================================================== */

/* 1. Light surfaces reclaim navy ink for headings, ledes, intros and subs. */
.section--cream :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.anatomy        :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.honesty        :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.receipt        :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.rr-accordion   :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.ev-install-info :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.ev-system      :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.trust-strip    :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.onsite-contrast :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.mission-disclosure :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])){
  color:#0d1b2e;
}

/* 1a. Exemption. .receipt is a light section holding one navy total row, so the
       surface rule above must not repaint the text sitting on that navy. */
.receipt .receipt__row--total,
.receipt .receipt__row--total :is(h1,h2,h3,h4,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]){
  color:var(--rr-ink);
}

/* 2. /solar. Restores the colour solar.html declares for itself. Its own
      .saft__sub is 0,1,0 and lost to the DNA 0,2,0 attribute selector.
      #4a5464 on #fdf6ea measures 7.13:1. */
.section--cream .saft__sub{ color:#4a5464; }

/* 3. /economics-of-solar. The segment sits on a green gradient, 74,222,128 to
      126,242,166. Its two siblings, --after and --mtg, are already navy
      #0b1730. This one matched [class*="intro"] by accident and went off
      white. Navy measures 10.22:1 on the dark end of the gradient. */
.eos-fin__seg--intro{ color:#0b1730; }

/* 4. Buttons. .btn--lg is a SIZE modifier, but the DNA layer lists it beside
      .btn--primary and hands it navy on amber ink. .btn--secondary keeps its
      own translucent dark background, so the pairing put navy text on navy.
      A size class must not decide ink, so the variant takes it back. */
.btn--secondary,
.btn--secondary.btn--lg,
.btn--ghost,
.btn--ghost.btn--lg{
  color:var(--rr-ink);
}

/* ===========================================================================
   BLOCK svc701b. The homepage lead form, #rh-quote.
   Navy surface so the DNA off white ink is correct here, and the form inherits
   the same .town-lead-form styling every other page already uses.
   =========================================================================== */
.rh-quote{
  background:var(--rr-navy-2,#0d1b2e);
  padding:clamp(32px,6vw,64px) 0 clamp(32px,6vw,64px);
  scroll-margin-top:96px;
}
.rh-quote__title{
  font-family:var(--rr-serif);
  font-size:clamp(28px,6.2vw,36px);
  line-height:1.15;
  margin:0 0 12px;
  color:var(--rr-ink);
}
.rh-quote__sub{
  margin:0 0 24px;
  max-width:52ch;
  color:var(--rr-ink-2);
}
.rh-quote__alt{
  margin:16px 0 0;
  font-size:16px;
  color:var(--rr-ink-3);
}
.rh-quote__alt a{ color:var(--rr-amber-hi); }
@media (max-width:767px){
  .rh-quote{ padding:24px 0 32px; }
}


/* ---- BLOCK svc701c: How Heard on a light card ----
   .rr-howheard__label is hardcoded var(--rdx-ink,#fff). Inside a navy form that
   is right. Inside .lead-card (#f6f8fc) it measured 1.06:1 on
   commercial-solar-calculator.html, i.e. invisible. 13 pages put the block on a
   light surface. Re-point the ink there only; navy forms are untouched.
   Measured with the corrected probe that skips gradient backgrounds. */
.lead-card .rr-howheard__label,
.section--cream .rr-howheard__label,
.rdn-light .rr-howheard__label,
.lead-card .rr-howheard__title,
.section--cream .rr-howheard__title{color:#0d1b2e}
.lead-card .rr-howheard__opt,
.section--cream .rr-howheard__opt,
.rdn-light .rr-howheard__opt{opacity:.78}
.lead-card .rr-howheard label,
.section--cream .rr-howheard label,
.rdn-light .rr-howheard label{color:#0d1b2e}


/* ---- BLOCK svc701d: options with a reason ----
   Ports the panel-upgrade.html pattern (three cards, each with a Best when
   line and a relative cost ladder) to the rest of the service pages.
   Self contained on purpose. .rr-tier and .rr-more live in page bundles that
   do not load everywhere, so this namespace depends on nothing but itself. */
.rdn-opts{margin-top:2rem;display:grid;gap:16px;
  grid-template-columns:repeat(auto-fit,minmax(268px,1fr))}
.rdn-opt{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.12);
  border-radius:16px;padding:1.5rem;display:flex;flex-direction:column}
.rdn-opt__n{font:700 16px/1 var(--font-sans,system-ui,sans-serif);letter-spacing:.09em;
  text-transform:uppercase;color:#8a94a6;margin:0 0 .5rem}
.rdn-opt__h{font-weight:800;color:#f5a524;font-size:1.375rem;line-height:1.35;
  margin:0 0 .75rem}
.rdn-ladder{display:flex;align-items:center;gap:.25rem;margin:0 0 .85rem}.rdn-ladder:where(:not(.rv-senior,.rv-senior *)){margin:0 0 12px}
.rdn-ladder i{width:16px;height:5px;border-radius:8px;background:rgba(255,255,255,.16)}
.rdn-ladder i.is-on{background:#f5a524}
.rdn-ladder__l{margin-left:.4rem;font-size:16px;letter-spacing:.06em;
  text-transform:uppercase;color:#8a94a6}
.rdn-opt__best{font-size:1rem;line-height:1.6;color:#f4f6fb;margin:0 0 .6rem}.rdn-opt__best:where(:not(.rv-senior,.rv-senior *)){margin:0 0 8px}
.rdn-opt__best b{color:#f7b23a;font-weight:700}
.rdn-opt__why{font-size:1rem;line-height:1.65;color:#c7d0dd;margin:0 0 1rem;flex:1}
.rdn-opt__cav{font-size:.9375rem;line-height:1.6;color:#8a94a6;margin:0;
  padding-top:.85rem;border-top:1px solid rgba(255,255,255,.1)}.rdn-opt__cav:where(:not(.rv-senior,.rv-senior *)){padding-top:12px}
.rdn-opts__foot{margin-top:1.5rem;font-size:1rem;line-height:1.65;color:#c7d0dd}
/* light surface variant */
.section--cream .rdn-opt,.rdn-light .rdn-opt{background:#fff;border-color:#dde3ec}
.section--cream .rdn-opt__best,.rdn-light .rdn-opt__best{color:#0d1b2e}
.section--cream .rdn-opt__why,.rdn-light .rdn-opt__why{color:#3d4757}
.section--cream .rdn-opt__h,.rdn-light .rdn-opt__h{color:#8a5a00}
.section--cream .rdn-opt__best b,.rdn-light .rdn-opt__best b{color:#8a5a00}
@media (max-width:700px){.rdn-opt{padding:1.5rem}}

/* ===== BLOCK svc702: the photo path that replaced the dead upload boxes =====
   The upload control never transmitted a byte. Two taps out to the phone's own
   messaging or mail app is the honest replacement. Works on navy and on light. */
.rdn-photo{margin:1rem 0;padding:1rem 1rem;border:1px solid var(--rr-line,#26364f);
  border-left:3px solid var(--rr-amber,#f5a524);border-radius:12px;
  background:rgba(245,165,36,.055)}
.rdn-photo__h{margin:0 0 .35rem;font-size:1rem;line-height:1.3;font-weight:800;
  color:var(--rr-ink,#f4f6fb)}.rdn-photo__h:where(:not(.rv-senior,.rv-senior *)){margin:0 0 4px}
.rdn-photo__p{margin:0 0 .8rem;font-size:.94rem;line-height:1.5;color:var(--rr-ink-2,#c7d0dd)}.rdn-photo__p:where(:not(.rv-senior,.rv-senior *)){margin:0 0 12px}
.rdn-photo__actions{display:flex;flex-wrap:wrap;gap:.5rem}
.rdn-photo__btn{flex:1 1 auto;min-width:11.5rem;min-height:48px;display:inline-flex;
  align-items:center;justify-content:center;text-align:center;padding:.7rem 1rem;
  border-radius:10px;font-size:.95rem;font-weight:800;text-decoration:none;
  background:var(--rr-amber,#f5a524);color:var(--rr-on-amber,#111f30);
  border:1px solid var(--rr-amber,#f5a524)}.rdn-photo__btn:where(:not(.rv-senior,.rv-senior *)){padding:12px 1rem}
.rdn-photo__btn--ghost{background:transparent;color:var(--rr-ink-2,#c7d0dd);
  border:1px solid var(--rr-line,#26364f)}
.rdn-photo__note{margin:.75rem 0 0;font-size:.82rem;line-height:1.45;color:var(--rr-ink-3,#8a94a6)}
/* light surfaces: the cream lead cards and any .rdn-light scope */
.lead-card .rdn-photo,.section--cream .rdn-photo,.rdn-light .rdn-photo{
  border-color:rgba(13,27,46,.16);background:rgba(245,165,36,.09)}
.lead-card .rdn-photo__h,.section--cream .rdn-photo__h,.rdn-light .rdn-photo__h{color:#0d1b2e}
.lead-card .rdn-photo__p,.section--cream .rdn-photo__p,.rdn-light .rdn-photo__p{color:#243349}
.lead-card .rdn-photo__note,.section--cream .rdn-photo__note,.rdn-light .rdn-photo__note{color:#4a5568}
.lead-card .rdn-photo__btn--ghost,.section--cream .rdn-photo__btn--ghost,
.rdn-light .rdn-photo__btn--ghost{color:#0d1b2e;border-color:rgba(13,27,46,.28)}
@media (max-width:420px){.rdn-photo__btn{flex:1 1 100%}}

/* ------------------------------------------------------------------ */
/* BLOCK svc705. Exemption for dark sub-surfaces inside light-guarded  */
/* wrappers. BLOCK svc701 above assumes every listed wrapper is a      */
/* light surface and paints navy #0d1b2e on descendant headings. Three */
/* of those wrappers are dark, so the heading landed navy on navy      */
/* (measured 1.01 to 1.06 contrast). Scoped so the genuinely light     */
/* .rr-accordion--cream panels keep their navy text.                   */
/* Measured on the patched build, 390x844, every details forced open   */
/* and every [hidden] stripped first: 0 failures across 21 pages, with */
/* zero regressions on an 8 page both-directions diff.                 */
/* UNSETTLED: an earlier run against the UNPATCHED LIVE site reported  */
/* 119 failures falling to 35. Local says 0 across a larger set. Those */
/* two disagree and the patch was not live when either ran, so neither */
/* number is a verified post-deploy figure. Settle it by running       */
/* contrast_remeasure.py --tag after against production once deployed. */
/* ------------------------------------------------------------------ */
.rr-accordion:not(.rr-accordion--cream) :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"],[class*="__sub"]:not([class*="__submit"])),
.ev-install-info .rr-anat__body :is(h1,h2,h3,h4,[class*="__title"]),
.ev-system .rr-anat__body :is(h1,h2,h3,h4,[class*="__title"]){color:#f4f6fb}

/* 1c. svc705. A cream accordion can contain a nested DARK .section.       */
/* The wrapper is genuinely light, so block 1b correctly spares it, but the */
/* assumption breaks one level deeper. Measured navy on navy at 1.10 on     */
/* battery-storage. Verified: 1 failure to 0, zero regressions.             */
.rr-accordion--cream .rr-accordion__panel .section :is(h1,h2,h3,h4,.section-title,[class*="__title"],[class*="lede"],[class*="intro"]){color:#f4f6fb}


/* ---- svc705b block 2: contrast on light backgrounds ---------------------
   Twelve failures, four separate root causes, each confirmed by CDP rule
   tracing rather than guessed. Specificity is matched to the losing rule on
   purpose. A weaker selector changes nothing and looks like a fix.
   Measured 390px, details forced open: 12 fixed, 0 regressions. */

/* 2a. The breadcrumb strip is coloured for a dark page. On body.rdn-light it
       renders on white, so off-white at 72 percent measured 1.06. */
body.rdn-light nav.rr-breadcrumbs[data-rr-breadcrumbs] .rr-breadcrumbs__link{color:#3d4657}
body.rdn-light nav.rr-breadcrumbs[data-rr-breadcrumbs] .rr-breadcrumbs__sep{color:#5a6474}
body.rdn-light nav.rr-breadcrumbs[data-rr-breadcrumbs] .rr-breadcrumbs__item--current{color:#8a5a06}

/* 2b. on-site-not-satellite carries section--cream but paints navy, so the
       svc701 cream rule put navy headings on a navy card. Same defect family
       as blocks 1b and 1c above. */
.onsite-contrast .onsite-card .onsite-card__title{color:#f4f6fb}

/* 2c. roof-card eyebrow: amber on a white card, measured 1.84. */
.roof-synergy .roof-card .roof-card__eyebrow{color:#8a5a06}

/* 2d. #page-home .rh-home a{color:inherit} outranks .hcr__go, so the amber
       button inherited off-white and measured 1.80. Restored at id weight. */
#page-home .rh-home a.hcr__go{color:#0a1526}
