/* ==========================================================================
   LadyChainSniper — the product site.

   Palette is lifted verbatim from src/report/card.ts, which already renders
   the daily P&L card users receive. Not sampled from artwork, not invented.

   GREEN IS NOT AN ACCENT. #3ce8a9 is card.ts's "up" semantic: it means a gain
   and nothing else. An earlier pass used it as the brand colour throughout and
   the page read as generic fintech. Magenta and cyan are the identity; green
   appears only where a real gain is shown.
   ========================================================================== */

@font-face{
  font-family:"JetBrains Mono";font-style:normal;font-weight:400;font-display:swap;
  src:url("assets/fonts/JetBrainsMono-Regular.woff2") format("woff2");
}
@font-face{
  font-family:"JetBrains Mono";font-style:normal;font-weight:700;font-display:swap;
  src:url("assets/fonts/JetBrainsMono-Bold.woff2") format("woff2");
}

html{scroll-behavior:auto}
@media (prefers-reduced-motion:no-preference){
  html:not(.scrubbing){scroll-behavior:smooth}
}
:root{
  --ground:#07070f;
  --raise:#0d0b1a;
  --line:#241d40;
  --magenta:#ff2fb0;
  --cyan:#38dbf7;
  --gain:#3ce8a9;
  --ink:#f6f6fb;
  --muted:#9a9ac0;
  --faint:#4a4a6b;
  --mono:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --gut:clamp(20px,5vw,64px);
}

*{box-sizing:border-box}
body{
  margin:0;background:var(--ground);color:var(--ink);
  font-family:var(--sans);-webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{color:inherit}
img,video{display:block;max-width:100%}

.mono{font-family:var(--mono)}
.muted{color:var(--muted)}
.faint{color:var(--faint)}
.gain{color:var(--gain)}

/* Display type: the treatment card.ts gives "DAILY SUMMARY" — mono, caps,
   heavily tracked, with a neon bloom. The real LadyRipple wordmark is a brush
   script that is not in this repo; rather than approximate it with some other
   script and get it subtly wrong, headlines use the face we actually own. */
.display{
  font-family:var(--mono);font-weight:700;text-transform:uppercase;
  letter-spacing:.10em;line-height:1.14;margin:0;text-wrap:balance;
  text-shadow:0 0 18px rgb(255 47 176 / .34),0 0 46px rgb(255 47 176 / .16);
}
.display .on{
  color:var(--cyan);
  text-shadow:0 0 18px rgb(56 219 247 / .40),0 0 46px rgb(56 219 247 / .18);
}
.eyebrow{
  font-family:var(--mono);font-size:.66rem;letter-spacing:.30em;
  text-transform:uppercase;color:var(--faint);margin:0 0 1.1rem;
}

/* ── nav ─────────────────────────────────────────────────────────── */
.nav{
  position:fixed;inset:0 0 auto;z-index:60;display:flex;
  align-items:center;justify-content:space-between;
  padding:1.1rem var(--gut);
  font-family:var(--mono);font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;
}
.nav a{color:var(--cyan);text-decoration:none;font-size:.64rem}

/* ── the scroll track ────────────────────────────────────────────────
   `--p` (0 → 1) is written by JS on .track by ONE rAF loop. Everything below
   reads it in CSS, so the whole hero is a single number with no per-element
   animation state that can fall out of sync. */
.track{height:330vh;position:relative}
.stage{
  position:sticky;top:0;height:100dvh;overflow:hidden;
  display:grid;place-items:center;background:#000;
}

/* On top of the footage, screen-blended. Behind it, the pool would tint the
   surround but not the video, which is exactly what makes the clip's box edge
   visible. Centred LOW so it sits behind the wrist: centred on the phone it
   lifts the screen's black and the display stops reading as OFF during the
   turn, which is the one thing this hero cannot afford. */
.glow{
  position:absolute;inset:0;z-index:5;pointer-events:none;mix-blend-mode:screen;
  background:
    radial-gradient(40% 24% at 38% 74%, color-mix(in srgb, var(--magenta) calc(var(--p) * 11%), transparent), transparent 72%),
    radial-gradient(40% 24% at 63% 76%, color-mix(in srgb, var(--cyan) calc(var(--p) * 8%), transparent), transparent 72%),
    radial-gradient(78% 46% at 50% 76%, #120a22, transparent 74%);
}

.hud{
  position:absolute;inset:clamp(14px,2.4vh,26px);z-index:4;pointer-events:none;
  opacity:calc(.55 - var(--p) * .55);
}
.hud i{position:absolute;width:clamp(24px,4vw,52px);height:clamp(24px,4vw,52px)}
.hud i:nth-child(1){top:0;left:0;border-top:1px solid var(--magenta);border-left:1px solid var(--magenta)}
.hud i:nth-child(2){top:0;right:0;border-top:1px solid var(--magenta);border-right:1px solid var(--magenta)}
.hud i:nth-child(3){bottom:0;left:0;border-bottom:1px solid var(--cyan);border-left:1px solid var(--cyan)}
.hud i:nth-child(4){bottom:0;right:0;border-bottom:1px solid var(--cyan);border-right:1px solid var(--cyan)}

.lede{
  position:absolute;top:clamp(72px,12vh,140px);left:0;right:0;z-index:6;
  text-align:center;padding:0 var(--gut);pointer-events:none;
  opacity:calc(1 - var(--p) * 3.1);
  transform:translateY(calc(var(--p) * -34px));
}
.lede h1{font-size:clamp(26px,5vw,58px)}
.lede p{
  margin:1.4rem auto 0;max-width:48ch;color:var(--muted);
  font-size:clamp(13px,1.35vw,15px);line-height:1.7;
}
.rule{
  margin:1.5rem auto 0;width:min(220px,42vw);height:1px;
  background:linear-gradient(90deg,transparent,var(--magenta),var(--cyan),transparent);
}
.cue{
  position:absolute;bottom:26px;left:0;right:0;z-index:6;text-align:center;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.34em;text-transform:uppercase;
  color:var(--faint);opacity:calc(1 - var(--p) * 3.4);pointer-events:none;
}
.cue span{display:block;margin:.7rem auto 0;width:1px;height:28px;
  background:linear-gradient(var(--magenta),transparent);opacity:.55}

/* ── the rig ──────────────────────────────────────────────────────────
   .frame is ASPECT-LOCKED to the clip and sized off viewport HEIGHT, never
   stretched to cover the viewport. The first version of this site let the
   engine `object-fit: cover` a 9:16 clip onto a wide desktop window, which
   blew it up to giant fingers with no phone in frame. Height-driven sizing is
   what keeps the composition intact at any window shape. */
.rig{position:relative;z-index:2;height:100dvh;display:grid;place-items:end center}
/* The offset is ANIMATED, not fixed. It starts low so the headline has clear
   air above the phone, then rises as the wrist turns so the end state is
   balanced. Held fixed, the headline fades out and leaves a quarter of the
   screen empty above a phone that has sunk to the floor. */
.frame{position:relative;aspect-ratio:540/960;height:min(116dvh,150vw);
  transform:translateY(calc(15dvh - var(--p) * 19dvh))}
.frame>*{position:absolute}

/* Narrow screens. The frame is sized off viewport HEIGHT on desktop, which on a
   portrait phone leaves a tiny handset stranded at the bottom of a screen of
   dead black. Here WIDTH is the binding constraint, so drive it from vw and
   give the headline the top of the screen to itself. */
@media (max-width:700px){
  .frame{height:min(84dvh,190vw);transform:translateY(calc(10dvh - var(--p) * 14dvh))}
  .lede{top:clamp(64px,10dvh,110px)}
  .lede p{font-size:13px;max-width:34ch}
  .payoff{bottom:clamp(20px,4dvh,44px)}
}

/* Short landscape windows: height is scarce, so shrink rather than overflow. */
@media (max-height:560px){
  .frame{height:min(92dvh,70vw);transform:none}
  .lede{top:16px}
  .lede p,.rule{display:none}
}

.turn{
  inset:0;width:100%;height:100%;object-fit:contain;
  -webkit-mask-image:
    linear-gradient(to right,transparent,#000 4%,#000 96%,transparent),
    linear-gradient(to bottom,transparent,#000 5%,#000);
  mask-image:
    linear-gradient(to right,transparent,#000 4%,#000 96%,transparent),
    linear-gradient(to bottom,transparent,#000 5%,#000);
  -webkit-mask-composite:source-in;mask-composite:intersect;
}

/* The glass. NOT a rotated rectangle: the phone does not finish perfectly
   face-on, so the UI is mapped onto four MEASURED corners with a homography
   (see app.js). A rotateY guess lines up in the middle and drifts at the
   corners. */
.screenwrap{
  top:0;left:0;transform-origin:0 0;overflow:hidden;border-radius:14px;
  background:#000;container-type:inline-size;
  opacity:calc((var(--p) - .52) * 4.2);
}
/* Her fingers overlap the glass, so the UI goes BEHIND them or the phone reads
   as a sticker. This plate is the film's last frame with everything lit made
   opaque and the dark screen left transparent. Luminance alone was not enough:
   her nails are BLACK and keyed out as holes, so the matte also carries a
   morphological close plus three explicit ellipses for the nail tips, which
   point into the screen and are therefore not enclosed. */
.plate{
  inset:0;width:100%;height:100%;pointer-events:none;
  opacity:calc((var(--p) - .52) * 4.2);
}

/* ── the bot screen, rendered in code so it stays crisp and selectable ── */
.tg{width:100%;height:100%;display:flex;flex-direction:column;background:#0b0a16;position:relative}
.island{position:absolute;top:1.9%;left:50%;transform:translateX(-50%);
  width:28%;height:3.2%;background:#000;border-radius:99px;z-index:5}
.home{position:absolute;bottom:1.4%;left:50%;transform:translateX(-50%);
  width:34%;height:.55%;background:#6a6a92;border-radius:99px;z-index:5}
.tgbar{padding:13.5% 5% 3%;display:flex;align-items:center;gap:3.4%;
  border-bottom:1px solid #221a3a;background:#100d20;flex:none}
.avatar{width:9.5%;aspect-ratio:1;border-radius:50%;flex:none;
  background:linear-gradient(140deg,var(--magenta),#410da9)}
.tgname{font-family:var(--mono);font-size:4.2cqw;font-weight:700;letter-spacing:.02em}
.tgsub{font-family:var(--mono);font-size:3.3cqw;color:#7d7aa8}
.tgbody{flex:1;padding:3.4% 3.4% 7.5%;display:flex;flex-direction:column;overflow:hidden}
.msg{
  background:#181233;border:1px solid #2b2150;border-radius:9px 9px 9px 3px;
  padding:3.4% 3.6%;font-family:var(--mono);font-size:3.05cqw;line-height:1.62;
  color:#ddd8f0;white-space:pre-wrap;
}
.msg .sep{color:#3a2f63}
.msg .up{color:var(--gain)}
.keys{padding:1.4% 0 0;display:flex;flex-direction:column;gap:1.6%}
.krow{display:flex;gap:1.6%}
.key{
  flex:1;background:#1a1436;border:1px solid #2e2358;border-radius:5px;
  padding:2.1% 1%;font-family:var(--mono);font-size:2.75cqw;text-align:center;
  color:#bdb6e0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

.payoff{
  position:absolute;left:0;right:0;bottom:clamp(28px,6vh,68px);z-index:6;
  text-align:center;padding:0 var(--gut);pointer-events:none;
  opacity:calc((var(--p) - .86) * 7);
  transform:translateY(calc(18px - min(18px,(var(--p) - .86) * 130px)));
}
.payoff h2{font-size:clamp(15px,2vw,24px)}
.payoff small{
  display:block;margin-top:.8rem;font-family:var(--mono);font-size:.6rem;
  letter-spacing:.34em;text-transform:uppercase;color:var(--cyan);
}

/* ── sections ─────────────────────────────────────────────────────── */
section{padding:clamp(72px,11vh,140px) var(--gut);border-top:1px solid var(--line)}
.wrap{max-width:1120px;margin:0 auto}
.sec-h{font-size:clamp(22px,3.2vw,38px)}
.lead{margin:1.6rem 0 0;max-width:60ch;color:var(--muted);font-size:.95rem;line-height:1.75}

/* Feature rows: the phone alternates side so the page does not march. */
.feat{display:grid;gap:clamp(28px,5vw,72px);align-items:center;
  grid-template-columns:1fr;margin-top:clamp(48px,7vh,88px)}
@media(min-width:900px){
  .feat{grid-template-columns:minmax(0,1fr) 20rem}
  .feat.flip{grid-template-columns:20rem minmax(0,1fr)}
  .feat.flip .feat-copy{order:2}
  .feat.flip .device{order:1}
}
.feat-copy p{color:var(--muted);font-size:.92rem;line-height:1.75;margin:1.1rem 0 0;max-width:52ch}
.tierpill{
  display:inline-block;margin-top:1.4rem;font-family:var(--mono);font-size:.6rem;
  letter-spacing:.2em;text-transform:uppercase;color:var(--cyan);
  border:1px solid var(--line);padding:.4rem .7rem;border-radius:99px;
}

/* A static device shell for the feature screens. */
.device{
  background:var(--raise);border:1px solid var(--line);border-radius:18px;
  padding:.85rem;position:relative;container-type:inline-size;
}
.device::before,.device::after{content:"";position:absolute;width:22px;height:22px;pointer-events:none}
.device::before{top:-1px;left:-1px;border-top:1px solid var(--magenta);border-left:1px solid var(--magenta)}
.device::after{bottom:-1px;right:-1px;border-bottom:1px solid var(--cyan);border-right:1px solid var(--cyan)}
.scr{background:#0b0a16;border-radius:12px;padding:.9rem .85rem;display:flex;flex-direction:column;gap:.55rem}
.seg{
  font-family:var(--mono);font-size:3.1cqw;line-height:1.6;color:#ddd8f0;
  white-space:pre-wrap;margin:0;
}
.seg.q{border-left:2px solid var(--magenta);padding-left:.6rem;color:#c9c3e4}
.dkeys{display:flex;flex-direction:column;gap:.3rem;margin-top:.35rem}
.dkey-row{display:flex;gap:.3rem}
.dkey{
  flex:1;background:#1a1436;border:1px solid #2e2358;border-radius:5px;
  padding:.42rem .25rem;font-family:var(--mono);font-size:2.6cqw;text-align:center;
  color:#bdb6e0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.samp{margin:.8rem 0 0;font-family:var(--mono);font-size:.56rem;color:var(--faint);line-height:1.6}

/* Command summary. */
.cmds{display:grid;gap:.6rem 2rem;margin-top:2.6rem;grid-template-columns:1fr}
@media(min-width:700px){.cmds{grid-template-columns:1fr 1fr}}
.cmd{display:flex;gap:.75rem;border-bottom:1px solid var(--line);padding-bottom:.7rem}
.cmd b{font-family:var(--mono);font-size:.78rem;font-weight:400;color:var(--ink);white-space:nowrap}
.cmd span{color:var(--muted);font-size:.78rem}

/* Plans. */
.plans{display:grid;gap:1.1rem;margin-top:clamp(44px,6vh,72px);grid-template-columns:1fr}
@media(min-width:860px){.plans{grid-template-columns:repeat(3,1fr)}}
.plan{background:var(--raise);border:1px solid var(--line);border-radius:14px;padding:1.7rem 1.5rem;position:relative}
.plan h3{margin:0;font-family:var(--mono);font-size:.7rem;letter-spacing:.24em;text-transform:uppercase}
.price{font-family:var(--mono);font-size:2.4rem;font-weight:700;margin:1.1rem 0 0}
.price s{display:block;margin:.45rem 0 0;font-size:.62rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--faint);text-decoration:none}
.plan .blurb{color:var(--muted);font-size:.84rem;margin:.6rem 0 0}
.spec{margin:1.5rem 0 0;font-family:var(--mono);font-size:.68rem}
.spec div{display:flex;justify-content:space-between;border-bottom:1px solid var(--line);padding-bottom:.45rem;margin-bottom:.45rem}
.spec dt{color:var(--faint)}
.plan ul{list-style:none;margin:1.4rem 0 0;padding:0}
.plan li{display:flex;gap:.6rem;font-size:.82rem;color:var(--muted);line-height:1.5;margin-bottom:.6rem}
.plan li i{font-family:var(--mono);font-style:normal;color:var(--gain)}
.plan li.no{color:var(--faint)}
.plan li.no i{color:var(--faint)}

.close{text-align:center}
.close h2{font-size:clamp(24px,4.4vw,52px)}

/* ── the seal ─────────────────────────────────────────────────────────
   The artwork's own background is repainted from #000 to --ground in the
   image file, so its square edge cannot read as a panel against the page.
   The bloom behind it is a radial on ::before rather than a drop-shadow:
   the image is opaque, so a drop-shadow would trace the SQUARE and put a
   rectangle of light behind a circular emblem. `isolation` gives .seal its
   own stacking context, which keeps the glow behind the image without a
   negative z-index that could slip under the page background entirely. */
.seal{
  position:relative;isolation:isolate;
  width:clamp(158px,24vw,248px);margin:0 auto 2.6rem;
}
.seal::before{
  content:"";position:absolute;inset:-32%;border-radius:50%;
  background:radial-gradient(closest-side,
    rgb(255 47 176 / .17),rgb(56 219 247 / .07) 56%,transparent 74%);
}
.seal img{position:relative;width:100%;height:auto}
footer{
  border-top:1px solid var(--line);padding:2.4rem var(--gut);
  font-family:var(--mono);font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--faint);display:flex;flex-wrap:wrap;gap:1rem;justify-content:space-between;
}
footer .warn{text-transform:none;letter-spacing:normal;font-size:.68rem}

/* ── CTAs: three garments, each used for one intent, no shared class ── */
.cta-open{
  display:inline-block;font-family:var(--mono);font-weight:700;text-transform:uppercase;
  letter-spacing:.16em;font-size:.74rem;padding:1rem 2rem;text-decoration:none;
  color:var(--ground);background:var(--magenta);
  transition:transform .18s ease,box-shadow .18s ease;
}
.cta-open:hover{transform:translateY(-2px);box-shadow:0 10px 34px rgb(255 47 176 / .32)}
.cta-cost{
  display:inline-block;font-family:var(--mono);text-transform:uppercase;letter-spacing:.16em;
  font-size:.68rem;color:var(--cyan);text-decoration:none;padding-bottom:.3rem;
  background-image:linear-gradient(var(--cyan),var(--cyan));background-repeat:no-repeat;
  background-position:0 100%;background-size:0% 1px;transition:background-size .3s ease;
}
.cta-cost:hover{background-size:100% 1px}
.cta-risk{
  font-family:var(--mono);font-size:.72rem;color:var(--muted);
  text-decoration:underline;text-underline-offset:5px;text-decoration-color:var(--faint);
  transition:color .18s ease;
}
.cta-risk:hover{color:var(--ink)}
.ctarow{display:flex;flex-wrap:wrap;align-items:center;gap:2rem;margin-top:2.4rem}

@media (prefers-reduced-motion:reduce){
  .track{height:auto}
  .stage{position:static;height:auto;padding:12vh 0}
  .rig{height:auto}
  .lede,.payoff{position:static;opacity:1;transform:none;margin:0 auto 6vh}
  .payoff{margin:6vh auto 0}
  .cue,.hud{display:none}
  .screenwrap,.plate{opacity:1!important}
  .cta-open,.cta-cost,.cta-risk{transition:none}
  .cta-open:hover{transform:none}
}


/* ── keyboard focus ───────────────────────────────────────────────────
   Every interactive thing on this page is a link styled as something else,
   so without this a keyboard user cannot see where they are. Ringed in
   magenta with an offset so it reads against the near-black ground. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--magenta);
  outline-offset:3px;
  border-radius:2px;
}
/* Pointer users keep the clean look: no ring on mouse click. */
a:focus:not(:focus-visible){outline:none}

/* Skip link, visible only once focused. */
.skip{
  position:absolute;left:var(--gut);top:-4rem;z-index:100;
  font-family:var(--mono);font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;
  background:var(--magenta);color:var(--ground);padding:.7rem 1.1rem;text-decoration:none;
  transition:top .18s ease;
}
.skip:focus{top:1rem}
