/* Inflow AI restoration VSL
   Dials: DESIGN_VARIANCE 3 / MOTION_INTENSITY 2 / VISUAL_DENSITY 2
   Aesthetic: utilitarian direct-response. Native CSS, no framework, no design system.
   Locks: Geist single family, 6px radius everywhere, #8000ff sole accent, light theme. */

@font-face {
  font-family: "Geist";
  src: url("fonts/Geist-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  /* `optional`, not `swap`. Geist runs ~15% narrower than the system fallback,
     so a late swap would rewrap the H1 from 3 lines to 2 and shift the LCP
     element by a full line. Preloaded and same-origin at 55KB, the font wins
     the ~100ms budget on essentially every visit; on the rare miss the visitor
     gets the fallback for the whole load with zero shift. Metric overrides were
     the alternative, but system-ui metrics vary per platform and this audience
     is on phones, so a single size-adjust figure would be wrong for most. */
  font-display: optional;
}

:root {
  /* ---- color. Brand is committed; #8000ff is 6.26:1 on white both ways. ---- */
  --brand:       oklch(53% 0.293 293.9);
  --brand-deep:  oklch(46% 0.260 293.9);

  --bg:          oklch(100% 0 0);
  --surface:     oklch(97.6% 0.006 294);
  --ink:         oklch(20% 0.012 294);   /* 18.1:1 on bg */
  --ink-2:       oklch(45% 0.014 294);   /*  7.5:1 on bg */
  --line:        oklch(90% 0.008 294);   /* decorative hairlines only */
  --line-input:  oklch(62% 0.014 294);   /* UI boundaries, 3.2:1 per WCAG 1.4.11 */
  --danger:      oklch(48% 0.180 25);    /*  7.2:1 on bg */

  /* ---- space. 4pt base. Every margin, padding and gap comes from here. ---- */
  --space-3xs: 0.25rem;   /*  4 */
  --space-2xs: 0.5rem;    /*  8 */
  --space-xs:  0.75rem;   /* 12 */
  --space-sm:  1rem;      /* 16 */
  --space-md:  1.5rem;    /* 24 */
  --space-lg:  2rem;      /* 32 */
  --space-xl:  3rem;      /* 48 */

  /* fluid steps, for space that should breathe with the viewport */
  --flow-sm: clamp(1rem, 2.5vw, 1.5rem);
  --flow-md: clamp(1.5rem, 4vw, 2rem);
  --flow-lg: clamp(2rem, 5vw, 3rem);
  --band:    clamp(3rem, 8vw, 6rem);

  /* ---- type. Four fixed roles plus three fluid display steps, ~1.25 apart. ---- */
  --text-sm:   0.9375rem;   /* 15: labels, cue, footer, errors, step numerals */
  --text-base: 1.0625rem;   /* 17: body copy */
  --text-lg:   1.3125rem;   /* 21: offer headings */
  --text-xl:   1.625rem;    /* 26: confirmation heading */
  --text-lede: clamp(1.0625rem, 2.1vw, 1.3125rem);
  --text-h2:   clamp(1.5rem, 3.4vw, 2rem);
  /* Sized for a long direct-response headline (~90 characters) landing in three
     lines. A short-headline scale would blow past the fold at this length. */
  --text-h1:   clamp(1.625rem, 3.6vw, 2.5rem);

  --radius: 6px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: var(--text-base);
  line-height: 1.6;
  font-kerning: normal;
  font-optical-sizing: auto;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; text-wrap: balance; letter-spacing: -0.03em; line-height: 1.1; }
p { margin: 0; text-wrap: pretty; }
img, svg { display: block; max-width: 100%; }

a { color: var(--brand); text-underline-offset: 0.2em; }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 2px;
}

/* One column for the whole page. At 50rem the 16:9 player clears the fold on a
   1440x900 laptop, and every edge on the page lines up with every other. */
.wrap {
  width: 100%;
  max-width: 50rem;
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2rem);
}

/* ---------- header ---------- */

.bar { border-bottom: 1px solid var(--line); }

/* 72px rather than 64: the wordmark is a two-line lockup and needs the height
   to stay legible. Still inside the 80px ceiling. */
.bar-inner {
  height: 72px;
  display: flex;
  align-items: center;
}

/* padding-block lifts the link to the 44px target PRODUCT.md commits to; the
   wordmark itself stays 40px. */
.logo { display: block; padding-block: var(--space-3xs); }
.logo img { height: 40px; width: auto; }

/* ---------- hero ---------- */

.hero {
  padding-block: var(--flow-md) var(--flow-lg);
  text-align: center;
}

h1 {
  font-size: var(--text-h1);
  font-weight: 620;
  max-width: 38ch;
  margin-inline: auto;
}

/* The price gets its own line and the page's one moment of large brand color.
   In direct response the number is the hook, not a detail buried in the run of
   the sentence. */
.price {
  display: block;
  margin-top: 0.18em;
  color: var(--brand);
}

/* Points at the video. An emoji is a deliberate exception to the no-emoji rule:
   it does navigational work here and is standard in this page's genre. */
.point {
  display: inline-block;
  /* Geist carries no emoji glyphs, so name the platform emoji fonts explicitly
     rather than trusting the fallback chain. */
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  font-size: 1.15em;
  line-height: 1;
  transform: translateY(0.12em);
}

.lede {
  margin: var(--flow-sm) auto var(--flow-md);
  max-width: 52ch;
  font-size: var(--text-lede);
  color: var(--ink-2);
}

/* ---------- video facade ---------- */

/* No max-width of its own: the player fills the wrap's content box so its edges
   line up with the logo and the section headings below. aspect-ratio reserves
   the box up front, so the player defining costs no layout shift. */
.player {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--ink);
}

wistia-player { display: block; width: 100%; height: 100%; }

/* Gated state. The blur sits on the player itself so the overlay button stays
   sharp, and pointer-events are killed so no stray tap reaches Wistia's own
   controls underneath. */
.player.is-locked wistia-player {
  filter: blur(14px);
  transform: scale(1.06);   /* hides the soft edge the blur leaves at the frame */
  pointer-events: none;
}

.gate {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: var(--space-sm);
  background: oklch(20% 0.012 294 / 0.35);
}
.gate-btn {
  max-width: 100%;
  padding-inline: var(--space-lg);
  box-shadow: 0 10px 30px oklch(20% 0.012 294 / 0.35);
}

/* Before the web component defines, paint the video's own swatch frame. This is
   Wistia's real poster, so there is no poster asset to produce or maintain.
   Wistia ships this blurred; it sharpens the moment the player takes over. */
wistia-player[media-id="tdb4u9jr6v"]:not(:defined) {
  background: center / contain no-repeat
    url("https://fast.wistia.com/embed/medias/tdb4u9jr6v/swatch");
  filter: blur(5px);
}

/* ---------- what you get ---------- */

.included { padding-block: var(--band); }

.included h2,
.convert h2 {
  font-size: var(--text-h2);
  font-weight: 620;
}

.offer {
  margin-top: var(--flow-lg);
  display: grid;
  /* min() so the track can shrink below 18rem on a 320px phone instead of
     forcing horizontal scroll. */
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  /* Row gap deliberately tighter than the gap under the heading, so the four
     items read as one group rather than four floating blocks. */
  gap: var(--flow-md) clamp(2rem, 5vw, 4rem);
}

.offer-item h3 {
  font-size: var(--text-lg);
  font-weight: 620;
  letter-spacing: -0.015em;
}
.offer-item p {
  margin-top: var(--space-2xs);
  color: var(--ink-2);
  max-width: 42ch;
}

/* ---------- convert band ---------- */

.convert {
  padding-block: var(--band);
  background: var(--surface);
  border-top: 1px solid var(--line);
}

.guarantee {
  margin-top: var(--space-xs);
  max-width: 42ch;
  color: var(--ink-2);
}

/* Numbers are earned here: this is a real ordered sequence and the order is the
   reassurance. One deliberate numbered list on the page, not section scaffolding. */
.steps {
  counter-reset: step;
  list-style: none;
  margin: var(--flow-md) 0 0;
  padding: 0;
  display: grid;
  gap: var(--space-xs);
}
.steps li {
  counter-increment: step;
  display: grid;
  grid-template-columns: var(--space-md) 1fr;
  gap: var(--space-xs);
  align-items: baseline;
}
.steps li::before {
  content: counter(step);
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  font-size: var(--text-sm);
  color: var(--brand);
}

/* ---------- form ---------- */

.form { display: grid; gap: var(--space-sm); }

/* Honeypot. Off-screen rather than display:none, which many bots skip. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.field { display: grid; gap: var(--space-2xs); }

.field label {
  font-size: var(--text-sm);
  font-weight: 550;
  color: var(--ink);
}

.field input,
.field select {
  min-height: 50px;
  padding: var(--space-2xs) var(--space-xs);
  font: inherit;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line-input);
  border-radius: var(--radius);
  transition: border-color 120ms linear, box-shadow 120ms linear;
}
/* Native select chrome varies wildly; normalise it and draw our own caret. */
.field select {
  appearance: none;
  padding-right: var(--space-lg);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 1.15rem center, right 0.85rem center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
.field input:focus,
.field select:focus {
  outline: 0;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px oklch(53% 0.293 293.9 / 0.22);
}
.field input[aria-invalid="true"],
.field select[aria-invalid="true"] { border-color: var(--danger); }

.err {
  font-size: var(--text-sm);
  color: var(--danger);
}
.form-err { margin-top: var(--space-3xs); }

.btn {
  min-height: 54px;
  margin-top: var(--space-2xs);
  padding-inline: var(--space-md);
  font: inherit;
  font-weight: 620;
  color: var(--bg);
  background: var(--brand);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 140ms linear, transform 120ms var(--ease);
}
.btn:hover { background: var(--brand-deep); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { background: var(--ink-2); cursor: progress; }

.convert-cta { margin-top: var(--flow-md); }
.convert-cta .btn { display: block; width: 100%; max-width: 24rem; }

.done { margin-top: var(--flow-md); max-width: 46ch; }
.done h3 { font-size: var(--text-xl); font-weight: 620; }
.done p { margin-top: var(--space-2xs); color: var(--ink-2); }

/* ---------- modal ---------- */

.modal {
  width: min(30rem, calc(100vw - 2rem));
  /* dvh, and scrollable: five fields plus a header overflow a small phone, and
     an open keyboard halves the viewport. Without this the submit button is
     unreachable exactly when someone is trying to press it. */
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  padding: var(--space-md);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink);
}
.modal::backdrop { background: oklch(20% 0.012 294 / 0.55); }

.modal-head {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: var(--space-sm);
}
.modal-head h2 { font-size: var(--text-xl); font-weight: 620; }

.modal-close {
  flex: none;
  width: 44px;
  height: 44px;
  margin: calc(var(--space-2xs) * -1) calc(var(--space-2xs) * -1) 0 0;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--ink-2);
  background: none;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}
.modal-close:hover { color: var(--ink); background: var(--surface); }

.modal-sub {
  margin: var(--space-2xs) 0 var(--space-md);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

/* Feedback for a completed action, which is the one motion this page earns. */
@media (prefers-reduced-motion: no-preference) {
  .done { animation: fade 320ms var(--ease) both; }
  .modal[open] { animation: fade 200ms var(--ease) both; }
  @keyframes fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
}

/* ---------- footer ---------- */

.foot {
  padding-block: var(--space-md);
  border-top: 1px solid var(--line);
  font-size: var(--text-sm);
  color: var(--ink-2);
}
.foot-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  justify-content: space-between;
  align-items: center;
}
.foot a {
  color: var(--ink-2);
  /* Padded to a 44px tap target; the label alone is only 24px tall. */
  display: inline-block;
  padding-block: var(--space-xs);
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
