/* perf-svc642.css
   -----------------------------------------------------------------------
   Two measured defects, one file. Loaded LAST so it wins on specificity
   ties without touching a single existing rule.

   DEFECT 1, counted with Playwright on live index.html at 390x844:
   736 elements carry a transition on a property the compositor cannot
   handle on its own thread. Breakdown by property:
       border-color   166      background      217
       box-shadow     210      color           103
       stroke          26      max-height        4
       visibility       4      all               3      top   1
   Every one of those forces a paint or a layout on the main thread when it
   runs. PageSpeed mobile reported 239 animated elements failing the
   "non-composited animations" audit, 19 long main thread tasks and 8.1s of
   main thread work.

   Why the fix is scoped to (hover:none): every one of those transitions is
   a hover or focus tint on a card, a link or a rule. A touch screen has no
   hover state, so on a phone they are paying main thread cost for a visual
   state the finger never enters. Desktop keeps all of it, unchanged.

   What is deliberately KEPT in the allowed list: transform, opacity,
   max-height, height and visibility. max-height and height are what make
   the reveal accordions slide instead of snap, and transform and opacity
   are what the hero rise and the scroll reveals ride on. Nothing that
   moves or reveals information loses its motion.

   DEFECT 2: four keyframe animations animate box-shadow or
   stroke-dashoffset, which are also non-composited, and two of them run
   INFINITE:
       rrAddrBreath   box-shadow      4.5s infinite   (address form)
       rrAnatFlow     stroke-dashoffset 3.2s infinite (anatomy diagram)
       rrAddrBloom    box-shadow      1.6s once
       rrPhonePulse   box-shadow      1.1s once
   An infinite non-composited animation never stops costing. Both attention
   cues are rebuilt below on a pseudo element using opacity and transform,
   which the compositor runs off the main thread. The cue a customer sees is
   the same ring. The cost is not.
   ----------------------------------------------------------------------- */

@media (hover: none) {

  /* 1. Composited properties only, on touch. */
  *, *::before, *::after {
    transition-property: transform, opacity, max-height, height, visibility !important;
  }

  /* 2. Kill the four non-composited keyframes on touch. */
  .js-cine.hero--ready .w3-heroform__row,
  .js-cine.hero--ready .town-lead-form,
  .js-cine.hero--ready .rr-hero-addr__form,
  .js-cine.hero--ready .rr-cine-landing.rr-cine,
  .hero.js-cine.hero--ready .hero__phone-pill.rr-cine {
    animation: none !important;
  }
  .rr-anat__flow { animation: none !important; }

  /* 3. Rebuild the address form cue on opacity. Same amber ring, composited. */
  .js-cine.hero--ready .w3-heroform,
  .js-cine.hero--ready .town-lead-form {
    position: relative;
  }
  .js-cine.hero--ready .w3-heroform::after,
  .js-cine.hero--ready .town-lead-form::after {
    content: "";
    position: absolute;
    inset: -6px;
    border-radius: 14px;
    box-shadow: 0 0 0 3px rgba(245, 165, 36, .22), 0 10px 40px rgba(245, 165, 36, .18);
    opacity: 0;
    pointer-events: none;
    animation: rdnRingBreath642 4.5s ease-in-out 1.25s infinite;
  }
  @keyframes rdnRingBreath642 {
    0%, 100% { opacity: 0 }
    50%      { opacity: 1 }
  }

  /* 4. Rebuild the phone pill cue on opacity and transform. */
  .hero.js-cine.hero--ready .hero__phone-pill { position: relative }
  .hero.js-cine.hero--ready .hero__phone-pill::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 9999px;
    box-shadow: 0 0 0 8px rgba(245, 165, 36, .20);
    opacity: 0;
    pointer-events: none;
    animation: rdnPillPulse642 1.1s cubic-bezier(.22, .61, .36, 1) 1.9s 1 both;
  }
  @keyframes rdnPillPulse642 {
    0%   { opacity: 0; transform: scale(.97) }
    45%  { opacity: 1; transform: scale(1) }
    100% { opacity: 0; transform: scale(1.02) }
  }
}

@media (prefers-reduced-motion: reduce) {
  .js-cine.hero--ready .w3-heroform::after,
  .js-cine.hero--ready .town-lead-form::after,
  .hero.js-cine.hero--ready .hero__phone-pill::after {
    animation: none !important;
    opacity: 0 !important;
  }
}

/* =======================================================================
   SPACING SNAP, svc642
   -----------------------------------------------------------------------
   Counted with Playwright on live /solar at 390x844. Every vertical
   padding, margin, gap and row-gap on the page was read as a RENDERED
   pixel value, not a declared one, and grouped. 14 distinct values were in
   use 5 or more times. The Raydn scale is 4, 8, 12, 16, 20, 24, 32, 40, 48,
   64. Five values were off it:

     17px  x22   .bfact__panel and friends, clamp lower bound 1.05rem
     29px  x5    .rdn-result__subgrid, .rr-sig__col, 1.8rem
     42px  x8    .bsw-section, clamp lower bound 2.6rem
     44px  x8    .town-section, .rdn-reviews-strip, hardcoded 44px
     14px  x5    .nav__mobile.rdn-mnav, hardcoded 14px

   None of them is a deliberate optical adjustment. They are each within
   3px of a value the system already uses hundreds of times, so they read
   as drift, not intent. Snapping each one to its nearest scale neighbour
   removes five values from the page vocabulary and moves nothing a
   customer can perceive. Largest single shift is 4px on .town-section.

   Not touched: the 2px on .nav__logo-img and .nav__logo-slogan. That is a
   real optical adjustment on the logo lockup, where the wordmark and the
   slogan have to sit tight to each other, and 4px visibly breaks it.
   ======================================================================= */

/* 17px to 16px */
.bfact__panel, .eix { padding-block: 1rem }

/* 29px to 32px */
.rdn-result__subgrid { margin-block: 2rem }
.rr-sig__col { padding-block: 2rem }
.rdn-payoff { margin: 2rem 0 1rem }
.rvx-step__nav { margin-top: 2rem }

/* 42px to 40px */
.bsw-section { padding-block: clamp(2.5rem, 6vw, 4.5rem) }

/* 44px to 40px */
.town-section { padding-top: 40px; padding-bottom: 40px }
.section.rdn-reviews-strip, .rdn-reviews-strip { padding-top: 40px; padding-bottom: 40px }

/* 14px to 16px, and the 6px gaps to 8px */
.nav__mobile.rdn-mnav { padding-left: 16px !important; padding-right: 16px !important; padding-top: 16px !important }
.nav__burger { gap: 8px }
.rr-breadcrumbs__list { gap: 8px }

/* =======================================================================
   AMBER RESTRAINT, svc642
   -----------------------------------------------------------------------
   Counted with Playwright on live index.html and /solar at 390x844. Every
   rendered element was tested for an amber value on colour, background,
   a border with non zero width, or an SVG stroke, then split by whether it
   sits inside something tappable (a, button, input, select, textarea,
   summary, label) or not.

     index.html   amber on tappable 183   amber on decoration 174
     /solar       amber on tappable 127   amber on decoration 159

   On /solar amber is on MORE decoration than action. That is the defect.
   Amber is the site's one signal that something can be pressed, and when
   half the amber on the screen is a chip outline or a dashed cell border,
   the signal stops working.

   What moves to grey, all non tappable containers:
     .hero-trust__chip    border and tint      x4 on index
     .rr-anat__chip       border and tint      x3
     .rr-worth__cell      dashed border, tint  x3
     .bdec__find          border and tint      x7 on /solar
     .w69b-frame__step    background           x5
     .w65-ba__tag         background           x3

   What deliberately STAYS amber, because it is hierarchy and not
   decoration, and pulling it would flatten information a reader uses:
     the protected hero italic  #f0a300
     every large figure         .rr-worth__num, .rr-impact__v,
                                .rr-impact__n, .rdn-story__sub-num
     every review star row      .rr-testimonials__stars, .rdn-rev-stars
     every diagram stroke that shows current or flow direction
     every amber on a tappable  unchanged, all 183 and 127 of them

   Net effect: the chips and cells read as containers, the numbers and the
   buttons keep the accent. No text loses contrast, because in each case
   below the label colour is untouched and only the frame changes.
   ======================================================================= */

.hero-trust__chip {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(138, 148, 166, .34);
}
.rr-anat__chip {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(138, 148, 166, .34);
}
.rr-worth__cell {
  border: 1px dashed rgba(138, 148, 166, .34);
  background: rgba(255, 255, 255, .035);
}
.bdec__find {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(138, 148, 166, .34);
}
.w69b-frame__step { background: rgba(138, 148, 166, .22) }
.w65-ba__tag      { background: rgba(138, 148, 166, .22) }

/* =======================================================================
   FORM IN THE FOLD, svc642, phone only
   -----------------------------------------------------------------------
   Measured with Playwright at 390x844. The fold is 844. Position of the
   first thing a customer can type into:

     /residential-electrical        input row at 1058   214px below the fold
     /panel-upgrade-edmonton        input row at  959   115px below the fold

   Both heroes already CONTAIN the phone drop form. It is just buried under
   a 102px three line paragraph, a second ghost button and the rating row.
   So nothing has to be written, added or cut. The block only has to be
   re-ordered, and re-ordering it costs no information: the paragraph, the
   ghost button and the rating all land directly under the form, inside the
   same screen, one thumb flick away.

   Done with flex order, on (max-width:820px) only, so desktop is byte for
   byte the layout that is live now. Reversible by deleting this block.

   New order on a phone:
     1 eyebrow      2 headline      3 price band
     4 call button and quote button
     5 the phone drop form
     6 the 5.0 and 70 reviews row
     7 the "one Master Electrician runs your job" paragraph
   ======================================================================= */

@media (max-width: 820px) {
  .rdn-hero__inner {
    display: flex;
    flex-direction: column;
  }
  .rdn-hero__inner > .rdn-hero__eyebrow { order: 1 }
  .rdn-hero__inner > h1                 { order: 2 }
  .rdn-hero__inner > .res-price         { order: 3 }
  .rdn-hero__inner > .rdn-hero__actions { order: 4 }
  .rdn-hero__inner > .w3-heroform       { order: 5 }
  .rdn-hero__inner > .rdn-hero-rating   { order: 6 }
  .rdn-hero__inner > .rdn-hero__sub     { order: 7; margin-top: 1rem !important }

  /* The availability line is reassurance, not the offer. It reads better
     under the form than above it, and moving it lifts the form 83px. */
  .res-price { display: flex; flex-direction: column }
  .res-price > .res-price__main  { order: 1 }
  .res-price > .res-price__band  { order: 2 }
  .res-price > .res-price__avail { order: 3 }
}

/* Ghost button drops below the form on a phone. It points at /contact,
   which is the same job the form now does inline, so above the form it was
   competing with itself. Nothing removed, it lands one flick down. */
@media (max-width: 820px) {
  .rdn-hero__inner > .rdn-hero__actions { display: contents }
  .rdn-hero__inner > .rdn-hero__actions > .rdn-cta { order: 4 }
  .rdn-hero__inner > .rdn-hero__actions > .rdn-cta--ghost { order: 7 }
  .rdn-hero__inner > .rdn-hero__sub { order: 8 }
  .rdn-hero__inner > .rdn-cta,
  .rdn-hero__inner > .rdn-hero__actions > .rdn-cta { width: 100%; box-sizing: border-box }
}

/* led-upgrades hero, phone only. The form landed at 905, 61px under the
   fold, because the claim line sits between the headline and the buttons.
   Ordering the claim below the form clears it and loses nothing: the claim
   still reads immediately under the thing it is a claim about. */
@media (max-width: 820px) {
  #section-1.ledc > .ledc__wrap { display: flex; flex-direction: column }
  #section-1.ledc > .ledc__wrap > .ledc__eyebrow    { order: 1 }
  #section-1.ledc > .ledc__wrap > h1                { order: 2 }
  #section-1.ledc > .ledc__wrap > .ledc__lede       { order: 3 }
  #section-1.ledc > .ledc__wrap > .ledc__actions    { order: 4 }
  #section-1.ledc > .ledc__wrap > .rdn-hero-rating  { order: 5 }
  #section-1.ledc > .ledc__wrap > .w3-heroform      { order: 6 }
  #section-1.ledc > .ledc__wrap > .ledc__claim      { order: 7 }
  #section-1.ledc > .ledc__wrap > .ledc-hero__img   { order: 8 }
}

/* Last 40px. The form's top edge was inside the fold on all four pages but
   on two of them only the first 11px of the input showed, which is not the
   same as a customer seeing a box they can type in. These trim the gaps in
   the mobile hero stack and drop the third led-upgrades button under the
   form. No copy removed, no font size reduced. */
@media (max-width: 820px) {
  .rdn-hero__inner > .rdn-hero__title,
  .rdn-hero__inner > h1                 { margin-bottom: 8px }
  .rdn-hero__inner > .res-price         { margin-block: 12px }
  .rdn-hero__inner > .w3-heroform       { margin-top: 12px }

  #section-1.ledc > .ledc__wrap > .ledc__actions { display: contents }
  #section-1.ledc .ledc__actions > .ledc__btn { order: 4; margin-top: 8px }
  #section-1.ledc .ledc__actions > .ledc__btn:nth-child(3) { order: 7 }
}

/* Recount after the first snap pass. /solar went from 6 off scale values
   used 5 or more times to 3, and from 16 distinct spacing values to 13.
   The three that survived, and what happened to each:

     44px  8 down to 6   still on .section, a base rule the .town-section
                         selector did not cover. Snapped here to 40.
     6px  22 down to 18   breadcrumb and chip gaps. Snapped to 8.
     2px  82, unchanged   this one is DELIBERATE and stays. It is the gap
                          inside inline icon and label pairs: an SVG next
                          to its own caption, a summary chevron next to its
                          own heading, a unit next to its own figure. 4px
                          visibly separates a glyph from the word it belongs
                          to, which is the opposite of what a gap that small
                          is for. Calling it drift would be wrong. It is
                          hairline optical spacing and it is one value used
                          consistently in one role, which is what a scale is
                          supposed to look like.
   ======================================================================= */
.section { padding-top: 40px; padding-bottom: 40px }
.rr-breadcrumbs__item, .rr-breadcrumbs__link, .hero-trust, .w66-mon__head { gap: 8px }

/* Both above lost specificity ties to two class selectors in the bundles
   and to the inline critical block, so they are forced. Verified by
   recount, not assumed. */
.section, .section.rdn-reviews-strip, .section.rdn-reveal-up, .section.section--cream {
  padding-top: 40px !important; padding-bottom: 40px !important;
}
.rr-breadcrumbs__item, .rr-breadcrumbs__link, .rr-breadcrumbs__list,
.hero-trust, .w66-mon__head { gap: 8px !important }

/* index.html carried one more, pre-existing on the live site and NOT
   introduced by this pass. Verified by running the same count against
   production first: live index reports 27px x49, so this is drift that was
   already there. 24 of the 48 carriers are the work type cards, whose
   padding comes out at 27px from a 1.7rem declaration. Snapped to 1.5rem. */
.work-type-card { padding-block: 1.5rem }
a.work-type-card, .work-type-card { padding-top: 24px !important; padding-bottom: 24px !important }
.rdn-vs, .rr-final-chip, .footer__trust-link, .rr-hero-addr__btn { gap: 8px !important }
