/* ════════════════════════════════════════════════════════════════════
   sub.css — v2 subpage shell (contact, pricing, …). Loads AFTER
   css/core.css and only adds the subpage-only recipes core does not
   carry: the .p-hero block, .grid2, the results bento, the final CTA
   (which lives in scenes.css on the homepage) and their responsive +
   degradation blocks. Dark is the only canvas; every rule consumes
   the --pg-* tokens core.css defines.

   Degradation matrix for the CSS-side animations here (wash, float,
   pulse, live dot): @media (prefers-reduced-motion) below, body.no-anim
   (stamped by js/sub.js under ?static / no-GSAP), html.is-ff sheds the
   always-on repainters. CSS defaults are the resolved pose — no-JS
   renders complete.
   ════════════════════════════════════════════════════════════════════ */

/* ── page hero (subpage recipe): badge → display title → blurb → CTAs.
   The wash tint is set per page via --hero-wash: emerald by default;
   the pricing hero is the ONLY place amber is allowed, e.g.
   --hero-wash:rgba(255,193,77,.12) on that page's .p-hero. ── */
.p-hero{
  position:relative;max-width:1180px;margin:0 auto;
  padding:186px 24px 88px;text-align:center;overflow:hidden;
}
.p-hero::before{
  content:"";position:absolute;left:50%;top:-180px;transform:translateX(-50%);
  width:960px;height:640px;border-radius:50%;pointer-events:none;
  background:radial-gradient(50% 50% at 50% 50%, var(--hero-wash, rgba(21,184,127,.12)), transparent 70%);
  animation:pg-wash-in 1.7s var(--pg-ease) .15s both;
}
@keyframes pg-wash-in{
  from{opacity:0;transform:translateX(-50%) scale(.82)}
  to{opacity:1;transform:translateX(-50%) scale(1)}
}
.p-hero>*{position:relative}
.p-hero__title{
  margin:0 auto;font-family:var(--pg-display);
  font-size:clamp(42px,6.2vw,78px);line-height:1.02;font-weight:500;
  letter-spacing:-.025em;color:var(--pg-ink);max-width:16ch;
}
/* the signature highlighter stroke: the marker gradient draws in
   left-to-right via background-size (JS, one-shot). Painted per line
   fragment, so multi-line marks keep their highlight. CSS default is
   the resolved 100% — no-JS/static render complete. */
.p-hero__title strong{
  font-weight:700;
  background-image:linear-gradient(transparent 70%, var(--pg-marker) 70%, var(--pg-marker) 94%, transparent 94%);
  background-repeat:no-repeat;background-position:0 0;background-size:100% 100%;
}
/* idle float for a hero product shot — `translate` only, never fights GSAP */
@keyframes pg-float{50%{translate:0 -10px}}
.p-hero__art--float img{animation:pg-float 7s ease-in-out infinite}
html.is-ff .p-hero__art--float img{animation:none}
/* WiFi pulse — rings radiating from the device, same language as the
   map pings. Sits behind the product image. */
.p-hero__art{position:relative}
.p-hero__art img{position:relative}
.p-hero__pulse{position:absolute;left:50%;top:50%;width:0;height:0;pointer-events:none}
.p-hero__pulse i{
  position:absolute;left:50%;top:50%;
  width:min(280px,52vw);aspect-ratio:1;transform:translate(-50%,-50%) scale(.35);
  border-radius:50%;border:1.5px solid rgba(21,184,127,.55);opacity:0;
  animation:pg-pulse 3.9s ease-out infinite;
}
.p-hero__pulse i:nth-child(2){animation-delay:1.3s}
.p-hero__pulse i:nth-child(3){animation-delay:2.6s}
@keyframes pg-pulse{
  0%{transform:translate(-50%,-50%) scale(.35);opacity:0}
  12%{opacity:.65}
  100%{transform:translate(-50%,-50%) scale(2);opacity:0}
}
html.is-ff .p-hero__pulse i{animation:none}
/* live dot — radiating ping, emerald = alive */
.live-dot{
  display:inline-block;position:relative;width:7px;height:7px;border-radius:50%;
  background:var(--pg-emerald-hi);margin-right:9px;vertical-align:1px;
}
.live-dot::after{
  content:"";position:absolute;inset:-4px;border-radius:50%;
  border:1px solid rgba(21,184,127,.7);
  animation:pg-ping 2.8s ease-out infinite;
}
@keyframes pg-ping{
  0%{transform:scale(.5);opacity:.9}
  70%,100%{transform:scale(1.7);opacity:0}
}
html.is-ff .live-dot::after{animation:none;opacity:0}
.p-hero__blurb{margin:22px auto 0;font-size:clamp(16px,1.9vw,18px);line-height:1.66;color:var(--pg-mute);max-width:56ch}
.p-hero__ctas{display:flex;justify-content:center;align-items:center;flex-wrap:wrap;gap:18px;margin-top:36px}
.p-hero__meta{margin:22px 0 0;font-size:13px;font-weight:600;letter-spacing:.04em;color:var(--pg-faint)}

/* ── two-up card grid (core carries .grid6/.card) ── */
.grid2{display:grid;grid-template-columns:repeat(2,1fr);gap:18px}

/* ── results bento ── */
.bento{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.bento__item{min-height:15rem;justify-content:flex-end}
.bento__item .vig{margin-top:auto;padding-top:0}
.bento__item--wide{grid-column:span 2}
.bento__item--invert{background:#0a0e14;border-color:rgba(238,242,246,.1)}
.bento__item--invert .vig__fig{color:#2ed49a}
.bento__item--invert .vig__label{color:rgba(238,242,246,.55)}
.bento__hero-fig .vig__fig{font-size:clamp(56px,6vw,88px)}

/* ── final CTA (scenes.css owns this on the homepage; subpages compose
   core + sub only, so the recipe rides here) ── */
.final{max-width:760px;margin:0 auto;padding:120px 24px 130px;text-align:center}
.final__title{
  margin:0;font-family:var(--pg-display);
  font-size:clamp(36px,5.6vw,64px);font-weight:500;line-height:1.04;
  letter-spacing:-.02em;color:var(--pg-ink);
}
.final__blurb{margin:18px auto 0;font-size:16.5px;line-height:1.65;color:var(--pg-mute);max-width:52ch}
.final__cta-wrap{position:relative;display:inline-block;margin-top:36px}
.final__cta-wrap::before{
  content:"";position:absolute;inset:-18px -30px;border-radius:999px;
  background:radial-gradient(50% 50% at 50% 50%, rgba(226,59,52,.22) 0%, rgba(226,59,52,0) 70%);
  pointer-events:none;
}
.final__reassure{margin:14px 0 0;font-size:13px;letter-spacing:.02em;color:var(--pg-faint)}
.final__rescue{margin:24px 0 0;font-size:14px;color:var(--pg-mute)}
.final__rescue a{color:var(--pg-ink);font-weight:600;text-decoration:none;border-bottom:1px solid var(--pg-hairline);padding-bottom:2px}
.final__rescue a:hover{color:var(--pg-emerald-hi);border-color:var(--pg-emerald)}

/* numbers that move stay tabular so nothing shivers mid-count */
[data-countup]{font-variant-numeric:tabular-nums}

/* ── responsive ── */
@media (max-width:1024px){
  .bento{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:900px){
  /* Top clearance scales with the viewport instead of a flat 150px: the nav is
     56px here, so 150px spent ~94px of a 640px screen on empty air and pushed
     the hero CTA below the fold (nothing tappable in the first screen on
     /pricing, /coverage and /api at 360x640). clamp() keeps the airy pose on
     tall phones and tightens it on short ones — no viewport-unit height, so
     mobile browser chrome cannot change the result. */
  .p-hero{padding:clamp(84px,15vh,150px) 20px clamp(40px,7vh,64px)}
  .grid2{grid-template-columns:1fr}
}
@media (max-width:560px){
  .bento{grid-template-columns:1fr}
  .bento__item--wide{grid-column:span 1}
}

/* ── degradation: OS preference and the ?static / no-GSAP pose
   (body.no-anim, stamped by js/sub.js) resolve every animation ── */
@media (prefers-reduced-motion: reduce){
  .p-hero::before{animation:none}
  .p-hero__art--float img{animation:none}
  .p-hero__pulse i{animation:none}
  .live-dot::after{animation:none;opacity:0}
}
.no-anim .p-hero::before{animation:none}
.no-anim .p-hero__art--float img{animation:none}
.no-anim .p-hero__pulse i{animation:none}
.no-anim .live-dot::after{animation:none;opacity:0}
