/* Homepage sections rebuilt EXACTLY from Figma (frame 5134:2) */

/* ============ SECTION 2 — An exclusive / designed for UK weather ============ */
.excl {
  background: var(--bg);
  padding: 2.25rem 0 5.625rem;
}
.excl-wrap {
  max-width: 90rem;
  margin: 0 auto;
  padding: 0 2.5rem;
}

/* certification badges row */
.excl-certs {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3rem;
  flex-wrap: wrap;
  margin-bottom: 4.5rem;
}
.excl-certs img {
  height: 3.5rem;
  width: auto;
}

.excl-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 39.375rem;
  gap: 6.25rem;
  align-items: center;
}

/* left copy */
.excl-eyebrow {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.75rem;
  line-height: 2.3125rem;
  letter-spacing: -0.08rem;
  color: var(--ink-70);
  margin: 1.5rem 0 0;
}
.excl-h {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2.25rem;
  line-height: 3.5rem;
  letter-spacing: -0.08rem;
  color: var(--ink-70);
  margin: 0;
}
.excl-italic {
  display: inline-block;
  font-weight: 600;
  font-style: italic;
  font-size: 3.75rem;
  line-height: 4rem;
  letter-spacing: -0.08rem;
  background: linear-gradient(87.3deg, #111111 21.751%, #e2fa5a 136.65%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.excl-left .btn {
  margin-top: 1.75rem;
}

/* stat cards — widened so values stay on one line */
.excl-stats {
  display: flex;
  gap: 1rem;
  margin-top: 3.5rem;
}
.excl-card {
  flex: 1;
  min-width: 0;
  /* 243 -> 224 on 2026-08-14, the user's own DevTools value ("min height ye krdo
     is class ki web main"). DESKTOP ONLY, and that needed no new rule —
     home-mobile.css already restates `min-height: 0` for the stacked cards.
     COSTS NOTHING BELOW §2: `.excl-grid` is 1360x650 either way (the video's
     630x650 drives it) and the left column is centred, so the three cards just
     lose 19 each and the column re-centres — heading 1585.5 -> 1595, stats
     1853.5 -> 1863, `.excl` still 904, `.pvsec` still 2256, docH still 14790.
     FLOOR IS 215: that is what card 1's own content needs (cards 2/3 need 195),
     and all three stretch to the tallest, so anything under 215 stops having an
     effect and 224 leaves 9px of slack. */
  min-height: 14rem;
  border-radius: 0.75rem;
  background: var(--white);
  border: 0.25rem solid #f6f6f6;
  padding: 1.5rem;
}
.excl-card img {
  /* 64x48, NOT Figma's 48 square, and the width is the only thing that moved
     (2026-08-18, the user's instruction: "is ka size increase kr sakte ... icon
     abi square main hai rectangle main le jao" — and then, crucially, "main sirf
     us chote icon ki baat kr rha na k pure icon ki"). Only the BADGE (the
     infinity / shield / bolt mark) had to grow: it was 26% of the artwork, i.e.
     12.9px inside the old 48 box. So the three assets carry a 200x150 viewBox
     with the badge group scaled 2x into the new right-hand space -> 23.7px.
     HEIGHT IS UNTOUCHED ON PURPOSE, and that is what makes this move nothing:
     the icon sits above the copy in a column here and inside a declared grid
     track on mobile, so a wider box costs no vertical space. Verified at both
     breakpoints: cards 224 / 113, .excl-stats 355, docH 14790 / 17336 and every
     section top identical to before.
     GROWING THE BADGE IN PLACE WAS TRIED AND REJECTED — at 1.5x and 1.8x it
     collides with the panel's stand and its bottom edge. The square viewBox has
     only ~6 units of margin past the badge, so there is nowhere for it to go but
     into the panel.
     DO NOT "TIDY" THIS BACK TO A SQUARE: <img> letterboxes on the default
     preserveAspectRatio, so a 230x150 viewBox in a 48 square renders the whole
     icon 36% smaller instead of cropping. THE BOX ASPECT MUST TRACK THE ASSET'S
     viewBox — 4.6rem/3rem is 230/150 exactly. Change one and you must change the
     other, or the panel silently shrinks.
     4.6, not 4: the badge then took a 2px gap off the panel's right edge
     ("in badges k left ki traf thora margin do 1-2 px"), which pushed it right
     and needed the extra 30 viewBox units of room. */
  width: 4.6rem;
  height: 3rem;
  margin-bottom: 1.25rem;
}
.excl-card h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 2rem;
  line-height: 2.6875rem;
  letter-spacing: -0.08rem;
  color: var(--ink);
  margin: 0;
  white-space: nowrap;
}
.excl-card p {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.25rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
  margin: 0.5rem 0 0;
}

/* right video card (auto-advancing slider) */
.excl-video {
  position: relative;
  width: 39.375rem;
  max-width: 100%;
  height: 40.625rem;
  border-radius: 0.75rem;
  overflow: hidden;
  margin: 0;
  box-shadow: 0 0.25rem 3.75rem 0 rgba(226, 250, 90, 0.85);
}
.excl-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.excl-photo.is-active {
  opacity: 1;
}
.excl-vgrad {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 17rem;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0));
}

/* top bar: progress line + play button, with margin between them */
.excl-top {
  position: absolute;
  top: 1.5rem;
  left: 1.5rem;
  right: 1.5rem;
  display: flex;
  align-items: center;
  gap: 1.25rem;
}
.excl-progress {
  flex: 1;
  display: flex;
  gap: 0.5rem;
}
.excl-progress .seg {
  flex: 1;
  height: 0.5rem;
  border-radius: 0.625rem;
  background: rgba(255, 255, 255, 0.4);
  overflow: hidden;
}
.excl-progress .seg i {
  display: block;
  height: 100%;
  background: #fff;
  border-radius: 0.625rem;
  transition: width 40ms linear;
}
.excl-play {
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.5rem;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* The play/pause glyph is an inline <svg width="14" height="14"> — those
   attributes are CSS px and would stay 14 while the button scales, so the
   size is restated here in rem (14/16) to keep it inside the fluid system. */
.excl-play svg {
  width: 0.875rem;
  height: 0.875rem;
}

.excl-caption {
  position: absolute;
  left: 2.5rem;
  right: 2.5rem;
  bottom: 2.5rem;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.25rem;
}
.excl-caption p {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 2rem;
  color: #fff;
  margin: 0;
  max-width: 26.875rem;
}
.excl-chip {
  flex: none;
  width: 2.5rem;
  height: 5rem;
  border-radius: 0.5rem;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
}
.excl-chip img {
  width: 1.375rem;
  height: 1.375rem;
}

/* The two narrow-viewport fallbacks that used to live here (was 1300px / 980px)
   are GONE as of 2026-08-04: §2 now has a real mobile layout from Figma's 428
   design in home-mobile.css, which flexes the grid to a column and reorders the
   video above the copy. Keeping them only re-declared what that already does.
   See design-reference/mobile/MOBILE-NOTES.md. */

/* ============ SECTION 3 — Solar-PV as easy as 1-2-3 ============ */
/* The section box now carries the step conveyor's scroll track (see "the five
   step cards" below), so it runs ~1400px taller than its own content and the
   gradient can no longer live on it — it would stretch. The paint moves to
   .pvsec-bg, a 100vh sticky layer, which is also what the user asked for:
   "background ko pin rkhna" (2026-08-06).

   `overflow: clip` is what keeps cards 4 and 5 out of the document's scroll
   width — they rest off-stage to the right, at slot D = x1272 inside a 1260
   column. `clip` and NOT `hidden`: hidden would make this a scroll container
   and the sticky stage inside would stop pinning. */
.pvsec {
  position: relative;
  overflow: clip;
  padding: 2.75rem 0 6rem;
}
.pvsec-bg {
  position: sticky;
  top: 0;
  /* below .pv-wrap. A sticky element is positioned, so without the pair of
     z-indexes it would paint over the heading. */
  z-index: 0;
  display: block;
  height: 100vh;
  /* contributes no height at all, exactly like §4's .psh-bg */
  margin-bottom: -100vh;
  background: linear-gradient(to top, #e2fa5a 0%, rgba(226, 250, 90, 0) 96%);
  pointer-events: none;
}
.pv-wrap {
  position: relative;
  z-index: 1;
  max-width: 83.75rem;
  margin: 0 auto;
  padding: 0 2.5rem;
}

/* floating quick-nav pill */
.pv-pill {
  position: relative;
  z-index: 6;
  width: 40.5rem;
  max-width: 100%;
  height: 4.25rem;
  margin: 0 auto;
  background: #fff;
  border-radius: 0.75rem;
  box-shadow: 0 0.5rem 2.5rem rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.25rem;
}
.pill-menu {
  width: 3.75rem;
  height: 3.75rem;
  flex: none;
  border: 0.125rem solid var(--ink);
  border-radius: 0.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
}
.pill-menu span {
  display: block;
  width: 1.6875rem;
  height: 0.1875rem;
  background: #000;
  border-radius: 0.125rem;
}
.pill-ask {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.5rem;
  letter-spacing: -0.03rem;
  color: var(--ink);
  margin-left: 0.25rem;
}
.pill-experts {
  font-family: var(--font-sans);
  font-style: italic;
  font-size: 1rem;
  color: var(--ink-70);
}
.pill-cta {
  margin-left: auto;
}

/* floating fixed variant — slides up from the bottom on scroll */
.quickbar {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  z-index: 100;
  width: min(40.5rem, calc(100% - 2rem));
  transform: translateX(-50%) translateY(180%);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.35s ease;
}
.quickbar.is-visible {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
  pointer-events: auto;
}
.quickbar .pv-pill {
  width: 100%;
  margin: 0;
}

/* ---- desktop quickbar == the mobile quickbar (user's call, 2026-08-05) ----
   Three instructions, one block: drop the two copy lines "abi k liye", make it
   "mobile ki trah … hamburger or button", then "hamburger or button ki height
   same kro or darmyan main margin km kro". The end point is Figma's own mobile
   bar (`FRAME "Frame 113" 7053:259`, 259x68) rendered at desktop scale, so
   every number below is copied from home-mobile.css rather than invented.

   `display: none` rather than deleting the spans: the strings stay in
   StickyQuickBar.tsx (restoring them is deleting one rule, not re-typing copy)
   and `none` takes them out of the a11y tree too, which `visibility` or a clip
   would not.

   Geometry, left to right: 4 + burger 60 + gap 4 + CTA 186 + 5 = 259. The 648
   width was sized for the text, so the shell is restated at 259 and the
   existing `fixed` + `translateX(-50%)` keeps it centred. The gap drops 16 -> 4
   and `.pill-cta` goes 52 -> 60 tall to match `.pill-menu`, which it does
   through the CHIP (`.btn`'s padding is 10/10/10/16, so 10 + 40 + 10 = 60) —
   not through a height, so nothing has to be forced. Its 186 width is
   DECLARED for the same reason mobile declares it: the markup carries a
   trailing space after "Get a quote", that space is part of the anonymous flex
   item, and left to content the button measures ~191 and eats the gap.
   `space-between` then pins the chip at 186 - 10 - 40 = 136.

   Selectors stay unscoped (not `.quickbar .pv-pill`) on purpose: `.pv-pill`
   exists nowhere but this bar, and a scoped selector would outrank
   home-mobile.css's own unscoped copies of these rules on specificity even
   though that file loads later. Untouched: the 68 height, the r12, the shadow,
   the slide-up transition, and all of .pill-menu. */
.pill-ask,
.pill-experts {
  display: none;
}
.quickbar {
  width: 16.1875rem; /* 259 */
  max-width: calc(100% - 2rem);
}
.pv-pill {
  gap: 0.25rem; /* 4, was 16 */
  padding: 0.25rem 0.3125rem 0.25rem 0.25rem; /* 4 / 5 / 4 / 4 */
}
.pill-cta {
  flex: none;
  width: 11.625rem; /* 186 */
  justify-content: space-between;
  gap: 0;
  font-size: 1.25rem; /* 20 */
  line-height: 1.6rem; /* 25.6 */
}
.pill-cta .chip {
  width: 2.5rem; /* 40 -> 10 + 40 + 10 = 60, level with the burger */
  height: 2.5rem;
}
.pill-cta .chip img {
  width: 1.75rem; /* 28 */
  height: 1.75rem;
}

/* heading */
.pv-head {
  text-align: center;
  margin-top: 0.5rem;
  position: relative;
}
.pv-h {
  margin: 0;
  font-family: var(--font-display);
}
.pv-h .pv {
  display: inline-block;
  font-weight: 600;
  font-style: italic;
  font-size: 3.25rem;
  line-height: 3.75rem;
  background: linear-gradient(87.3deg, #111111 21.751%, #e2fa5a 136.65%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.pv-h .rest {
  display: block;
  font-weight: 400;
  font-size: 3.25rem;
  line-height: 3.75rem;
  letter-spacing: -0.08rem;
  color: var(--ink);
}

/* read how it works */
.pv-how {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 1.625rem;
}
.how-thumb {
  position: relative;
  width: 5rem;
  height: 5rem;
  border-radius: 0.5rem;
  border: 0.125rem solid var(--accent);
  overflow: hidden;
  flex: none;
}
.how-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.how-play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
}
.how-play svg {
  width: 0.75rem;
  height: 0.75rem;
}
.pv-how a {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1rem;
  color: var(--ink);
  text-decoration: underline;
}

/* ============ the five step cards — a scroll-driven conveyor ============
   User's spec, 2026-08-06: five steps instead of three, and once card 1 has
   reached the top the stack floats — card 1 peels away up-left at 45 degrees
   while 2 takes its place, 3 takes 2's, 4 takes 3's.

   THE MODEL: cards have no positions of their own. The stage has three SLOTS
   on Figma's own stair and five cards travel through them:

       A (0,0)  slot 0, opacity 1
             B (424,140)  slot 1, opacity .7
                   C (848,280)  slot 2, opacity .7
                         D (1272,420)  off-stage right, opacity 0
                               E (1696,560)

   424 = the 412 card + the 12 gap, 140 = Figma's stagger, so the slot lattice
   IS the approved resting render and p=0 reproduces it exactly. Five cards
   through three slots is TWO advances: [1,2,3] -> [2,3,4] -> [3,4,5].

   `--pv-p` (0 -> 2, fractional) is the ONLY thing PvSteps.tsx writes; every
   number below is derived from it in calc(), the same division of labour as
   InstallsCarousel's `--icar-pitch` — which is why home-mobile.css can opt
   out of the whole mechanism without the component knowing a breakpoint.

   THREE properties, THREE elements. `transform` on .pvc-card belongs to the
   hover layer (the -4px lift) and `translate` belongs to the motion layer
   (.pvc-card is a reveal target, variant `up`). The conveyor is a third
   consumer, so it drives a wrapper — .pvc-slot — and all three compose.

   The 45-degree exit is x and y travelling the same 520: clearing slot A
   needs x <= -412 and y <= -487, so 520 is the smallest equal pair with room
   to spare. The card is transparent by t=0.6 (312px in), long before it could
   reach anything above the section. */
@property --pv-p  { syntax: "<number>";  inherits: true;  initial-value: 0; }
@property --pv-i  { syntax: "<integer>"; inherits: false; initial-value: 0; }
@property --pv-s  { syntax: "<number>";  inherits: false; initial-value: 0; }
@property --pv-sc { syntax: "<number>";  inherits: false; initial-value: 0; }
@property --pv-t  { syntax: "<number>";  inherits: false; initial-value: 0; }
@property --pv-o  { syntax: "<number>";  inherits: true;  initial-value: 1; }

/* 767 of stage + 2 advances x 700 of scroll each. The stage must sit FLUSH at
   the track's top — PvSteps.tsx derives the progress from
   (stage.top - track.top), so a margin here and not on the track would offset
   it. That is also why the old .pv-cards margin-top lives on the track now. */
.pv-track {
  margin-top: 3.5rem;
  height: 135.4375rem;
}
.pv-cards {
  position: sticky;
  /* the 80px gap the user asked for before it starts floating */
  top: 5rem;
  height: 47.9375rem; /* 767 = slot C's 280 + the 487 card */
}
.pvc-slot {
  --pv-s: calc(var(--pv-i) - var(--pv-p)); /* fractional slot number */
  --pv-sc: max(var(--pv-s), 0); /* on-stage part */
  --pv-t: clamp(0, calc(0 - var(--pv-s)), 1); /* exit progress */
  /* exit fade x entry fade x the slot's own dim. The dim is 1 -> 0.8 (raised
     from Figma's 0.7 on the user's instruction, 2026-08-06). Note the entry
     factor keeps an off-stage card at exactly 0, which the hover rule relies
     on — and the hover's `* 1.5` still clears 1 from 0.8 (needs >= 1.25). */
  --pv-o: calc(
    clamp(0, calc((0.6 + var(--pv-s)) / 0.6), 1) * clamp(0, calc(3 - var(--pv-s)), 1) *
      (1 - 0.2 * clamp(0, var(--pv-s), 1))
  );
  position: absolute;
  left: 0;
  top: 0;
  width: 25.75rem;
  /* card 1 highest: the only overlap in the whole run is a peeling card
     crossing the one arriving behind it, and it must pass in front */
  z-index: calc(20 - var(--pv-i));
  translate: calc(26.5rem * var(--pv-sc) - 32.5rem * var(--pv-t))
    calc(8.75rem * var(--pv-sc) - 32.5rem * var(--pv-t));
}
.pvc-card {
  position: relative;
  /* keeps the hover shadow and the sketch zoom self-contained */
  isolation: isolate;
  width: 100%;
  height: 30.4375rem;
  opacity: var(--pv-o);
  background: #fff;
  border-radius: 0.75rem;
  /* Figma: title at +40,+32; text column 300 wide (40 -> 340), so right pad 72 */
  padding: 2rem 4.5rem 0 2.5rem;
  /* Figma effects: [] on all three cards — no shadow */
}
/* Figma's faint panels extending slots A and B down to the common 767
   baseline (0+767, 140+627, 280+487 — slot C needs none). They belong to the
   SLOT, not the card: one that travelled with its card would tear the stair
   apart, which is why these are static siblings and no longer ::before. */
.pvc-fill {
  position: absolute;
  z-index: 0;
  width: 25.75rem;
  background: rgba(255, 255, 255, 0.24);
  border-radius: 0.75rem;
}
.pvc-fill-a {
  left: 0;
  top: 0;
  height: 47.9375rem;
}
.pvc-fill-b {
  left: 26.5rem;
  top: 8.75rem;
  height: 39.1875rem;
}

/* ---- no JS, or reduced motion: the same five cards as a static two-row
   stair, 3 + 2. One row cannot hold five slots (5 x 424 = 2120 against a 1260
   column), so the second row restarts the stair. Every conveyor declaration
   is undone with a matching selector, so source order alone decides and there
   is no !important anywhere. The pinned background is deliberately kept —
   sticky is not motion. */
@media (scripting: none), (prefers-reduced-motion: reduce) {
  .pv-track {
    height: auto;
  }
  .pv-cards {
    position: static;
    height: auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 0.75rem;
  }
  .pvc-slot {
    --pv-o: 0.8;
    position: static;
    flex: none;
    translate: none;
    z-index: auto;
  }
  .pvc-slot[data-step="1"],
  .pvc-slot[data-step="4"] {
    --pv-o: 1;
  }
  .pvc-slot[data-step="2"],
  .pvc-slot[data-step="5"] {
    margin-top: 8.75rem;
  }
  .pvc-slot[data-step="3"] {
    margin-top: 17.5rem;
  }
  .pvc-fill {
    display: none;
  }
}
.pvc-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}
/* Solid ink, NOT the dark->lime italic gradient Figma paints here — the user
   asked for it flat on 2026-08-06 ("make background simple this color gradient
   ko hta do"), pointing at this rule with #111111 typed into it. A deliberate
   deviation from same-to-same, so it is written down rather than inferred.
   #111111 is the gradient's own first stop, i.e. what the glyphs already read
   as across most of the box. The clip/fill machinery goes with it: keeping
   `background-clip: text` without a paint does nothing, and keeping the paint
   without the clip would render a solid bar over the letters. */
.pvc-title {
  display: inline-block;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 2.5rem;
  line-height: 3.75rem;
  color: #111111;
}
.pvc-num {
  display: inline-block;
  /* Figma: same gradient but fill.opacity 0.4 */
  opacity: 0.4;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 1.25rem;
  line-height: 3.75rem;
  background: linear-gradient(87.3deg, #111111 21.751%, #e2fa5a 136.65%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.pvc-desc {
  /* Figma: body at +40,+100; title box ends at 92 -> 8px gap */
  margin: 0.5rem 0 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.525rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
  max-width: 18.75rem;
}
/* Figma: image rect 404x223 at +(-8),+232, scaleMode FILL, card clipsContent.
   The 8px left overhang is clipped away, so the visible box is 396x223 at
   left 0 (16px inset from the card's right edge) showing the right of the fill. */
/* The wrapper carries the sketch's absolute box (constraints vertical TOP at
   +232) and clips the hover zoom. It has to exist because .pvc-card cannot take
   overflow:hidden — that would cut off the z-index:-1 filler panel above. */
.pvc-sketchwrap {
  position: absolute;
  left: 0;
  top: 14.5rem;
  width: 24.75rem;
  height: 13.9375rem;
  display: block;
  overflow: hidden;
}
.pvc-sketch {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 100% 50%;
}

/* The narrow-viewport fallback that used to live here (was 1100px, moved to
   767.98px when the fluid floor dropped) is GONE as of 2026-08-04: §3 now has a
   real mobile layout from Figma's 428 design in home-mobile.css, and the two
   fought each other — its `min-height: 28.75rem` beat the real 439 card height.
   See design-reference/mobile/MOBILE-NOTES.md. */

/* ==========================================================================
   SECTION 4 — PRODUCT SHOWCASE
   Figma FRAME "Frame 81" [5134:157] 0,3465 1920x1894 clip
   Namespace .pshow / .psh-*  (verified unused in home.css, base.css)
   ========================================================================== */
.pshow {
  position: relative;
  /* Frame 81 clipsContent; no fill -> page #fefff9 shows.
     MUST be `clip`, not `hidden`: `hidden` makes this a scroll container, which
     silently no-ops position:sticky on .psh-bg / .psh-left (computed style still
     reads "sticky", it just renders like "static"). `clip` clips without
     creating a scrollport, so the sticky children keep using the viewport. */
  overflow: clip;
}
/* FRAME "Modern white building on a cliff..." IMAGE fill.
   Pinned full-viewport backdrop for the whole section: sticky at top:0 with a
   -100vh bottom margin so it occupies no flow space (section height stays
   102 + cards + 102). .pshow's `clip` trims it as the section exits. */
.psh-bg {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100vh;
  margin-bottom: -100vh;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}
.psh-bg img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* RECTANGLE "Rectangle 3" 1920x526, linear #fff -> transparent, fill opacity .32 */
.psh-bg-fade {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 32.875rem;
  background: linear-gradient(to bottom, #ffffff 0%, rgba(255, 255, 255, 0) 100%);
  opacity: 0.32;
}

/* content band 1260 wide (x 330..1590): left col 501 + gap 139 + cards 620 */
.psh-wrap {
  position: relative;
  z-index: 1;
  width: 78.75rem;
  margin: 0 auto;
  padding: 6.375rem 0; /* content starts y3567; section ends y5359 */
  display: flex;
  align-items: flex-start;
  gap: 8.6875rem;
}
/* Pinned text column: full viewport height, 80px breathing room top + bottom.
   flex-start so the inline-flex .psh-btn doesn't stretch to the column width.

   KNOWN ISSUE, deliberately left in place (see design-lock.json
   known_deviations.psh-left-100vh): `100vh` is the one length in this section
   that does not scale with the design, and as a flex item this column's height
   feeds .psh-wrap. So whenever the scaled card stack falls below the window
   height, this column — not the cards — dictates the section height: at 1000px
   wide the stack is 890 but 100vh is 1000, so §4 renders ~120px too tall and
   every section below it shifts down by the same amount. Also reachable at 1920
   on a window taller than 1690px. The one-line fix is `margin-bottom: -100vh`
   (the trick .psh-bg already uses 30 lines above), verified a no-op at the 1920
   canvas — but the design is LOCKED, so do not apply it without the user asking. */
.psh-left {
  position: sticky;
  top: 0;
  box-sizing: border-box;
  width: 31.3125rem;
  height: 100vh;
  padding: 5rem 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* ---- heading TEXT [5134:295] 315x141, Host Grotesk 64/70.4 ls -1.28 ---- */
.psh-h {
  position: relative;
  width: 19.6875rem;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 4rem;
  line-height: 4.4rem;
  letter-spacing: -0.08rem;
  color: var(--ink);
}
/* VECTOR "Vector 1" 296x0 stroke #E2FA5A w12 -> lime highlight behind line 2 */
.psh-h-bar {
  position: absolute;
  left: 0;
  top: 7rem;
  /* Sized to the word it underlines, with Figma's own ~2.6px overhang past the
     glyphs. Was 18.5rem (296) for "installation", which measures 293.41; then
     14.875rem (238) for "included" (235.56) on 2026-08-13; now "Package"
     (239.68) as of 2026-08-17, again on the user's instruction that the line
     sit under the new word exactly as it did under the old one. The 2.44
     overhang is carried across each time. RE-MEASURE IF THE WORD CHANGES. */
  width: 15.125rem;
  height: 0.75rem;
  background: var(--accent);
  z-index: 0;
}
.psh-h-thin,
.psh-h-em {
  position: relative;
  z-index: 1;
}
.psh-h-thin {
  color: var(--ink-70); /* HostGrotesk-Regular 400, #111 @ fill.opacity .7 */
}
.psh-h-em {
  font-weight: 600; /* HostGrotesk-SemiBoldItalic */
  font-style: italic;
  color: var(--ink);
}

/* ---- check badges FRAME 16 [5134:282] 470x24, gap 24 ---- */
.psh-checks {
  margin: 2rem 0 0; /* heading bottom 141 -> 173 */
  padding: 0;
  list-style: none;
  display: flex;
  /* Figma runs these two side by side on one 470-wide row. Stacked on
     2026-08-13 ("ye 2 points ko ek dosre k niche le ao"). The 16 row gap is the
     one every other tick list on this page already uses (.psh-bullets,
     .sob-bullets), rather than reusing the 24 that was the COLUMN gap.
     Desktop only by construction — home-mobile.css sets `display: none`. */
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
}
.psh-checks li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.22rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
  white-space: nowrap;
}
.psh-checks img {
  flex: 0 0 1.5rem;
  width: 1.5rem;
  height: 1.5rem;
}

/* ---- lime callout FRAME 17 [5134:279] 333x111 r8 #E2FA5A stroke #111 w2 ---- */
.psh-callout {
  box-sizing: border-box;
  width: 20.8125rem;
  height: 6.9375rem;
  margin: 3.75rem 0 0; /* checks bottom 197 -> 257 */
  border: 0.125rem solid var(--ink);
  border-radius: 0.5rem;
  background: var(--accent);
  text-align: center;
}
.psh-callout-t {
  margin: 0.625rem 0 0; /* -> box y 12 */
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 2rem;
  line-height: 2.66rem;
  letter-spacing: -0.08rem;
  color: var(--ink);
}
.psh-callout-s {
  margin: 0.25rem 0 0; /* -> box y 59 */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 1.995rem;
  letter-spacing: -0.08rem;
  color: var(--ink-70);
}

/* ---- reviews row FRAME 12 [5134:296] 501x24, gap 12 ---- */
.psh-reviews {
  /* Figma's fixed 349px gap (callout bottom 368 -> 717) becomes `auto` so the
     reviews + CTA bottom-anchor inside the 100vh column, honouring its 80px
     bottom padding at any viewport height. Same trick as §11's contact card. */
  margin: auto 0 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.psh-reviews p {
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.525rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
  white-space: nowrap;
}
.psh-reviews p em {
  font-weight: 600; /* InstrumentSans-SemiBoldItalic */
  font-style: italic;
}
/* .tp-stars 125x24 / .tp-logo 94x24 reused from home.css: their crop
   transforms already match Figma "image 111" / "image 110" exactly.
   Row gap is 12, but Figma's stars->logo gap is 6, so pull it back 6. */
.psh-reviews .tp-stars + .tp-logo {
  margin-left: -0.375rem;
}

/* ---- "Link - Solid Black" 60 tall r12 #111 pad 10/10/10/16 gap 9.99 ---- */
.psh-btn {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  gap: 0.624375rem;
  height: 3.75rem;
  padding: 0.625rem 0.625rem 0.625rem 1rem;
  border-radius: 0.75rem;
  background: var(--ink);
  /* Figma gives this button `effects: []`. The cast shadow that used to appear
     only on hover was promoted to the RESTING state on 2026-08-13 ("button ko
     shadow do like hover main jo diya howa") — same values, so the two states
     stay one family. Not clipped by this element's own `overflow: hidden`
     (that is for the sheen; an outer box-shadow paints outside it anyway). */
  box-shadow: 0 0.875rem 1.875rem -0.875rem rgba(17, 17, 17, 0.7);
  color: #fff;
  text-decoration: none;
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.6rem;
  letter-spacing: -0.01rem;
  white-space: nowrap;
}
.psh-btn-ico {
  flex: 0 0 2.5rem;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.5rem;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
}
.psh-btn-ico img {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
}
.psh-btn-reviews {
  margin: 1.5rem 0 0 0.25rem; /* Figma x=334 vs band x=330 */
}

/* ---- cards column: 620 wide, 24px gaps (558 + 24 + 542 + 24 + 542) ---- */
.psh-cards {
  width: 38.75rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.psh-card {
  position: relative;
  box-sizing: border-box;
  width: 38.75rem;
  /* Figma is 20 top / 24 sides / 16 bottom. Opened up to 32 top and sides on
     2026-08-13 ("solar panel text k uper se or side se margin brhao"). Two
     things are keyed to the SIDE value and had to move with it: `.psh-bullets`
     declared 572 (620 - 24 - 24), and `.psh-rule`'s negative margin, which is
     what makes the dashed line full-bleed. `.psh-shot` and `.psh-logo-onshot`
     are absolute, so padding does not touch them. */
  padding: 2rem 2rem 1rem;
  background: #fff;
  border-radius: 0.5rem;
  overflow: hidden; /* clipsContent */
}
/* brand logos: h20; widths 54 / 112 / 60 */
.psh-logo {
  display: block;
  height: 1.25rem;
}
.psh-logo-longi {
  width: 3.375rem;
}
/* Figma stacks the brand mark above the title. The LONGi one moved onto the
   product cut-out on 2026-08-13 — first its bottom-right corner, then CENTRED
   along its bottom edge with a 20px inset ("logo ko image k center bottom main
   kro or niche se 20px margin de dena"). Both offsets are written as calcs off
   `.psh-shot`'s own box — absolute at (356,48) 240x240 — rather than as bare
   numbers, so the relationship survives if that box is ever resized:
     right = the shot's 24 inset + half its leftover width -> centre on x476
     top   = 48 + 240 - 20 margin - 20 mark height = 248 */
/* Centred on the shot's column WITHOUT knowing the mark's own width: left and
   right are pinned to the shot's two edges (356 and the card's 24 inset) and
   `margin-inline: auto` does the centring. That matters because the three marks
   are different widths — LONGi 54, Enphase 112, AlphaESS 60 — so a calc built
   off any one of them would mis-centre the other two. No transform, so nothing
   here can collide with the motion layer. */
.psh-logo-onshot {
  position: absolute;
  left: 22.25rem;                 /* = .psh-shot's left  */
  right: 1.5rem;                  /* = .psh-shot's right */
  margin-inline: auto;
  top: 1rem;                      /* 16 — the user's own value */
}
.psh-logo-enphase {
  width: 7rem;
}
.psh-logo-alphaess {
  width: 3.75rem;
}
/* Figma's own weight and offsets. The 2026-08-13 bolding and 8px left margin
   are MOBILE ONLY ("ye sirf mobile main change krni hai") — see home-mobile.css.
   A soft text-shadow went on with them and came straight back off ("shadow hta
   do title k peeche se"); do not reintroduce it on either breakpoint. */
.psh-title {
  margin: 0.5625rem 0 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2rem;
  line-height: 2.66rem;
  letter-spacing: -0.08rem;
  color: var(--ink);
}
.psh-sub {
  width: 19.5625rem; /* drives the exact 2-line wrap */
  margin: 0.5rem 0 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.525rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}
.psh-card .psh-btn {
  margin-top: 2.5rem;
}
/* product cutout RECTANGLE "image 123" 240x240 at card-relative 356,48 */
.psh-shot {
  position: absolute;
  left: 22.25rem;
  top: 3rem;
  width: 15rem;
  height: 15rem;
  object-fit: cover;
}
/* DESKTOP-ONLY looping clip, card 1 (2026-08-17). It replaces the cut-out AND the
   brand mark above it, because the clip carries its own logos — so the box is the
   union of the two, at the user's own numbers: 240 wide x 270 tall ("box for video
   270px*240px ka hojay ga or uper se thori space aa jay gi").
     top    = 288 - 270 = 18, i.e. the shot's BOTTOM edge stays exactly where it
              was and the box grows 30px upward into the band `.psh-logo-onshot`
              occupied at y16 — hence the 2px of space left at the top.
     height = 270. The source is 480x540, exactly 2x the box, so `object-fit:
              cover` crops nothing and the browser gets the clean 2:1 downscale
              (the `logo-2x.webp` sharpness rule).
   Width is NOT restated, so the horizontal footprint is identical to the still's.
   Nothing below can move: the element is absolute, so the card's flow (title /
   blurb / CTA / bullets at y320.78) never sees it — verified by A/B in the live
   DOM. This only MODIFIES `.psh-shot`, so the hover zoom and its transition come
   free; `.d-only` / `.m-only` in home-mobile.css hide it below 768, where the
   still is what ships. */
.psh-shot-vid {
  top: 1.125rem; /* 18 */
  height: 16.875rem; /* 270 */
}
/* bullet list FRAME 16: 572 wide, rows gap 16, icon 24 + gap 8 + text 540 */
/* Figma stacks these one per row. The client's four short points go TWO-UP as
   of 2026-08-13 ("2 point k samne 2 points"), so the list is a 2-column grid:
   572 - 24 gap = 274 per column, of which the 24 icon + 8 gap leave 242 for the
   text. Mobile stays one per row — see home-mobile.css, where the card is only
   340 wide and a second column would leave ~130 for the text. */
.psh-bullets {
  /* was a declared 35.75rem (572 = 620 - 24 - 24); the card's side padding moved
     to 32, so the width comes from the content box instead of a second number
     that has to be kept in sync. */
  width: auto;
  /* Figma's 84 existed to clear `.psh-shot`, which is absolute and ends at y288.
     Cut to 40 on 2026-08-13 ("points k uper se margin km kro"), then nudged back
     to 56 the same day ("thora sa margin brhao") — the CTA above it is a solid
     black block and 40 read tight against it.
     RE-MEASURE against the shot's 288 before cutting this below ~24. */
  margin: 3.5rem 0 0;
  padding: 0;
  list-style: none;
  /* Figma stacks these one per row; two-up here since 2026-08-13 ("2 point k
     samne 2 points"). A fixed 274 track per column: 572 - 24 gap, of which the
     24 icon + 8 gap leave 242 for the text. The content-packing variant that
     briefly replaced this is MOBILE ONLY ("ye b sirf mobile main changes krni
     hai") — see home-mobile.css. */
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem 1.5rem;
  /* the user's own values, from DevTools 2026-08-13 — a faint panel behind the
     points with a dashed edge. DESKTOP ONLY ("web main" / "web pe"), so
     home-mobile.css resets all four. `box-sizing` is border-box globally, so the
     16 padding + 2 border come out of the 556, leaving 520 for the two tracks.
     RECOLOURED FROM LIME TO INK on 2026-08-14, again the user's own DevTools
     values, hex8 verbatim: the edge was rgba(226,250,90,.6) and the panel
     rgba(226,250,90,.12). #11111124 is ink at 14.1%, #11111110 ink at 6.3%.
     Geometry-neutral by construction — padding, border width and radius are
     untouched, so nothing reflows (measured: card heights 510.94 x3 / 486.53 x2,
     list 556x100, track 248, docH 14790 all identical before and after). */
  padding: 1rem;
  border: 0.125rem dashed #11111124;
  border-radius: 0.75rem;
  background: #11111110;
}
.psh-bullets li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.psh-bullets img {
  flex: 0 0 1.5rem;
  width: 1.5rem;
  height: 1.5rem;
}
.psh-bullets span {
  /* was 33.75rem (540), the full text column of the old one-per-row list; the
     2-column grid sizes the track instead. min-width:0 lets a long point wrap
     inside its cell rather than blowing the track out. */
  min-width: 0;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.22rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
}
/* VECTOR "Vector 9": full-bleed 620, 1px, #111 @ .12, strokeDashes [8,8] */
.psh-rule {
  display: block;
  height: 0.0625rem;
  /* the negative side margin MUST equal the card's side padding, or the dashed
     line stops being full-bleed. Moved 24 -> 32 with it on 2026-08-13.
     The top gap is the space UNDER the points; cut 40 -> 24 the same day
     ("points k niche se km kro margin"). */
  margin: 1.5rem -2rem 0;
  background-image: repeating-linear-gradient(
    to right,
    rgba(17, 17, 17, 0.12) 0 0.5rem,
    transparent 0.5rem 1rem
  );
}
.psh-note {
  margin: 0.9375rem 0 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.psh-note img {
  flex: 0 0 1.5rem;
  width: 1.5rem;
  height: 1.5rem;
}
.psh-note p {
  width: 33.75rem;
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 0.875rem;
  line-height: 1.0675rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}

/* The narrow-viewport fallback that used to live here (was 1320px, moved to
   767.98px when the fluid floor dropped) is GONE as of 2026-08-05: §4 now has a
   real mobile layout in home-mobile.css, built from Figma's own mobile frame
   7053:60. That fallback was authored as a narrow-DESKTOP fallback and fought
   the real numbers — its `width: auto` on .psh-sub / .psh-bullets span and its
   static 200px .psh-shot all had to be undone. */

/* ==========================================================================
   SECTION 5 — TRUST BAND ("Trust us, you can trust us.")
   Figma FRAME "Frame 124" [5142:2414] 12,5359 1896x436 r=12 fill #000000
          effects:[] strokes:[] clipsContent  constraints TOP/CENTER
   Content GROUP "Group 10" [5142:2415] 342,5479 1260x196 (CENTER/CENTER)
   Namespace .tband-*  (.trust-* is TAKEN by home.css:521 — do not use)
   ========================================================================== */
.tband-sec {
  position: relative;
}
/* band: 1896 of 1920 -> 12px gutters. Content 1260 wide sits at band-relative
   x330 (330 left / 306 right — Figma is NOT symmetric here), which the
   24px left padding on a centred flex child reproduces exactly:
   24 + (1896-24-1260)/2 = 330. */
.tband {
  width: 118.5rem;
  max-width: calc(100% - 1.5rem);
  margin: 0 auto;
  border-radius: 0.75rem;
  background: #000000;
  overflow: hidden; /* clipsContent: true */
  display: flex;
  justify-content: center;
  padding: 7.5rem 0 7.5rem 1.5rem; /* 5479-5359 = 120 top; 5795-5675 = 120 bottom */
}
/* 285 + 40 + 285 + 40 + 285 + 40 + 285 = 1260 */
.tband-inner {
  width: 78.75rem;
  display: flex;
  align-items: flex-start;
  gap: 2.5rem;
}

/* ---- TEXT [5142:2416] 285x112, vertically centred in the 196-tall group ---- */
.tband-title {
  width: 17.8125rem;
  flex: none;
  align-self: center; /* group 196, title 112 -> +42 == Figma y5521 */
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 3rem;
  line-height: 3.5rem;
  letter-spacing: -0.08rem;
  color: #ffffff;
}

/* ---- the three stat columns (285 wide, text centred) ---- */
.tband-col {
  position: relative;
  width: 17.8125rem;
  flex: none;
}
/* VECTOR "Vector 7"/"Vector 8" [5142:2426/2427] 972,5480 & 1297,5480
   0x195, stroke 2px dash [8,8] -> Figma scales to 8.125/8.125 over 195
   (12 exact periods) with a half-dash phase offset; stroke paint is a
   vertical GRADIENT_LINEAR white 0 -> white 1 @52.4% -> white 0, opacity .12 */
.tband-col + .tband-col::before {
  content: "";
  position: absolute;
  left: -1.3125rem; /* gap 40 -> centre 972; 2px wide */
  top: 0.0625rem; /* group top 5479, vector top 5480 */
  width: 0.125rem;
  height: 12.1875rem;
  background-image: repeating-linear-gradient(
    to bottom,
    #ffffff 0 0.25390625rem,
    rgba(255, 255, 255, 0) 0.25390625rem 0.76171875rem,
    #ffffff 0.76171875rem 1.015625rem
  );
  -webkit-mask-image: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0%,
    #000000 52.403843%,
    rgba(0, 0, 0, 0) 100%
  );
  mask-image: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0%,
    #000000 52.403843%,
    rgba(0, 0, 0, 0) 100%
  );
  opacity: 0.12;
}

/* ---- logo slot: all three rects are 80 tall, top-aligned at group y0 ---- */
.tband-logo {
  height: 5rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tband-logo img {
  display: block;
  object-fit: cover; /* scaleMode FILL (source aspect already matches) */
}
.tband-logo-which {
  width: 10.625rem;
  height: 5rem;
} /* image 115 */
.tband-logo-sq {
  width: 5rem;
  height: 5rem;
} /* image 118 / 119 */

/* ---- TEXT 285x64, Host Grotesk 400 24/32 ls -1.28, #fff, centred ---- */
.tband-t1 {
  margin: 1rem 0 0; /* logo bottom y5559 -> text top y5575 */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 2rem;
  letter-spacing: -0.08rem;
  text-align: center;
  color: #ffffff;
}
/* ---- TEXT 285x32, Host Grotesk 400 16/32 ls -1.28, #fff fill-opacity .7 ---- */
.tband-t2 {
  margin: 0.25rem 0 0; /* t1 bottom y5639 -> t2 top y5643 */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1rem;
  line-height: 2rem;
  letter-spacing: -0.08rem;
  text-align: center;
  color: rgba(255, 255, 255, 0.7);
}

/* The TWO narrow-viewport fallbacks that used to live here (a 1320px block moved
   to 767.98px, plus a 720px block that was already below the floor) are GONE as
   of 2026-08-05: §5 now has a real mobile layout in home-mobile.css, built from
   Figma's own mobile frame 7053:242. Both were narrow-DESKTOP fallbacks and
   fought the real numbers — the 720 one shrank the title to 36/42 where Figma
   mobile keeps the full 48/56, and it hid the dashed dividers outright, where
   mobile turns them into full-bleed horizontal rules. */

/* ==========================================================================
   SECTION 6 — "Solar installations without salespeople" CAROUSEL
   Figma heading TEXT [5142:2429] 330,5915 454x64 (Host Grotesk 600 italic 60/64)
         sub     TEXT [5142:2428] 330,5983 310x56 (Host Grotesk 400 36/56 #111@.7)
         nav     [5142:2778] 1502,5951 & [5142:2774] 1550,5951  40x64 r8 #111@.08
         sheet   RECTANGLE "Rectangle 15" [5142:3021] 318,6067 757x632 r12 #fff
                 DROP_SHADOW #000@0.16 off(0,4) blur40
         slides  330 / 1095 / 1860, 733x608  -> pitch 765 (733 + 32 gap)
   Namespace .icar-*  (verified unused in home.css, base.css)
   ========================================================================== */
.icar {
  position: relative;
  /* Homepage frame clipsContent: slide 3 is cut off at the canvas edge */
  overflow: hidden;
  /* section 5 ends y5795 -> heading y5915; slides end y6687 -> section 7 y6807 */
  padding: 7.5rem 0;
}

/* ---- heading row (content column 330..1590) ---- */
.icar-head {
  position: relative;
  width: 78.75rem;
  margin: 0 auto;
}
.icar-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 3.75rem;
  line-height: 4rem;
  letter-spacing: -0.08rem;
}
/* GRADIENT_LINEAR handles (0,.5)->(1.3722,.0943), stops #111 @.5144 / #e2fa5a @1
   -> over the 454x64 text box: 87.61deg, 70.59%, 136.95% */
.icar-h-em {
  display: inline-block;
  background: linear-gradient(87.61deg, #111111 70.59%, #e2fa5a 136.95%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.icar-sub {
  margin: 0.25rem 0 0; /* heading box ends y5979 -> sub box y5983 */
  /* Figma's box is 310, which held "without salespeople." on one line. The copy
     became "for long-term savings" on 2026-08-13, which needs 330 and was
     wrapping to two lines (+56 on the whole section). 336 restores the single
     line with 6px of slack against font-metric drift — the same reason
     .iexc-chips carries 4px. Mobile is unaffected: home-mobile.css sets
     `width: auto` on this element. */
  width: 21rem;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2.25rem;
  line-height: 3.5rem;
  letter-spacing: -0.08rem;
  color: var(--ink-70);
}

/* ---- prev / next ---- */
.icar-nav {
  position: absolute;
  right: 0;
  top: 2.25rem; /* 5951 - 5915 */
  display: flex;
  gap: 0.5rem; /* 1550 - 1542 */
}
.icar-navbtn {
  width: 2.5rem;
  height: 4rem;
  border: 0;
  border-radius: 0.5rem;
  background: var(--ink-08);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
}
.icar-navbtn:disabled {
  cursor: default; /* Figma defines no disabled state -> no visual change */
}
.icar-navico {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
}
/* both nav vectors are the same geometry in the spec; the render shows the
   first one mirrored */
.icar-navico-prev {
  transform: scaleX(-1);
}

/* ---- track ---- */
.icar-viewport {
  /* left padding lands the track on the content column (x330) while the
     section's own overflow:hidden clips the overflowing slides */
  margin-top: 2.5rem; /* sub box ends y6039 -> slide top y6079 */
  padding-left: calc((100% - 78.75rem) / 2);
  /* the strip is draggable (below 768 it is a native scroller instead) */
  cursor: grab;
}
.icar-track {
  --icar-pitch: 47.8125rem; /* 733 card + 32 gap */
  --icar-i: 0;
  /* live pointer-drag offset, written by InstallsCarousel (px, by ref) */
  --icar-drag: 0px;
  display: flex;
  gap: 2rem;
  width: max-content;
  /* Travel is CLAMPED to the track's own overhang, so the LAST slide END-ALIGNS
     with the content column's right edge — i.e. with the nav buttons above it —
     instead of parking at the column's left with ~527px of dead space to its
     right (user, 2026-08-13). A percentage in a translate resolves against the
     element's OWN box, and the track is `width: max-content`, so `100%` is the
     whole strip: `100% - 78.75rem` is exactly `trackWidth - column`. That makes
     the clamp self-calibrating — add or resize a slide and it follows, the same
     division of labour --icar-pitch already has for the step. */
  transform: translateX(
    calc(var(--icar-drag) - min(var(--icar-i) * var(--icar-pitch), 100% - 78.75rem))
  );
  transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}
/* while a drag is live: no easing to fight the finger, no text selection, and
   the grabbing cursor forced past the CTA's own UA `pointer` */
.icar-track.is-dragging {
  transition: none;
  user-select: none;
}
.icar-track.is-dragging,
.icar-track.is-dragging * {
  cursor: grabbing;
}
.icar-slide {
  position: relative;
  width: 45.8125rem;
  flex: none;
}
/* the active slide sits on a white sheet inset -12px on all sides */
.icar-slide.is-active::before {
  content: "";
  position: absolute;
  inset: -0.75rem;
  border-radius: 0.75rem;
  background: #ffffff;
  box-shadow: 0 0.25rem 2.5rem rgba(0, 0, 0, 0.16);
  z-index: 0;
}
.icar-slide > * {
  position: relative;
  z-index: 1;
}

/* ---- card 733x460 r12 clip ---- */
.icar-card {
  position: relative;
  height: 28.75rem;
  border-radius: 0.75rem;
  overflow: hidden; /* clipsContent: true */
}
/* Frame 125: fill #fff + stroke #000@0.12 w2 INSIDE */
.icar-card-1 {
  background: var(--white);
  box-shadow: inset 0 0 0 0.125rem rgba(0, 0, 0, 0.12);
}
/* Frame 126 [5142:2784]: fill #e2fa5a@0.40 (sits under the photo) */
.icar-card-2 {
  background: rgba(226, 250, 90, 0.4);
}
/* Frame 126 [5142:2521]: fill #fff + stroke #111 w2 INSIDE + INNER_SHADOW lime blur40 */
.icar-card-3 {
  background: var(--white);
  box-shadow: inset 0 0 0 0.125rem #111111, inset 0 0 2.5rem #e2fa5a;
}
.icar-photo {
  position: absolute;
  max-width: none; /* beats base.css `img { max-width: 100% }` — the rect is
                      wider than the card it is clipped by */
  object-fit: cover; /* scaleMode FILL */
}
/* VECTOR group [5383:3306/3308/3311/3309] — Vector 12 origin card-rel 139,60,
   SVG is padded 3px for the 6px centre-aligned stroke */
.icar-overlay {
  position: absolute;
  left: 8.5rem;
  top: 3.5625rem;
  width: 15.09375rem;
  height: 6.5625rem;
}

/* ---- dot-grid card (Figma placeholder graphic on slide 3) ---- */
.icar-dots {
  position: absolute;
  inset: 2rem; /* 1892-1860 = 32 all round */
  display: flex;
  flex-direction: column;
  justify-content: space-between; /* 10 rows over 396px */
}
.icar-dotrow {
  display: flex;
  justify-content: space-between; /* 18 dots over 669px */
}
.icar-dotrow span {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--accent);
}

/* ---- label TEXT 733x40, Host Grotesk 400 32/40 ls -1.28 ---- */
.icar-label {
  margin: 1.25rem 0 0; /* card ends y6539 -> label y6559 */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2rem;
  line-height: 2.5rem;
  letter-spacing: -0.08rem;
  color: var(--ink);
}

/* ---- bullets + CTA row, y6623..6687 ---- */
.icar-foot {
  margin-top: 1.5rem; /* label ends y6599 -> row y6623 */
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}
/* FRAME "Frame 16" [5142:2436] 468x64 AUTO HORIZONTAL WRAP gap24 / counterAxis16 */
.icar-bullets {
  width: 29.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
}
.icar-bullets li {
  height: 1.5rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.icar-bullets img {
  flex: 0 0 1.5rem;
  width: 1.5rem;
  height: 1.5rem;
  opacity: 0.7; /* the Success vectors are #111111 @ fill-opacity .70 */
}
.icar-bullets span {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.22rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
  white-space: nowrap;
}
/* FRAME "Arrow Icon Wrapper" [5142:2514] 40x64 r8 fill #e2fa5a */
.icar-cta {
  flex: none;
  width: 2.5rem;
  height: 4rem;
  border-radius: 0.5rem;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
}
.icar-cta img {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
}

/* The TWO narrow-viewport fallbacks that used to live here (1320px and 820px,
   both moved to 767.98px when the fluid floor dropped) are GONE as of
   2026-08-05: §6 now has a real mobile layout in home-mobile.css, built from
   Figma's own mobile frame. Both were narrow-DESKTOP fallbacks and fought the
   real numbers hard — they shrank the heading to 40/44 and the caption to 24/32
   where Figma mobile keeps 48/56 and 32/40, dropped `.icar-sub`'s width, and
   drove the slide pitch off `100vw` instead of Figma's 364. */

/* ============================================================================
   SECTION 7 — "An exclusive installations" lime panel
   Figma FRAME "Frame 78" [5142:1262] 330,6807 1260x671 r=12 fill #e2fa5a clip
   Left column  : padding 80 (text at +80,+80 / chips at +80,+411, 502x180)
   Right column : inset 32 top/right/bottom, 598 wide
                  card  [5142:1322] +32   598x206 r8 #fff
                  shot  [5142:3025] +250  598x389 r12 #111
   Heights fall out exactly: 80+37.24-2.24+64+8+64+160+180+80 = 671
                             32+206+12+389+32                 = 671
   ========================================================================== */
.iexc {
  /* .icar's 120px bottom padding already covers the y6687 -> y6807 gap.
     Frame 78 ends y7478; section 8's aerial band starts y7598 -> 120px below. */
  padding: 0 0 7.5rem;
}
.iexc-panel {
  width: 78.75rem;
  max-width: calc(100% - 3rem);
  margin: 0 auto;
  border-radius: 0.75rem;
  background: var(--accent);
  overflow: hidden; /* clipsContent: true */
  display: flex;
  align-items: stretch;
}

/* ---- left column: 80 + 502 content ---- */
.iexc-left {
  flex: 1 1 auto;
  min-width: 0;
  padding: 5rem 0 5rem 5rem;
}
/* TEXT [5142:3046] Host Grotesk 400 28/37.24 ls -1.28 #111 @.70 */
.iexc-eyebrow {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.75rem;
  line-height: 2.3275rem;
  letter-spacing: -0.08rem;
  color: var(--ink-70);
}
/* TEXT [5142:3045] Host Grotesk 600 italic 60/64 ls -1.28
   eyebrow box ends y6924.24, heading box starts y6922 -> -2.24 */
.iexc-h {
  margin: -0.14rem 0 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 3.75rem;
  line-height: 4rem;
  letter-spacing: -0.08rem;
}
/* GRADIENT_LINEAR handles (0,.5)->(1.37216,.09434), stops #111 @.51442 / #e2fa5a @1
   -> over the 304x64 text box: 86.44deg, 70.59%, 136.62% */
.iexc-h-em {
  display: inline-block;
  background: linear-gradient(86.44deg, #111111 70.59%, #e2fa5a 136.62%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* TEXT [5142:3044] 357x64 (2 lines) Instrument Sans 400 24/32 ls -0.16 #111 @.70
   heading box ends y6986 -> sub box y6994 */
.iexc-sub {
  margin: 0.5rem 0 0;
  width: 22.3125rem;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 2rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}

/* ---- chip grid: FRAME "Frame 88" [5142:1265] 502x180, WRAP, both gaps 0
   rows are 195+161+146 = 502 | 185+188 = 373 | 179+166 = 345
   sub box ends y7058 -> chips y7218 */
.iexc-chips {
  margin-top: 10rem;
  width: 31.625rem; /* Figma 502; +4px slack so row 1 (502.0) cannot wrap on font-metric drift */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}
/* FRAME "Link - Solid Black" 60px tall, r12, pad[10,10,10,16], itemSpacing 9.99.
   These are <button role="tab">, so the UA styles have to be zeroed or the default
   border eats into the 60px (box-sizing is border-box globally) and the row widths
   drift off Figma's 195+161+146 / 185+188 / 179+166. */
.iexc-chip {
  flex: none;
  height: 3.75rem;
  border: 0;
  border-radius: 0.75rem;
  padding: 0.625rem 0.625rem 0.625rem 1rem;
  margin: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.624375rem;
  opacity: 0.2; /* node opacity on chips 2-7 = Figma's own unselected state */
}
.iexc-chip.is-active {
  opacity: 1;
  background: var(--white); /* chip 1 fill #fff at opacity 1 = the selected state */
  cursor: default;
}
.iexc-chip:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: 0.125rem;
}
/* TEXT Geist 600 20/25.6 ls -0.16 #111 */
.iexc-chip-t {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.6rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
  white-space: nowrap;
}
/* FRAME "Arrow Icon Wrapper" 40x40 r8 fill #111; VECTOR stroke #ffffff w1.66667 */
.iexc-chip-ico {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.5rem;
  background: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
}
.iexc-chip-ico img {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
}

/* ---- what replaced the chips: CTA + Trustpilot (2026-08-18) ----------------
   The tabs are off (see SHOW_TABS in ExclusiveTabs.tsx) and these two take their
   place. THE WHOLE POINT IS THE HEIGHT BUDGET: this section has no declared
   height anywhere — the panel is 671 because the left column's content adds up to
   it, and the right column stretches to match (see the banner at the top of §7).
   The chips block spent exactly 340 of that:

       160 (.iexc-chips margin-top) + 180 (3 rows x 60) = 340

   so the replacement has to spend 340 too, or the panel shrinks and every
   section below §7 moves up with it ("section ki height choti ni krni"). It
   does, exactly:

       40 (this margin) + 60 (CTA) + 216 (row margin) + 24 (Trustpilot) = 340

   THE 40 IS THE USER'S OWN VALUE ("ye margin 40px kro", 2026-08-18, with the
   sub->CTA gap ringed) — it started as the chips' own 160 so the CTA began where
   they did, and was cut to 40 so it sits directly under the sub. THE 216 IS NOT A
   TASTE VALUE: it is whatever is left of the 340 once the CTA is placed, and it
   lands the Trustpilot row's bottom exactly on the column's 80 padding, i.e.
   bottom-anchored, which is what was asked for. The two are locked together —
   move one and the other MUST absorb it, then re-check `.iexc-panel` still
   measures 671.

   Both are DESKTOP-ONLY — home-mobile.css hides them, matching §4, whose own
   reviews row and CTA are already hidden below 768. */
.iexc-cta {
  /* base.css's `.btn` is inline-flex, which would put this in a line box and add
     the font's leading to the 60. Block-level + hug keeps the box exactly 60 and
     leaves the label's own hug width intact. */
  display: flex;
  width: max-content;
  margin-top: 2.5rem; /* 40 — the user's own value, was the chips' 160 */
}
/* §4's `.psh-reviews` recipe verbatim (FRAME 12 [5134:296] 501x24, gap 12) rather
   than a second review-row vocabulary. Only the top margin differs, because §4
   bottom-anchors with `margin: auto 0 0` inside a 100vh column while this column
   derives the panel's height and so cannot use an auto margin — an auto margin
   resolves to 0 with no free space, which would take 96 off the panel. */
.iexc-reviews {
  margin-top: 13.5rem; /* 216 — the remainder of the chips' 340; see above */
  display: flex;
  align-items: center;
  gap: 0.75rem;
  /* Figma's own row height (FRAME 12 [5134:296] is 501x24) and it has to be
     DECLARED here, unlike in §4. The `<p>`'s line-height is Figma's fractional
     24.4, so an auto row measures 24.41 — and because this column *derives* the
     panel's height, that 0.41 became a 671.41 panel, +0.41 on every section top
     below §7 and +1 on docH. §4 never showed it: its column is 100vh, so the
     drift landed in whitespace. `align-items: center` keeps the text centred in
     the 24, and .tp-stars / .tp-logo are exactly 24 already. */
  height: 1.5rem;
}
.iexc-reviews p {
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.525rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
  white-space: nowrap;
}
.iexc-reviews p em {
  font-weight: 600; /* InstrumentSans-SemiBoldItalic */
  font-style: italic;
}
/* Row gap is 12, but Figma's stars->logo gap is 6, so pull it back 6 — §4's own
   correction, and the reason both rows read identically. */
.iexc-reviews .tp-stars + .tp-logo {
  margin-left: -0.375rem;
}

/* ---- right column (the tabpanel) ----
   Flex column so the panel height stays locked at Figma's 671 while the card's
   copy changes length: the LEFT column's content is exactly 671 tall, the panel
   is align-items:stretch, so this box is always 671-64 = 607. The card takes what
   its text needs and .iexc-shot absorbs the rest. Nothing is hardcoded — at the
   Figma copy's 5 lines that still resolves to card 206 + 12 + shot 389. */
.iexc-right {
  flex: 0 0 37.375rem;
  width: 37.375rem;
  /* 1260 = 80 + 502 + 48 + 598 + 32 */
  margin: 2rem 2rem 2rem 3rem;
  display: flex;
  flex-direction: column;
}
/* FRAME "Frame 89" [5142:1322] 598x206 r=8 fill #fff pad 23/24 -> 550px text column.
   206 = 23 + 5 lines x 32 + 23; each extra line adds 32 and takes it off the shot. */
.iexc-card {
  flex: none;
  border-radius: 0.5rem;
  background: var(--white);
  padding: 1.4375rem 1.5rem;
  /* Figma's authored 206, as a FLOOR not a height (added 2026-08-05 with the
     tab crossfade). Six of the seven tabs run to 5 lines and already measure
     exactly 206, but "Battery" is 4 lines and measured 174 — so switching to
     or from it stepped the white card 32px and the image 32px the other way,
     mid-fade, which is the one thing a crossfade cannot hide. Flooring at the
     Figma number holds all seven at 206 / shot 389 and leaves the resting
     render (tab 1 = 206) untouched. It is a floor, so the height lock still
     works: past ~5 lines the card grows and .iexc-shot gives up the space.
     Inert on mobile, where the same copy runs to 9 lines / 334. */
  min-height: 12.875rem;
}
.iexc-card p {
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 2rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}
/* characterStyleOverrides 0-7 -> InstrumentSans-Medium w500, solid #111 */
.iexc-card b {
  font-weight: 500;
  color: var(--ink);
}
/* FRAME "Frame 116" [5142:3025] 598x389 r=12 fill #111 clip; card ends y7045 -> y7057.
   No aspect-ratio: the height is the card's leftover space (389 at the Figma copy),
   so a longer paragraph shrinks the image rather than growing the section. */
.iexc-shot {
  position: relative;
  flex: 1 1 auto;
  /* Floor for the height lock. The Figma crop is 2.42x the box width and sits 4.489%
     off its left edge, so it stops covering the right edge once the box drops under
     598*389/(1448*0.95511) = 168.3px — i.e. past ~12 lines of card copy. Below that
     the section grows (as it must anyway past ~17 lines) instead of leaking #111.
     Every shipped tab is 4-5 lines => 389-421px, nowhere near this. */
  min-height: 10.625rem;
  margin-top: 0.75rem;
  width: 100%;
  border-radius: 0.75rem;
  background: var(--ink);
  overflow: hidden;
}
/* the six tabs Figma doesn't specify: plain full-bleed fill, any native size */
.iexc-shot img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  max-width: none; /* home.css img { max-width: 100% } would clamp 1448 -> 598 */
  object-fit: cover;
  display: block;
}
/* RECTANGLE [5142:3027] 1448x1086 at -65,-563 within the 598x389 frame — the exact
   Figma crop, for the one tab the design defines.
   Expressed HEIGHT-driven (%of the box) + a translate in % of the image's OWN box,
   so it scales proportionally with the box instead of re-cropping: the old
   left/top/width percentages were calibrated to 389px of height and would have
   reframed the shot the moment the card grew.
     height    279.1774% = 1086/389   -> width follows the 1448:1086 intrinsic ratio
     translate  -4.4890% = -65/1448,  -51.8416% = -563/1086 */
.iexc-shot[data-crop='figma'] img {
  width: auto;
  height: 279.1774%;
  transform: translate(-4.489%, -51.8416%);
}
/* INNER_SHADOW #111111 off(0,0) blur40 — Figma paints it above children, so overlay it */
.iexc-shot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 0.75rem;
  box-shadow: inset 0 0 2.5rem #111111;
  pointer-events: none;
}

/* The TWO narrow-viewport fallbacks that used to live here (1320px and 1080px,
   both moved to 767.98px when the fluid floor dropped) are GONE as of
   2026-08-05: §7 now has a real mobile layout in home-mobile.css, built from
   Figma's own mobile frame 7053:516. Both were narrow-DESKTOP fallbacks and
   fought the real numbers — they kept the 24px gutters where mobile is
   full-bleed, shrank the heading to 40/44 and both 24/32 paragraphs to 20/28
   where Figma mobile keeps 48/56 and 24/32, and pinned `.iexc-shot` to
   `aspect-ratio: 598/389` where mobile authors a flat 389 in a 388 box. */

/* ============================================================================
   SECTION 8 — "Save on Electricity Bills"
   Loose children of the Homepage frame, y7598–8924 (no wrapper frame):
     aerial band FRAME [5157:330]  12,7598 1896x780 r=12 #000, INNER_SHADOW #000 @.25 blur40
     heading     TEXT  [5157:417] 690,8418  541x60
     paragraph   TEXT  [5157:418] 330,8494 1260x96
     card row    FRAME [5157:347] 330,8630 1260x294 r=12 #f5f6f0, gap 12, pad 12
   ========================================================================== */
.sob {
  /* cards end y8924 -> section 9 ("Insights & updates") starts y9044 */
  padding: 0 0 7.5rem;
}

/* ---- aerial band: 1896 of 1920 -> 12px gutters, same as .tband ---- */
.sob-band {
  position: relative;
  width: 118.5rem;
  max-width: calc(100% - 1.5rem);
  margin: 0 auto;
  aspect-ratio: 1896 / 780;
  border-radius: 0.75rem;
  background: #000000;
  overflow: hidden; /* clipsContent: true */
}
/* RECTANGLE "image 156" [5383:3325] 1920x1080 at -12,-118, as % of the 1896x780 frame */
.sob-band img {
  position: absolute;
  left: -0.6329%;
  top: -15.1282%;
  width: 101.2658%;
  max-width: none; /* home.css img { max-width: 100% } would clamp 1920 -> 1896 */
  height: 138.4615%;
  object-fit: cover;
  display: block;
}
/* DESKTOP-ONLY looping clip, 2026-08-18 ("is image ki jga video krdo" + "mobile pe
   image jese hai wese hi rehne do just web pe change kro"). See app/page.tsx for the
   full reasoning; the parts that matter here:

   This is a NEW rule rather than `.sob-band :is(img, video)`, because the clip is
   already framed to the band — 1880x780, i.e. 2.41026 against the band's own
   2.430769 — so it just fills the frame and needs none of the Figma rect's
   percentages. `object-fit: cover` then trims 0.84% of its height, centred, which is
   why no crop is applied in the encode either: a pre-crop would remove the same 4px
   top and bottom and throw the pixels away for nothing. Nothing above is touched, so
   the still's own box is provably unchanged — verified by A/B in the live DOM.

   There is deliberately no second crop recipe here to keep in sync with the one
   above. The hover zoom and the reduced-motion opt-out DO have to reach the video,
   so those four selectors (and only those) grew a `:is(img, video)` — at (0,1,1) and
   (0,2,1) respectively, i.e. the same specificity they already had, so nothing in
   the cascade moved. */
.sob-band video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* INNER_SHADOW paints above children in Figma -> overlay, not a plain inset shadow */
.sob-band::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 0.75rem;
  box-shadow: inset 0 0 2.5rem rgba(0, 0, 0, 0.25);
  pointer-events: none;
}

/* ---- heading: Host Grotesk 600 italic 52/60, letterSpacing 0 (NOT -1.28), CENTER
   band ends y8378 -> heading box y8418 ----

   The top margin is 7.5rem (120), NOT Figma's 40, as of 2026-08-18 — the user's own
   DevTools value ("is ka margin ye krdo"), set once the band became a clip with its
   own burnt-in headline, which the old 40 crowded. So this is now an AUTHORED
   DEVIATION from Figma: do not "restore" 2.5rem.

   DESKTOP ONLY, and the mobile override is REQUIRED rather than tidy: home-mobile.css
   does not otherwise restate this margin, so without it the 428 column would take the
   same +80. It restates 2.5rem on `.sob-h` there.

   Measured before the edit by injecting the declaration in the live DOM: everything
   from the heading down moves exactly +80 (.sob-h / .sob-p / .sob-note / .sob-cards /
   .blog-h / .ftr-h), docH 14790 -> 14870, and the band plus every section above it
   (.pvsec 2256, .pshow 4853, .icar 8094.88, .iexc 9106.88, .sob 9897.88) does not
   move at all. */
.sob-h {
  margin: 7.5rem 0 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 3.25rem;
  line-height: 3.75rem;
  letter-spacing: 0;
}
/* GRADIENT_LINEAR handles (0,.5)->(1.37216,.09434), stops #111 @.51442 / #e2fa5a @1
   -> over the 541x60 text box: 88.12deg, 70.58%, 137.04% */
.sob-h-em {
  display: inline-block;
  background: linear-gradient(88.12deg, #111111 70.58%, #e2fa5a 137.04%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ---- paragraph: 1260 wide, 3 lines, centred. heading ends y8478 -> y8494 ---- */
.sob-p {
  margin: 1rem auto 0;
  /* Figma's box is the full 1260 content column, which the old four-sentence
     paragraph filled. The client's two-line copy left a stranded "cost upfront."
     on line 2, so the measure was narrowed on the user's instruction
     (2026-08-13). 780 is the balance point: the copy needs 1377 on one line, and
     700 is where it breaks to three — so 780 gives two near-even lines and still
     reads at ~65 characters, which is inside the comfortable measure. */
  width: 48.75rem;
  max-width: calc(100% - 3rem);
  text-align: center;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 2rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}

/* ---- card row. paragraph ends y8590 -> y8630
   1260 - 24 pad - 24 gaps = 1212 / 3 = 404 per card ---- */
.sob-cards {
  margin: 2.5rem auto 0;
  width: 78.75rem;
  max-width: calc(100% - 3rem);
  border-radius: 0.75rem;
  background: var(--panel); /* #f5f6f0 */
  padding: 0.75rem;
  display: flex;
  gap: 0.75rem;
}
/* FRAME "Link - Solid Black" 404x270 r=12 #fff, effects [] -> no shadow.
   32 pad + 60 icon + 60 gap + 32 title + 6 gap + 48 sub + 32 pad = 270, so no height needed */
.sob-card {
  flex: 1 1 0;
  min-width: 0;
  border-radius: 0.75rem;
  background: var(--white);
  padding: 2rem;
}
/* FRAME "Frame 1707481505" 60x60 r=8 fill #e2fa5a. The squares were empty in the
   frame this was first ported from and the note here said "empty by design"; the
   updated design fills all three, so the box centres its glyph. */
.sob-ico {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3.75rem;
  height: 3.75rem;
  border-radius: 0.5rem;
  background: var(--accent);
}
/* THE 40 MUST BE CSS IN REM, never a width="40" attribute on the <img>. HTML and SVG
   width/height attributes are CSS px and ignore the fluid root, so the icon would stay 40
   while its 60 box scaled — the same leak `.excl-play svg` documents. (60 - 40) / 2 lands a
   symmetric 10 inset, measured on all three at 1920 and 428.
   No mobile rule is needed: home-mobile.css declares no `.sob-ico`, so the box is 60 there
   too and this 40 carries over, which is what "40*40" asked for at both breakpoints. */
.sob-ico img {
  width: 2.5rem;
  height: 2.5rem;
}

/* TEXT Host Grotesk 500 24/32 ls -1.28 #111 — icon ends y8734, title box y8794 */
.sob-card h3 {
  margin: 3.75rem 0 0;
  font-family: var(--font-display);
  font-weight: 500;
  /* Figma is 24/32; raised to 28/36 on the user's instruction 2026-08-13
     ("heading ka font size thora sa increase kro"). Checked at both
     breakpoints: all three titles still hold ONE line. */
  font-size: 1.75rem;
  line-height: 2.25rem;
  letter-spacing: -0.08rem;
  color: var(--ink);
}
/* TEXT Instrument Sans 400 16/24 ls -0.16 #111 @.70, 2 lines. title ends y8826 -> y8832 */
.sob-card p {
  margin: 0.375rem 0 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.5rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}
/* ---- footnote line, NOT in Figma -----------------------------------------
   Added 2026-08-13 with the client's finance copy: it is the footnote for the
   asterisk on card 3's "Pay off anytime*". Sits between the paragraph and the
   card panel, centred like both. Deliberately one step down from `.sob-p`
   (16/24 against its 24/32) and on --ink-60 rather than --ink-70, so it reads
   as small print rather than a second paragraph — though the user took it to
   full --ink on 2026-08-13, so size alone carries that distinction now.
   The 32 above / 24 below is theirs too, and it is deliberately asymmetric:
   the note annotates the asterisk in CARD 3, not the paragraph, so it sits
   nearer the panel it belongs to. The lower gap has to be set on the panel
   (`.sob-note + .sob-cards`) rather than as a margin-bottom here, because
   adjacent sibling margins collapse and `.sob-cards`' own 40 would win. */
.sob-note {
  margin: 2rem auto 0;
  text-align: center;
  font-family: var(--font-sans);
  /* 500, not 400 — user, 2026-08-13. Matches the tick labels' weight. */
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.5rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
}
.sob-note + .sob-cards {
  margin-top: 1.5rem;
}

/* ---- four-point tick list, NOT in Figma ----------------------------------
   Added 2026-08-13 with the client's finance copy, on the instruction that the
   points carry "tick icon k sath ... jese product section main ticks hai". So
   every value here is §4's `.psh-bullets` verbatim — the same 24px
   home-check.svg, the same 8px icon gap, the same 16px row gap and the same
   Instrument Sans 500 16/19.52 — rather than a second bullet vocabulary. The
   card has no declared height in either sheet, so the list simply grows it. */
.sob-bullets {
  /* paragraph -> first tick. 16 read too tight against the 32 card padding
     (user, 2026-08-13: "points k uper wala margin thora zyada kro"). */
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.sob-bullets li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.sob-bullets img {
  flex: 0 0 1.5rem;
  width: 1.5rem;
  height: 1.5rem;
}
.sob-bullets span {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.22rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
}

/* The TWO narrow-viewport fallbacks that used to live here (a 1000px block moved
   to 767.98px, plus a 620px block that was already below the floor) are GONE as
   of 2026-08-05: §8 now has a real mobile layout in home-mobile.css, built from
   Figma's own mobile frame. Both were narrow-DESKTOP fallbacks and fought the
   real numbers — they shrank the heading to 36/44 and the paragraph to 20/30
   where Figma mobile keeps 48/56 and 24/32, wrapped the cards 2-up instead of
   stacking them, and the 620 block cut the icon->title gap from 60 to 32. */

/* ============================================================================
   SECTION 9 — "Insights & updates" blog
   Loose children of the Homepage frame, y9044–9660:
     heading  TEXT  [5151:4264]  330,9044  487x64
     sub      TEXT  [5151:4263]  330,9116  357x32
     CTA      FRAME [5151:4266] 1389,9066  201x60   (reuses base.css .btn .btn-dark .btn-lg)
     3 cards  FRAME [5151:4275/4368/4375] @ 330/757/1184, 9188  406x472 r=12 #fff
   ========================================================================== */
/* RECTANGLE "Rectangle 16" [5151:4382] 0,9044 1920x736 IS this section's background:
   GRADIENT_LINEAR handles (0.5,1)->(0.5,0), stops #e2fa5a a1 @0 / #e2fa5a a0 @1.
   Content is 616 tall (9044->9660) + 120 pad = 736, so the rect matches the box exactly. */
.blog {
  background: linear-gradient(to top, #e2fa5a 0%, rgba(226, 250, 90, 0) 100%);
  /* cards end y9660 -> the black FRAME 84 band (section 10) starts y9780 */
  padding: 0 0 7.5rem;
}

/* ---- heading row (content column 330..1590) ---- */
.blog-head {
  position: relative;
  width: 78.75rem;
  max-width: calc(100% - 3rem);
  margin: 0 auto;
}
.blog-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 3.75rem;
  line-height: 4rem;
  letter-spacing: -0.08rem;
}
/* GRADIENT_LINEAR handles (0,.5)->(1.37216,.09434), stops #111 @.51442 / #e2fa5a @1
   -> over the 487x64 text box: 87.78deg, 70.58%, 136.98% */
.blog-h-em {
  display: inline-block;
  background: linear-gradient(87.78deg, #111111 70.58%, #e2fa5a 136.98%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* heading box ends y9108 -> sub box y9116 */
.blog-sub {
  margin: 0.5rem 0 0;
  width: 22.3125rem;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 2rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}
.blog-cta {
  position: absolute;
  right: 0;
  top: 1.375rem; /* 9066 - 9044 */
}

/* ---- card row. sub ends y9148 -> cards y9188. 406*3 + 21*2 = 1260 ---- */
.blog-cards {
  width: 78.75rem;
  max-width: calc(100% - 3rem);
  margin: 2.5rem auto 0;
  display: flex;
  gap: 1.3125rem;
}
/* 306 img + 12 + 32.8 tag + 16 + 28 title + 6 + 51.24 excerpt + 20 pad = 472 */
/* the whole card is the <a>, so it needs blockifying (base.css already zeroes
   the anchor colour and underline) */
.blog-card {
  display: block;
  flex: 1 1 0;
  min-width: 0;
  border-radius: 0.75rem;
  background: var(--white);
  overflow: hidden; /* clipsContent: true */
  padding-bottom: 1.25rem;
}
/* RECTANGLE "image 140" 406x306 scaleMode FILL, flush to the card's top corners.
   The source files are ~398x300 at the same 1.327 aspect, so cover crops nothing. */
/* clip box for the hover zoom — the <img> is in normal flow here, so scaling it
   without this would paint over the tag row instead of growing inside its box */
.blog-shotwrap {
  display: block;
  overflow: hidden;
}
.blog-shot {
  display: block;
  width: 100%;
  aspect-ratio: 406 / 306;
  object-fit: cover;
}
/* tag + date row, card-relative +20,+318; "1 day ago" starts 12px after the 145px tag */
.blog-meta {
  margin: 0.75rem 1.25rem 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
/* FRAME "Link - Solid Black" 145x33 r=12 fill #111, pad[6,10,6,10]; text fill #fefff9 */
.blog-tag {
  flex: none;
  border-radius: 0.75rem;
  background: var(--ink);
  padding: 0.375rem 0.625rem;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.3rem;
  letter-spacing: -0.01rem;
  color: var(--bg); /* #fefff9, not pure white */
}
.blog-date {
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.3rem;
  letter-spacing: -0.01rem;
  color: var(--ink); /* solid, no .70 */
  white-space: nowrap;
}
/* TEXT 366x28 textAutoResize HEIGHT — the box is the full 366px content width while the
   glyphs are only ~205px, so the gradient must be clipped over a BLOCK of 366px.
   An inline-block here would size to the text and skew the gradient.
   -> over 366x28: 88.70deg, 70.56%, 137.14% */
.blog-card h3 {
  display: block;
  margin: 1rem 1.25rem 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.75rem;
  letter-spacing: -0.08rem;
  background: linear-gradient(88.7deg, #111111 70.56%, #e2fa5a 137.14%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* TEXT 366x51 (3 lines) Instrument Sans 400 14/17.08 ls -0.16 #111 @.70 */
.blog-card p {
  margin: 0.375rem 1.25rem 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 0.875rem;
  line-height: 1.0675rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}

/* The narrow-viewport fallback that used to live here (was 1000px, moved to
   767.98px when the fluid floor dropped) is GONE as of 2026-08-05: §9 now has a
   real mobile layout in home-mobile.css, built from Figma's own mobile frame.
   It was a narrow-DESKTOP fallback and fought the real numbers — it shrank the
   heading to 40/44 where Figma mobile keeps 48/56, and wrapped all three cards
   2-up where mobile shows exactly ONE. */

/* =========================================================================
   SECTION 10 — "We're a family business." dark band
   FRAME "Frame 84" [5134:357] 0,9780 1920x572 clipsContent fill #000000

   Namespace .fbiz-*  — a `.fam-*` prefix would brush home.css:897's `.family`
   block (the reference build's own, non-Figma-accurate take on this section),
   including `.family h2` at :905 and `.family h2 em` at :910.
   Height falls out of the content: 120 + 64 + 32 + 116 + 60 + 60 + 120 = 572,
   so the section needs no explicit height.

   GROUP "Group 7" [5157:1397] (two copies of the §7 panel image with a lime
   drop shadow) is `visible: false` in Figma — absoluteRenderBounds is null and
   the render shows nothing there. Deliberately NOT built.
   ========================================================================= */
.fbiz {
  position: relative;
  isolation: isolate; /* keeps .fbiz-glow's paint order local (see CLAUDE.md) */
  overflow: hidden;   /* clipsContent: true */
  background: #000000;
}

/* ---- RECTANGLE "Rectangle 6" [5134:358] 0,0 1920x572, PATTERN fill @ .04 ----
   The pattern's source node is not in the spec (sourceNodeId "-1:-1"), so it was
   measured off the render: 4x4px squares on a 24px grid, phase x22 / y20, white
   at 4% (rgb 9-10 on black). tileType RECTANGULAR, spacing 0, alignment START. */
.fbiz-dots {
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Crect width='4' height='4' fill='%23ffffff' fill-opacity='.04'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 1.5rem 1.5rem;
  background-position: 1.375rem 1.25rem;
}

/* ---- FRAME "Frame 1707481506" [5157:1393] 1144,-1 776x572 clip ---- */
.fbiz-photo {
  position: absolute;
  top: 0;
  right: 0;
  width: 48.5rem;
  height: 100%;
  overflow: hidden;
}
/* RECTANGLE "image 127" [5383:3327] 1144,-1 776x629 scaleMode FILL.
   Sits 1px above the frame and 56px below it; the frame clips both.
   Anchored right so narrower viewports crop the (already faded) left edge.
   `max-width: none` or home.css's `img { max-width: 100% }` clamps it to 776
   and re-crops the faces. */
.fbiz-photo img {
  position: absolute;
  top: -0.0625rem;
  right: 0;
  width: 48.5rem;
  height: 39.3125rem;
  max-width: none;
  object-fit: cover;
}
/* Four black fade rects, all `#000 a1 -> #000 a0`, stacked exactly as Figma
   paints them (two duplicated pairs — the fade really is applied twice):
     RECTANGLE "Rectangle 10" [5383:3328] + [5134:373]  1144,-1  191x629  L->R
     RECTANGLE "Rectangle 11" [5134:374]   rot -90deg -> black y571 -> clear y267
     RECTANGLE "Rectangle 11" [5383:3329]  rot -90deg -> black y628 -> clear y324
   Alpha-over-black compositing is order-independent, so one element with four
   background layers reproduces all four rects. */
.fbiz-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, #000000 0%, rgba(0, 0, 0, 0) 100%) 0 0 / 11.9375rem 100% no-repeat,
    linear-gradient(to right, #000000 0%, rgba(0, 0, 0, 0) 100%) 0 0 / 11.9375rem 100% no-repeat,
    linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000000 100%) 0 16.6875rem / 100% 19rem no-repeat,
    linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000000 100%) 0 20.25rem / 47.125rem 19rem no-repeat;
}

/* ---- RECTANGLE "Rectangle 5" [5134:362] ----------------------------------
   NOT the 670x670 square its absoluteBoundingBox suggests: it is a 26x922 bar
   at 372,-268 rotated 45deg (long axis down-left), fill #e2fa5a, LAYER_BLUR 314.
   26 and 922 come from the reference build's clean node dump
   (../Solar heatable/_figma-ref/5134-357.json) — 670.59 is just the rotated bbox.
   That thinness is why the render's peak is only ~8% lime, not a solid blob.

   Figma layer-blur radius -> CSS blur: match the *support*. Figma's
   absoluteRenderBounds = shape + radius, i.e. support = r; a CSS 3-box blur has
   support 2.82sigma, so sigma = 314 / 2.82 = 111px. That also lands the peak at
   0.75*26/(1.88*111) = 9.3% against the render's measured 8.1%. The usual
   "radius / 2" rule of thumb (157px) would be ~30% too faint and 40% too wide.

   Painted AFTER the heading and paragraph but BEFORE the button, hence the
   z-index: 1 on .fbiz-btn below. */
.fbiz-glow {
  position: absolute;
  left: 2.625rem;   /* centre lands at 55.2,67.2 — the bar's rotated centre */
  top: -24.625rem;
  width: 1.625rem;
  height: 57.625rem;
  background: #e2fa5a;
  transform: rotate(45deg);
  filter: blur(6.9375rem);
  pointer-events: none;
}

/* ---- content column (330..1590 at the 1920 canvas) ---- */
.fbiz-inner {
  position: relative;
  width: 78.75rem;
  max-width: calc(100% - 3rem);
  margin: 0 auto;
  padding: 7.5rem 0;
}

/* ---- ELLIPSE "Ellipse 2" [5134:359] 330,160 628x8, LAYER_BLUR 64 ----------
   Lime at the right handle (1,.5), white at the left (0,.5). Same support rule:
   64 / 2.82 = 23px. Measured render peak 12.1% vs 14.1% predicted — the same
   ~14% overshoot as .fbiz-glow, i.e. the rule is consistent. */
.fbiz-hglow {
  position: absolute;
  left: 0;
  top: 10rem;
  width: 39.25rem;
  max-width: 100%;
  height: 0.5rem;
  border-radius: 50%;
  background: linear-gradient(to left, #e2fa5a 0%, #ffffff 100%);
  filter: blur(1.4375rem);
  pointer-events: none;
}

/* ---- TEXT [5134:360] 330,120 628x64 — Host Grotesk 600 italic 60/64 ls -1.28
   textAutoResize WIDTH_AND_HEIGHT -> the gradient span hugs the glyphs. ---- */
.fbiz-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 3.75rem;
  line-height: 4rem;
  letter-spacing: -0.08rem;
}
/* GRADIENT_LINEAR handles (0,.5)->(1.21386,.171875), stops #ffffff @0 / #e2fa5a @1
   -> over the 628x64 text box: 88.42deg, 0.14%, 121.28%.
   Note this is the white->lime paint, NOT the dark->lime one the other headings use. */
.fbiz-h-em {
  display: inline-block;
  background: linear-gradient(88.42deg, #ffffff 0.14%, #e2fa5a 121.28%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ---- TEXT [5134:361] 330,216 690x116 — Instrument Sans 400 24/29.28 ls -0.16
   The 690px width is load-bearing: it is what wraps the copy to exactly 4 lines. */
.fbiz-p {
  margin: 2rem 0 0;
  width: 43.125rem;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 1.83rem;
  letter-spacing: -0.01rem;
  color: #ffffff;
}

/* ---- FRAME "Link - Solid Black" [5134:363] 330,392 215x60 ----------------
   The name lies: fill is #e2fa5a with a #111111 chip and #111111 label — the
   inverse of base.css's .btn-dark. Everything else (r12, pad 10/10/10/16,
   gap ~10, Geist 600 20 ls -0.16, 40x40 r8 chip, 28px arrow) is already the
   shared .btn .btn-lg recipe, so only the two colours are re-declared.
   VECTOR "JgTGlz8TK" [5134:370] is stroked #ffffff -> arrow-white.svg.
   z-index lifts it above .fbiz-glow, matching Figma's paint order.
   Figma defines no hover state; the darker lime mirrors home.css's own
   invented .btn-dark / .btn-light hovers. */
.fbiz-btn {
  position: relative;
  z-index: 1;
  margin-top: 3.75rem;
  background: var(--accent);
}
/* Lime pill on the black band: it should brighten, not darken (#d5f43e read as
   "pressed" against the dark ground), and the lift shadow has to be lime — an
   ink shadow is invisible on #111. */
.fbiz-btn:hover {
  background: #eaff78;
  box-shadow:
    0 1rem 2.125rem -1rem rgba(226, 250, 90, 0.55),
    inset 0 0 0 0.0625rem rgba(17, 17, 17, 0.12);
}
.fbiz-btn:active {
  box-shadow:
    0 0.1875rem 0.625rem -0.375rem rgba(226, 250, 90, 0.5),
    inset 0 0 0 0.0625rem rgba(17, 17, 17, 0.12);
}
.fbiz-btn:hover .chip {
  box-shadow: 0 0 0 0.1875rem rgba(17, 17, 17, 0.18); /* lime ring is invisible here */
}
.fbiz-btn:focus-visible {
  outline-color: var(--accent);
}
.fbiz-btn .chip {
  background: var(--ink);
}

/* The THREE narrow-viewport fallbacks that used to live here (1320px and 1000px,
   both moved to 767.98px, plus a 720px block that was already below the floor)
   are GONE as of 2026-08-05: §10 now has a real mobile layout in
   home-mobile.css, built from Figma's own mobile frame 7053:608. All three were
   narrow-DESKTOP fallbacks and fought the real numbers — they made the photo
   `position: relative` and 260 tall where mobile keeps it absolute at 424,
   replaced the fade with a bottom-up one where mobile's is top-down, shrank the
   heading to 40/44 and the body to 18/24 where Figma mobile keeps 48/64 and
   24/29.28, and moved `.fbiz-hglow` to 96 where Figma puts it at 84. */

/* =========================================================================
   SECTION 11a — "Your Question Answered" FAQ block
   Loose children of the Homepage frame, y10472–11224 (no wrapper frame):
     TEXT  [5134:393] 330,10472 458x120   heading
     TEXT  [5134:392] 330,10612 491x96    sub
     FRAME [5134:394] 330,10996 510x228   r8  "Frame 100" contact card
     FRAME [5134:404] 972,10472 618x752   r12 "Frame 101" question list

   Namespace .qna-*  — `.faq*` is TAKEN by home.css (`.faq`, `.faq-item`,
   `.faq-item.open`, plus `.faq h2` in the :40 group selector).
   Column math: 510 + 132 gap + 618 = 1260. The row's height comes from the
   question list (12 + 9*72 + 8*10 + 12 = 752); the contact card is
   bottom-anchored with `margin-top: auto`, which reproduces Figma's 288px
   gap without hardcoding it.
   ========================================================================= */
.qna {
  padding: 7.5rem 0 0; /* §10 ends y10352 -> heading y10472 */
}
.qna-row {
  width: 78.75rem;
  max-width: calc(100% - 3rem);
  margin: 0 auto;
  display: flex;
  align-items: stretch;
  gap: 8.25rem;
}
.qna-left {
  width: 31.875rem;
  flex: none;
  display: flex;
  flex-direction: column;
}
/* Host Grotesk 600 italic 52/60 — letterSpacing is 0 here, not the -1.28 the
   other display headings use. 2 lines x 60 = the node's 120px height. */
.qna-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 3.25rem;
  line-height: 3.75rem;
  letter-spacing: 0;
}
/* `textAutoResize: HEIGHT` -> the box is the full 458px while the glyphs are
   narrower, so the gradient is laid out over 458px. `display: block` at that
   width, NOT inline-block (see the §9 card-title note).
   GRADIENT_LINEAR handles (0,.5)->(1.3722,.0943), stops #111 @.1554 / #e2fa5a @1
   -> over 458x120: 85.57deg, 22.02%, 136.29%. */
.qna-h-em {
  display: block;
  width: 28.625rem;
  max-width: 100%;
  background: linear-gradient(85.57deg, #111111 22.02%, #e2fa5a 136.29%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* heading box ends y10592 -> sub y10612. Host Grotesk (not Instrument Sans)
   400 24/32 ls -0.16, #111 @ .70. Copy says "Salesflow" — a Figma placeholder,
   reproduced verbatim. */
.qna-sub {
  margin: 1.25rem 0 0;
  width: 30.6875rem;
  max-width: 100%;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 2rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}
/* FRAME "Frame 100" r8 fill #111111 @ .04 (NOT --ink-08, which is .08), pad 20.
   20 + 96 + 32 + 60 + 20 = 228, so no height is declared. */
.qna-card {
  margin-top: auto;
  padding: 1.25rem;
  border-radius: var(--radius-sm);
  background: rgba(17, 17, 17, 0.04);
}
.qna-card p {
  margin: 0;
  width: 29.375rem;
  max-width: 100%;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 2rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}
.qna-card .btn {
  margin-top: 2rem;
}

/* FRAME "Frame 101" [5134:404] r12, vertical #f5f6f0 -> #e2fa5a, AL pad 12 gap 10 */
.qna-faqs {
  flex: 1;
  min-width: 0;
  padding: 0.75rem;
  border-radius: var(--radius);
  background: linear-gradient(to bottom, #f5f6f0 0%, #e2fa5a 100%);
  overflow: hidden; /* clipsContent: true */
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
/* Each row: 594x72 r12 #fff, pad [16,16,16,24], gap ~10.
   24 + 504 text + 10 + 40 chip + 16 = 594, so the text takes `flex: 1` exactly.
   Figma wires NO interaction on any of the nine rows and defines no answer
   content, so they are static, not an accordion. Don't invent one. */
/* Now a disclosure row: the shell keeps Figma's r12 white box, and the 72px
   height + [16,16,16,24] padding move to the <button> so a CLOSED row still
   measures exactly 72 and the list still totals 12 + 9*72 + 8*10 + 12 = 752. */
.qna-faq {
  border-radius: var(--radius);
  background: var(--white);
  overflow: hidden; /* clips the answer panel while it collapses */
}
.qna-faq-h {
  margin: 0; /* the <h3> is structure only — the button is the whole row */
}
.qna-faq-btn {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  width: 100%;
  height: 4.5rem;
  padding: 1rem 1rem 1rem 1.5rem;
  border: 0;
  margin: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}
/* grid-template-rows 0fr -> 1fr animates to the answer's real height with no
   magic max-height. `visibility` keeps a closed answer out of the a11y tree and
   interpolates discretely, so it stays visible for the whole collapse. */
.qna-faq-panel {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition:
    grid-template-rows 340ms var(--ease-premium),
    visibility 340ms var(--ease-premium);
  transition-behavior: allow-discrete;
}
.qna-faq.is-open .qna-faq-panel {
  grid-template-rows: 1fr;
  visibility: visible;
}
.qna-faq-panel-in {
  overflow: hidden; /* required for the 0fr row to actually collapse */
  min-height: 0;
}
/* separator borrowed from §4's VECTOR "Vector 9" (#111 @.12, strokeDashes [8,8])
   rather than invented, so the rule reads as part of the design language */
.qna-faq-a {
  margin: 0;
  padding: 1rem 1.5rem 1.25rem;
  background-image: repeating-linear-gradient(
    to right,
    rgba(17, 17, 17, 0.12) 0 0.5rem,
    transparent 0.5rem 1rem
  );
  background-repeat: no-repeat;
  background-position: 1.5rem 0;
  background-size: calc(100% - 3rem) 0.0625rem;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.5rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}
/* Geist 400 (Regular — not the 600 the buttons use) 20/25.6 ls -0.16 */
.qna-faq-q {
  flex: 1;
  min-width: 0;
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.6rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
}
/* "Arrow Icon Wrapper" — 40x40 r8 #f6f6f6 with rotation 1.5708 rad (+90deg),
   which is how the shared right-pointing arrow.svg becomes a down chevron. */
.qna-faq-chip {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: #f6f6f6;
}
.qna-faq-chip img {
  width: 1.75rem;
  height: 1.75rem;
  transform: rotate(90deg);
}

/* =========================================================================
   SECTION 11b — footer
   FRAME "Frame 101" [5134:459] 330,11344 1260x1396 r12 clip, vertical
   #f5f6f0 -> #e2fa5a, AL VERTICAL pad 12 gap 10, holding
     FRAME [5134:460] 1236x1302 r12 #fff  (CTA + photo + link columns)
     FRAME [5134:534] 1236x60   r12 #fff  ("© 2026.")
   1396 = 12 + 1302 + 10 + 60 + 12, and the card's own
   80 + 96 + 16 + 72 + 40 + 60 + 40 + 534 + 61 + 263 + 40 = 1302,
   so neither needs a declared height.

   Namespace .ftr-*  — `.footer*` is TAKEN by home.css (`.footer`, `.footer-cta`,
   and the reference build's whole non-Figma-accurate footer block).
   ========================================================================= */
.ftr {
  padding: 7.5rem 0 9.375rem; /* FAQ ends y11224 -> footer y11344; page ends y12890 */
}
.ftr-shell {
  width: 78.75rem;
  max-width: calc(100% - 3rem);
  margin: 0 auto;
  padding: 0.75rem;
  border-radius: var(--radius);
  background: linear-gradient(to bottom, #f5f6f0 0%, #e2fa5a 100%);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.ftr-card {
  padding: 5rem 0 2.5rem;
  border-radius: var(--radius);
  background: var(--white);
  overflow: hidden; /* the photo is full-bleed, so r12 must clip it */
}
/* TEXT [5134:472] 350,11436 559x96 — Host Grotesk 400 (Regular) 40/48 ls -1.28,
   CENTER, textAutoResize WIDTH_AND_HEIGHT with an explicit newline in the
   string, hence the <br /> rather than a wrap width. */
.ftr-h {
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2.5rem;
  line-height: 3rem;
  letter-spacing: -0.08rem;
  color: var(--ink);
}
/* TEXT [5134:463] 405,11548 448x72 — the 448px width wraps this to 3 lines */
.ftr-sub {
  width: 28rem;
  max-width: 100%;
  margin: 1rem auto 0;
  text-align: center;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.525rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
}
/* base.css's .btn is inline-flex, so `margin: auto` needs an explicit flex box */
.ftr-cta {
  display: flex;
  width: max-content;
  margin: 2.5rem auto 0;
}
/* RECTANGLE " 1235104227" [5134:461] 342,11760 1236x534 FILL, plus
   RECTANGLE "Rectangle 12" [5134:462] 342,12037 1236x258 — #fff a0 -> a1,
   i.e. the photo's bottom 258px fading into the card. */
.ftr-photo {
  position: relative;
  margin-top: 2.5rem;
  height: 33.375rem;
}
.ftr-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ftr-photo::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 16.125rem;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #ffffff 100%);
}
/* Bottom row: all four columns top-aligned at y12355, 263 tall.
   Card-relative x: brand 40, nav 440 / 705 / 971 — a 265.33px pitch that runs
   to the card's right edge, hence 1fr tracks rather than fixed widths. */
.ftr-bottom {
  display: flex;
  margin-top: 3.8125rem;
  padding-left: 2.5rem;
}
.ftr-brand {
  width: 20rem;
  flex: none;
  margin-right: 5rem;
  display: flex;
  flex-direction: column;
}
/* RECTANGLE "image 141" [5157:1388] 382,12355 117x60 — pixel-identical to the
   header's logo (visible PSNR infinite, alpha delta 0), so it is reused rather
   than re-extracted. Its white DROP_SHADOW blur 100 is a no-op: the logo sits
   on the white card.
   Both consumers point at logo-2x.webp (234x120), NOT logo.webp (1024x524):
   a 1024 source in a 117px box is an 8.75x runtime downscale, and the browser's
   cheap filter measures 17% under Figma's own render on edge energy. */
.ftr-logo {
  width: 7.3125rem;
  height: 3.75rem;
  object-fit: cover;
}
.ftr-blurb {
  margin: 1rem 0 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.525rem;
  letter-spacing: -0.01rem;
  color: var(--ink-70);
}
/* 382 / 430 / 478 -> a 48px pitch on 40px chips = 8px gap. Bottom-anchored so
   the column's 263px height (set by the nav columns) yields Figma's 75px gap. */
.ftr-social {
  margin-top: auto;
  display: flex;
  gap: 0.5rem;
}
.ftr-social span {
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--ink);
}
.ftr-social img {
  width: 1.5rem;
  height: 1.5rem;
}
.ftr-nav {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
/* Host Grotesk 600 italic 20/26.6 ls 0, textAutoResize WIDTH_AND_HEIGHT
   -> inline-block. Same paint as .qna-h-em (stops #111 @.1554 / #e2fa5a @1)
   but each 27px-tall box has its own width, hence its own angle + end stop. */
.ftr-navh {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 1.25rem;
  line-height: 1.6625rem;
  letter-spacing: 0;
}
.ftr-navh span {
  display: inline-block;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* MUST be `background-image`, not the `background` shorthand: the shorthand resets
   background-clip to border-box, wiping the `text` set above, so the gradient paints
   the whole 27px-tall box and the transparent text vanishes — a solid lime bar with
   no letters. Same trap as .grad-italic, reached from the opposite direction.
   (The other sections get away with `background` because theirs sits in the SAME
   rule, declared BEFORE the clip.) */
.ftr-navh-services span {
  background-image: linear-gradient(84.08deg, #111111 22.54%, #e2fa5a 135.58%); /* 77x27 */
}
.ftr-navh-company span {
  background-image: linear-gradient(84.88deg, #111111 22.25%, #e2fa5a 136%); /* 89x27 */
}
.ftr-navh-general span {
  background-image: linear-gradient(83.59deg, #111111 22.77%, #e2fa5a 135.3%); /* 71x27 */
}
.ftr-nav ul {
  margin: 1.25rem 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
/* Geist 500 (Medium) 16/25.6 ls -0.16 #111. Figma wires no prototype target on
   any of the 16 items, so they are plain <li> text, not links. */
.ftr-nav li {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.6rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
}
/* FRAME [5134:534] 1236x60 r12 #fff — TEXT is Instrument Sans 500 16/19.52
   CENTER inside 1156 (i.e. 40px insets), which centres identically in 1236. */
.ftr-legal {
  height: 3.75rem;
  border-radius: var(--radius);
  background: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.22rem;
  letter-spacing: -0.01rem;
  color: var(--ink);
}

/* The THREE narrow-viewport fallbacks that used to live here (1320px and 1080px,
   both moved to 767.98px, plus a 720px block that was already below the floor)
   are GONE as of 2026-08-05: §11a AND §11b now have real mobile layouts in
   home-mobile.css, built from Figma's own mobile frames 7053:624 / 7053:679.
   Note all three blocks mixed §11a and §11b rules, which is why they had to go
   together. They were narrow-DESKTOP fallbacks and fought the real numbers hard:
   the 720 one put `padding: 1rem` on `.qna-faq` (which sits OUTSIDE the button
   that owns Figma's padding, so every row rendered 32 too tall), shrank the FAQ
   heading to 36/42 and the question to 17/22, dropped the footer's `<br />`, and
   made `.ftr-nav` a 2-up grid where mobile stacks three full-width blocks. */

/* =========================================================================
   INTERACTION LAYER — hover / press / focus states
   -------------------------------------------------------------------------
   Figma specifies NO interactive states anywhere in the file (no variants, no
   prototype hover reactions), so everything below is authored for this build,
   not extracted. Two rules kept it honest:

     1. The RESTING render is untouched. Every declaration here lives behind
        :hover / :active / :focus-visible, and none of them change the box
        model — only background, box-shadow, opacity and transform. So the
        Figma-exact measurements (§7's 195+161+146 chip rows, §4's 60px pills,
        the footer's 265.33px pitch) still hold.
     2. Only things that are actually clickable get a hover. The §8 / §9 cards,
        the nine §11a FAQ rows and the 19 footer nav / social items are inert
        in Figma (no targets, no handlers) — a hover on those would promise a
        click that never happens, so they are deliberately left alone.

   Shared vocabulary, from base.css's .btn: a 2px lift, a tight low shadow, one
   specular pass, the arrow chip leading by 3px, and a press that settles the
   lift. Per-element character on top of that. Motion tokens: --ease-premium /
   --dur-hover / --dur-press.
   ========================================================================= */

/* ---- header: logo ---- */
.logo {
  transition: transform var(--dur-hover) var(--ease-premium);
}
.logo-link:hover .logo {
  transform: translateY(-0.0625rem);
}
.logo-link:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: 0.25rem;
  border-radius: 0.25rem;
}

/* ---- header: the three nav links ----
   Each is text + a 24px dropdown chevron on a 4px gap, so the underline stops
   28px short of the right edge (chevrons do not get underlined) and wipes in
   from the left. The chevron drops 2px, hinting at the menu that opens below. */
.nav-link {
  position: relative;
}
.nav-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 1.75rem; /* 24px chev + 4px gap */
  bottom: 0.0625rem;
  height: 0.09375rem;
  border-radius: 0.0625rem;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-hover) var(--ease-premium);
}
.nav-link:hover::after,
.nav-link:focus-visible::after {
  transform: scaleX(1);
}
.nav-link .chev {
  transition: transform var(--dur-hover) var(--ease-premium);
}
.nav-link:hover .chev {
  transform: translateY(0.125rem);
}
.nav-link:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: 0.25rem;
  border-radius: 0.25rem;
}

/* ---- §2: slideshow play / pause ----
   36px white square on the dark image. It flips to the brand lime rather than
   just greying, which is the clearest possible "this is the live control". */
.excl-play {
  transition:
    background var(--dur-hover) var(--ease-premium),
    transform var(--dur-hover) var(--ease-premium),
    box-shadow var(--dur-hover) var(--ease-premium);
}
.excl-play:hover {
  background: var(--accent);
  transform: scale(1.08);
  box-shadow: 0 0.375rem 1.125rem -0.5rem rgba(0, 0, 0, 0.55);
}
.excl-play:active {
  transform: scale(0.96);
  transition-duration: var(--dur-press);
}
.excl-play:focus-visible {
  outline: 0.125rem solid #fff;
  outline-offset: 0.1875rem;
}

/* ---- §3: "or, read how it works" ----
   A text link, so it gets a text-link hover: the rule it already has thickens
   and drops away from the baseline. No lift, no shadow — it is not a button. */
.pv-how a {
  text-decoration-thickness: 0.0625rem;
  text-underline-offset: 0.125rem;
  transition:
    text-decoration-thickness var(--dur-hover) var(--ease-premium),
    text-underline-offset var(--dur-hover) var(--ease-premium);
}
.pv-how a:hover {
  text-decoration-thickness: 0.125rem;
  text-underline-offset: 0.25rem;
}
.pv-how a:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: 0.1875rem;
  border-radius: 0.1875rem;
}

/* ---- §4: the four product-showcase pills ----
   Same recipe as base.css's .btn-dark, re-declared because .psh-btn is its own
   class rather than a .btn variant (Figma gives it a 60px height and a 9.99px
   gap that .btn does not have). */
.psh-btn {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition:
    background var(--dur-hover) var(--ease-premium),
    box-shadow var(--dur-hover) var(--ease-premium),
    transform var(--dur-hover) var(--ease-premium);
}
.psh-btn::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  bottom: 0;
  left: -55%;
  width: 46%;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.1) 30%,
    rgba(255, 255, 255, 0.38) 50%,
    rgba(255, 255, 255, 0.1) 70%,
    rgba(255, 255, 255, 0) 100%
  );
  transform: skewX(-18deg);
}
/* same band and same @keyframes btn-sheen as base.css's .btn — see the token
   note there for why the sweep has its own --dur-sheen / --ease-sheen */
.psh-btn:hover::before {
  animation: btn-sheen var(--dur-sheen) var(--ease-sheen) 80ms;
}
/* Hover goes DARKER than the resting #111, not lighter — the user's call on
   2026-08-13 ("hover pe or dark kr dena"), which reverses the .btn-dark recipe
   this rule used to copy (#111 -> #212121). The cast shadow now lives at rest,
   so hover deepens it instead of introducing it, or the lift would read as
   nothing happening. */
.psh-btn:hover {
  background: #000000;
  transform: translateY(-0.125rem);
  box-shadow:
    0 1.125rem 2.25rem -0.875rem rgba(17, 17, 17, 0.8),
    inset 0 0 0 0.0625rem rgba(255, 255, 255, 0.08);
}
.psh-btn:active {
  transform: translateY(0);
  box-shadow:
    0 0.1875rem 0.5rem -0.3125rem rgba(17, 17, 17, 0.7),
    inset 0 0 0 0.0625rem rgba(255, 255, 255, 0.08);
  transition-duration: var(--dur-press);
}
.psh-btn:focus-visible {
  outline: 0.125rem solid var(--accent);
  outline-offset: 0.1875rem;
}
.psh-btn-ico {
  transition: box-shadow var(--dur-hover) var(--ease-premium);
}
.psh-btn-ico img {
  transition: transform var(--dur-hover) var(--ease-premium);
}
.psh-btn:hover .psh-btn-ico {
  box-shadow: 0 0 0 0.1875rem rgba(226, 250, 90, 0.3);
}
.psh-btn:hover .psh-btn-ico img {
  transform: translateX(0.1875rem);
}
.psh-btn:active .psh-btn-ico img {
  transform: translateX(0.0625rem);
}

/* ---- §6: carousel prev / next ----
   These two are the one place where the arrow's DIRECTION is the whole point,
   so the hover is directional rather than a lift: each arrow leads the way it
   travels. .icar-navico-prev is the same asset under scaleX(-1), so its nudge
   has to re-declare the flip — and must come last, since both selectors carry
   identical specificity.
   :disabled is excluded rather than styled: Figma defines no disabled state. */
.icar-navbtn {
  transition:
    background var(--dur-hover) var(--ease-premium),
    box-shadow var(--dur-hover) var(--ease-premium);
}
.icar-navico {
  transition: transform var(--dur-hover) var(--ease-premium);
}
.icar-navbtn:not(:disabled):hover {
  background: rgba(17, 17, 17, 0.15);
  box-shadow: inset 0 0 0 0.0625rem rgba(17, 17, 17, 0.12);
}
.icar-navbtn:not(:disabled):active {
  background: rgba(17, 17, 17, 0.2);
  transition-duration: var(--dur-press);
}
.icar-navbtn:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: 0.1875rem;
}
.icar-navbtn:not(:disabled):hover .icar-navico {
  transform: translateX(0.1875rem);
}
.icar-navbtn:not(:disabled):hover .icar-navico-prev {
  transform: scaleX(-1) translateX(0.1875rem); /* mirrored space -> moves left */
}

/* ---- §6: the lime arrow CTA on each slide ---- */
.icar-cta {
  transition:
    background var(--dur-hover) var(--ease-premium),
    box-shadow var(--dur-hover) var(--ease-premium),
    transform var(--dur-hover) var(--ease-premium);
}
.icar-cta img {
  transition: transform var(--dur-hover) var(--ease-premium);
}
.icar-cta:hover {
  background: #eaff78;
  transform: translateY(-0.125rem);
  box-shadow: 0 0.75rem 1.625rem -0.75rem rgba(226, 250, 90, 0.75);
}
.icar-cta:hover img {
  transform: translateX(0.1875rem);
}
.icar-cta:active {
  transform: translateY(0);
  box-shadow: 0 0.125rem 0.5rem -0.3125rem rgba(226, 250, 90, 0.7);
  transition-duration: var(--dur-press);
}
.icar-cta:active img {
  transform: translateX(0.0625rem);
}
.icar-cta:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: 0.1875rem;
}

/* ---- §7: the seven tab chips ----
   Figma already hands us both end states — chip 1's #fff fill at opacity 1 is
   "selected", chips 2-7's node opacity .20 is "unselected" — so the hover is
   an interpolation between two given values rather than an invented look: the
   chip leans toward selected without arriving. The transition also covers the
   is-active swap, so switching tabs cross-fades the white fill.
   Nothing here touches the box model: the row sums (195+161+146 / 185+188 /
   179+166) are load-bearing. */
.iexc-chip {
  transition:
    opacity var(--dur-hover) var(--ease-premium),
    background var(--dur-hover) var(--ease-premium),
    transform var(--dur-hover) var(--ease-premium);
}
.iexc-chip-ico {
  transition: transform var(--dur-hover) var(--ease-premium);
}
.iexc-chip-ico img {
  transition: transform var(--dur-hover) var(--ease-premium);
}
.iexc-chip:not(.is-active):hover {
  opacity: 0.58;
  background: rgba(255, 255, 255, 0.45);
}
.iexc-chip:not(.is-active):hover .iexc-chip-ico img {
  transform: translateX(0.1875rem);
}
.iexc-chip:not(.is-active):active {
  transform: translateY(0.0625rem);
  transition-duration: var(--dur-press);
}

/* ---- §7: the tabpanel content swap ----
   Added 2026-08-05 on the user's instruction ("on click content smoothly change
   hona chahiye"). The chip selection still flips on the same tick as the click,
   so the control never feels laggy; only the PANEL lags, by exactly one
   fade-out. ExclusiveTabs.tsx holds `sel` (the chip) and `shown` (the painted
   content) separately and stamps `.is-swapping` on .iexc-right for the 200ms
   between them — see the component for the timing contract. Both halves must
   agree: this file owns the 200ms, the component owns the same 200ms.

   `.is-swapping` lands on `.iexc-card` and `.iexc-shot`, NOT on their parent
   `.iexc-right`, and that is load-bearing: `.iexc-right` is a motion reveal
   target, so MotionLayer stamps `rv-v-up` + `rv-in` on it and motion.css hides
   it via `html.rv-on :is(…, .iexc-right, …):not(.rv-in)`. Letting React own
   that className would wipe `rv-in` on the first tab switch and the whole
   column would drop back to opacity 0 / translate 100px. Neither child is a
   reveal target, so they are safe to make dynamic.

   The copy fades and lifts 6px. The IMAGE fades on opacity ONLY — never
   transform — because .iexc-shot[data-crop='figma'] img carries the load-
   bearing translate(-4.489%, -51.8416%) Figma crop, and a transform here would
   replace it and re-frame tab 1. .iexc-shot's own #111 fill shows through at
   the midpoint, so the image swap is a dip through ink rather than a true
   crossfade — which is what the dark panel and its inset #111 shadow already
   look like, so it reads as the panel dimming and relighting. */
.iexc-card p {
  transition:
    opacity 200ms var(--ease-premium),
    transform 200ms var(--ease-premium);
}
/* opacity only, and NOT via a shared shorthand with the rule above: `transform`
   in the img's transition list would animate the crop itself. Leaving tab 1
   (translate -4.489%, -51.8416%) for tab 2 (translate none) is 563px of travel
   on the image's own box, so it would visibly slide in as it fades. */
.iexc-shot img {
  transition: opacity 200ms var(--ease-premium);
}
.iexc-card.is-swapping p {
  opacity: 0;
  transform: translateY(0.375rem);
}
.iexc-shot.is-swapping img {
  opacity: 0;
}

/* ---- sticky quick bar: the hamburger ----
   A 2px ink outline with three ink bars, so the premium move is the inversion
   it is already drawn for: the box fills, the bars go white. */
.pill-menu {
  transition:
    background var(--dur-hover) var(--ease-premium),
    box-shadow var(--dur-hover) var(--ease-premium);
}
.pill-menu span {
  transition: background var(--dur-hover) var(--ease-premium);
}
.pill-menu:hover {
  background: var(--ink);
  box-shadow: 0 0.5rem 1.25rem -0.625rem rgba(17, 17, 17, 0.5);
}
.pill-menu:hover span {
  background: #fff;
}
.pill-menu:active {
  box-shadow: 0 0.125rem 0.375rem -0.25rem rgba(17, 17, 17, 0.5);
  transition-duration: var(--dur-press);
}
.pill-menu:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: 0.1875rem;
}

/* ---- reduced motion: keep the colour feedback, drop the movement ---- */
@media (prefers-reduced-motion: reduce) {
  .logo,
  .nav-link::after,
  .nav-link .chev,
  .excl-play,
  .pv-how a,
  .psh-btn,
  .psh-btn-ico,
  .psh-btn-ico img,
  .icar-navbtn,
  .icar-navico,
  .icar-cta,
  .icar-cta img,
  .iexc-chip,
  .iexc-chip-ico,
  .iexc-chip-ico img,
  .iexc-card p,
  .iexc-shot img,
  .pill-menu,
  .pill-menu span {
    transition-duration: 1ms;
  }
  /* the tab swap itself still happens — it is state, not decoration; only the
     6px lift on the copy goes (and the component skips the 200ms wait) */
  .iexc-card.is-swapping p {
    transform: none;
  }
  .logo-link:hover .logo,
  .nav-link:hover .chev,
  .excl-play:hover,
  .excl-play:active,
  .psh-btn:hover,
  .psh-btn:active,
  .psh-btn:hover .psh-btn-ico img,
  .psh-btn:active .psh-btn-ico img,
  .icar-navbtn:not(:disabled):hover .icar-navico,
  .icar-cta:hover,
  .icar-cta:active,
  .icar-cta:hover img,
  .icar-cta:active img,
  .iexc-chip:not(.is-active):hover .iexc-chip-ico img,
  .iexc-chip:not(.is-active):active {
    transform: none;
  }
  .icar-navbtn:not(:disabled):hover .icar-navico-prev {
    transform: scaleX(-1);
  }
  .nav-link:hover::after,
  .nav-link:focus-visible::after {
    transform: scaleX(1);
  }
  .psh-btn:hover::before {
    animation: none;
  }
}

/* =========================================================================
   CARD LAYER — card hover / press / focus + image zoom
   -------------------------------------------------------------------------
   Second half of the authored interaction layer (see the banner above for the
   ground rules: resting render untouched, box model untouched). Added on the
   user's request 2026-07-30, together with making the §11a FAQ rows and the §9
   blog cards genuinely clickable.

   Two shared ingredients, so eight different cards still read as one system:

     --dur-zoom 700ms   images ease in slower than chrome does. A 220ms photo
                        zoom reads as a twitch; 700ms reads as deliberate.
     scale(1.06)        every card image, on the card's hover — never the
                        image's own, so the whole card is the trigger.

   Every zoom container is clipped. Three of them already were (`.blog-card`,
   `.psh-card`, `.icar-card` all carry Figma's clipsContent), and §3's needed a
   new `.pvc-sketchwrap` because `.pvc-card` must NOT take overflow:hidden — it
   would cut off the z-index:-1 filler panel that extends columns 1 and 2 down
   to card 3's baseline.

   Not covered, deliberately: §5's `.tband-col` (a logo + two text lines on
   black, no card box to lift), §7's `.iexc-card` (copy inside a tabpanel, and
   its sibling `.iexc-shot` carries the load-bearing 279.1774% / -4.489% /
   -51.8416% Figma crop that a scale() would have to compose with), and the §10
   / §11b section photographs, which are backgrounds rather than cards.
   ========================================================================= */

:root {
  --dur-zoom: 700ms;
}

/* ---- §2: the three stat cards (24% / 30 year / HPBC) ----
   Shadow ONLY, on the user's instruction (2026-08-05): no lift, no zoom, no
   colour change. They are inert boxes — Figma wires no target and there is
   nothing inside them to click — so depth is the whole affordance. The card is
   #fff inside a 4px #f6f6f6 border on the cream page, so the shadow has to be
   soft and low or the border reads as a second edge. */
.excl-card {
  transition: box-shadow var(--dur-hover) var(--ease-premium);
}
.excl-card:hover {
  box-shadow: 0 1.25rem 2.75rem -1.25rem rgba(17, 17, 17, 0.24);
}

/* ---- §2: the slideshow card ----
   Hovering anywhere on the 630x650 card does three things at once (user's
   call, 2026-08-05):
     1. Figma's lime glow (0 4px 60px rgba(226,250,90,.85)) intensifies and
        gains an ink shadow underneath it, so the card gets depth as well as
        halo — the lime alone just spreads and never reads as "closer".
     2. All three photos zoom 1.06. The zoom goes on .excl-photo, which is the
        crossfading stack, so the transition MUST restate opacity .6s ease —
        that is ExclusiveVideo.tsx's own crossfade and dropping it would make
        the slideshow hard-cut. .excl-video is overflow:hidden, so the extra
        6% is clipped by the card's own r12.
     3. The lime arrow chip grows 80 -> 96 tall. .excl-caption is
        align-items:flex-end and bottom-anchored, so it grows UPWARD out of the
        card's bottom inset and the caption text does not move.
   Height is the one box-model change in this whole layer, and it is deliberate:
   it only exists while hovered, and it is what the user asked for. */
.excl-video {
  transition: box-shadow 320ms var(--ease-premium);
}
.excl-photo {
  transition:
    opacity 0.6s ease,
    transform var(--dur-zoom) var(--ease-premium);
}
.excl-chip {
  transition:
    height var(--dur-hover) var(--ease-premium),
    background var(--dur-hover) var(--ease-premium),
    box-shadow var(--dur-hover) var(--ease-premium);
}
.excl-chip img {
  transition: transform var(--dur-hover) var(--ease-premium);
}
.excl-video:hover {
  box-shadow:
    0 0.5rem 5.5rem 0 rgba(226, 250, 90, 0.95),
    0 1.5rem 3.25rem -1.5rem rgba(17, 17, 17, 0.42);
}
.excl-video:hover .excl-photo {
  transform: scale(1.06);
}
.excl-video:hover .excl-chip {
  height: 6rem; /* 96, from Figma's 80 */
  box-shadow: 0 0.75rem 1.5rem -0.75rem rgba(226, 250, 90, 0.8);
}
.excl-video:hover .excl-chip img {
  transform: translateX(0.1875rem);
}

/* ---- §3: the five step cards on the conveyor ----
   A card in a faded slot brightens to full on hover, which is the
   Figma-derived part; the shadow and the sketch zoom are the new layer. The
   card at slot A already sits at 1, so without this it was the only one that
   did not respond.

   `* 1.5` and not a flat `opacity: 1`: it takes the slot dim's 0.7 to 1.05 ->
   clamped to 1, but leaves an OFF-STAGE card's 0 at 0. Cards 4 and 5 rest
   invisible yet still take pointer events (nothing sits behind them, so that
   is harmless) — a flat 1 would flash one of them into full view on hover.
   The 0.3s below then smooths the scroll-driven opacity too, which at a real
   scroll speed reads as easing rather than lag. */
.pvc-card {
  transition:
    opacity 0.3s ease,
    box-shadow var(--dur-hover) var(--ease-premium),
    transform var(--dur-hover) var(--ease-premium);
}
.pvc-sketch {
  transition: transform var(--dur-zoom) var(--ease-premium);
}
.pvc-card:hover {
  opacity: min(1, calc(var(--pv-o) * 1.5));
  transform: translateY(-0.25rem);
  box-shadow: 0 1.5rem 3rem -1.5rem rgba(17, 17, 17, 0.28);
}
.pvc-card:hover .pvc-sketch {
  transform: scale(1.06);
}

/* ---- §4: the three product cards ----
   620x558 boxes in a sticky-scroll column — far too big to lift without
   looking cheap, so they gain definition instead: a hairline ring plus depth,
   and the product cutout pushes forward. */
.psh-card {
  transition: box-shadow var(--dur-hover) var(--ease-premium);
}
.psh-shot {
  transition: transform var(--dur-zoom) var(--ease-premium);
}
/* ---- the card the reader is on ----
   Added 2026-08-13: whichever card is nearest the middle of the viewport gets a
   soft shadow, one at a time, purely to say "you are reading this one". Set by
   `PshCardFocus`, which writes the class with `classList` rather than through
   React — `.psh-card` is a motion reveal target, and letting React own its
   className would drop `rv-in` and snap the card back to invisible (trap 7).

   DELIBERATELY LIGHTER THAN, AND BEFORE, `:hover`. Both selectors are (0,2,0),
   so source order is the only thing separating them — moving this rule below
   the hover would make the focus shadow win while the pointer is down on a
   card. Hover keeps the two-shadow stack; this is a single soft cast at .28. */
.psh-card.is-focus {
  box-shadow: 0 1.25rem 3rem -1.5rem rgba(17, 17, 17, 0.28);
}
/* Strengthened 2026-08-05 on the user's instruction. Still no lift — the change
   is depth only, now a two-shadow stack: a wide soft cast at .46 for the drop
   itself plus a tight contact shadow at .26 right under the card, which is what
   actually makes a 620-wide box look lifted off the sky photo. The old single
   .30 cast was invisible against §4's bright background. */
.psh-card:hover {
  box-shadow:
    0 2rem 4.5rem -1.5rem rgba(17, 17, 17, 0.46),
    0 0.625rem 1.25rem -0.75rem rgba(17, 17, 17, 0.26),
    inset 0 0 0 0.0625rem rgba(17, 17, 17, 0.1);
}
/* absolutely positioned at 356,48 240x240 inside a 620-wide card, so 1.06
   grows it 7px a side (349..603) and never reaches the 620 edge */
.psh-card:hover .psh-shot {
  transform: scale(1.06);
}

/* ---- §6: the carousel slides ----
   The active slide's white sheet is a ::before at inset -12px, so the depth
   change belongs on that pseudo-element, not on the slide box. */
.icar-slide.is-active::before {
  transition: box-shadow var(--dur-hover) var(--ease-premium);
}
.icar-photo {
  transition: transform var(--dur-zoom) var(--ease-premium);
}
.icar-slide:hover .icar-photo {
  transform: scale(1.05);
}
.icar-slide.is-active:hover::before {
  box-shadow: 0 0.625rem 3.25rem rgba(0, 0, 0, 0.24);
}
/* slide 3 is Figma's lime dot grid instead of a photo — the dots breathe out
   from the centre so it responds like its siblings */
.icar-dots {
  transition: transform var(--dur-zoom) var(--ease-premium);
}
.icar-slide:hover .icar-dots {
  transform: scale(1.03);
}

/* ---- §8: the three benefit cards ----
   Not links (Figma wires no target), so this stays presentational: a small
   lift and the 60x60 lime square — which is empty by design in Figma — gains
   a ring rather than pretending to be a button. */
.sob-card {
  transition:
    box-shadow var(--dur-hover) var(--ease-premium),
    transform var(--dur-hover) var(--ease-premium);
}
.sob-ico {
  transition:
    transform var(--dur-hover) var(--ease-premium),
    box-shadow var(--dur-hover) var(--ease-premium);
}
.sob-card:hover {
  transform: translateY(-0.1875rem);
  box-shadow: 0 1.125rem 2.5rem -1.25rem rgba(17, 17, 17, 0.22);
}
.sob-card:hover .sob-ico {
  transform: scale(1.06);
  box-shadow: 0 0 0 0.25rem rgba(226, 250, 90, 0.35);
}

/* ---- §8: the aerial band ----
   Added 2026-08-05 on the user's instruction. The band is a section photograph,
   not a card — so it gets the zoom and nothing else: no lift, no shadow, no
   affordance, because there is nothing to click. The <img> is a 1920x1080 crop
   positioned in % of the 1896x780 frame and already overflows it on every side,
   so scale(1.06) about its own centre cannot expose an edge, and .sob-band's
   overflow:hidden + r12 clips the rest. --dur-zoom (700ms) is the same curve
   the card photos use, so this reads as one system with §3/§4/§6/§9.

   `:is(img, video)` since 2026-08-18, when the desktop still became a clip: the
   video is pre-cropped to the band exactly, so it does NOT overflow the frame the
   way the <img> does — but `overflow: hidden` on .sob-band is what actually clips
   the zoom, and scale(1.06) about the centre only ever pulls the edges outward, so
   the guarantee is unchanged. Specificity is identical to the bare `img` it
   replaces — `:is()` takes its most specific argument, and both are type
   selectors — so nothing else in the cascade moved. */
.sob-band :is(img, video) {
  transition: transform var(--dur-zoom) var(--ease-premium);
}
.sob-band:hover :is(img, video) {
  transform: scale(1.06);
}

/* ---- §9: the three blog cards (now the <a> itself) ----
   The one card set that is a real link, so it gets the full treatment: lift,
   depth, a 700ms image zoom, and the ink tag flipping to lime — the brand's
   own accent doing the work instead of a generic "read more" chevron. */
.blog-card {
  transition:
    box-shadow var(--dur-hover) var(--ease-premium),
    transform var(--dur-hover) var(--ease-premium);
}
.blog-shot {
  transition: transform var(--dur-zoom) var(--ease-premium);
}
.blog-tag {
  transition:
    background var(--dur-hover) var(--ease-premium),
    color var(--dur-hover) var(--ease-premium);
}
.blog-card p {
  transition: color var(--dur-hover) var(--ease-premium);
}
.blog-card:hover {
  transform: translateY(-0.25rem);
  box-shadow: 0 1.5rem 3rem -1.375rem rgba(17, 17, 17, 0.26);
}
.blog-card:hover .blog-shot {
  transform: scale(1.06);
}
.blog-card:hover .blog-tag {
  background: var(--accent);
  color: var(--ink);
}
.blog-card:hover p {
  color: var(--ink);
}
.blog-card:active {
  transform: translateY(-0.0625rem);
  box-shadow: 0 0.5rem 1.25rem -0.75rem rgba(17, 17, 17, 0.3);
  transition-duration: var(--dur-press);
}
.blog-card:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: 0.1875rem;
}

/* ---- §11a: the nine FAQ rows (now a real accordion) ----
   The rows sit on a #f5f6f0 -> #e2fa5a gradient, so a white card cannot lift
   into more white — it slides 3px toward the reader instead, and the grey chip
   takes the brand lime. Open state keeps the lime chip and flips the arrow a
   further 180deg (Figma's own +90deg rotation is the closed position). */
.qna-faq {
  transition:
    box-shadow var(--dur-hover) var(--ease-premium),
    transform var(--dur-hover) var(--ease-premium);
}
.qna-faq-chip {
  transition:
    background var(--dur-hover) var(--ease-premium),
    box-shadow var(--dur-hover) var(--ease-premium);
}
.qna-faq-chip img {
  transition: transform 340ms var(--ease-premium);
}
.qna-faq:hover {
  transform: translateX(0.1875rem);
  box-shadow:
    0 0.625rem 1.625rem -0.875rem rgba(17, 17, 17, 0.25),
    inset 0 0 0 0.0625rem rgba(17, 17, 17, 0.06);
}
.qna-faq:hover .qna-faq-chip,
.qna-faq.is-open .qna-faq-chip {
  background: var(--accent);
}
.qna-faq:hover .qna-faq-chip {
  box-shadow: 0 0 0 0.1875rem rgba(226, 250, 90, 0.35);
}
.qna-faq.is-open {
  box-shadow: 0 0.875rem 2rem -1.125rem rgba(17, 17, 17, 0.24);
}
.qna-faq.is-open .qna-faq-chip img {
  transform: rotate(270deg); /* 90deg closed (Figma) -> 270deg open */
}
.qna-faq-btn:focus-visible {
  outline: 0.125rem solid var(--ink);
  outline-offset: -0.1875rem;
  border-radius: var(--radius);
}
.qna-faq-btn:active {
  transition-duration: var(--dur-press);
}

/* ---- reduced motion: keep colour and state, drop movement and zoom ---- */
@media (prefers-reduced-motion: reduce) {
  /* .excl-photo is deliberately NOT in this list: its 0.6s opacity is
     ExclusiveVideo's own slide crossfade, and zeroing it would turn the
     slideshow into a hard cut. Only its hover transform is dropped, below. */
  .excl-card,
  .excl-video,
  .excl-chip,
  .excl-chip img,
  .pvc-card,
  .pvc-sketch,
  .psh-card,
  .psh-shot,
  .icar-slide.is-active::before,
  .icar-photo,
  .icar-dots,
  .sob-card,
  .sob-ico,
  .sob-band :is(img, video),
  .blog-card,
  .blog-shot,
  .blog-tag,
  .blog-card p,
  .qna-faq,
  .qna-faq-chip,
  .qna-faq-chip img,
  .qna-faq-panel {
    transition-duration: 1ms;
  }
  .excl-video:hover .excl-photo,
  .excl-video:hover .excl-chip img,
  .pvc-card:hover,
  .pvc-card:hover .pvc-sketch,
  .psh-card:hover .psh-shot,
  .icar-slide:hover .icar-photo,
  .icar-slide:hover .icar-dots,
  .sob-card:hover,
  .sob-card:hover .sob-ico,
  .sob-band:hover :is(img, video),
  .blog-card:hover,
  .blog-card:hover .blog-shot,
  .blog-card:active,
  .qna-faq:hover {
    transform: none;
  }
  /* the chip's growth is movement, so it goes; its glow stays */
  .excl-video:hover .excl-chip {
    height: 5rem;
  }
  /* the chevron flip is state, not decoration — it stays */
  .qna-faq.is-open .qna-faq-chip img {
    transform: rotate(270deg);
  }
}

/* ==========================================================================
   §1 HERO CALLOUT — the "Updated Homepage" treatment          DESKTOP ONLY
   FRAME "Updated Homepage" 7073:22 > FRAME "Frame 22" 7073:809
     > GROUP "Group 38" 7073:884, 400x79 @ (1300,553)
   plus VECTOR "Vector 2" 7073:891, 440x0 @ (848,593)

   This replaces FRAME "Frame 17" 7064:865 — the 333x111 solid #E2FA5A card
   with a 2px #111 INSIDE border and r8 — which is what home.css still paints
   and what the 428 frame still specifies. A full diff of the two heros (79 vs
   83 nodes) found ONLY these two changes: every photo, scrim, the header, the
   h1, the sub, the checks, the CTA, the reviews row (FRAME 7073:870) and the
   panel outline (GROUP 7073:875) are byte-identical geometry, so nothing else
   in §1 is touched here.

   WHY A min-width QUERY, the first in this sheet: the Figma file has no
   updated 428 frame, so mobile must keep the lime box. 767.99px is the exact
   complement of home-mobile.css's `max-width: 767.98px`, so not one rule that
   applies below 768 changes and home-mobile.css is not edited at all — the
   mobile render is unchanged BY CONSTRUCTION, not by care.

   Type is NOT restated: .callout-card already carries var(--font-display) and
   letter-spacing -0.08rem (Figma's -1.28), and .callout-title / .callout-sub
   already carry 32/500/--ink and 24/400/--ink-70. Both Figma nodes are
   lineHeightUnit INTRINSIC_%, so `line-height: normal` stays correct. Only the
   container and the layout change.
   ========================================================================== */
/* The three Group 38 elements do not exist below 768, and `display: none` is
   their DEFAULT rather than a mobile override — the desktop block below is what
   turns them on. That is deliberate: it means no `max-width` rule is needed
   anywhere, so home-mobile.css is not edited at all and the 428 render cannot
   move. Without this the two arcs would render as inline 147x79 images inside
   the lime card and the empty highlighter span would open an anonymous block,
   both of which shift the mobile layout. (A `display: none` <img> is still
   fetched — the same 2 KB mobile already spends on the hidden .callout-dash.) */
.callout-hl,
.callout-arc {
  display: none;
}

@media (min-width: 767.99px) {
  /* Group 38's right edge lands on 1700, i.e. a 220 inset from the 1920
     canvas => calc(50% - 46.25rem). The old card was 333 wide at a 218 inset,
     so the right edge moves 2 left while the box gains 67 and loses 32. */
  .hero-callout {
    top: 34.5625rem;                            /* 553 */
    right: max(1.5rem, calc(50% - 46.25rem));   /* 220 @1920 -> x1300..1700 */
    width: 25rem;                               /* 400 */
  }

  /* Vector 2 kept its paint exactly (2px, dashes [8,8], GRADIENT_LINEAR
     #E2FA5A -> #111111 left to right) and changed only its geometry: it used
     to be 637 long and run UNDER the card to its right edge, and now it is 440
     and stops 12 short of the group's left arc. Its 2px CENTER stroke puts the
     ink on y592..594, i.e. the group's own vertical centre (553 + 79/2). */
  .callout-dash {
    right: calc(100% + 0.75rem);   /* 12 clear of the callout's left edge */
    left: auto;
    top: 2.4375rem;                /* 592 - 553 */
    width: 27.5rem;                /* 440 — the node box, matching how the 637
                                      asset was placed (its 1px round caps
                                      overhang, as they did before) */
  }

  /* The card itself: no fill, no border, no radius. `overflow: visible`
     because the arcs sit ON the group's own top and bottom edges, where the
     inherited `overflow: hidden` would shave their anti-aliasing.

     §4's .psh-callout joins it here — one rule set for both, so the two
     callouts cannot drift. `position: relative` is what makes each one the
     containing block for its own absolutely-positioned pill and arcs. */
  .callout-card,
  .psh-callout {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 25rem;           /* 400 */
    height: 4.9375rem;      /* 79 = 43 + 4 + 32 */
    background: none;
    border: 0;
    border-radius: 0;
    overflow: visible;
  }

  /* §4's box was a DECLARED 333x111 in a `flex-start` column, so the new 79
     would pull .psh-reviews and .psh-btn-reviews up by 32. The 32 of bottom
     margin gives it straight back: 60 + 79 + 32 == 60 + 111, so the callout's
     footprint in the column is unchanged and nothing below it moves. Keep the
     two numbers in step if either ever changes. */
  .psh-callout {
    margin: 3.75rem 0 2rem; /* was 60 0 0 against a 111-tall box */
  }

  /* FRAME "Frame 1707481602" 7073:886 — a 306-wide column, itemSpacing 4,
     counterAxisAlignItems CENTER, which lands it on a symmetric 47 inset
     either side of the 400 group. `position: relative` is load-bearing: the
     lime pill is absolutely positioned and would otherwise paint OVER the
     text, since positioned descendants paint after static content regardless
     of DOM order. Making the text positioned too puts both in the same paint
     step, where DOM order decides and the pill (first) stays behind. That is
     also why this needs no negative z-index. */
  .callout-title,
  .callout-sub,
  .psh-callout-t,
  .psh-callout-s {
    position: relative;
    width: 19.125rem;       /* 306 */
    margin: 0;
    /* §4 declared 2.66rem / 1.995rem where §1 leaves this at `normal`. Both
       Figma nodes are lineHeightUnit INTRINSIC_%, i.e. 42.56 / 31.92 is what
       Figma's own engine calls `normal` — so `normal` is the faithful value AND
       the one that makes the two callouts render identically. Host Grotesk
       gives 42 / 32 here, which is what the sub's 5 below is calibrated to. */
    line-height: normal;
  }
  .callout-sub,
  .psh-callout-s {
    /* Figma's itemSpacing is 4, and this is 5 for the reason home-mobile.css
       already documents on this very element: both nodes are INTRINSIC_%, so
       line-height stays `normal`, and Host Grotesk gives the 32px title a 42
       line box where Figma's box is 43. At a literal 4 the sub lands on 599
       against Figma's 600. The 5 absorbs that 1px and puts the sub on 600..632
       exactly, which also lands the content bottom on 632 = 553 + 79, i.e.
       flush with the declared height instead of 1px shy of it. */
    margin-top: 0.3125rem;  /* 5 -> renders at Figma's 4 */
  }

  /* RECTANGLE "Rectangle 40" 7073:885 — 109x40 r12 solid #E2FA5A at group-rel
     (250,5), behind "upfront". */
  .callout-hl {
    display: block;         /* switched on — `none` is the default, see above */
    position: absolute;
    left: 15.625rem;        /* 250 */
    top: 0.3125rem;         /*   5 */
    width: 6.8125rem;       /* 109 */
    height: 2.5rem;         /*  40 */
    border-radius: 0.75rem; /*  12 */
    background: var(--accent);
  }

  /* RECTANGLE "Rectangle 38" / "Rectangle 39" 7073:889/:890. Figma renders an
     INSIDE stroke by outlining it at double weight CENTRED and masking the
     outer half away, which is why the raw strokeGeometry spans 4 where the
     node says weight 2 — its own SVG export carries that mask, and measuring
     the 2x render confirms the band really is r37.5..39.5 (centre-line 38.5).
     CSS cannot do this: there is no dash-length control on `border`, and a
     border-left on an r39.5 box paints a tapering wedge, not a 2px arc. */
  .callout-arc {
    display: block;         /* switched on — `none` is the default, see above */
    position: absolute;
    top: 0;
    width: 9.1875rem;       /* 147 */
    height: 4.9375rem;      /*  79 */
    max-width: none;
  }
  .callout-arc-l {
    left: 0;
  }
  .callout-arc-r {
    left: 15.8125rem;       /* 253 */
    transform: scaleX(-1);  /* Figma's 180deg rotation of the same node */
  }
}
