/* ============================================================================
   Ledgester /story/  -  "Sach Mein?"  illustrated scrollytelling landing.
   Design system + scene choreography. Vanilla CSS, no libraries.

   Three modes (set on <html> by story.js):
     .no-js            -> MODE_STATIC floor: every scene shows its FINAL pose,
                          doubts pre-struck, stamps imprinted. Fully readable.
     .js.mode-static   -> reduced-motion / saveData: same final poses, JS-gated
                          fade-in only.
     .js.mode-step     -> primary mobile: IntersectionObserver crossfades poses
                          A..D at scroll thresholds. data-state on each .stage.
     .js.mode-scrub    -> desktop enhancement: continuous --p (0..1) per stage
                          drives in-between choreography on top of the poses.

   One accent (#0066FF) and it always means "proven or paid".
   No em/en dashes anywhere. Numbers reconcile: 5000 + 450 + 450 = 5900.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; cursor: pointer; }
a { color: inherit; }

:root {
  --ink:        #0A0A0A;
  --ink-2:      #52525B;
  --ink-3:      #6B6B73;
  --paper:      #FBFBFD;
  --paper-2:    #F3F2EE;   /* app cream surface */
  --line:       #E7E7EA;
  --accent:     #0066FF;
  --accent-ink: #0047CC;
  --accent-10:  rgba(0,102,255,.10);
  --accent-06:  rgba(0,102,255,.06);
  --night:      #08080C;
  --night-2:    #111119;
  --app-green:  #128a4f;   /* mic, lives inside phone glass only */
  --app-green-2:#e7f4ec;
  --red:        #E5484D;
  --amber:      #C77B22;

  --serif: 'Fraunces', Georgia, serif;

  /* time-of-day wash, driven by story.js writing --clock (0..1) on :root */
  --clock: 0;
  --warmth: 0;

  --rail-w: 190px;
  --maxw: 1180px;
}

/* ---- time-of-day wash: one fixed overlay, never above 6% ---- */
.wash {
  position: fixed; inset: 0; z-index: 60; pointer-events: none;
  background:
    radial-gradient(120% 90% at 78% 8%,
      rgba(255, 214, 140, calc(var(--warmth) * 0.10)) 0%,
      rgba(255, 170, 90,  calc(var(--warmth) * 0.06)) 40%,
      transparent 72%);
  opacity: 1;
  transition: none;
}
@media (prefers-reduced-motion: reduce) { .wash { display: none; } }

/* ============================ shared type ============================ */
.kicker {
  font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 600; color: var(--ink-3);
}
.serif { font-family: var(--serif); font-style: italic; font-weight: 400; }

/* the doubt lockups: live DOM text, huge Fraunces italic */
.doubt {
  margin: 0;
  font-family: var(--serif); font-style: italic; font-weight: 400;
  line-height: .96; letter-spacing: -.02em;
  font-size: clamp(2.4rem, 9vw, 6.4rem);
  color: var(--ink);
  position: relative; display: inline-block;
}
.doubt .q2 { color: var(--accent); display: block; }
/* the strike overlay: aria-hidden svg absolutely on top, drawn on prove */
.doubt-strike {
  position: absolute; left: -2%; top: 42%; width: 104%; height: 40%;
  pointer-events: none; overflow: visible;
}
.doubt-strike path {
  fill: none; stroke: var(--accent); stroke-width: 7; stroke-linecap: round;
  stroke-dasharray: var(--len, 1200); stroke-dashoffset: var(--len, 1200);
  /* The transition lives HERE, not only on .struck, so the line animates in
     BOTH directions. With it declared only on the struck state, removing the
     class snapped the line away instead of retracting it. */
  transition: stroke-dashoffset .34s ease;
}

/* copy panels */
.copy { max-width: 30rem; }
.copy .en { font-size: clamp(1.05rem, 1.4vw, 1.35rem); line-height: 1.5; color: var(--ink); font-weight: 500; margin: 0 0 .5rem; }
.copy .hi { font-size: clamp(.95rem, 1.2vw, 1.1rem); line-height: 1.55; color: var(--ink-2); margin: 0; }
.copy .en .em { font-family: var(--serif); font-style: italic; color: var(--accent); }

/* ============================ hero ============================ */
.hero {
  position: relative; min-height: 100svh;
  padding: clamp(20px, 4vw, 40px);
  display: grid; grid-template-rows: auto 1fr auto;
  overflow: hidden;
}
.hero-top { max-width: var(--maxw); margin: 0 auto; width: 100%; }
/* header bar: brand left, auth right. Lives in the hero's top row rather than
   fixed, so it never overlaps the scroll-driven scenes below. */
.hero-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: clamp(14px, 2.4vw, 22px);
}
.hero-brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 15px; letter-spacing: -.02em;
  color: var(--ink); text-decoration: none;
}
.hero-brand .hero-mark { display: block; border-radius: 6px; flex: none; }
.hero-auth { display: flex; align-items: center; gap: 6px; }
.ha-login, .ha-signup {
  font: inherit; font-size: 13.5px; font-weight: 600;
  border-radius: 9px; text-decoration: none; white-space: nowrap;
}
.ha-login {
  color: var(--ink-2); padding: 8px 12px;
  transition: color .15s ease, background .15s ease;
}
.ha-login:hover { color: var(--ink); background: rgba(10,10,10,.05); }
.ha-signup {
  color: #fff; background: var(--accent); border: 0; cursor: pointer;
  padding: 9px 16px; box-shadow: 0 4px 14px var(--accent-10);
  transition: background .15s ease, transform .15s ease;
}
.ha-signup:hover { background: var(--accent-ink); transform: translateY(-1px); }
.ha-login:focus-visible, .ha-signup:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
@media (max-width: 460px) {
  .ha-login { padding: 8px 9px; }
  .ha-signup { padding: 9px 13px; }
}
.hero-fine { margin-top: 6px; font-size: 12.5px; color: var(--ink-2); }
.hero-mid {
  max-width: var(--maxw); margin: 0 auto; width: 100%;
  display: grid; grid-template-columns: 1.15fr .85fr; align-items: center; gap: 2rem;
}
.hero-head { font-family: var(--serif); font-style: italic; line-height: .92;
  font-size: clamp(3rem, 12vw, 9rem); letter-spacing: -.03em; margin: 0; }
.hero-head .l1 { color: var(--ink); display: block; }
.hero-head .l2 { color: var(--accent); display: block; }
.hero-cursor {
  display: inline-block; width: .06em; height: .82em; background: var(--accent);
  margin-left: .06em; vertical-align: -.06em; animation: blink 1.06s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }
.hero-phone-wrap { justify-self: center; align-self: end; width: min(300px, 74vw); position: relative; }
.hero-bottom { max-width: var(--maxw); margin: 0 auto; width: 100%; text-align: center; padding-top: 8px; }
.hero-cue { font-size: 13.5px; color: var(--ink-2); }
.hero-cue b { color: var(--ink); font-weight: 600; }
.hero-skip {
  display: inline-block; margin-top: 8px; font-size: 12.5px; color: var(--accent);
  text-decoration: none; border-bottom: 1px solid var(--accent-10); padding-bottom: 1px;
}
.hero-skip:hover { border-color: var(--accent); }
.scroll-chevron { margin: 10px auto 0; width: 22px; height: 22px; color: var(--ink-3); animation: bob 1.8s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(6px); } }
@media (max-width: 780px) {
  .hero-mid { grid-template-columns: 1fr; text-align: center; gap: 1.2rem; }
  .hero-phone-wrap { align-self: center; width: min(240px, 64vw); }
}

/* ============================ phone shell ============================ */
.phone {
  width: 100%; aspect-ratio: 320 / 660; position: relative;
  filter: drop-shadow(0 24px 48px rgba(10,10,20,.14));
}
.phone > .phone-bezel { width: 100%; height: 100%; }
.phone .screen-html {
  position: absolute; overflow: hidden;
  /* screen inset inside the 320x660 bezel (see phone svg) */
  left: 5.6%; top: 4.4%; right: 5.6%; bottom: 4.4%;
  border-radius: 26px;
}
.screen-html * { box-sizing: border-box; }

/* ============================ scene + sticky stage ============================ */
.scene { position: relative; }
.stage {
  position: sticky; top: 0; height: 100svh;
  display: grid; place-items: center; overflow: hidden;
}
.stage-inner {
  position: relative; width: 100%; max-width: var(--maxw);
  height: 100%; margin: 0 auto; padding: 0 clamp(16px, 4vw, 48px);
  display: grid; grid-template-columns: 1fr minmax(240px, 320px) 1fr; align-items: center; gap: 2rem;
}
.stage .doubt-slot { grid-column: 1 / 2; justify-self: end; text-align: right; align-self: center; }
.stage .phone-slot  { grid-column: 2 / 3; justify-self: center; width: 100%; position: relative; }
.stage .copy-slot   { grid-column: 3 / 4; justify-self: start; }

/* Desktop: the doubt sits behind the phone as a muted background question.
   Uses an explicit muted colour that clears >=3:1 large-text contrast, instead
   of a blanket .34 opacity (which pushed both lines below WCAG AA and made the
   accent q2 line near-invisible). The q2 accent + mobile stay full-strength. */
@media (min-width: 781px) {
  .stage .doubt { color: #83838A; }
  .scene.dark .stage .doubt { color: rgba(255,255,255,.5); }
}

/* dark scenes */
.scene.dark { background: var(--night); color: #fff; }
.scene.dark .copy .en { color: #fff; }
.scene.dark .copy .hi { color: rgba(255,255,255,.62); }
.scene.dark .doubt { color: #fff; }

/* timestamp: a little postmark stamped on top of the phone. Centred over the
   phone via left/right/margin (NOT transform) so the rotate+scale stampIn stays
   free. Anchored to .phone-slot (position:relative), straddling its top edge. */
.timestamp {
  position: absolute; z-index: 6;
  left: 0; right: 0; margin-inline: auto; width: max-content; top: -14px;
  font-family: var(--serif); font-style: italic; font-size: clamp(13px, 1.35vw, 18px);
  color: var(--accent); background: rgba(255,255,255,.93);
  border: 2px solid var(--accent); border-radius: 8px;
  padding: 3px 11px; transform: rotate(-4deg) scale(.6); opacity: 0;
  transform-origin: center; letter-spacing: .01em; font-weight: 500;
  white-space: nowrap; pointer-events: none;
  box-shadow: 0 7px 18px rgba(10,10,20,.14);
}
/* closing scenes have no phone; drop the stamp to a visible top-centre spot */
.scene.ghar .timestamp, #cta .timestamp { top: clamp(18px, 6vh, 56px); }
.stage[data-state]:not([data-state="idle"]) .timestamp { animation: stampIn .16s cubic-bezier(.2,1.4,.5,1) forwards; }
.no-js .timestamp, .mode-static .timestamp { opacity: .92; transform: rotate(-4deg) scale(1); }

@keyframes stampIn {
  0%   { opacity: 0; transform: rotate(-4deg) scale(1.5); }
  60%  { opacity: 1; transform: rotate(-4deg) scale(.92); }
  100% { opacity: .92; transform: rotate(-4deg) scale(1); }
}

/* ============================ pose system ============================ */
/* Each scene's phone/overlay has .pose-* layers; the active pose is revealed
   by data-state on the stage. Default (JS idle) = pose A visible. */
.pose { transition: opacity .3s ease; }
[data-poses] .pose { position: absolute; inset: 0; opacity: 0; }
[data-poses] .pose.pose-a { opacity: 1; }

.stage[data-state="a"] .pose { opacity: 0; }
.stage[data-state="a"] .pose-a { opacity: 1; }
.stage[data-state="b"] .pose { opacity: 0; }
.stage[data-state="b"] .pose-b { opacity: 1; }
.stage[data-state="c"] .pose { opacity: 0; }
.stage[data-state="c"] .pose-c { opacity: 1; }
.stage[data-state="d"] .pose { opacity: 0; }
.stage[data-state="d"] .pose-d { opacity: 1; }
.stage[data-state="done"] .pose { opacity: 0; }
.stage[data-state="done"] .pose:last-child { opacity: 1; }

/* no-js / static: show the LAST pose of each scene */
.no-js [data-poses] .pose, .mode-static [data-poses] .pose { opacity: 0 !important; transition: none; }
.no-js [data-poses] .pose-final, .mode-static [data-poses] .pose-final { opacity: 1 !important; }
/* and pre-strike the doubts */
.no-js .doubt-strike path, .mode-static .doubt-strike path { stroke-dashoffset: 0 !important; }

/* struck state (set by JS when proof lands) */
.stage.struck .doubt-strike path { stroke-dashoffset: 0; transition: stroke-dashoffset .5s ease .05s; }

/* ============================ scoreboard ============================ */
.scoreboard {
  position: fixed; z-index: 50; right: 14px; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 10px; align-items: center;
  padding: 12px 8px; border: 1px solid var(--line); border-radius: 999px;
  background: rgba(251,251,253,.82); backdrop-filter: blur(8px);
  opacity: 0; transition: opacity .4s ease;
}
.scoreboard.show { opacity: 1; }
.sb-count { font-size: 10.5px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; writing-mode: vertical-rl; letter-spacing: .04em; }
.sb-slots { display: flex; flex-direction: column; gap: 7px; }
.sb-slot { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--ink-3); transition: background .3s, border-color .3s, transform .3s; }
.sb-slot.hit { background: var(--accent); border-color: var(--accent); transform: scale(1.18); }
@media (max-width: 780px) {
  .scoreboard {
    right: 0; left: 0; top: 0; bottom: auto; transform: none; width: 100%;
    flex-direction: row; justify-content: center; gap: 8px; border-radius: 0;
    border: none; border-bottom: 1px solid var(--line); padding: 6px 10px; height: 30px;
  }
  .sb-count { writing-mode: horizontal-tb; }
  .sb-slots { flex-direction: row; gap: 6px; }
}

/* ============================ sticky mini CTA ============================ */
.mini-cta {
  position: fixed; z-index: 55; left: 50%; bottom: 16px; transform: translate(-50%, 140%); visibility: hidden;
  background: var(--ink); color: #fff; border: none; border-radius: 999px;
  padding: 11px 20px; font-size: 14px; font-weight: 600; letter-spacing: .01em;
  box-shadow: 0 10px 30px rgba(10,10,20,.28); transition: transform .35s cubic-bezier(.2,.9,.3,1);
}
.mini-cta.show { transform: translate(-50%, 0); visibility: visible; }
.mini-cta.retire { transform: translate(-50%, 140%); }

/* ============================ rubber stamp rig ============================ */
.stamp {
  position: absolute; font-weight: 800; letter-spacing: .02em;
  border: 3px solid currentColor; border-radius: 8px; padding: 5px 11px;
  color: var(--accent); background: transparent; text-transform: uppercase;
  font-size: 15px; transform: rotate(-8deg) scale(1.6); opacity: 0;
  font-family: 'Inter', sans-serif;
}
.stamp.thunk { animation: thunk .14s cubic-bezier(.2,1.5,.5,1) forwards; }
.no-js .stamp, .mode-static .stamp { opacity: .95; transform: rotate(-8deg) scale(1); }
@keyframes thunk {
  0%   { opacity: 0; transform: rotate(-8deg) scale(1.6); }
  55%  { opacity: 1; transform: rotate(-8deg) scale(.9); }
  100% { opacity: .95; transform: rotate(-8deg) scale(1); }
}
.stamp.green { color: var(--app-green); }
.stamp.red { color: var(--red); }
.stamp.paid { color: var(--app-green); font-size: 17px; }

/* ============================ odometer ============================ */
.odo { font-variant-numeric: tabular-nums; font-weight: 700; }

/* ============================ hand doodles ============================ */
.doodle path, .doodle circle, .doodle line { fill: none; stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.scribble { font-family: var(--serif); font-style: italic; color: var(--ink-2); font-size: 13px; line-height: 1.3; }

/* ============================ mobile stage layout (step mode) ============================ */
@media (max-width: 780px) {
  .stage { height: auto; min-height: 100svh; top: 0; }
  .stage-inner { grid-template-columns: 1fr; gap: 1rem; padding: 40px 18px 24px; align-content: center; }
  .stage .doubt-slot { grid-column: 1; justify-self: center; text-align: center; opacity: 1; order: 1; }
  .stage .phone-slot  { grid-column: 1; order: 2; width: min(260px, 66vw); justify-self: center; }
  .stage .copy-slot   { grid-column: 1; order: 3; justify-self: center; text-align: center; }
  .copy { max-width: 30rem; }
  /* sit the stamp on the phone's top edge, clear of the doubt heading above */
  .timestamp { top: -6px; }
  .scene.ghar .timestamp, #cta .timestamp { top: clamp(14px, 4vh, 40px); }
}

/* reduced motion: kill all non-essential animation */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* utility */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ============================ CTA scene ============================ */
.cta-stage { background: var(--night); color: #fff; }
.cta-wrap { text-align: center; max-width: 460px; padding: 0 20px; }
.cta-doubt { font-size: clamp(2.6rem, 8vw, 5rem); color: #fff; line-height: 1; margin: 0; }
.cta-lead { color: rgba(255,255,255,.6); font-size: 1.05rem; margin: 12px 0 26px; }
.cta-invoice { background: #fff; color: var(--ink); border-radius: 18px; padding: 22px; text-align: left;
  box-shadow: 0 30px 70px rgba(0,0,0,.5); }
.cta-inv-head { display: flex; justify-content: space-between; align-items: baseline; border-bottom: 1px dashed var(--line); padding-bottom: 12px; margin-bottom: 16px; }
.cta-inv-head span { font-size: 11px; letter-spacing: .18em; color: var(--ink-3); font-weight: 700; }
.cta-inv-head b { font-family: var(--serif); font-style: italic; font-size: 22px; color: var(--accent); }
.cta-flbl { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); font-weight: 700; display: block; margin-bottom: 6px; }
.cta-field input { width: 100%; border: 1.5px solid var(--line); border-radius: 12px; padding: 14px; font-size: 16px; font-weight: 600; letter-spacing: .02em; }
.cta-field input:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-10); }
.cta-err { color: #B4262A; font-size: 12.5px; margin: 8px 0 0; }
.cta-submit { position: relative; width: 100%; margin-top: 14px; background: var(--ink); color: #fff; border: none;
  border-radius: 12px; padding: 15px; font-size: 15px; font-weight: 700; overflow: hidden; }
.cta-submit .cta-stamp { position: absolute; inset: 0; display: grid; place-items: center; font-family: 'Inter',sans-serif;
  font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); border: 3px solid var(--accent);
  border-radius: 10px; transform: rotate(-7deg) scale(1.5); opacity: 0; background: #fff; }
.cta-submit.pressed .cta-stamp { animation: thunk .16s cubic-bezier(.2,1.5,.5,1) forwards; }
.cta-fine { text-align: center; color: var(--ink-3); font-size: 12px; margin: 12px 0 0; }
.cta-ok { margin-top: 14px; text-align: center; color: var(--app-green); font-weight: 700; font-size: 14px; }

/* ============================ footer ============================ */
.story-foot { background: var(--night); color: rgba(255,255,255,.7); padding: 28px 20px 40px; }
.story-foot-in { max-width: var(--maxw); margin: 0 auto; display: flex; justify-content: space-between; align-items: center; font-size: 14px; }
.story-foot-in span { font-weight: 700; color: #fff; }
.story-foot-in a { color: rgba(255,255,255,.7); text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.2); }

/* ============================ review fixes: mobile fit + perf + a11y ============================ */
/* mobile scoreboard: solid bar, no per-frame backdrop reblur */
@media (max-width: 780px) {
  .scoreboard { backdrop-filter: none; background: rgba(251,251,253,.97); }
}

/* short viewports: keep doubt + phone + copy inside one sticky pane in MODE_STEP.
   Without this the stacked column overflows a pinned frame and the copy sits below the fold. */
@media (max-width: 780px) {
  .stage .phone-slot { width: min(220px, 52vw); }
  .phone { max-height: 52svh; width: auto; margin-inline: auto; }
}
@media (max-width: 780px) and (max-height: 740px) {
  .stage-inner { padding: 30px 18px 16px; gap: .55rem; }
  .stage .phone-slot { width: min(150px, 38vw); }
  .doubt { font-size: clamp(1.8rem, 7.5vw, 2.8rem); }
  .copy .hi { display: none; }                         /* keep the EN line; drop the second paragraph */
  .copy .en { font-size: 1rem; }
}
