/* PinTraderPro marketing site.
   Tokens match app-ng/src/styles.css so the site and the app read as one thing.
   Layout obeys the fable5 rule: no ch caps on prose, no centred narrow column,
   no redundant width:100%. Long lines split into columns on ultrawide. */

:root{
  --bg:#14111c; --panel:#1e1a2a; --panel2:#252034; --line:rgba(240,236,248,.10);
  --text:#f2eef8; --muted:#9c92b0; --faint:#6f6684;
  --gold:#ffd257; --gold-ink:#2a2113; --gold-soft:rgba(255,210,87,.14);
  --ok:#46d69a; --scan:#5ce0c8; --pin:#b22222; --pin-hot:#e33;
  --shadow:0 18px 50px rgba(0,0,0,.45);
  --pad:clamp(16px,4vw,44px);
}
*{box-sizing:border-box}
/* overflow-x:CLIP, not hidden. The oversized pin mark is absolutely positioned
   with a negative `right` so it bleeds off the edge; that extends the scrollable
   area, and `hidden` on body does not stop the document from reporting it -- the
   page still scrolls sideways. `clip` does not create a scroll container, so the
   bleed is drawn and then cut. Caught by scripts/verify-marketing.py, which
   measures scrollWidth - clientWidth at three widths. */
html{scroll-behavior:smooth; overflow-x:clip}
/* The whole background. Percentage-positioned radials scale WITH the viewport
   instead of sliding across it, so the composition holds from a phone to a
   2560-wide desktop -- which the logo watermark that used to sit on top of this
   did not. The warm pool top-right was rgba(178,34,34) = CSS firebrick, a colour
   that appears nowhere in the real artwork; it is the brand red (#78241C, lifted
   for luminance on a dark ground) now. `fixed` keeps it from sliding under the
   content as you scroll, and it degrades to a flat --bg wherever it is not
   supported. */
body{
  margin:0; overflow-x:clip;
  background:
    radial-gradient(72% 55% at 85% -5%, rgba(150,48,38,.30), transparent 68%),
    radial-gradient(60% 45% at -5% 55%, color-mix(in srgb, var(--scan) 7%, transparent), transparent 60%),
    radial-gradient(90% 60% at 50% 105%, rgba(120,36,28,.14), transparent 70%),
    var(--bg);
  background-attachment:fixed;
  color:var(--text);
  font:16px/1.6 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit}
.wrap{padding-inline:var(--pad)}

/* ---------- the oversized mark: REMOVED ---------- */
/* There used to be an 880px copy of the logo bled off the right edge here,
   .pinWatermark, plus a bob animation and a wrapper that existed purely to clip
   the overflow it caused. It was sized in vw against a fixed vw offset, so the
   crop and its position relative to the hero text changed at every window width
   -- it read as a stray graphic at most resolutions rather than a watermark.
   The background is the gradient on `body` now and nothing else, which cannot
   land wrong at any size. If a mark comes back here, give it a fixed aspect and
   anchor it to the hero grid, not to the viewport. */

/* ---------- nav ---------- */
/* header / nav / .brand / .btn now live in assets/nav.css, loaded before this
   file, so the field guide and the legal pages get the SAME header instead of a
   second brand-only one. Do not redefine them here. */

/* ---------- hero ---------- */
.hero{position:relative; z-index:1; padding-block:clamp(48px,7vw,96px) clamp(40px,5vw,72px);
  display:grid; gap:clamp(32px,5vw,72px); align-items:center;
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr)}
@media(max-width:980px){ .hero{grid-template-columns:minmax(0,1fr)} }

.eyebrow{display:flex; align-items:center; gap:9px; font-size:12px; font-weight:700;
  letter-spacing:.22em; text-transform:uppercase; color:var(--gold); margin:0 0 20px}
.eyebrow .dot{width:7px; height:7px; border-radius:50%; background:var(--ok);
  box-shadow:0 0 0 4px rgba(70,214,154,.16); animation:blip 2.4s infinite}
@keyframes blip{0%,100%{opacity:1}50%{opacity:.35}}

h1{font-size:clamp(40px,6.6vw,92px); line-height:.99; letter-spacing:-.04em;
  margin:0 0 24px; font-weight:830}
h1 em{font-style:normal; color:var(--gold)}
.sub{font-size:clamp(17px,1.55vw,21px); color:var(--muted); margin:0 0 32px}
.herobtns{display:flex; gap:14px; flex-wrap:wrap; align-items:center}
.note{font-size:13.5px; color:var(--faint); margin-top:20px}

/* ---------- the phone + scan demo ---------- */
.heroDemo{display:flex; flex-direction:column; align-items:center; gap:18px}
.phone{
  position:relative; width:min(88vw,340px); padding:11px 11px 13px;
  border-radius:40px; background:linear-gradient(160deg,#2c2740,#171320);
  border:1px solid rgba(255,255,255,.10);
  box-shadow:0 40px 90px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.10);
}
.phoneNotch{position:absolute; top:11px; left:50%; transform:translateX(-50%);
  width:104px; height:20px; border-radius:0 0 14px 14px; background:#0d0a14; z-index:4}
.phoneScreen{position:relative; border-radius:31px; overflow:hidden; background:#0d0a14}

.scanStage{position:relative; overflow:hidden; line-height:0}
/* The source is 780px wide and the phone frame caps at 340px, so this only ever
   scales DOWN -- a max constraint is enough, no explicit width needed. */
.scanPhoto{display:block; max-inline-size:100%; height:auto;
  transition:filter .5s, transform 6s linear}
.scanStage.dim .scanPhoto{filter:brightness(.66) saturate(.85)}

/* The mask overlay sits in the PHOTO's pixel space (viewBox set in scan.js), so
   it scales with the image and every outline lands on its pin at any width. */
.scanMasks{position:absolute; inset:0; overflow:visible}
.smask{
  fill:transparent; stroke:var(--scan); stroke-width:5;
  stroke-linejoin:round; stroke-linecap:round;
  filter:drop-shadow(0 0 6px rgba(92,224,200,.75));
  transition:stroke .35s, fill .45s, opacity .35s, stroke-width .35s;
}
/* The draw-on. scan.js sets dasharray/dashoffset to the measured path length and
   then releases the offset; the transition is what makes it trace the pin. */
.smask.draw{transition:stroke-dashoffset .38s ease-out, stroke .35s, fill .45s,
                       opacity .35s, stroke-width .35s}
/* Being identified: marching dashes. Each pin is an independent embed + match,
   so they all march at once and stop one at a time. */
.smask.work{animation:march .85s linear infinite}
@keyframes march{to{stroke-dashoffset:-32}}
.smask.named{fill:rgba(92,224,200,.14)}
.smask.faded{stroke:rgba(240,236,248,.34); fill:rgba(240,236,248,.05);
             stroke-width:3; filter:none}
.smask.best{
  stroke:var(--gold); stroke-width:7; fill:rgba(255,210,87,.20);
  animation:bestGlow 1.5s ease-in-out infinite;
}
@keyframes bestGlow{
  0%,100%{filter:drop-shadow(0 0 6px rgba(255,210,87,.65))}
  50%    {filter:drop-shadow(0 0 16px rgba(255,210,87,.95))}
}

.scanBoxes{position:absolute; inset:0}
.slabel{
  position:absolute; white-space:nowrap; transform:translate(-2px, calc(-100% - 5px));
  font-size:9.5px; font-weight:700; letter-spacing:.01em; line-height:1;
  padding:3px 6px; border-radius:5px; background:var(--scan); color:#06251f;
  opacity:0; transition:opacity .25s, transform .25s;
}
.slabel.on{opacity:1; transform:translate(-2px, calc(-100% - 8px))}
.slabel.faded{opacity:0}
.slabel.best{background:var(--gold); color:var(--gold-ink); opacity:1; font-size:10.5px}

.scanSweep{position:absolute; left:0; right:0; top:0; height:34%; opacity:0;
  background:linear-gradient(180deg, transparent, rgba(92,224,200,.30) 65%, rgba(92,224,200,.9));
  border-bottom:2px solid var(--scan)}
.scanSweep.go{animation:sweep 1.9s cubic-bezier(.4,0,.5,1) forwards}
@keyframes sweep{
  0%{transform:translateY(-38%); opacity:0}
  12%{opacity:1}
  88%{opacity:1}
  100%{transform:translateY(300%); opacity:0}
}

.scanFlash{position:absolute; inset:0; background:#fff; opacity:0; pointer-events:none}
.scanFlash.go{animation:flash .34s ease-out}
@keyframes flash{0%{opacity:.85}100%{opacity:0}}

/* THE PHONE MUST NOT RESIZE. Everything below the photo is text that changes as
   the demo runs -- the status line, then a pin name of unknown length -- and the
   phone is in the hero, so any height change shoves the whole page under it. Two
   separate causes, both fixed by reserving the space instead of growing into it:
     1. .scanHud grew when a status string wrapped to two lines
     2. .scanVerdict animated max-height 0 -> 120px, so the phone got ~150px taller
        mid-demo and shorter again on replay
   Fixed heights + one-line clamps, and the verdict now fades in rather than
   expands.

   KEEP min-width:0. It looks like a no-op and is not: the initial value of
   min-width is `auto`, not 0, and on a flex item `auto` resolves to the
   content-based minimum size. Without this line the status refuses to shrink
   below its own text and the ellipsis never engages -- it overflows the phone
   instead. A lint that reads it as "equals the default" is wrong here. */
.scanHud{display:flex; align-items:center; gap:10px; padding:11px 14px;
  height:50px; box-sizing:border-box;
  background:#0d0a14; border-top:1px solid rgba(255,255,255,.07)}
.scanStatus{font-size:13px; font-weight:650; color:var(--muted); transition:color .3s;
  min-width:0; flex:1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.scanStatus.ok{color:var(--ok)} .scanStatus.gold{color:var(--gold)}
.scanStatus.busy{color:var(--scan)}
.scanReplay{margin-left:auto; background:transparent; border:1px solid var(--line);
  color:var(--muted); border-radius:8px; width:28px; height:28px; cursor:pointer;
  font-size:14px; line-height:1; transition:color .15s, border-color .15s}
.scanReplay:hover{color:var(--gold); border-color:var(--gold)}

/* The slot is ALWAYS there, at a fixed height, and only its contents fade. The
   pin name is the one string here with no length bound at all -- catalog names
   run to 60+ characters -- so it is clamped to one line rather than allowed to
   wrap and push the phone taller. */
.scanVerdict{display:flex; flex-direction:column; justify-content:center; gap:3px;
  height:74px; padding:0 14px; box-sizing:border-box;
  opacity:0; overflow:hidden; background:#0d0a14;
  transition:opacity .45s ease}
.scanVerdict.show{opacity:1}
.vTag{font-size:10px; font-weight:800; letter-spacing:.18em; text-transform:uppercase; color:var(--gold)}
.scanVerdict strong{font-size:17px; letter-spacing:-.015em;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.vWhy{font-size:12.5px; color:var(--muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}

.demoCaption{margin:0; font-size:13px; color:var(--faint); text-align:center}
.demoCaption b{color:var(--muted)}

/* ---------- proof strip ---------- */
.proof{position:relative; z-index:1; display:grid; gap:2px;
  grid-template-columns:repeat(auto-fit,minmax(170px,1fr));
  border:1px solid var(--line); border-radius:18px; overflow:hidden;
  background:var(--line); margin-bottom:8px}
.proof > div{background:var(--panel); padding:24px 22px; display:flex; flex-direction:column; gap:5px}
.proof b{font-size:clamp(25px,2.6vw,36px); letter-spacing:-.035em; color:var(--gold); font-weight:820}
.proof span{font-size:13.5px; color:var(--muted)}

/* ---------- sections ---------- */
section{position:relative; z-index:1; padding-block:clamp(58px,7vw,92px); border-top:1px solid var(--line)}
h2{font-size:clamp(28px,3.6vw,46px); letter-spacing:-.03em; margin:0 0 14px; font-weight:790}
.lede{color:var(--muted); margin:0 0 42px; font-size:clamp(17px,1.4vw,20px)}

.steps{display:grid; grid-template-columns:repeat(auto-fit,minmax(250px,1fr)); gap:26px; counter-reset:s}
.step{position:relative; padding-top:56px}
.step::before{counter-increment:s; content:counter(s);
  position:absolute; top:0; left:0; width:38px; height:38px; border-radius:50%;
  display:grid; place-items:center; font-weight:820; font-size:15px;
  background:var(--gold); color:var(--gold-ink); box-shadow:0 5px 18px rgba(255,210,87,.28)}
.step h3{margin:0 0 9px; font-size:19px; letter-spacing:-.015em}
.step p{margin:0; color:var(--muted); font-size:15.5px}

/* ---------- the bet ---------- */
.betSection .bet{padding:30px 34px; border-left:4px solid var(--gold);
  background:linear-gradient(90deg,var(--gold-soft),transparent 72%); border-radius:0 18px 18px 0}
.bet p{margin:0; font-size:clamp(19px,2.3vw,30px); line-height:1.32; letter-spacing:-.02em;
  color:var(--text); font-weight:600}
.bet cite{display:block; margin-top:14px; font-style:normal; font-size:13.5px; color:var(--faint)}
.betNote{margin-top:30px; margin-bottom:0}
.betNote b{color:var(--text)}

/* ---------- features ---------- */
.grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(272px,1fr)); gap:22px}
.card{background:var(--panel); border:1px solid var(--line); border-radius:18px; padding:28px;
  box-shadow:var(--shadow); transition:transform .18s, border-color .18s}
.card:hover{transform:translateY(-3px); border-color:rgba(255,210,87,.35)}
.card h3{margin:0 0 10px; font-size:18.5px; letter-spacing:-.015em}
.card p{margin:0; color:var(--muted); font-size:15.5px}
.ico{width:42px; height:42px; border-radius:12px; display:grid; place-items:center;
  margin-bottom:18px; background:var(--gold-soft); color:var(--gold); font-size:20px}
.card.sunny{border-color:rgba(255,210,87,.32);
  background:linear-gradient(150deg, rgba(255,210,87,.09), var(--panel) 58%)}
.card.sunny .ico{background:var(--gold); color:var(--gold-ink)}

/* ---------- pricing ---------- */
.plans{display:grid; grid-template-columns:repeat(auto-fit,minmax(276px,1fr)); gap:24px; align-items:start}
.plan{background:var(--panel); border:1px solid var(--line); border-radius:20px; padding:32px;
  box-shadow:var(--shadow)}
.plan.feature{border-color:var(--gold); position:relative;
  background:linear-gradient(165deg, rgba(255,210,87,.07), var(--panel) 52%)}
.plan.feature::after{content:"Best value"; position:absolute; top:-12px; left:32px;
  background:var(--gold); color:var(--gold-ink); font-size:11.5px; font-weight:820;
  letter-spacing:.1em; text-transform:uppercase; padding:5px 12px; border-radius:99px}
.plan h3{margin:0 0 6px; font-size:16px; color:var(--muted); font-weight:650}
.price{font-size:clamp(38px,3.6vw,50px); font-weight:830; letter-spacing:-.04em; margin:0}
.price small{font-size:15px; font-weight:600; color:var(--muted); letter-spacing:0}
.plan ul{list-style:none; padding:0; margin:24px 0 28px}
.plan li{padding:9px 0 9px 27px; position:relative; color:var(--muted); font-size:15.5px}
.plan li::before{content:"✓"; position:absolute; left:0; color:var(--ok); font-weight:820}
.plan .btn{display:block; text-align:center}

.referral{margin-top:28px; padding:26px 28px; border:1px dashed rgba(255,210,87,.55);
  border-radius:16px; background:var(--gold-soft)}
.referral p{margin:0; font-size:clamp(16px,1.5vw,20px); color:var(--muted)}
.referral strong{color:var(--gold)}

/* ---------- finale ---------- */
.finale{text-align:center; border-top:1px solid var(--line)}
.finalePin{width:96px; height:96px; margin:0 0 22px;
  filter:drop-shadow(0 12px 32px rgba(178,34,34,.65)); animation:bob 4s ease-in-out infinite}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
.finale .lede{margin-bottom:34px}

/* ---------- footer ---------- */
footer{position:relative; z-index:1; border-top:1px solid var(--line);
  padding-block:44px; color:var(--faint); font-size:14px}
.frow{display:flex; gap:28px; flex-wrap:wrap; align-items:center}
.frow a{text-decoration:none; color:var(--muted)}
.frow a:hover{color:var(--text)}
.fspacer{margin-left:auto}

/* ---------- ultrawide: split long prose into columns, never cap it ---------- */
@media(min-width:1600px){
  .lede, .betNote, .referral p{columns:2; column-gap:clamp(30px,3vw,60px)}
}
@media(min-width:2300px){
  .lede, .betNote, .referral p{columns:3}
}

@media(prefers-reduced-motion:reduce){
  *{animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important}
}
