/* =============================================================================
   INDEX.HTML  ·  page layout only (visual system lives in styles.css)
   Owner: PAGE-HOME builder.
   ========================================================================== */

/* Hero: left-aligned text inside a centered column (calmer with the control
   embedded in the headline than full centering). */
.hero {
  position: relative;
}

.hero .wrap {
  position: relative;
  z-index: 1;
  max-width: 46rem;
  text-align: left;
}

/* Frosted backing behind the hero copy so it stays crisp over the dot-field.
   Feathered edges (radial mask) keep it from reading as a hard box; the dots
   stay faintly visible through the glass for depth. Negative inset means no
   layout shift. Sits above the canvas but behind the text (z-index -1 inside
   the wrap's own stacking context). */
.hero .wrap::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -1.75rem -2rem;
  border-radius: 44px;
  background: rgba(250, 249, 247, 0.55);
  -webkit-backdrop-filter: blur(7px) saturate(112%);
  backdrop-filter: blur(7px) saturate(112%);
  -webkit-mask-image: radial-gradient(118% 100% at 42% 46%, #000 58%, transparent 100%);
  mask-image: radial-gradient(118% 100% at 42% 46%, #000 58%, transparent 100%);
  pointer-events: none;
}

/* Where backdrop-filter is unsupported, the translucent fill alone still lifts
   the text off the dots. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hero .wrap::before {
    background: rgba(250, 249, 247, 0.8);
  }
}

/* The living dot-field background (hero-bg.js injects this canvas as the hero's
   first child). Sits behind the text; never intercepts pointer events (the
   ripple reads the cursor from the window). */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Section rhythm for the plain <section> blocks this page owns. */
.work,
.stats,
.dash-teaser,
.svc,
.other,
.contact {
  margin-top: var(--sect);
}

/* Work section heading column reads like the rest of the site's kickers. */
.work .section__h,
.stats .section__h,
.dash-teaser .section__h,
.svc .section__h,
.other .section__h,
.contact .section__h {
  margin-top: 0;
}

/* -----------------------------------------------------------------------------
   DASHBOARD TEASER  ·  home-page link into dashboard.html
   Copy column + a static (non-interactive) echo of the live depreciation
   curve, so the promise "watch it move" reads honest: the real, moving
   version lives one click away on the data page.
   -------------------------------------------------------------------------- */
.dash-teaser__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-7);
  align-items: center;
}

@media (min-width: 900px) {
  .dash-teaser__inner {
    grid-template-columns: 52fr 48fr;
    gap: var(--s-8);
  }
}

.dash-teaser__copy .section__intro {
  max-width: 34rem;
}

.dash-teaser__copy .btn-pill {
  margin-top: var(--s-6);
}

.dash-teaser__vis svg {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--r-card);
}

/* Services row: heading block stays in the centered wrap; the scroller itself
   goes full-bleed via .svc__scroller (already handled in styles.css). */
.svc__more {
  margin-top: var(--s-5);
  font: 400 var(--fs-small) var(--font-sans);
}

/* Proof strip gets hairlines above and below, per spec 8.2 (optional, used
   here to separate it from the work grid and the services row). */
.proof {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
