/* Funnel and confirmation styles.
 *
 * A separate file, not an addition to styles.css, on purpose. Appending rules
 * to a stylesheet every page already has cached means a browser holding the old
 * copy renders the new pages with half their CSS missing — which looks exactly
 * like a broken build and is not one. A new filename has no cache entry to go
 * stale.
 *
 * Loaded only by the four funnel pages. guide/ready.html keeps its own inline
 * <style> block and does not read this file — it is self-contained by design
 * and should stay that way.
 */

/* ---- pitch rail ---------------------------------------------------------- */

/* Product lockup at the head of the pitch rail, where the guide funnel puts its
   cover shot. Sits on --page-bg, so this is the colour lockup, not the -white
   one the dark product heroes use. Centres with the rest of the rail once the
   grid stacks. */
.funnel-lockup{display:block;width:min(272px,70%);height:auto;
  margin:0 0 var(--space-xl)}
@media(max-width:900px){
  .funnel-lockup{margin:0 auto var(--space-xl)}
}
/* the confirmation pages centre their whole column, so the lockup follows */
.funnel-lockup.is-centered{margin-left:auto;margin-right:auto}

/* The cohort counter is borrowed from the MessageOS pricing panel, where it is
   centred inside a narrow column. The pitch rail is ragged-left until the grid
   stacks, so it follows the copy rather than floating centred against it.
   The rail already carries a rule per card; the counter's own top and bottom
   borders turned that into a ladder of five lines, so it goes unruled here and
   earns its separation from space instead. */
.funnel-pitch .avail-seats{justify-items:start;border:0;padding:0;
  margin-top:var(--space-3xl)}
/* The rail is 468px wide, and at the shared 44px the headline runs to four
   lines and breaks its own gradient phrase across two of them. */
.funnel-pitch .h1{font-size:clamp(26px,2.9vw,38px)}
@media(max-width:900px){
  .funnel-pitch .avail-seats{justify-items:center}
}
.funnel-pitch .funnel-meta{display:block;margin-top:var(--space-md)}

/* ---- numbered cards ------------------------------------------------------ */

/* These began as a <style> block inside guide/ready.html. That page still owns
   its own copy; this is the second one, for the pages that borrowed the
   pattern. If they ever drift, guide/ready.html's inline copy wins, which is
   the safe direction. */
.inside{background:var(--white);padding:var(--space-4xl) 0}
.inside-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-2xl);margin-top:var(--space-2xl)}
@media(max-width:760px){.inside-grid{grid-template-columns:1fr;gap:var(--space-xl)}}
.inside-item{border-top:2px solid var(--dark-gray);padding-top:var(--space-md)}
.inside-item .n{font-family:var(--font-mono);font-size:11px;letter-spacing:1.5px;color:var(--ultra);display:block;margin-bottom:var(--space-sm)}
.inside-item h3{font-family:var(--font-serif);font-weight:400;text-transform:uppercase;font-size:22px;line-height:1.05;color:var(--dark-gray);margin-bottom:8px}
.inside-item p{font-size:14px;color:var(--medium-gray);line-height:1.55}

/* In the pitch rail they stack against a column already carrying a lockup and
   an h1, so they run one-up and quieter than the full-width set. */
.funnel-pitch .inside-grid{grid-template-columns:1fr;gap:var(--space-md);
  margin-top:var(--space-lg);text-align:left}
.funnel-pitch .inside-item{border-top-width:1px;padding-top:var(--space-sm)}
.funnel-pitch .inside-item h3{font-size:15px;letter-spacing:.5px;margin-bottom:2px}
.funnel-pitch .inside-item p{font-size:13px}

/* ---- rail cards ---------------------------------------------------------- */

/* Each deliverable is its own surface. As bare rows they read as a list no
   matter how they were spaced or weighted; as cards they read as three things
   you get. Inside the dark panel they sit as raised tiles rather than boxes
   with heavy borders — a light wash and a hairline is enough separation
   against #34343F. */
.rail-cards{list-style:none;margin:var(--space-2xl) 0 0;padding:0;
  display:grid;gap:var(--space-sm)}
.rail-card{display:grid;grid-template-columns:auto 1fr;align-items:center;
  gap:var(--space-md);
  background:var(--card-bg);
  border:1px solid var(--border-color);
  border-radius:10px;
  padding:var(--space-md) var(--space-lg)}
/* Azure, not ultra. styles.css says it plainly next to .badge — ultra is
   unreadable as small type on a light field (1.7:1 on white). Azure is the
   other end of the same brand gradient and clears AA. */
.rail-card .n{font-family:var(--font-mono);font-size:11px;font-weight:500;
  letter-spacing:1.5px;color:var(--azure);
  font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.rail-card .t{font-size:15px;line-height:1.35;font-weight:500;
  color:var(--dark-gray);letter-spacing:.1px}

/* ---- confirmation bleed -------------------------------------------------- */

/* The full-viewport payoff screen, after guide/ready.html.
   The four phrase sizes are custom properties rather than fixed numbers: each
   phrase is tuned so it runs edge to edge, and that tuning is a function of the
   glyphs it contains, so every page needs its own four. Measure, do not
   estimate — render the phrase at 100px in the real face and take
   coef = 9456 / width. */
.bleed{--u:min(1vw,1.6vh);
  --art:min(880px,calc(58 * var(--u)),38vh);
  position:relative;isolation:isolate;
  min-height:calc(100vh - var(--nav-h,78px));min-height:calc(100svh - var(--nav-h,78px));
  display:flex;flex-direction:column;justify-content:center;justify-content:safe center;
  background:radial-gradient(ellipse 120% 90% at 50% 38%,#E8E8E8 0%,#DCDCDC 55%,#CDCDCD 100%);
  padding:calc(3.4 * var(--u)) 0 max(calc(4.2 * var(--u)),120px)}

.bleed-meta{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--space-md);
  padding:0 clamp(16px,3vw,44px);font-family:var(--font-mono);font-size:clamp(9px,.85vw,12px);
  letter-spacing:1.5px;text-transform:uppercase;color:var(--dark-gray);opacity:.55}

.bleed-type{position:relative;z-index:1;text-align:center;color:var(--dark-gray);
  font-family:var(--font-serif);font-weight:400;text-transform:uppercase;line-height:.78;
  margin:0;padding:0 clamp(8px,1.5vw,24px)}
.bleed-line{display:grid;justify-items:center;align-items:center}
.bleed-line .ph{grid-area:1/1;display:block;white-space:nowrap}
.bleed-line .ph-b{opacity:0}
.bleed-l1 .ph-a{font-size:calc(var(--l1a,13.4) * var(--u))}
.bleed-l1 .ph-b{font-size:calc(var(--l1b,10.66) * var(--u))}
.bleed-l2 .ph-a{font-size:calc(var(--l2a,17.9) * var(--u))}
.bleed-l2 .ph-b{font-size:calc(var(--l2b,24.76) * var(--u))}

.bleed-art{position:relative;z-index:2;width:var(--art);
  margin:calc(-.086 * var(--art)) auto calc(-.103 * var(--art));pointer-events:none}
.bleed-art img{width:100%;height:auto;display:block;
  filter:drop-shadow(0 34px 42px rgba(0,0,0,.30)) drop-shadow(0 6px 12px rgba(0,0,0,.14))}

/* A square logomark stands taller than the guide's cover shot at the same
   width, so pages using one set a smaller --art and a lighter overlap. */
/* 26vh, not 30: the mark sits between two lines of type that are taller than
   the guide's, and at 30vh the section outgrew the viewport by ~180px. */
.bleed.is-mark{--art:min(500px,calc(33 * var(--u)),26vh)}
.bleed.is-mark .bleed-art{margin:calc(-.06 * var(--art)) auto calc(-.07 * var(--art))}
.bleed.is-mark .bleed-art img{filter:drop-shadow(0 24px 34px rgba(0,0,0,.22))}
@media(max-width:640px){
  .bleed.is-mark{--art:min(56vw,34vh)}
}

/* Type-only variant, for the pages with no artwork at all. Their products have
   none, and a flat mark blown up to fill the hole reads as a placeholder.
   Until there is real art, those pages let the type carry it.

   The art was also doing structural work: at line-height .78 the glyphs
   overflow their boxes by ~11% top and bottom, and the book sat in that gap.
   Remove it and the two lines collide, so the gap has to be put back
   explicitly. It scales off --u so it tracks the type at every viewport. */
.bleed.is-type .bleed-type + .bleed-type{margin-top:calc(7 * var(--u))}
@media(max-width:640px){
  .bleed.is-type .bleed-type + .bleed-type{margin-top:calc(5 * var(--u))}
}

.bleed-cta{position:sticky;bottom:clamp(16px,3.5vh,44px);z-index:5;text-align:center;margin-top:calc(2.4 * var(--u))}
.bleed-cta::before{content:"";position:absolute;left:50%;top:-16px;transform:translateX(-50%);
  width:min(620px,90vw);height:calc(100% + 30px);border-radius:var(--radius-full);
  background:rgba(226,226,226,.55);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);z-index:-1}
.bleed-cta .btn{font-size:13px;letter-spacing:1.5px;padding:calc(1.5 * var(--u)) calc(3.9 * var(--u));min-height:max(52px,calc(4.7 * var(--u)));border-radius:var(--radius-full)}

@media(max-width:640px){
  .bleed-type{line-height:.84}
  .bleed{--art:min(82vw,52vh)}
  .bleed-art{width:var(--art);margin:calc(-.043 * var(--art)) auto calc(-.055 * var(--art))}
  .bleed-cta .btn{padding:20px 34px;min-height:60px;font-size:11px;width:calc(100% - 48px)}
}

.next-band{background:var(--dark-gray);color:var(--white);padding:var(--space-4xl) 0}
.next-band .h1{color:#fff;font-size:clamp(30px,5vw,60px);line-height:.95;margin-bottom:var(--space-md)}
.next-band p{color:rgba(255,255,255,.55);max-width:40em;margin-bottom:var(--space-xl)}
.next-band .eyebrow{color:var(--ultra)}

/* ---- entrance ------------------------------------------------------------ */
/* clip-path wipes rather than per-letter spans: splitting the lines into
   inline-blocks would drop the font's kerning and drift the tuned line widths.
   Pure CSS, so it runs with or without JS. */
@keyframes fnlWipe{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 -2% 0 0)}}
@keyframes fnlRise{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:none}}
@keyframes fnlArt{from{opacity:0;transform:scale(.955)}to{opacity:1;transform:none}}
.bleed-meta{animation:fnlRise .7s ease-out .1s both}
.bleed-l1{animation:fnlWipe 1s cubic-bezier(.16,.8,.24,1) .15s both}
.bleed-art{animation:fnlArt 1.3s cubic-bezier(.16,.8,.24,1) .38s both}
.bleed-l2{animation:fnlWipe 1s cubic-bezier(.16,.8,.24,1) .62s both}
.bleed-cta{animation:fnlRise .8s cubic-bezier(.16,.8,.24,1) 1.12s both}
@media (prefers-reduced-motion:reduce){
  .bleed-meta,.bleed-l1,.bleed-art,.bleed-l2,.bleed-cta{animation:none}
}

/* the swap: phrase A gives way to phrase B */
@keyframes fnlOut{from{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-.1em)}}
@keyframes fnlIn{from{opacity:0;transform:translateY(.12em)}to{opacity:1;transform:none}}
.bleed-l1 .ph-a{animation:fnlOut .7s cubic-bezier(.16,.8,.24,1) 2.4s both}
.bleed-l1 .ph-b{animation:fnlIn .85s cubic-bezier(.16,.8,.24,1) 2.52s both}
.bleed-l2 .ph-a{animation:fnlOut .7s cubic-bezier(.16,.8,.24,1) 2.6s both}
.bleed-l2 .ph-b{animation:fnlIn .85s cubic-bezier(.16,.8,.24,1) 2.72s both}
@media (prefers-reduced-motion:reduce){
  .bleed-line .ph-a,.bleed-line .ph-b{animation:none}
}

/* ---- consent row --------------------------------------------------------- */

/* Message Guard is free, so there is no checkout to carry the terms agreement
   and Stripe will not issue a $0 payment link. The form asks instead. Sits
   under the fields, above the button, so it is read before the click rather
   than after it. */
.consent{display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:start;
  margin-top:var(--space-lg)}
.consent input{width:18px;height:18px;margin:1px 0 0;flex:none;accent-color:var(--azure);cursor:pointer}
.consent label{font-size:13px;line-height:1.45;color:var(--medium-gray);cursor:pointer}
.consent a{color:var(--dark-gray);text-decoration:underline;text-underline-offset:2px}
.consent a:hover{color:var(--azure)}
/* the same invalid treatment the text fields get */
.consent input[aria-invalid="true"]{outline:2px solid var(--score-poor,#E5484D);outline-offset:2px}

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

/* The onboarding intake, ported off Google Forms. Not a stepper: twelve
   questions one-at-a-time is a slog, and unlike the qualification funnels
   there is no gate to run — every answer is kept. So it is one page in
   labelled sections, which is also what makes it scannable before someone
   commits to filling it in.

   Visible labels rather than the funnel's sr-only + placeholder pattern. A
   placeholder disappears the moment you type, which is fine for "First name"
   and actively hostile for "List 3-5 of your product's most important
   features". */
.intake{max-width:720px;margin:0 auto}
.intake-sec{margin-top:var(--space-3xl)}
.intake-sec:first-of-type{margin-top:0}
.intake-sec > h2{font-family:var(--font-mono);font-size:11px;font-weight:500;
  letter-spacing:2px;text-transform:uppercase;color:var(--azure);
  margin:0 0 var(--space-lg);padding-bottom:var(--space-sm);
  border-bottom:1px solid var(--border-color)}

.intake .fields{gap:var(--space-lg) 10px}
.intake label{display:block;font-size:14px;font-weight:600;color:var(--dark-gray);
  margin-bottom:6px;line-height:1.4}
.intake label .opt{font-weight:400;color:var(--medium-gray)}
.intake .hint{display:block;font-size:13px;font-weight:400;color:var(--medium-gray);
  margin-top:2px;line-height:1.45}

/* matches .fields input exactly, since nothing in the codebase styled one yet */
.intake textarea{width:100%;min-height:120px;background:var(--card-bg);
  border:1.5px solid var(--border-color);border-radius:var(--radius-md);
  padding:14px 16px;color:var(--dark-gray);font-family:var(--font-sans);
  font-size:16px;line-height:1.5;resize:vertical;
  transition:border-color .15s,box-shadow .15s}
.intake textarea::placeholder{color:var(--light-gray)}
.intake textarea:focus{outline:none;border-color:var(--ultra);
  box-shadow:0 0 0 3px rgba(239,161,255,.22)}
.intake textarea[aria-invalid="true"]{border-color:var(--vermilion)}

.intake .actions{margin-top:var(--space-2xl)}
.intake .actions .btn{width:100%}
