/* ==========================================================================
   NextRenew — landing page

   Flat matte, exactly like the app. design_tokens.dart is explicit about this:
   "Full-screen background — flat matte", "Card/container surface — flat tone",
   "Accent shadows without glow tint", accentGlow is "flat, no extra glow".
   So: no gradients, no gloss highlights, no backdrop blur, no grain overlay.
   Depth comes only from NeuShadow's light/dark pair, same as the app.

   Palette: nextrenew/lib/theme/app_theme.dart (AppColors)
   Type:    Inter — the face the app loads via GoogleFonts.interTextTheme
   ========================================================================== */

:root {
  --bg:       #1A2120;   /* AppColors.background */
  --bg-alt:   #1C2423;   /* AppColors.backgroundAlt */
  --bg-deep:  #171D1D;   /* AppColors.bgDeep */
  --surface:  #1D2524;   /* AppColors.surface */
  --border:   #2A3533;   /* AppColors.surfaceBorder */

  --mint:      #349B91;  /* AppColors.accent */
  --mint-dark: #2E8B82;  /* AppColors.accentDark */

  --text:  #D6DEDD;      /* AppColors.textPrimary */
  --muted: #9CA9A8;      /* AppColors.textSecondary */
  --faint: #8B9796;      /* AppColors.textMuted, lifted to hold AA */

  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --gut:  clamp(20px, 4vw, 52px);
  --maxw: 1240px;

  /* NeumorphicMatteContainer, MatteSurfaceType.embossed — the widget's own
     defaults: depth 6, blur 16, intensity 1.12. A light lobe up-left and a
     heavier dark lobe down-right is what makes the app's surfaces read as
     carved rather than drawn. */
  --emboss:
    -6px -6px 16.6px -1px rgba(42, 53, 51, .56),
     6px  8px 18.6px -1px rgba(15, 20, 20, .99);

  /* the same relationship at chip and button scale (depth 4, blur 12) */
  --emboss-sm:
    -4px -4px 12.5px -1px rgba(42, 53, 51, .56),
     4px  6px 13.9px -1px rgba(15, 20, 20, .99);

  /* The container paints a noise layer at 1.4% alpha. That grain is most of
     what "matte" means here, so surfaces carry it rather than the page. */
  --matte-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.028'/%3E%3C/svg%3E");

  /* A device is not a neumorphic card: a plain dark cast, no light lobe. */
  --device-shadow:
    0 26px 52px -18px rgba(0, 0, 0, .78),
    0  8px 18px  -8px rgba(0, 0, 0, .6);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }
::selection { background: var(--mint); color: #06100F; }

.wrap {
  width: 100%; max-width: var(--maxw); margin-inline: auto;
  padding-inline-start: max(var(--gut), env(safe-area-inset-left));
  padding-inline-end: max(var(--gut), env(safe-area-inset-right));
}

/* ── type ────────────────────────────────────────────────────────────────── */
.d1 { font-size: clamp(35px, 4.9vw, 62px); font-weight: 600; line-height: 1.06; letter-spacing: -0.042em; }
.d2 { font-size: clamp(26px, 3.1vw, 40px); font-weight: 600; line-height: 1.15; letter-spacing: -0.034em; }
.d3 { font-size: clamp(17px, 1.5vw, 20px); font-weight: 600; letter-spacing: -0.022em; }
.lead { color: var(--muted); font-size: clamp(15.5px, 1.15vw, 17.5px); line-height: 1.62; }
.mask { display: block; overflow: hidden; padding-bottom: .04em; }
.mask > span { display: block; }

/* ── nav ─────────────────────────────────────────────────────────────────── */
.nav {
  position: fixed; inset: 0 0 auto; z-index: 50;
  display: flex; align-items: center; justify-content: flex-start;
  padding-block: calc(7px + env(safe-area-inset-top)) 7px;
  padding-inline-start: max(var(--gut), env(safe-area-inset-left));
  padding-inline-end: max(var(--gut), env(safe-area-inset-right));
  border-bottom: 1px solid transparent;
  transition: background .3s ease, border-color .3s ease;
}
.nav.is-stuck { background: var(--bg); border-bottom-color: rgba(42, 53, 51, .45); }
.brand { display: flex; align-items: center; gap: 10px; min-block-size: 44px; }
.brand img { width: 26px; height: 26px; border-radius: 7px; }
.brand span { font-weight: 600; font-size: 15.5px; letter-spacing: -.02em; }

/* ── button — flat fill, no inset gloss ──────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 14px 22px;
  border-radius: 16px;                       /* AppRadius.md */
  font-size: 14px; font-weight: 600; letter-spacing: -.012em; white-space: nowrap;
  transition: background .2s ease, color .2s ease, border-color .2s ease,
              box-shadow .2s ease, transform .16s ease;
}
.btn svg { width: 15px; height: 15px; }
.btn:active { transform: scale(.97); }       /* AnimatedScale 0.97 on tap */

/* PrimaryButton.primary — flat mint (MintGradient.accent is a flat pair) with
   the accent-tinted drop shadow the widget actually casts. */
.btn--primary {
  background: var(--mint);
  color: #071510;
  box-shadow: 0 5px 20px rgba(52, 155, 145, .30),
              0 4px 12px rgba(0, 0, 0, .40);
}
.btn--primary:hover { background: var(--mint-dark); }
.btn--primary:active {
  box-shadow: 0 6px 28px 1px rgba(52, 155, 145, .50),
              0 4px 10px rgba(0, 0, 0, .35);
}

/* PrimaryButton.secondary — surface fill, hairline border,
   NeuShadow.raised(blur: 12, offset: 4). */
.btn--line {
  background-color: var(--surface);
  background-image: var(--matte-noise);
  color: var(--text);
  border: 1px solid rgba(42, 53, 51, .55);
  box-shadow: var(--emboss-sm);
}
.btn--line:hover { border-color: rgba(52, 155, 145, .6); }
.btn--sm { min-block-size: 44px; padding: 10px 16px; font-size: 13px; border-radius: 10px; }

/* ── app screen — flat frame, matching a matte card ──────────────────────── */
.shot {
  --w: 280px;
  position: relative; width: var(--w); aspect-ratio: 1284 / 2778;
  border-radius: calc(var(--w) * .148);
  padding: calc(var(--w) * .026);
  background: #131817;
  border: 1px solid rgba(42, 53, 51, .55);   /* surfaceBorder @ .55, as the app */
  box-shadow: var(--device-shadow);
}
.shot__screen {
  position: relative; height: 100%; overflow: hidden;
  border-radius: calc(var(--w) * .122);
  background: var(--bg);
}
.shot__screen img { width: 100%; height: 100%; object-fit: cover; }
.shot__island {
  position: absolute; z-index: 2; top: calc(var(--w) * .052); left: 50%; translate: -50% 0;
  width: 27%; height: calc(var(--w) * .08);
  background: #05090A; border-radius: 999px;
}

/* ── hero ────────────────────────────────────────────────────────────────── */
.hero {
  position: relative; z-index: 0;
  padding-top: clamp(96px, 12vh, 130px);
  padding-bottom: clamp(52px, 6vw, 84px);
}
@media (min-width: 901px) {
  .hero {
    min-height: 100svh;
    display: grid;
    align-items: center;
    padding-block: clamp(72px, 8vh, 96px);
  }
}
/* Copy left, whole device right. It used to be a centred stack whose screen
   was cropped by the next section; now nothing is cut off. */
.hero__grid {
  display: grid;
  /* The copy takes the slack so the pair spans the container instead of
     floating in the middle of it. The max-width on .hero__copy is what stops
     the old failure mode: an uncapped 1fr column strands short headline lines
     against a wide empty gutter. */
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(30px, 5vw, 84px);
  align-items: center;
}
@media (min-width: 901px) {
  /* The phone sets the row height. The copy remains one cohesive group and is
     centered inside that height; the phone keeps its requested optical drop. */
  .hero__grid { align-items: stretch; }
  .hero__copy {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .hero__shot {
    align-items: flex-start;
    margin-top: clamp(16px, 2vh, 24px);
  }
}
.hero__copy { max-width: 36rem; }
.hero h1 { margin-top: 0; }
.hero .lead { margin-top: 22px; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
.hero__fine { margin-top: 18px; font-size: 13px; color: var(--faint); }

.hero__shot { display: flex; justify-content: center; }
.hero__shot .shot {
  /* Width gives it presence on large displays; viewport height keeps the
     enlarged device inside shorter laptop screens. */
  --w: clamp(220px, min(21vw, 35vh), 310px);
}

@media (max-width: 900px) {
  .hero__grid { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: clamp(38px, 6vw, 56px); }
  .hero__copy { display: flex; flex-direction: column; align-items: center; max-width: 34rem; }
  .hero h1, .hero .lead { max-width: 20ch; }
  .hero .lead { max-width: 46ch; }
  .hero__cta { justify-content: center; }
}

/* ── three things it does ────────────────────────────────────────────────── */
/* Each major beat is a different matte plane. The one-pixel seams are drawn
   from the app's own surfaceBorder token, so the page reads as a sequence of
   sections without introducing ornamental dividers or unrelated colours. */
.does {
  position: relative; z-index: 1;
  padding-block: clamp(76px, 9vw, 124px) clamp(84px, 10vw, 140px);
  overflow: clip;
  background-color: var(--bg-alt);
  background-image: var(--matte-noise);
  border-block: 1px solid rgba(42, 53, 51, .72);
}
.does__head { text-align: center; max-width: 39rem; margin-inline: auto; }
.trio {
  margin-top: clamp(60px, 7vw, 104px);
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 2.6vw, 38px);
  perspective: 1700px;
}
/* preserve-3d has to hold all the way down or .trio's perspective never
   reaches .shot, and the rotations flatten out. */
.card, .card figure { transform-style: preserve-3d; }
.card { text-align: center; }
.card figure { display: flex; justify-content: center; }
.card .shot { --w: clamp(152px, 19.5vw, 248px); }
/* Transforms do not affect layout, so the caption has to be pushed clear of the
   frame's transformed footprint and its shadow by hand. */
.card h3 { margin-top: clamp(46px, 4.4vw, 66px); position: relative; }
.card p  { position: relative; }
.card p { margin-top: 9px; font-size: 14.5px; color: var(--muted); }

/* Resting fan. GSAP animates *to* these values, so they also stand alone as
   the reduced-motion and no-JS pose. */
.card:nth-child(1) .shot { transform: rotateY( 16deg) translateZ(-60px) translateY( 14px); }
.card:nth-child(2) .shot { transform: rotateY(  0deg) translateZ( 40px) translateY(-14px); }
.card:nth-child(3) .shot { transform: rotateY(-16deg) translateZ(-60px) translateY( 14px); }
.card:nth-child(2) h3, .card:nth-child(2) p { position: relative; }

@media (max-width: 900px) {
  .trio { perspective: none; }
  .card .shot { transform: none !important; }
}
@media (max-width: 760px) {
  .trio { grid-template-columns: 1fr; gap: 54px; max-width: 340px; margin-inline: auto; }
}

/* ── privacy ─────────────────────────────────────────────────────────────── */
.priv {
  position: relative;
  padding-block: clamp(76px, 9vw, 124px);
  overflow: clip;
  text-align: center;
  background: var(--bg-deep);
  border-bottom: 1px solid rgba(42, 53, 51, .72);
}
.priv h2 { max-width: 34rem; margin-inline: auto; }
.priv .lead { margin: 22px auto 0; max-width: 52ch; }
.priv__row {
  margin-top: clamp(36px, 4vw, 52px);
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
}
.priv__row li {
  padding: 12px 21px; border-radius: 999px;
  background-color: var(--surface);
  background-image: var(--matte-noise);
  border: 1px solid rgba(42, 53, 51, .55);
  box-shadow: var(--emboss-sm);
  font-size: 13.5px; font-weight: 500; color: var(--muted);
}

/* ── close ───────────────────────────────────────────────────────────────── */
.close {
  position: relative;
  padding-block: clamp(76px, 9vw, 124px);
  overflow: clip;
  text-align: center;
  background-color: var(--bg-alt);
  background-image: var(--matte-noise);
  border-bottom: 1px solid rgba(42, 53, 51, .72);
}
.close h2 { max-width: 30rem; margin-inline: auto; }
.close .lead { max-width: 44ch; margin: 18px auto 0; }
.close__cta { display: flex; justify-content: center; flex-wrap: wrap; gap: 11px; margin-top: 28px; }

/* ── footer ──────────────────────────────────────────────────────────────── */
.foot {
  border-top: 1px solid rgba(42, 53, 51, .45);
  padding-top: 30px;
  padding-bottom: max(30px, env(safe-area-inset-bottom));
}
.foot__in {
  display: flex; flex-wrap: wrap; gap: 14px 32px;
  align-items: center; justify-content: space-between;
  font-size: 13px; color: var(--faint);
}
.foot__links { display: flex; flex-wrap: wrap; gap: 22px; }
.foot__links a, .foot__ifl { display: inline-flex; align-items: center; min-block-size: 44px; }
.foot__links a:hover { color: var(--text); }
.foot__ifl { color: var(--muted); border-bottom: 1px solid var(--border); transition: color .2s ease, border-color .2s ease; }
.foot__ifl:hover { color: var(--mint); border-bottom-color: var(--mint); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .mask > span { transform: none !important; }
}

/* ══ live UI overlay ═══════════════════════════════════════════════════════
   A simulation of the app's renewal loop, sitting on the hero screenshot.
   Everything scales off the frame width, so it stays in proportion at every
   viewport. Built from the app's own values: RenewalDecisionCard uses a
   surface fill with an accent border at 36% alpha; AppRadius.md is 16.
   ═════════════════════════════════════════════════════════════════════════ */
.ui {
  position: absolute; inset: 0; z-index: 3;
  font-size: calc(var(--w) * 0.037);          /* ~12.7px at the 344px frame */
  text-align: left;                           /* .hero centres text; app UI is not */
  pointer-events: none;
}

/* iOS drops a banner just under the status bar */
.ui__notif {
  position: absolute; top: 8%; left: 4.5%; right: 4.5%;
  display: grid; grid-template-columns: auto 1fr; gap: .7em; align-items: center;
  padding: .72em .82em;
  border-radius: 1.35em;
  background-color: #232D2C;
  background-image: var(--matte-noise);
  border: 1px solid rgba(42, 53, 51, .55);
  box-shadow: -.34em -.34em .95em -.07em rgba(42, 53, 51, .5),
               .34em  .46em 1.06em -.07em rgba(15, 20, 20, .99);
  opacity: 0;
}
.ui__notif img { width: 2.1em; height: 2.1em; border-radius: .55em; }
.ui__meta {
  display: flex; justify-content: space-between; gap: .6em;
  font-size: .62em; letter-spacing: .09em; color: var(--faint);
}
.ui__title { font-size: .96em; font-weight: 600; letter-spacing: -.01em; margin-top: .1em; }

/* _RenewalDecisionCard, rising over the bottom of the screen */
.ui__decision {
  position: absolute; left: 4.5%; right: 4.5%; top: 8%;
  padding: .95em 1em .9em;
  border-radius: 1.4em;
  background-color: var(--surface);
  background-image: var(--matte-noise);
  border: 1px solid rgba(52, 155, 145, .36);   /* accent @ .36, as the widget */
  box-shadow: -.34em -.34em .95em -.07em rgba(42, 53, 51, .5),
               .34em  .46em 1.06em -.07em rgba(15, 20, 20, .99);
  opacity: 0;
}
.ui__dtop {
  display: flex; align-items: center; gap: .45em;
  font-size: .78em; font-weight: 600; letter-spacing: .01em; color: var(--mint);
}
.ui__dtop svg { width: 1.15em; height: 1.15em; }
.ui__dlabel {
  margin-top: .75em;
  font-size: .62em; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint);
}
.ui__dnote {
  margin-top: .28em; font-size: 1em; font-weight: 500;
  letter-spacing: -.015em; line-height: 1.35;
}
.ui__dacts { display: grid; grid-template-columns: 1fr 1fr; gap: .55em; margin-top: .85em; }
.ui__act {
  padding: .62em 0; border-radius: .85em; text-align: center;
  font-size: .8em; font-weight: 600; letter-spacing: -.01em;
  background-color: var(--surface); color: var(--muted);
  background-image: var(--matte-noise);
  border: 1px solid rgba(42, 53, 51, .55);
  box-shadow: -.2em -.2em .5em -.04em rgba(42, 53, 51, .5),
               .2em  .28em .58em -.04em rgba(15, 20, 20, .95);
}
.ui__act--keep { background: var(--mint); color: #071510; border-color: transparent; }

/* Without motion the loop never runs, so the card is simply shown and the
   banner is dropped — the decision is the point, the banner is the flourish. */
@media (prefers-reduced-motion: reduce) {
  .ui__decision { opacity: 1; }
  .ui__notif { display: none; }
}

/* ══ focus ════════════════════════════════════════════════════════════════ */
:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--mint);
  outline-offset: 3px;
  border-radius: 10px;
}

/* Google Play before it ships: same shape so the pair stays balanced, but
   plainly inactive — no link, no focus stop, no hover, no magnetism. */
.btn.is-soon {
  color: var(--faint);
  cursor: default;
  box-shadow: none;
  background-image: none;
  background-color: transparent;
  border-color: rgba(42, 53, 51, .5);
}
.btn.is-soon:hover { border-color: rgba(42, 53, 51, .5); }
.btn.is-soon svg { opacity: .6; }
