/* Barecost — committed dark palette. Every colour is painted explicitly so the
   page holds regardless of the visitor's OS theme. */

:root {
  --ink: oklch(0.11 0 0);
  --surface: oklch(0.16 0 0);
  --surface-2: oklch(0.20 0 0);
  --text: oklch(0.98 0 0);
  --muted: oklch(0.74 0 0);
  --dim: oklch(0.56 0 0);
  --lime: oklch(0.87 0.22 128);
  --lime-ink: oklch(0.11 0 0);
  --rule: oklch(0.26 0 0);
  --danger: oklch(0.70 0.19 25);

  --pad: clamp(20px, 5vw, 52px);
  --gap: clamp(14px, 2vw, 20px);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; }

a { color: var(--lime); }

:focus-visible { outline: 2px solid var(--lime); outline-offset: 3px; border-radius: 4px; }

.wrap { max-width: 1200px; margin: 0 auto; padding-inline: var(--pad); }

.display {
  font-family: 'Archivo Black', 'Archivo', sans-serif;
  text-transform: uppercase;
  letter-spacing: -0.04em;
  line-height: 0.95;
  margin: 0;
  text-wrap: balance;
}

.mono { font-family: 'JetBrains Mono', ui-monospace, monospace; font-variant-numeric: tabular-nums; }

/* --- nav ------------------------------------------------------------------ */

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Sticky so the section links stay reachable after you use them. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: oklch(0.11 0 0 / 0.88);
  backdrop-filter: saturate(150%) blur(12px);
  -webkit-backdrop-filter: saturate(150%) blur(12px);
  border-bottom: 1px solid oklch(1 0 0 / 0.07);
}

/* Anchor targets clear the sticky bar instead of hiding behind it. */
#get, #how, #price { scroll-margin-top: 84px; }

.nav { display: flex; align-items: center; gap: 22px; padding-block: 18px; }
.brand { display: flex; align-items: center; gap: 9px; font-family: 'Archivo Black', sans-serif; font-size: 18px; letter-spacing: -0.02em; }
.brand .tick { width: 26px; height: 26px; border-radius: 8px; background: var(--lime); display: grid; place-items: center; flex-shrink: 0; }
.nav .spacer { flex-grow: 1; }
.nav a { color: var(--muted); text-decoration: none; font-size: 14.5px; font-weight: 500; }
.nav a:hover { color: var(--text); }
/* On a phone the nav has no room for the marketing section links, so those go.
   Real page links stay: this rule used to hide every navlink, which stripped
   Studio and Account from the app pages where they are the only navigation
   there is - fine on desktop, and on mobile each page lost the way to the
   other. Anchor links are the ones that scroll this page; the rest go
   somewhere. */
@media (max-width: 720px) {
  .nav .navlink[href^="#"] { display: none; }
}

/* --- buttons -------------------------------------------------------------- */

.btn {
  display: inline-block;
  padding: 16px 32px;
  background: var(--lime);
  color: var(--lime-ink);
  border: 0;
  border-radius: 100px;
  font-family: inherit;
  font-weight: 700;
  font-size: clamp(16px, 2vw, 19px);
  cursor: pointer;
  text-decoration: none;
  min-height: 52px;
}
.btn:hover { filter: brightness(1.08); }
.btn-sm { padding: 11px 22px; font-size: 14px; min-height: 44px; }
.btn-ghost { background: none; color: var(--text); border: 2px solid var(--rule); }

/* --- hero ----------------------------------------------------------------- */

.hero { text-align: center; padding-block: clamp(32px, 6vw, 56px) clamp(28px, 4vw, 40px); }
.hero h1 { font-size: clamp(38px, 8vw, 88px); margin-bottom: 24px; }
.hero h1 .alt { color: var(--lime); }
.hero .sub {
  font-size: clamp(17px, 2.4vw, 22px);
  color: var(--muted);
  max-width: 40ch;
  margin: 0 auto 32px;
  text-wrap: pretty;
}

.pill {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 8px 17px; border: 1.5px solid var(--rule); border-radius: 100px;
  font-size: 13.5px; font-weight: 600; margin-bottom: 26px;
}
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--lime); }

/* --- capture form --------------------------------------------------------- */

.capture { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.capture form { display: flex; gap: 10px; width: min(520px, 100%); }
.capture input {
  flex-grow: 1; min-width: 0;
  padding: 15px 20px; border-radius: 100px;
  border: 1.5px solid var(--rule); background: var(--surface);
  color: var(--text); font-family: inherit; font-size: 16px;
}
.capture input::placeholder { color: var(--dim); }
.capture .note { font-size: 14px; color: var(--dim); }
.capture .msg { font-size: 15px; font-weight: 600; min-height: 22px; }
.capture .msg.ok { color: var(--lime); }
.capture .msg.err { color: var(--danger); }
@media (max-width: 560px) {
  .capture form { flex-direction: column; }
  .capture .btn { width: 100%; }
}

/* --- reel ----------------------------------------------------------------- */

.reel { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 11px; }

/* Never hide clips on small screens. The cheapest ones carry the argument,
   and most of the traffic is mobile - so it scrolls sideways instead. */
@media (max-width: 900px) {
  .reel {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: 10px;
    padding-bottom: 10px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--rule) transparent;
  }
  .reel .clip { flex: 0 0 40%; scroll-snap-align: start; }
  .reel::-webkit-scrollbar { height: 4px; }
  .reel::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 2px; }
}
@media (max-width: 560px) {
  .reel .clip { flex: 0 0 58%; }
}

.clip { position: relative; aspect-ratio: 9 / 16; border-radius: 16px; overflow: hidden; margin: 0; background: oklch(0.18 0 0); }
.clip video { width: 100%; height: 100%; object-fit: cover; display: block; }
.clip .meta {
  position: absolute; inset-inline: 0; bottom: 0; padding: 12px;
  display: flex; flex-direction: column; gap: 3px;
  background: linear-gradient(transparent, oklch(0 0 0 / 0.8));
}
.clip .meta .name { font-size: 11.5px; font-weight: 500; color: oklch(0.85 0 0); }
.clip .meta .cost { font-size: 15px; color: var(--lime); }
.caption { text-align: center; margin-top: 16px; font-size: 13.5px; color: var(--dim); }

/* --- compare -------------------------------------------------------------- */

.band { background: var(--lime); color: var(--lime-ink); padding-block: clamp(48px, 7vw, 72px); }
.band h2 { font-size: clamp(30px, 5.5vw, 54px); text-align: center; margin-bottom: 20px; }
.band-lede {
  text-align: center; font-size: clamp(16px, 2vw, 18px); font-weight: 500;
  max-width: 54ch; margin: 0 auto 40px; opacity: 0.78; text-wrap: pretty;
}
.band-punch {
  text-align: center; font-size: clamp(16px, 2vw, 19px); font-weight: 500;
  max-width: 56ch; margin: 32px auto 0; text-wrap: pretty;
}

/* Price ladder — bar length is proportional to the real charge. */
.ladder { display: flex; flex-direction: column; gap: 12px; max-width: 760px; margin-inline: auto; }
.rung {
  display: grid;
  grid-template-columns: minmax(140px, 1fr) minmax(0, 2.4fr) auto;
  align-items: center; gap: 16px;
}
.rung-model { font-size: 15px; font-weight: 700; white-space: nowrap; }
.rung-spec { font-weight: 500; opacity: 0.6; font-size: 13px; }
.rung-bar { height: 30px; border-radius: 6px; background: oklch(0.11 0 0); display: block; }
.rung-cost { font-size: clamp(18px, 2.6vw, 24px); font-weight: 700; text-align: right; min-width: 4ch; }
@media (max-width: 620px) {
  .rung { grid-template-columns: 1fr auto; gap: 4px 12px; }
  .rung-bar { grid-column: 1 / -1; height: 18px; }
}

.volrow { margin-top: 40px; text-align: center; }
.volrow .headline { font-size: clamp(17px, 2.2vw, 20px); font-weight: 600; margin-bottom: 18px; }
.volrow .chips { display: flex; gap: 9px; justify-content: center; flex-wrap: wrap; }
.chip {
  padding: 11px 22px; border-radius: 100px; border: 0; cursor: pointer;
  font-family: inherit; font-size: 14.5px; font-weight: 600; min-height: 44px;
  background: oklch(0.11 0 0 / 0.12); color: var(--lime-ink);
}
.chip[aria-pressed="true"] { background: var(--ink); color: var(--lime); font-weight: 700; }

/* --- steps ---------------------------------------------------------------- */

.section { padding-block: clamp(48px, 7vw, 76px); }
.section h2 { font-size: clamp(30px, 5.5vw, 54px); text-align: center; margin-bottom: 14px; }
.section .lede { text-align: center; font-size: 18px; color: var(--muted); margin: 0 auto 48px; max-width: 46ch; }

.steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); }
@media (max-width: 820px) { .steps { grid-template-columns: 1fr; } }
.step { padding: clamp(24px, 3vw, 32px); border-radius: 22px; background: var(--surface); display: flex; flex-direction: column; gap: 14px; }
.step .n { font-family: 'Archivo Black', sans-serif; font-size: 46px; color: var(--lime); line-height: 1; letter-spacing: -0.04em; }
.step h3 { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; margin: 0; }
.step p { font-size: 15.5px; color: var(--muted); margin: 0; text-wrap: pretty; }

/* --- pricing -------------------------------------------------------------- */

.counter { display: flex; align-items: center; justify-content: center; gap: 14px; margin-bottom: 40px; flex-wrap: wrap; }
.counter .mono { font-size: 13px; color: var(--lime); }
.counter .track { width: 200px; height: 7px; border-radius: 4px; background: oklch(0.22 0 0); overflow: hidden; }
.counter .fill { height: 100%; background: var(--lime); }

.plans { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap); max-width: 760px; margin-inline: auto; }
@media (max-width: 760px) { .plans { grid-template-columns: 1fr; } }

.plan { padding: 30px; border-radius: 22px; background: var(--surface); display: flex; flex-direction: column; }
.plan.featured { background: var(--surface-2); border: 2px solid var(--lime); }
.plan .head { display: flex; align-items: center; gap: 10px; min-height: 26px; flex-wrap: wrap; }
.plan .name { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.plan .tag { font-size: 10px; letter-spacing: 0.06em; padding: 5px 10px; border-radius: 100px; background: var(--lime); color: var(--lime-ink); font-weight: 700; }
.plan .who { font-size: 14px; color: var(--muted); margin-top: 6px; }
.plan .price { display: flex; align-items: baseline; gap: 11px; margin: 24px 0 6px; }
.plan .price .now { font-family: 'Archivo Black', sans-serif; font-size: 50px; letter-spacing: -0.05em; line-height: 1; }
/* The strike belongs on the number, not on the words "Regular price".
   An earlier rule struck the whole span and a later one shrank it to 13px, so
   between them the line was unreadable. */
.plan .price .was { font-size: 17px; color: oklch(0.72 0 0); }
.plan .price .was .lbl {
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: oklch(0.58 0 0);
}
.plan .price .was s {
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  text-decoration-color: oklch(0.62 0 0);
}
.plan .forever { font-size: 13px; color: var(--dim); margin-bottom: 26px; }
.plan ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; flex-grow: 1; }
.plan li { display: flex; gap: 11px; align-items: flex-start; font-size: 14.5px; color: oklch(0.88 0 0); }
.plan li svg { flex-shrink: 0; margin-top: 3px; }
.plan .btn { margin-top: 26px; width: 100%; text-align: center; }

/* --- faq ------------------------------------------------------------------ */

.faq { background: var(--surface); padding-block: clamp(48px, 7vw, 72px); }
.faq h2 { font-size: clamp(28px, 4.5vw, 46px); margin-bottom: 34px; }
.qa { padding-block: 24px; border-top: 1.5px solid var(--rule); display: grid; grid-template-columns: 310px 1fr; gap: 48px; align-items: start; }
@media (max-width: 820px) { .qa { grid-template-columns: 1fr; gap: 10px; } }
.qa .q { font-size: 18px; font-weight: 700; line-height: 1.4; letter-spacing: -0.015em; }
.qa .a { font-size: 15.5px; line-height: 1.65; color: var(--muted); text-wrap: pretty; }

/* --- close ---------------------------------------------------------------- */

.close { text-align: center; padding-block: clamp(56px, 8vw, 84px); }
.close h2 { font-size: clamp(34px, 6vw, 62px); margin-bottom: 30px; }
.close h2 .alt { color: var(--lime); }
.close .fine { margin-top: 20px; font-size: 14px; color: var(--dim); }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* --- footnotes ------------------------------------------------------------ */

sup { font-size: 0.66em; vertical-align: super; line-height: 0; }
.footnote {
  font-size: 13px;
  line-height: 1.6;
  color: var(--dim);
  max-width: 68ch;
  margin: 10px auto 0;
  text-wrap: pretty;
}
.footnote.centred { text-align: center; }
.band .footnote { color: oklch(0.11 0 0 / 0.62); }
.dim { color: var(--dim); }
.close .fine a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.close .fine a:hover { color: var(--lime); }

/* --- consent -------------------------------------------------------------- */
/* Analytics stay off until this is answered. Accept and reject carry equal
   weight by design — a reject button that is harder to find is not consent. */

.consent {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 200;
  background: var(--surface);
  border-top: 1.5px solid var(--rule);
  padding: 18px var(--pad) calc(18px + env(safe-area-inset-bottom, 0px));
}
.consent[hidden] { display: none; }
.consent-inner {
  max-width: 1200px;
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 28px;
}
.consent-copy { flex-grow: 1; }
.consent-h { font-weight: 700; font-size: 15.5px; margin: 0 0 4px; }
.consent-copy p { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--muted); max-width: 78ch; }
.consent-copy a { color: var(--lime); }
.consent-actions { display: flex; gap: 10px; flex-shrink: 0; }
.consent-actions .btn { white-space: nowrap; }

@media (max-width: 760px) {
  .consent-inner { flex-direction: column; align-items: stretch; gap: 14px; }
  .consent-actions { justify-content: stretch; }
  .consent-actions .btn { flex-grow: 1; text-align: center; }
}

/* --- legal pages ---------------------------------------------------------- */

.legal { max-width: 720px; margin-inline: auto; padding-block: clamp(40px, 6vw, 72px) 96px; }
.legal h1 { font-family: 'Archivo Black', sans-serif; font-size: clamp(32px, 5vw, 46px); letter-spacing: -0.035em; margin: 0 0 10px; text-transform: uppercase; }
.legal .updated { font-size: 14px; color: var(--dim); margin: 0 0 34px; }
.legal h2 { font-size: 19px; font-weight: 700; letter-spacing: -0.015em; margin: 34px 0 10px; }
.legal p, .legal li { font-size: 15.5px; line-height: 1.7; color: var(--muted); }
.legal p { margin: 0 0 14px; }
.legal ul { margin: 0 0 14px; padding-left: 20px; }
.legal li { margin-bottom: 7px; }
.legal strong { color: var(--text); font-weight: 600; }
.legal a { color: var(--lime); }
.legal .back { display: inline-block; margin-bottom: 26px; font-size: 14px; color: var(--muted); text-decoration: none; }
.legal .back:hover { color: var(--lime); }
.legal table { border-collapse: collapse; width: 100%; margin: 0 0 18px; font-size: 14.5px; }
.legal th { text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--dim); padding: 0 12px 8px 0; border-bottom: 1.5px solid var(--rule); }
.legal td { padding: 10px 12px 10px 0; border-bottom: 1px solid var(--rule); color: var(--muted); vertical-align: top; line-height: 1.55; }

/* Site-wide generation status bar.
   Sticky rather than fixed so it never covers content on a short screen, and
   it only exists in the DOM while something is actually running. */
/* Fixed, not sticky. Both this and .topbar were sticky at top:0, so they
   occupied the same offset and the nav sat on top of the bar - all the
   customer saw was a green sliver above the header. The nav is pushed down by
   the bar's measured height instead, which js/progress.js publishes as
   --progress-h so a wrapped line on mobile still fits. */
.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 10px 16px;
  font-size: 14px;
  font-weight: 500;
  background: oklch(0.87 0.22 128);
  color: oklch(0.11 0 0);
}
.progress-bar a {
  color: inherit;
  font-weight: 700;
  text-underline-offset: 3px;
}
.progress-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: oklch(0.11 0 0);
  animation: progress-pulse 1.4s ease-in-out infinite;
}
.progress-dot.done { animation: none; }

@keyframes progress-pulse {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .progress-dot { animation: none; }
}

/* Signed-in dashboard.
   The home page for someone who has already bought. Same type and colour as
   the marketing page so it reads as the same product, not a different app. */
.dash { padding: 46px 0 70px; }
.dash-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 34px;
}
.dash-head .display { font-size: clamp(30px, 5vw, 46px); margin: 6px 0 8px; }
.dash-head .sub { margin: 0; max-width: 52ch; }

.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px;
}
.dash-card {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 20px;
  border: 1px solid oklch(0.26 0 0);
  border-radius: 14px;
  background: oklch(0.14 0 0);
}
.dash-big { font-size: 30px; font-weight: 700; letter-spacing: -0.02em; margin: 0; }
.dash-card .dim { font-size: 13px; line-height: 1.45; }
.dash-card .linkish {
  margin-top: auto;
  padding-top: 8px;
  font-size: 13px;
  color: oklch(0.87 0.22 128);
  text-underline-offset: 3px;
}

.dash-meter {
  height: 5px;
  border-radius: 100px;
  background: oklch(0.24 0 0);
  overflow: hidden;
}
.dash-meter i {
  display: block;
  height: 100%;
  width: 0;
  background: oklch(0.87 0.22 128);
  transition: width 0.4s ease;
}

.dash-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; font-size: 14px; }
.dash-list li { display: flex; align-items: center; gap: 8px; }
.ok-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: oklch(0.87 0.22 128);
  flex: 0 0 auto;
}

.dash-recent { margin-top: 30px; }
.dash-strip {
  display: grid;
  grid-auto-flow: column;
  /* Fixed width, not 1fr. With two clips in a wide container each fr took
     half the page and the panel became a video wall. These are thumbnails. */
  grid-auto-columns: 132px;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 6px;
}
/* Two designs for this card existed at once. The older one made the whole
   figure the video and pinned every span inside it to the bottom-left corner,
   which the newer caption - a date and two buttons, both spans - inherited. So
   the date, Save and Remove were all stacked in the same 8px corner on top of
   the clip. Scoped to the anchor now, which is the only thing that is still a
   video. */
.dash-thumb {
  scroll-snap-align: start;
}
.dash-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.dash-thumb > a span {
  position: absolute;
  left: 8px;
  bottom: 8px;
  padding: 3px 7px;
  border-radius: 6px;
  font-size: 12px;
  background: oklch(0.11 0 0 / 0.82);
  color: oklch(0.98 0 0);
}

@media (max-width: 620px) {
  .dash-head { align-items: flex-start; }
  .dash-head .btn { width: 100%; text-align: center; }
}

/* Only while something is actually running: the bar is out of flow, so the
   page and the nav both step down by exactly its height. */
body.has-progress { padding-top: var(--progress-h, 0px); }
body.has-progress .topbar { top: var(--progress-h, 0px); }

/* [hidden] has to win.
   The default UA rule is `[hidden] { display: none }`, which any later
   display declaration beats on specificity alone - `.btn { display: inline-flex }`
   did, so hiding the buy button for a signed-in customer did nothing visible.
   Every script here hides things by setting .hidden, so this makes that mean
   what it says. */
[hidden] { display: none !important; }

/* Thumbnail caption: when it was made, and what you can do with it. */
.dash-thumb { display: flex; flex-direction: column; gap: 6px; }
.dash-thumb > a {
  position: relative;
  display: block;
  border-radius: 12px;
  overflow: hidden;
  background: oklch(0.16 0 0);
  aspect-ratio: 9 / 16;
}
.dash-thumb figcaption {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 11px;
  line-height: 1.35;
}
.dash-thumb .acts { display: flex; gap: 10px; }
.dash-thumb button {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  color: oklch(0.87 0.22 128);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.dash-thumb .thumb-del { color: oklch(0.58 0 0); }
.dash-thumb .thumb-del:hover { color: oklch(0.7 0.19 25); }
.dash-thumb button:disabled { cursor: default; opacity: 0.6; }

/* The nav button was grey text on a green pill.
   `.nav a` sets the muted link colour and outranks `.btn` on specificity, so
   every button inside the nav lost its own colour. Buttons keep theirs. */
.nav a.btn { color: var(--lime-ink); }
.nav a.btn:hover { color: var(--lime-ink); }

/* The clip reel already scrolls sideways on a phone - what was missing was
   any sign that it does. The hint below is the whole fix; an earlier attempt
   restyled the reel itself and broke it, because the base rule sets
   grid-template-columns and that outranks grid-auto-columns, so all five
   clips were squeezed to 57px and nothing overflowed to scroll. */
.swipe-hint { display: none; }

@media (max-width: 900px) {
  .swipe-hint {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    margin-top: 12px;
    font-size: 13px;
    color: var(--dim);
  }
  .swipe-hint svg { animation: nudge 1.8s ease-in-out infinite; }
}

@keyframes nudge {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(5px); }
}
@media (prefers-reduced-motion: reduce) {
  .swipe-hint svg { animation: none; }
}

/* Planned, not included.
   The pricing page listed four features that did not exist, tick-marked
   alongside the ones that did. Anything unbuilt now reads as unbuilt: greyed,
   with a clock instead of a tick and the words spelled out. A roadmap is fine
   to show; a roadmap printed as a feature list is a misrepresentation. */
.plan li .planned { color: var(--dim); }
.plan li .planned em { font-style: normal; color: oklch(0.52 0 0); }



/* The signed-in dashboard uses .eyebrow, and index.html does not load
   setup.css where it was defined. Same class of bug as the language-model
   section rendering unstyled: correct markup, right rule, wrong file. */
.eyebrow { font-size: 11px; letter-spacing: 0.09em; color: var(--lime); margin: 0; }

/* Made in Barecost. Two up on a desktop, one up on a phone - these are the
   clips that have to look expensive, so they get room rather than being
   shrunk to fit four across. */
.showcase { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 18px; margin-top: 28px; }
.show { margin: 0; border: 1px solid var(--rule); border-radius: 14px; overflow: hidden; background: var(--surface); }
/* Portrait, because that is what the studio makes and what the reel above
   already shows - these are for phones. */
.show video { width: 100%; display: block; aspect-ratio: 9 / 16; object-fit: cover; background: oklch(0.14 0 0); }
.show figcaption { padding: 14px 16px 16px; }
.show-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin: 0; }
.show-genre { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--dim); }
/* One colour for every price. Green for cheap and red for dear reads as safe
   and dangerous, which is not what a price is. */
.show-cost { font-size: 17px; font-weight: 700; color: var(--lime); }
.show-title { font-family: 'Archivo Black', sans-serif; font-size: 19px; margin: 7px 0 3px; }
.show-spec { font-size: 13px; margin: 0; }
.show-prompt { margin-top: 11px; font-size: 13px; }
.show-prompt summary { cursor: pointer; color: var(--dim); }
.show-prompt summary:hover { color: var(--text); }
.show-prompt p { margin: 8px 0 0; color: var(--dim); line-height: 1.55; }


/* Shared by the studio and the account page - both were one long scroll.
   Lives here rather than in app.css because account.html does not load that,
   and a tab strip with no styling is a row of unmarked buttons. */
/* Tabs.
   Four short pages rather than one scroll of 3.6 screens. Two of these
   sections used to sit below the Generate button, so anybody who made a clip
   and stopped scrolling never found out they existed. */
.tabs {
  display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 22px;
  border-bottom: 1px solid var(--rule); padding-bottom: 10px;
}
.tab {
  font: inherit; font-size: 14px; padding: 9px 15px; cursor: pointer;
  border: 1px solid transparent; border-radius: 10px;
  background: transparent; color: var(--dim);
}
.tab:hover { color: var(--text); background: oklch(0.18 0 0); }
.tab[aria-selected="true"] {
  color: oklch(0.11 0 0); background: var(--lime); font-weight: 700;
}
.tab:focus-visible { outline: 2px solid var(--lime); outline-offset: 2px; }
.tab-badge {
  margin-left: 7px; padding: 1px 7px; border-radius: 100px;
  background: oklch(0.28 0 0); color: var(--text); font-size: 11px; font-weight: 700;
}
.tab[aria-selected="true"] .tab-badge { background: oklch(0.11 0 0 / 0.25); color: inherit; }
@media (max-width: 620px) {
  .tabs { gap: 4px; }
  .tab { padding: 8px 11px; font-size: 13px; }
}

/* The film leading the page. One at a time, changing every second day, so the
   homepage is not the same page it was last week without anybody editing it. */
/* --- terms of sale ------------------------------------------------------ */
/* Six short answers rather than a wall of policy. Somebody about to spend
   $49 reads six headings; nobody reads a page of prose. */
.selling-grid { display: grid; gap: 22px 34px; margin-top: 22px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.selling-item h3 { font-size: 15px; margin: 0 0 6px; letter-spacing: -0.01em; }
.selling-item p { font-size: 14px; line-height: 1.55; color: var(--muted); margin: 0 0 6px; }
.selling-item strong { color: var(--fg); }

/* A button that cannot do anything yet should not look like one that can. */
.btn.is-waiting { opacity: 0.75; }
.checkout-note { max-width: 46ch; margin: 14px auto 0; text-align: center;
  font-size: 14px; line-height: 1.5; color: var(--muted); }

/* Consent to immediate delivery. Sits with the prices because that is the
   decision it belongs to, and turns amber rather than red when missed - a
   box somebody has not reached yet is not an error. */
.buy-consent { display: flex; gap: 10px; align-items: flex-start; max-width: 62ch;
  margin: 24px auto 0; padding: 14px 16px; border: 1px solid var(--rule);
  border-radius: 12px; font-size: 14px; line-height: 1.55; color: var(--muted);
  transition: border-color 0.2s, background 0.2s; }
.buy-consent input { margin-top: 3px; flex: none; width: 18px; height: 18px; }
.buy-consent strong { color: var(--fg); }
.buy-consent.needs-tick { border-color: var(--warn, #f5a524);
  background: color-mix(in oklch, var(--warn, #f5a524) 8%, transparent); }

/* --- the takeover -------------------------------------------------------- */
/* One film, full screen, once a day. The clip is portrait, so it keeps its
   own shape over a blurred wash of its own poster rather than being cropped
   to fit a landscape screen. */
/* Scrollable, and centred only while it fits. A short screen - a phone in
   landscape, a laptop with a small window - would otherwise centre content
   taller than the viewport and clip the top and bottom off it, taking the way
   out with them. "safe" centring falls back to start-aligned instead. */
.takeover { position: fixed; inset: 0; z-index: 200; display: grid;
  place-items: safe center; overflow-y: auto; overscroll-behavior: contain;
  background: oklch(0.08 0 0); isolation: isolate; }
.takeover-bg { position: absolute; inset: -8%; z-index: -1;
  background-size: cover; background-position: center;
  filter: blur(64px) saturate(1.2) brightness(0.38); transform: scale(1.12); }
.takeover-inner { display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 380px);
  gap: 44px; align-items: center; padding: 24px; max-width: 860px; }
.takeover video { width: 100%; display: block; aspect-ratio: 9 / 16;
  object-fit: cover; max-height: 74vh; border-radius: 14px;
  box-shadow: 0 30px 90px oklch(0 0 0 / 0.6); }
.takeover-title { font-family: "Archivo Black", sans-serif;
  font-size: clamp(30px, 5vw, 46px); margin: 8px 0 8px; line-height: 1.02; }
.takeover-spec { margin: 0; font-size: 14px; color: var(--dim); }
.takeover-cost { margin-left: 10px; font-size: 20px; font-weight: 700; color: var(--lime); }
.takeover-note { margin: 14px 0 22px; font-size: 14px; line-height: 1.55;
  color: var(--muted); max-width: 34ch; }
/* Big enough to hit without aiming, and away from the video controls. */
.takeover-x { position: absolute; top: 18px; right: 20px; z-index: 2;
  width: 44px; height: 44px; border: 0; border-radius: 50%; cursor: pointer;
  background: oklch(1 0 0 / 0.1); color: oklch(0.98 0 0); font-size: 26px;
  line-height: 1; display: grid; place-items: center; }
.takeover-x:hover { background: oklch(1 0 0 / 0.2); }
.takeover-x:focus-visible { outline: 2px solid var(--lime); outline-offset: 2px; }

@media (max-width: 860px) {
  .takeover-inner { grid-template-columns: 1fr; gap: 20px; justify-items: center;
    text-align: center; padding: 16px; }
  .takeover video { max-width: 220px; max-height: 40vh; }
  .takeover-note { margin-left: auto; margin-right: auto; }
}

/* Not much vertical room: the film gives way to the words and the way out. */
@media (max-height: 700px) {
  .takeover video { max-height: 34vh; }
  .takeover-title { font-size: clamp(22px, 4vw, 30px); }
  .takeover-note { margin: 10px 0 14px; }
}

/* --- read before paying --------------------------------------------------- */
/* Three short lines that would otherwise be discovered after the payment and
   become a refund. It is a dialog rather than fine print because this is the
   moment somebody decides, and it earns the screen. */
.prebuy { position: fixed; inset: 0; z-index: 210; display: grid;
  place-items: safe center; overflow-y: auto; overscroll-behavior: contain;
  background: oklch(0.08 0 0 / 0.86); padding: 24px; }
.prebuy-card { position: relative; width: min(560px, 100%);
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: 18px; padding: 30px 28px 24px; }
.prebuy-h { font-family: "Archivo Black", sans-serif; font-size: 26px;
  margin: 6px 0 6px; letter-spacing: -0.02em; }
.prebuy-sub { margin: 0 0 20px; font-size: 14px; color: var(--muted); }
.prebuy-item { display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 14px; margin-bottom: 8px; border-radius: 12px;
  border: 1px solid transparent; background: oklch(0.14 0 0);
  font-size: 14px; line-height: 1.5; color: var(--muted); cursor: pointer;
  transition: border-color 0.15s, background 0.15s; }
.prebuy-item:hover { background: oklch(0.16 0 0); }
.prebuy-item input { margin-top: 2px; flex: none; width: 18px; height: 18px; cursor: pointer; }
.prebuy-item strong { color: var(--fg); display: block; margin-bottom: 2px; }
/* Unanswered, after they tried to continue. Amber: not an error, just the
   one still waiting. */
.prebuy-item.needs-tick { border-color: var(--warn, #f5a524);
  background: color-mix(in oklch, var(--warn, #f5a524) 9%, transparent); }
.prebuy-legal { font-size: 13px; margin-top: 14px; background: none;
  border: 1px dashed var(--rule); }
.prebuy-msg { margin: 12px 0 0; font-size: 13.5px; color: var(--warn, #f5a524); }
.prebuy-actions { display: flex; gap: 12px; align-items: center;
  justify-content: flex-end; margin-top: 20px; }
.prebuy-x { position: absolute; top: 12px; right: 14px; width: 40px; height: 40px;
  border: 0; border-radius: 50%; background: none; color: var(--muted);
  font-size: 26px; line-height: 1; cursor: pointer; display: grid; place-items: center; }
.prebuy-x:hover { color: var(--fg); background: oklch(1 0 0 / 0.07); }
.prebuy-x:focus-visible { outline: 2px solid var(--lime); outline-offset: 2px; }
@media (max-width: 620px) {
  .prebuy { padding: 12px; }
  .prebuy-card { padding: 26px 18px 18px; }
  .prebuy-actions { flex-direction: column-reverse; align-items: stretch; }
}

/* For the minority sent a code rather than a price. Quiet, but where they
   will look for it: with the prices. */
.havecode { margin: 18px auto 0; font-size: 14px; color: var(--muted); }
.havecode a { color: var(--lime); }
.prebuy-code { margin: 14px 0 0; font-size: 13px; text-align: center; }

/* --- the private mirror --------------------------------------------------- */
/* The test site is identical to the live one by design, which is exactly why
   it has to announce itself. Somebody an hour into a session will otherwise
   not remember which they are looking at. */
.testbanner { position: sticky; top: 0; z-index: 300; margin: 0;
  padding: 7px 16px; text-align: center; font-size: 13px; font-weight: 600;
  background: var(--warn, #f5a524); color: oklch(0.15 0 0); }
.prebuy-sim { margin: 16px 0 4px; padding: 14px 16px; border-radius: 12px;
  border: 1px solid color-mix(in oklch, var(--warn, #f5a524) 45%, transparent);
  background: color-mix(in oklch, var(--warn, #f5a524) 9%, transparent); }
.prebuy-sim-h { margin: 0 0 12px; font-size: 13.5px; line-height: 1.5;
  color: var(--warn, #f5a524); }
.prebuy-sim .field { display: block; }
.prebuy-sim .field span { display: block; margin-bottom: 6px; font-size: 12.5px;
  color: var(--muted); }
.prebuy-sim input { width: 100%; padding: 10px 12px; border-radius: 9px;
  border: 1px solid var(--rule); background: oklch(0.12 0 0); color: inherit;
  font: inherit; font-size: 14px; }

/* Offered to Solo customers on their own dashboard, since the pricing
   section they would otherwise find it in is hidden from them. */
.upgrade-note { margin: 26px 0 0; padding: 20px 22px; border-radius: 14px;
  border: 1px solid var(--rule); background: var(--surface); }
.upgrade-note p { margin: 0 0 8px; font-size: 14.5px; line-height: 1.55; }
.upgrade-note .btn { margin-top: 8px; }
.upgrade-msg { color: var(--warn, #f5a524); font-size: 13.5px; }

.prebuy-signin { margin: 12px 0 0; font-size: 13px; text-align: center; }

/* Who you are, and the way out.
   Defined here rather than only in setup.css because the signed-in home page
   loads neither setup.css nor app.css, and its nav is built by landing.js -
   so an unstyled browser button would appear on the one page that does not
   declare these classes in its own HTML. Same values as setup.css, which
   still wins on the pages that load it. */
.nav .who { font-size: 13.5px; color: var(--dim); }
.nav .linkbtn {
  background: none; border: 0; color: var(--muted); font-family: inherit;
  font-size: 14px; cursor: pointer; padding: 6px 4px; text-decoration: underline;
  text-underline-offset: 2px; min-height: 44px;
}
.nav .linkbtn:hover { color: var(--lime); }

/* On a phone the address is what pushes Sign out off the screen.
   It fits for a short address and does not for a real one: at 375px,
   qa@local.test left the button one pixel inside the viewport and
   bekurtz@gmail.com pushed it 37px past the edge, taking the only way out of
   the site with it. Knowing which account you are in is a convenience;
   leaving is a function, so the address is what goes. */
@media (max-width: 560px) {
  .nav .who { display: none; }
}
