/* KFX Studio marketing site.
   Same palette as the dashboard so the product doesn't feel like a different company after signup.
   Dark, one accent, generous vertical rhythm — the slide thumbnails are the only bright thing. */

:root {
  --bg:        #0b0b0d;
  --band:      #101014;
  --surface:   #16161b;
  --line:      #24242c;
  --text:      #f4f4f6;
  --dim:       #9d9daa;
  --mute:      #6b6b78;
  --accent:    #ff6b35;
  --accent-dk: #e2551f;
  --r:  12px;
  --r-lg: 20px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
[hidden] { display: none !important; }

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; }
.wrap.narrow { max-width: 760px; }
.center { text-align: center; }

h1, h2, h3 { line-height: 1.15; letter-spacing: -0.025em; }
em { font-style: normal; color: var(--accent); }

/* ───────── nav ───────── */
.nav {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 32px;
  padding: 14px 24px;
  background: rgba(11,11,13,.82);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; color: var(--text); text-decoration: none; letter-spacing: -0.01em; }
/* The real mark, not a letter. Every page still writes a literal "K" inside .brand-mark; rather
   than editing nine spans across seven files, the glyph is hidden and the SVG drawn behind it —
   which also means the text stays in the DOM for anything that reads it.
   The icon is INLINED rather than linked. A linked background that fails to load — blocked, cached
   wrong, offline for a moment — leaves a 28px hole on a near-black page with nothing to show it
   broke, because the "K" behind it is hidden. Inline, there is no request to fail. The solid fill
   is a second-line fallback: worst case the mark is a brand-coloured tile, never a black gap. */
.brand-mark {
  width: 28px; height: 28px; flex: 0 0 auto;
  border-radius: 22%;  /* matches the tile's own rx=225/1024, so it never clips the art */
  background: #e2551f url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024' width='1024' height='1024' role='img' aria-label='KFX Studio'%3E%3Ctitle%3EKFX Studio%3C/title%3E%3Cdefs%3E%3ClinearGradient id='bg' gradientUnits='userSpaceOnUse' x1='0' y1='0' x2='1024' y2='1024'%3E%3Cstop offset='0' stop-color='%23ff8f5e'/%3E%3Cstop offset='1' stop-color='%23e2551f'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='1024' height='1024' rx='225' fill='url(%23bg)'/%3E%3Crect x='161' y='272' width='320' height='490' rx='72' fill='%23fff' opacity='.32'/%3E%3Crect x='278' y='232' width='370' height='560' rx='88' fill='%23fff' opacity='.58'/%3E%3Crect x='393' y='192' width='470' height='640' rx='105' fill='%23fff'/%3E%3Cpath d='M568 392 L760 512 L568 632 Z' fill='url(%23bg)'/%3E%3C/svg%3E") center / contain no-repeat;
  font-size: 0; color: transparent; user-select: none;
}
.nav-links { display: flex; gap: 26px; margin-right: auto; }
.nav-links a { color: var(--dim); text-decoration: none; font-size: 14.5px; font-weight: 500; }
.nav-links a:hover { color: var(--text); }
.nav-cta { display: flex; gap: 10px; }

/* Hamburger — only ever visible under 820px, where .nav-links becomes a drop-down panel. */
.nav-burger {
  display: none; margin-left: auto;
  width: 40px; height: 40px; padding: 10px 9px;
  background: transparent; border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer; flex-direction: column; justify-content: space-between;
}
/* Lives inside the collapsed menu only — see the note in index.html. */
.nav-menu-signin { display: none; }
.nav-burger span { display: block; height: 2px; background: var(--text); border-radius: 2px; transition: transform .16s, opacity .16s; }
.nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ───────── buttons ───────── */
.btn {
  background: var(--accent); color: #1a0d06;
  border: 0; border-radius: var(--r);
  padding: 10px 18px;
  font: inherit; font-weight: 650; font-size: 14.5px;
  cursor: pointer; text-decoration: none; display: inline-block;
  transition: background .13s, transform .08s;
}
.btn:hover { background: var(--accent-dk); }
.btn:active { transform: translateY(1px); }
.btn-lg { padding: 15px 30px; font-size: 16px; border-radius: 14px; }
.btn-block { width: 100%; padding: 13px; margin-top: 8px; }
.btn-ghost {
  background: transparent; color: var(--dim);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 10px 16px; font: inherit; font-size: 14.5px; font-weight: 500; cursor: pointer;
}
.btn-ghost:hover { color: var(--text); border-color: var(--mute); }
.link { background: none; border: 0; color: var(--accent); font: inherit; font-weight: 600; cursor: pointer; padding: 0; }

/* ───────── hero ───────── */
/* The art column is deliberately the wider half: the slides are the product, and at the old
   1.05fr/.95fr with a 56px gutter the three covers capped out around 155px each. */
.hero {
  display: grid; grid-template-columns: .92fr 1.08fr; gap: 44px; align-items: center;
  max-width: 1180px; margin: 0 auto; padding: 84px 24px 76px;
}

.pill {
  display: inline-block; margin-bottom: 22px;
  padding: 5px 13px; border-radius: 999px;
  background: rgba(255,107,53,.12); color: var(--accent);
  font-size: 12.5px; font-weight: 650;
}
.hero h1 { font-size: clamp(38px, 5.2vw, 60px); font-weight: 800; }

/* Typewriter on the last word. The span reserves the width of the longest word in the set so the
   headline doesn't reflow — and on a two-line h1 a reflow shoves the whole hero around. */
.typer { display: inline-flex; align-items: baseline; min-width: 11ch; }
.caret {
  display: inline-block; width: 3px; height: .82em;
  margin-left: 3px; background: var(--accent); border-radius: 1px;
  animation: caretBlink 1.05s steps(1) infinite;
}
@keyframes caretBlink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.lede { color: var(--dim); font-size: 17.5px; margin-top: 22px; max-width: 55ch; }
.hero-actions { display: flex; align-items: center; gap: 16px; margin-top: 32px; flex-wrap: wrap; }
.hero-note { color: var(--mute); font-size: 13.5px; }
.hero-ticks { list-style: none; display: flex; gap: 22px; margin-top: 30px; flex-wrap: wrap; }
.hero-ticks li { color: var(--dim); font-size: 14px; position: relative; padding-left: 20px; }
.hero-ticks li::before {
  content: ''; position: absolute; left: 0; top: 7px;
  width: 11px; height: 6px; border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

/* Fanned stack rather than a flat row. Three covers laid square read as a contact sheet; angled
   and overlapped they read as a deck you could pick up, which is what's being sold. The centre
   card stays upright and full-size so the one you actually look at isn't the tilted one. */
.phone-row { display: flex; gap: 0; justify-content: center; align-items: center; perspective: 900px; }
.phone {
  flex: 0 1 200px; max-width: 200px; aspect-ratio: 9/16;
  border-radius: 16px; overflow: hidden;
  border: 1px solid var(--line); background: var(--surface);
  display: grid; place-items: center; color: var(--mute); font-weight: 700;
  box-shadow: 0 22px 50px rgba(0,0,0,.45);
  transition: transform .42s cubic-bezier(.76,0,.24,1), opacity .42s ease;
}
.phone img { width: 100%; height: 100%; object-fit: cover; display: block; }

.phone.ph-1 { transform: rotate(-7deg) scale(.875) translateY(8px); z-index: 1; margin-right: -26px; opacity: .92; }
.phone.ph-2 { transform: rotate(-1deg); z-index: 3; }
.phone.ph-3 { transform: rotate(6deg)  scale(.875) translateY(8px); z-index: 1; margin-left: -26px;  opacity: .92; }

/* Lifting the hovered card out of the fan makes the stack feel like objects, and tells you the
   covers are interactive before you click one. */
.phone:hover { transform: rotate(0deg) scale(1.03) translateY(-6px); z-index: 4; opacity: 1; }

/* ───────── sections ───────── */
.band { background: var(--band); border-block: 1px solid var(--line); padding: 76px 0; margin: 76px 0; }
section.wrap { padding-block: 8px; }
.sec-title { font-size: clamp(26px, 3.4vw, 36px); font-weight: 750; text-align: center; }
.sec-sub { color: var(--dim); text-align: center; margin-top: 12px; }
.band h2 { font-size: clamp(24px, 3.2vw, 33px); font-weight: 750; }
.band .sub { color: var(--dim); margin-top: 16px; font-size: 17px; }

/* steps */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 20px; margin-top: 44px; }
.step { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 24px; }
.step-n {
  width: 30px; height: 30px; border-radius: 9px;
  background: rgba(255,107,53,.14); color: var(--accent);
  display: grid; place-items: center; font-weight: 800; font-size: 14px; margin-bottom: 14px;
}
.step h3 { font-size: 16.5px; font-weight: 650; margin-bottom: 8px; }
.step p { color: var(--dim); font-size: 14.5px; }

/* ───────── how it works: steps + device demo ───────── */
/* The demo is the point of this section, so it gets the larger half. */
.how-grid { display: grid; grid-template-columns: .82fr 1.18fr; gap: 52px; align-items: center; margin-top: 44px; }

.steps-list { list-style: none; display: flex; flex-direction: column; gap: 26px; position: relative; }
/* Hairline threading the number bubbles, so the four steps read as one sequence. */
.steps-list::before {
  content: ''; position: absolute; left: 15px; top: 24px; bottom: 24px;
  width: 1px; background: var(--line);
}
.step-row { display: flex; gap: 16px; align-items: flex-start; position: relative; }
.step-row .step-n { flex: 0 0 auto; margin-bottom: 0; position: relative; z-index: 1; }
.step-row h3 { font-size: 16.5px; font-weight: 650; margin-bottom: 6px; }
.step-row p { color: var(--dim); font-size: 14.5px; }

/* ── the demo ──
   One 18s timeline shared by both devices: the laptop runs steps 1-3 and then holds on the
   finished deck while the phone takes over for step 4. Whichever device is idle dims and drops
   back, so attention moves without anything needing to be said. */
/* Bottom padding leaves room for the phone, which sits below and right of the laptop. */
.demo-stage { position: relative; padding: 0 0 90px 0; }

.laptop { width: 100%; max-width: 540px; margin: 0 auto; animation: deviceFocus 18s infinite; }
.laptop-screen {
  height: 260px; overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line); border-radius: 12px 12px 3px 3px;
  border-bottom-width: 3px;
}
.laptop-strip { animation: laptopRoll 18s infinite; }
.laptop-base {
  height: 9px; margin: 0 auto; width: 116%; max-width: none; transform: translateX(-7%);
  background: linear-gradient(180deg, var(--surface), #0e0e12);
  border: 1px solid var(--line); border-top: 0;
  border-radius: 0 0 9px 9px;
}

.lp { height: 260px; padding: 15px 18px; display: flex; flex-direction: column; gap: 11px; }
.ui-bar { display: flex; gap: 5px; margin-bottom: 2px; }
.ui-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--line); }
.ui-label { font-size: 11px; font-weight: 650; color: var(--mute); letter-spacing: .04em; text-transform: uppercase; }
.ui-field {
  flex: 1; background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  padding: 9px 10px; font-size: 11px; line-height: 1.55; color: var(--dim);
  overflow: hidden;
}
.ui-caret { display: inline-block; width: 2px; height: 10px; background: var(--accent); vertical-align: -1px; margin-left: 2px; animation: caretBlink 1s steps(1) infinite; }
.ui-hook { font-size: 11.5px; font-weight: 650; color: var(--text); margin-top: auto; }
.ui-foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ui-cap { font-size: 10.5px; color: var(--mute); line-height: 1.4; flex: 1; }
.ui-btn {
  align-self: flex-start; background: var(--accent); color: #1a0d06;
  padding: 7px 13px; border-radius: 8px; font-size: 11.5px; font-weight: 700;
}
.ui-btn.sm { padding: 6px 11px; font-size: 11px; }
.ui-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ui-chip {
  padding: 5px 10px; border-radius: 999px; font-size: 11px; font-weight: 600;
  background: var(--surface); border: 1px solid var(--line); color: var(--mute);
}
.ui-chip.is-on { background: rgba(255,107,53,.15); border-color: var(--accent); color: var(--accent); }
.ui-note { margin-top: auto; font-size: 11px; color: var(--mute); }
.ui-prog { height: 5px; border-radius: 999px; background: var(--surface); overflow: hidden; }
.ui-prog i { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 999px; animation: uiFill 18s infinite; }
.ui-thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; margin-top: 2px; }
.ui-thumb {
  aspect-ratio: 9/16; border-radius: 5px; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line);
}
.ui-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ui-thumb.d1 { animation: thumbIn 18s infinite; }
.ui-thumb.d2 { animation: thumbIn 18s infinite .5s; }
.ui-thumb.d3 { animation: thumbIn 18s infinite 1s; }
.ui-thumb.d4 { animation: thumbIn 18s infinite 1.5s; }

/* 132px was too narrow: six 9:16 thumbnails plus a header and a button simply did not fit the
   frame, so every panel overflowed its screen. Sized from the content out instead — 3 columns of
   ~43px covers, two rows, header and button = ~250px of screen. */
/* Proper phone proportions: 176px of screen at 380px tall is ~9:19.5, which is what a modern
   handset actually is. At 172x250 it read as a squat card. */
.phone-mock {
  position: absolute; right: -6px; bottom: 0;
  width: 194px;
  border-radius: 30px; padding: 9px;
  background: #17171d; border: 1px solid #2b2b34;
  box-shadow: 0 24px 54px rgba(0,0,0,.6), inset 0 0 0 1px rgba(255,255,255,.04);
  /* Hidden until the laptop hands over — see phoneEnter. Nothing to look at before then, and an
     idle phone sitting there through the whole first half draws the eye off the laptop. */
  animation: phoneEnter 18s infinite;
}
/* Notch and side button — cheap, and without them the frame reads as a card. */
.phone-mock::before {
  content: ''; position: absolute; top: 17px; left: 50%; transform: translateX(-50%);
  width: 54px; height: 5px; border-radius: 3px; background: #26262e; z-index: 2;
}
.phone-mock::after {
  content: ''; position: absolute; right: -2px; top: 96px;
  width: 2px; height: 42px; border-radius: 2px; background: #2b2b34;
}
.phone-screen { height: 380px; overflow: hidden; border-radius: 22px; background: var(--bg); }
.phone-strip { animation: phoneRoll 18s infinite; }
.pp { height: 380px; padding: 26px 12px 12px; display: flex; flex-direction: column; gap: 10px; }
.pp-top { font-size: 10.5px; font-weight: 700; color: var(--mute); text-transform: uppercase; letter-spacing: .05em; }
.pp-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.pp-grid span {
  position: relative; aspect-ratio: 9/16; border-radius: 4px; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line);
}
.pp-grid img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Numbered ticks — picking order is the thing that matters when posting a slideshow. */
.pp-grid .sel i {
  position: absolute; top: 2px; right: 2px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--accent); color: #1a0d06;
  font-size: 8px; font-weight: 800; font-style: normal;
  display: grid; place-items: center;
}
.pp-compose { display: flex; gap: 8px; align-items: flex-start; }
.pp-thumb { width: 34px; aspect-ratio: 9/16; object-fit: cover; border-radius: 4px; flex: 0 0 auto; }
.pp-cap-text { font-size: 10px; line-height: 1.45; color: var(--dim); }
.pp-posted { position: relative; flex: 1; border-radius: 10px; overflow: hidden; }
.pp-posted img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pp-badge {
  position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 999px;
  background: rgba(0,0,0,.72); backdrop-filter: blur(6px);
  color: #fff; font-size: 10.5px; font-weight: 700;
}
.pp-tags { font-size: 10px; color: var(--accent); }
.pp-btn {
  margin-top: auto; position: relative;
  background: var(--accent); color: #1a0d06; text-align: center;
  padding: 7px; border-radius: 8px; font-size: 11px; font-weight: 700;
}
/* Tap pulse — the only thing suggesting a finger, which is enough to read as a recording. */
.tap {
  position: absolute; left: 50%; top: 50%; width: 26px; height: 26px; margin: -13px 0 0 -13px;
  border-radius: 50%; background: rgba(255,255,255,.55);
  animation: tapPing 18s infinite;
}
.pp-done { margin: auto; display: flex; flex-direction: column; align-items: center; gap: 9px; color: var(--dim); font-size: 12px; font-weight: 600; }
.pp-tick {
  width: 13px; height: 13px; border-radius: 50%;
  background: #3ddc97; position: relative; flex: 0 0 auto;
}
.pp-tick::after {
  content: ''; position: absolute; left: 4.5px; top: 2.5px;
  width: 3px; height: 6px;
  border-right: 2px solid #0b0b0d; border-bottom: 2px solid #0b0b0d;
  transform: rotate(42deg);
}

/* Laptop holds each of its first three panels, then rests on the finished deck. */
@keyframes laptopRoll {
  0%, 12%   { transform: translateY(0); }
  16%, 27%  { transform: translateY(-260px); }
  31%, 43%  { transform: translateY(-520px); }
  47%, 100% { transform: translateY(-780px); }
}
/* Phone stays on its first panel until the deck exists, then runs its three. */
@keyframes phoneRoll {
  0%, 55%   { transform: translateY(0); }
  60%, 72%  { transform: translateY(-380px); }
  77%, 100% { transform: translateY(-760px); }
}
/* The phone waits at the edge rather than vanishing. Parked it is pushed right and down, scaled
   back and dimmed — present enough that you know the story has a second half, quiet enough that it
   doesn't compete with the laptop. When its turn comes it slides in and comes up to full strength.
   Hiding it outright made the handoff a surprise; parking it makes it a promise. */
@keyframes phoneEnter {
  0%, 44%   { opacity: .38; transform: translateX(38px) translateY(18px) scale(.88); }
  56%, 96%  { opacity: 1;   transform: translateX(0) translateY(0) scale(1); }
  100%      { opacity: .38; transform: translateX(38px) translateY(18px) scale(.88); }
}
/* Active device sits forward and bright; idle device recedes. */
@keyframes deviceFocus {
  0%, 46%   { opacity: 1; transform: translateY(0) scale(1); }
  56%, 94%  { opacity: .58; transform: translateY(4px) scale(.985); }
  100%      { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes uiFill {
  0%, 31%  { width: 0; }
  43%      { width: 100%; }
  100%     { width: 100%; }
}
@keyframes thumbIn {
  0%, 31%   { opacity: 0; transform: translateY(6px); }
  38%, 100% { opacity: 1; transform: none; }
}
@keyframes tapPing {
  0%, 50%  { opacity: 0; transform: scale(.6); }
  56%      { opacity: .8; transform: scale(1); }
  62%, 100%{ opacity: 0; transform: scale(1.7); }
}

@media (max-width: 900px) {
  .how-grid { grid-template-columns: 1fr; gap: 40px; }
  .demo-stage { max-width: 460px; margin: 0 auto; }
}

/* ───────── proof ───────── */
.proof { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; margin-top: 40px; }
.proof-item { padding: 26px 24px; border-left: 1px solid var(--line); }
.proof-item:first-child { border-left: 0; padding-left: 0; }
.proof-n { font-size: clamp(34px, 4.6vw, 52px); font-weight: 800; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; line-height: 1; }
.proof-l { color: var(--dim); font-size: 14px; margin-top: 9px; }
/* 1080x1920 is far longer than a "11" or "~30s", so it needs its own size or it wraps mid-figure. */
.proof-item:last-child .proof-n { font-size: clamp(26px, 3.2vw, 38px); letter-spacing: -0.02em; }
.proof-x { opacity: .5; margin: 0 1px; }
@media (max-width: 700px) {
  .proof { grid-template-columns: 1fr; }
  .proof-item { border-left: 0; border-top: 1px solid var(--line); padding: 20px 0; }
  .proof-item:first-child { border-top: 0; padding-top: 0; }
}

/* features */
.feats { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 20px; margin-top: 44px; }
.feat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 26px; }
.feat h3 { font-size: 16.5px; font-weight: 650; margin-bottom: 10px; }
.feat p { color: var(--dim); font-size: 14.5px; }

/* examples
   This section exists to prove the output is good, so the covers are sized to be READ, not
   glanced at. minmax(160px) put five ~200px thumbnails in a row and the slide copy — the actual
   thing being judged — was illegible. 250px gives four per row on desktop, three on a laptop. */
.examples { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 22px; margin-top: 40px; }
.examples img {
  width: 100%; aspect-ratio: 9/16; object-fit: cover;
  border-radius: var(--r); border: 1px solid var(--line); display: block;
}
.example { margin: 0; }
/* The hook under each cover is the point of this grid: it shows five different businesses got five
   genuinely different decks, which the images alone don't communicate at thumbnail size. */
.example figcaption {
  margin-top: 12px; font-size: 14px; line-height: 1.45; color: var(--dim);
}

.examples-hint { margin-top: 10px; font-size: 13.5px; color: var(--mute); }

/* The cover is a button into the deck, so it has to look like one. */
.example-open {
  display: block; width: 100%; padding: 0;
  background: none; border: 0; cursor: pointer; font: inherit; text-align: left;
  color: inherit;
}
.example-shot { position: relative; border-radius: var(--r); overflow: hidden; }
.example-shot::after {
  content: attr(data-count);
  position: absolute; right: 9px; bottom: 9px;
  padding: 3px 9px; border-radius: 999px;
  background: rgba(0,0,0,.66); backdrop-filter: blur(6px);
  color: #fff; font-size: 11.5px; font-weight: 650;
}
/* TikTok-style view count, bottom-left of a cover. Only rendered when a deck actually carries a
   `views` number in the manifest — see landing.js. A deck that was never posted shows nothing
   rather than a placeholder, because at this size a greyed-out number still reads as a real one. */
.example-views {
  position: absolute; left: 9px; bottom: 9px;
  display: flex; align-items: center; gap: 4px;
  color: #fff; font-size: 12px; font-weight: 650;
  text-shadow: 0 1px 4px rgba(0,0,0,.7);
}
.example-views svg { width: 13px; height: 13px; fill: #fff; }

.example-open img { transition: transform .22s ease; }
.example-open:hover .example-shot img { transform: scale(1.035); }
.example-open:hover figcaption { color: var(--text); }
.example-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: var(--r); }

/* ───────── deck viewer ───────── */
.deck-modal {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(6,6,8,.9); backdrop-filter: blur(14px);
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; justify-items: center;
  gap: 10px; padding: 24px;
  animation: deckIn .18s ease;
}
@keyframes deckIn { from { opacity: 0; } to { opacity: 1; } }

.deck-stage { display: flex; flex-direction: column; align-items: center; gap: 14px; margin: 0; min-height: 0; }
.deck-stage img {
  max-height: 74vh; max-width: min(420px, 82vw);
  width: auto; border-radius: 14px;
  border: 1px solid var(--line);
  box-shadow: 0 30px 70px rgba(0,0,0,.6);
  display: block;
}
.deck-meta { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; max-width: 460px; }
.deck-meta-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; }
.deck-caption { color: var(--dim); font-size: 13.5px; line-height: 1.5; }
.deck-tags { color: var(--accent); font-size: 12.5px; line-height: 1.5; }
.deck-badge {
  padding: 3px 10px; border-radius: 999px;
  background: rgba(255,107,53,.15); color: var(--accent);
  font-size: 11.5px; font-weight: 700; text-transform: capitalize;
}
.deck-hook { font-size: 14.5px; font-weight: 600; }
.deck-count { color: var(--mute); font-size: 13px; }

.deck-close, .deck-nav {
  background: rgba(255,255,255,.08); border: 0; color: #fff;
  width: 44px; height: 44px; border-radius: 50%;
  font-size: 26px; line-height: 1; cursor: pointer;
  display: grid; place-items: center; flex: 0 0 auto;
  transition: background .13s;
}
.deck-close:hover, .deck-nav:not(:disabled):hover { background: rgba(255,255,255,.2); }
.deck-nav:disabled { opacity: .25; cursor: default; }
.deck-close { position: absolute; top: 18px; right: 18px; z-index: 2; }

.deck-dots { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 7px; }
.deck-dot {
  width: 7px; height: 7px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.26); cursor: pointer; transition: background .13s, transform .13s;
}
.deck-dot.is-on { background: var(--accent); transform: scale(1.3); }

@media (max-width: 720px) {
  /* Arrows would eat the width the slide needs; swipe and the dots cover navigation. */
  .deck-modal { grid-template-columns: 1fr; padding: 16px; }
  .deck-nav { display: none; }
  .deck-stage img { max-height: 68vh; max-width: 86vw; }
  .deck-hook { font-size: 13.5px; }
}

/* pricing */
.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); gap: 20px; margin-top: 44px; align-items: start; }
.plan { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 28px; position: relative; }
.plan.is-popular { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.plan-tag {
  position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  background: var(--accent); color: #1a0d06;
  padding: 3px 12px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
}
.plan h3 { font-size: 17px; font-weight: 650; }
.plan-blurb { color: var(--mute); font-size: 13.5px; margin-top: 4px; }
.plan-price { font-size: 40px; font-weight: 800; margin: 18px 0 2px; letter-spacing: -0.03em; }
.plan-period { color: var(--mute); font-size: 13.5px; }
.plan ul { list-style: none; margin: 22px 0; display: flex; flex-direction: column; gap: 10px; }
.plan li { color: var(--dim); font-size: 14.5px; padding-left: 22px; position: relative; }
.plan li::before {
  content: ''; position: absolute; left: 0; top: 7px;
  width: 11px; height: 6px; border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}
.plans-note { text-align: center; color: var(--mute); font-size: 13px; margin-top: 26px; }

/* faq */
.faq { margin-top: 36px; display: flex; flex-direction: column; gap: 10px; }
.faq details { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 16px 20px; }
.faq summary { cursor: pointer; font-weight: 600; font-size: 15.5px; list-style: none; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; float: right; color: var(--accent); font-weight: 700; }
.faq details[open] summary::after { content: '−'; }
.faq p { color: var(--dim); font-size: 14.5px; margin-top: 12px; }

/* cta + footer */
.cta { padding: 90px 0; }
.cta h2 { font-size: clamp(26px, 3.6vw, 38px); font-weight: 750; margin-bottom: 26px; }
.foot { border-top: 1px solid var(--line); padding: 26px 0; margin-top: 40px; }
.foot-inner { display: flex; justify-content: space-between; align-items: center; color: var(--mute); font-size: 13.5px; flex-wrap: wrap; gap: 12px; }
.foot nav { display: flex; gap: 20px; }
.foot a { color: var(--mute); text-decoration: none; }
.foot a:hover { color: var(--text); }

/* ─────────────────────── motion ───────────────────────
   Sections fade up as they come into view. Nothing here is load-bearing: .reveal only gets its
   start state once JS confirms IntersectionObserver, so with JS off or unsupported the page is
   simply static rather than permanently invisible — which is what a CSS-only version would risk. */
.js-reveal .reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity .55s cubic-bezier(.22,.61,.36,1), transform .55s cubic-bezier(.22,.61,.36,1);
}
.js-reveal .reveal.is-in { opacity: 1; transform: none; }

/* Children stagger so a row of cards arrives as a sequence, not a block. */
.js-reveal .reveal-group > * {
  opacity: 0; transform: translateY(16px);
  transition: opacity .5s cubic-bezier(.22,.61,.36,1), transform .5s cubic-bezier(.22,.61,.36,1);
  transition-delay: calc(var(--i, 0) * 65ms);
}
.js-reveal .reveal-group.is-in > * { opacity: 1; transform: none; }

/* The hero shouldn't fade — it's above the fold and would flash empty on first paint. It gets a
   one-off entrance instead. */
.hero-copy > * { animation: heroUp .6s cubic-bezier(.22,.61,.36,1) backwards; }
.hero-copy > *:nth-child(1) { animation-delay: .04s; }
.hero-copy > *:nth-child(2) { animation-delay: .10s; }
.hero-copy > *:nth-child(3) { animation-delay: .16s; }
.hero-copy > *:nth-child(4) { animation-delay: .22s; }
.hero-copy > *:nth-child(5) { animation-delay: .28s; }
.phone-row .phone { animation: phoneUp .7s cubic-bezier(.22,.61,.36,1) backwards; }
.phone-row .phone:nth-child(1) { animation-delay: .16s; }
.phone-row .phone:nth-child(2) { animation-delay: .08s; }
.phone-row .phone:nth-child(3) { animation-delay: .24s; }

@keyframes heroUp { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes phoneUp { from { opacity: 0; transform: translateY(26px) scale(.96); } }

.btn, .step, .feat, .plan, .faq details { transition: transform .16s ease, border-color .16s ease, background .16s ease; }
.step:hover, .feat:hover { transform: translateY(-3px); border-color: var(--mute); }
.plan:hover { transform: translateY(-3px); }

/* One switch turns all of it off. Everything above is decorative — nothing is the only cue for
   state — so removing it costs the page nothing. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js-reveal .reveal,
  .js-reveal .reveal-group > * { opacity: 1; transform: none; transition: none; }
  .hero-copy > *, .phone-row .phone { animation: none; }
  .step:hover, .feat:hover, .plan:hover { transform: none; }
  .caret { animation: none; }
}

/* ─────────────────────── responsive ───────────────────────
   Four steps: 1000px (hero stacks), 820px (nav collapses), 720px (slide rows become swipeable),
   560px (small phones). Before this the page had two media queries total and went sideways on
   anything narrower than an iPhone SE. */

@media (max-width: 1000px) {
  .hero { grid-template-columns: 1fr; gap: 44px; padding: 56px 24px 64px; }
  .hero-art { order: -1; }
  .lede { font-size: 16.5px; }
  /* Stacked, the art has the full measure, so cap it or three covers stretch to 300px each. */
  .phone-row { max-width: 620px; margin: 0 auto; }
}

@media (max-width: 820px) {
  .nav { gap: 12px; padding: 12px 16px; flex-wrap: wrap; }
  .nav-burger { display: flex; }

  /* The links become a full-width panel under the bar. `order` puts it on its own row below the
     brand and CTAs rather than squeezed between them. */
  .nav-links {
    display: none; order: 3; width: 100%;
    flex-direction: column; gap: 0; margin: 0;
    border-top: 1px solid var(--line);
  }
  .nav-links.is-open { display: flex; }
  .nav-links a { padding: 13px 4px; font-size: 15.5px; border-bottom: 1px solid var(--line); }
  .nav-links > :last-child { border-bottom: 0; }
  .nav-menu-signin {
    display: block; width: 100%; text-align: left;
    padding: 13px 4px; font: inherit; font-size: 15.5px; font-weight: 500;
    background: none; border: 0; border-bottom: 1px solid var(--line);
    color: var(--dim); cursor: pointer;
  }

  .nav-cta { margin-left: auto; }
  .nav-cta .btn, .nav-cta .btn-ghost { padding: 9px 13px; font-size: 13.5px; }

  .band { padding: 56px 0; margin: 56px 0; }
  .cta { padding: 64px 0; }
  .steps, .feats, .plans { margin-top: 32px; }
}

@media (max-width: 720px) {
  /* Slide rows become horizontal snap-scrollers instead of shrinking to thumbnails. A phone has
     no room for five 9:16 covers side by side at any size worth looking at, and this is the one
     section a visitor is here to actually inspect. The partly-visible next card is what tells
     them it scrolls. */
  .examples {
    display: flex; gap: 14px;
    overflow-x: auto; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    /* Bleed to the viewport edges so cards run off-screen rather than stopping at the gutter. */
    margin-inline: -24px; padding: 0 24px 6px;
    scrollbar-width: none;
  }
  .examples::-webkit-scrollbar { display: none; }
  .example { flex: 0 0 62vw; max-width: 280px; scroll-snap-align: start; }

  .phone-row {
    gap: 12px; margin-inline: -24px; padding: 0 24px 4px;
    overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  }
  .phone-row::-webkit-scrollbar { display: none; }
  .phone { flex: 0 0 46vw; max-width: 240px; scroll-snap-align: center; }
  /* The offset/fade on the outer two only reads as depth in a centred trio. In a scrolling row it
     just looks like two broken cards. */
  .phone.ph-1, .phone.ph-3 { transform: none; opacity: 1; }

  .hero { padding: 40px 20px 52px; }
  .hero h1 { font-size: clamp(32px, 8.5vw, 44px); }
  .hero-ticks { gap: 10px 22px; margin-top: 24px; }
  .hero-actions { gap: 12px; margin-top: 26px; }
  .btn-lg { padding: 14px 24px; font-size: 15.5px; }

  .wrap { padding: 0 20px; }
  .band { padding: 48px 0; margin: 48px 0; }
  .steps, .feats, .plans { gap: 14px; }
  .step, .feat { padding: 20px; }
  .plan { padding: 24px 20px; }
}

@media (max-width: 560px) {
  /* On a 320px viewport the old minmax() tracks (290px feats, 268px plans) were wider than the
     content box itself, which forced the whole page to scroll sideways. */
  .steps, .feats, .plans { grid-template-columns: 1fr; }
  .plan-price { font-size: 34px; }

  .nav-cta .btn-ghost { display: none; }   /* "Sign in" also lives in the collapsed menu footer */
  .hero-actions { align-items: stretch; flex-direction: column; }
  .hero-actions .btn { width: 100%; }
  .hero-note { text-align: center; }

  .example { flex-basis: 72vw; }
  .phone { flex-basis: 56vw; }

  .foot-inner { justify-content: center; text-align: center; }
  .foot nav { justify-content: center; flex-wrap: wrap; gap: 12px 18px; }
  .legal { padding: 48px 20px 64px; }
  .legal h1 { font-size: 27px; }
}

/* ───────── modal ───────── */
.modal { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.72); backdrop-filter: blur(6px); display: grid; place-items: center; padding: 20px; }
.modal-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 30px; width: 100%; max-width: 400px; position: relative; }
.modal-x { position: absolute; top: 14px; right: 16px; background: none; border: 0; color: var(--mute); font-size: 26px; line-height: 1; cursor: pointer; }
.modal-x:hover { color: var(--text); }
.modal-card h3 { font-size: 20px; font-weight: 700; }
.modal-sub { color: var(--mute); font-size: 14px; margin-top: 6px; margin-bottom: 22px; }
.modal-card label { display: block; font-size: 12.5px; font-weight: 600; color: var(--dim); margin-bottom: 6px; margin-top: 14px; }
.modal-card input {
  width: 100%; background: var(--bg); border: 1px solid var(--line); border-radius: var(--r);
  padding: 11px 13px; color: var(--text); font: inherit;
}
.modal-card input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(255,107,53,.13); }
.modal-err { color: #ff5f57; font-size: 13.5px; margin-top: 14px; }
.modal-alt { text-align: center; color: var(--mute); font-size: 13.5px; margin-top: 18px; }

/* ───────────── legal + pricing pages ─────────────
   Long-form reading, so the measure is capped near 70ch and the type is a step larger than the
   marketing page. These pages exist partly for payment-provider verification, which means a human
   reviewer reads them top to bottom — clarity beats density. */
.legal { max-width: 760px; margin: 0 auto; padding: 72px 24px 96px; }
.legal h1 { font-size: 34px; line-height: 1.2; margin: 0 0 8px; letter-spacing: -.02em; }
.legal .updated { color: var(--dim); font-size: 14px; margin: 0 0 40px; }
.legal h2 {
  font-size: 19px; margin: 40px 0 12px; letter-spacing: -.01em;
  padding-top: 24px; border-top: 1px solid var(--line);
}
.legal h2:first-of-type { border-top: 0; padding-top: 0; }
.legal h3 { font-size: 15px; margin: 24px 0 8px; }
.legal p, .legal li { color: var(--dim); line-height: 1.7; font-size: 15px; }
.legal p { margin: 0 0 14px; }
.legal ul { margin: 0 0 14px; padding-left: 22px; }
.legal li { margin-bottom: 7px; }
.legal a { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
.legal strong { color: var(--text); font-weight: 600; }
.legal table { width: 100%; border-collapse: collapse; margin: 0 0 18px; font-size: 14px; }
.legal th, .legal td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.legal th { color: var(--text); font-weight: 600; }
.legal td { color: var(--dim); }
/* Wide tables must scroll inside themselves rather than pushing the page sideways on a phone. */
.legal .table-wrap { overflow-x: auto; }

.legal-contact {
  margin-top: 40px; padding: 18px 20px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
}
.legal-contact p:last-child { margin-bottom: 0; }


/* The hero art holds two things now — the fanned slideshow covers and a finished UGC video — so it
   needs to lay them out side by side and wrap on narrow screens. It had no base rule before,
   because it only ever contained one child. */
.hero-art { display: flex; align-items: center; justify-content: center; gap: 26px; flex-wrap: wrap; }

/* ── hero UGC video ──
   Sits beside the slideshow covers so the hero shows BOTH halves of the product. Autoplay only
   works muted, and only inline on iOS — hence both attributes on the element. */
.hero-video { position: relative; flex: 0 0 auto; }
.hero-video video {
  width: 190px; aspect-ratio: 9/16; object-fit: cover; display: block;
  border-radius: 18px; background: #111;
  box-shadow: 0 18px 50px rgba(0,0,0,.45);
}
.hero-video-tag {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: -11px;
  padding: 4px 12px; border-radius: 99px; white-space: nowrap;
  background: var(--accent, #ff6b35); color: #1a0d06;
  font-size: 11px; font-weight: 800; letter-spacing: .03em;
}
@media (max-width: 900px) { .hero-video video { width: 150px; } }
@media (max-width: 620px) { .hero-video video { width: 128px; } }


/* ── UGC examples ──
   Two finished videos under the deck grid, so "Real output" covers both halves of the product
   rather than only the slideshows. */
.ugc-title { margin-top: 54px; }
.ugc-examples { display: flex; gap: 22px; justify-content: center; flex-wrap: wrap; margin-top: 26px; }
.ugc-examples video {
  width: 260px; aspect-ratio: 9/16; object-fit: cover; display: block;
  border-radius: 18px; background: #111; border: 1px solid var(--line);
  box-shadow: 0 16px 44px rgba(0,0,0,.38);
}
@media (max-width: 620px) { .ugc-examples video { width: calc(50% - 11px); min-width: 140px; } }


/* On a phone the hero held a video plus three fanned covers. It wrapped, but wrapping is not the
   same as reading well — the covers shrank to thumbnails and the video lost the prominence it is
   there for. Below 620px the video leads at full size and the covers sit under it, smaller. */
@media (max-width: 620px) {
  .hero-art { gap: 18px; }
  .hero-video video { width: 168px; }
  .hero-art .phone-row { transform: scale(.78); transform-origin: top center; }
}
