/* WebMage brand tokens.
 *
 * Taken verbatim from the WebMage marketing site (mageweb/css), not invented,
 * so this funnel and webmage.ai look like the same company. If the brand moves,
 * this file is the one place to change.
 */
:root {
  --void: #0C1022;
  --deep: #151B33;
  --deeper: #10152A;
  --rune-teal: #3DF2D3;
  --spell-violet: #7B5CFF;
  --spell-magenta: #E14FFF;
  --hologram: linear-gradient(100deg, var(--rune-teal), var(--spell-violet) 55%, var(--spell-magenta));
  --moonlight: #E8ECFF;
  --mist: #8B93B8;
  --line: rgba(139, 147, 184, 0.18);

  --font-display: "Unbounded", system-ui, sans-serif;
  --font-body: "Sora", system-ui, -apple-system, sans-serif;

  --max-width: 1160px;
  --radius: 14px;

  /* The funnel is a single committed dark world, like the marketing site.
   * Declared explicitly so the page never borrows a host's background. */
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; overflow-x: clip; }

body {
  margin: 0;
  background: var(--void);
  color: var(--moonlight);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1.0625rem;
  line-height: 1.65;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, .display { font-family: var(--font-display); font-weight: 700; line-height: 1.15; text-wrap: balance; }
h1 { font-size: clamp(2rem, 5.2vw, 3.4rem); margin: 0 0 1rem; letter-spacing: -0.02em; }
h2 { font-size: clamp(1.5rem, 3.4vw, 2.3rem); margin: 0 0 1rem; letter-spacing: -0.01em; }
h3 { font-size: 1.15rem; margin: 0 0 .5rem; }
p  { margin: 0 0 1rem; max-width: 65ch; }
a  { color: var(--rune-teal); }

.grad {
  background: var(--hologram);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Layout -------------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--max-width); margin-inline: auto; padding-inline: 20px; }
.narrow { max-width: 720px; }
section { padding-block: clamp(2.75rem, 7vh, 5rem); }
.stack { display: flex; flex-direction: column; gap: 1rem; }
.grid { display: grid; gap: 1.25rem; }
@media (min-width: 760px) { .grid.cols-3 { grid-template-columns: repeat(3, 1fr); } .grid.cols-2 { grid-template-columns: repeat(2, 1fr); } }

/* Surfaces ------------------------------------------------------------ */
.card {
  background: var(--deep);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem;
}
.card.lift { background: var(--deeper); }
.rule { height: 1px; background: var(--line); border: 0; margin-block: 2rem; }

.eyebrow {
  font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--mist); margin: 0 0 .75rem; font-weight: 500;
}

.day-no {
  font-family: var(--font-display); font-size: .8rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--rune-teal);
}

/* Buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--font-display); font-weight: 600; font-size: 1rem;
  padding: 1rem 1.6rem; border-radius: var(--radius); border: 0;
  cursor: pointer; text-decoration: none; width: 100%;
  /* The longest label ("Yes, add the Launch Pack ($99)") wraps on a phone.
     Let it wrap evenly rather than leaving one orphaned word. */
  line-height: 1.3; text-align: center; text-wrap: balance;
  transition: transform .12s ease, filter .12s ease;
}
.btn-primary { background: var(--hologram); color: #0A0E1C; }
.btn-primary:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.07); }
.btn-primary:disabled { opacity: .45; cursor: not-allowed; }
.btn-ghost {
  background: transparent; color: var(--mist);
  border: 1px solid var(--line); font-weight: 400; font-size: .95rem; padding: .8rem 1.2rem;
}
.btn-ghost:hover { color: var(--moonlight); }
.btn:focus-visible, .field input:focus-visible { outline: 2px solid var(--rune-teal); outline-offset: 2px; }

/* Forms --------------------------------------------------------------- */
.field { display: block; margin-bottom: 1rem; }
.field label { display: block; font-size: .88rem; color: var(--mist); margin-bottom: .4rem; }
.field input {
  width: 100%; padding: .85rem 1rem; font: inherit; color: var(--moonlight);
  background: var(--void); border: 1px solid var(--line); border-radius: 10px;
}
.field input::placeholder { color: rgba(139,147,184,.6); }
.field .hint { font-size: .8rem; color: var(--mist); margin-top: .35rem; }

.notice { border-radius: 10px; padding: .85rem 1rem; font-size: .92rem; }
.notice-error { background: rgba(225,79,255,.1); border: 1px solid rgba(225,79,255,.35); color: #FFD9FB; }
.notice-ok { background: rgba(61,242,211,.08); border: 1px solid rgba(61,242,211,.3); color: #CFFFF5; }

/* Lists --------------------------------------------------------------- */
.ticks { list-style: none; padding: 0; margin: 0 0 1rem; }
.ticks li { position: relative; padding-left: 1.6rem; margin-bottom: .55rem; }
.ticks li::before { content: "✦"; position: absolute; left: 0; color: var(--rune-teal); }

.muted { color: var(--mist); }
.small { font-size: .88rem; }
.center { text-align: center; }

/* The price, stated once, plainly. */
.price { font-family: var(--font-display); font-size: 2.6rem; font-weight: 700; }
.price .was { font-size: 1.1rem; color: var(--mist); text-decoration: line-through; margin-right: .5rem; }

/* Two panels: everything to say on the left, the checkout on the right. --
   One column until there is room for two, and the checkout follows the
   reader down the long left-hand side rather than scrolling away. */
.panels { display: grid; gap: 2rem; align-items: start; }
@media (min-width: 980px) {
  .panels { grid-template-columns: minmax(0, 1fr) 400px; gap: 3rem; }
  .panel-side { position: sticky; top: 1.5rem; }
}
.panel-main > :first-child { margin-top: 0; }
.checkout-card { border-color: rgba(61,242,211,.28); }

/* Enrollment progress ------------------------------------------------- */
.progress { background: var(--deeper); border-bottom: 1px solid var(--line); padding-block: 1.15rem; }
.progress-head {
  display: flex; align-items: flex-start; gap: .6rem;
  margin: 0 0 .85rem; max-width: none; font-size: 1rem;
}
.progress-tick {
  flex: none; width: 1.4rem; height: 1.4rem; border-radius: 50%;
  display: grid; place-items: center; font-size: .8rem;
  background: var(--rune-teal); color: #0A0E1C; font-weight: 700;
  margin-top: .15rem;
}
.progress-line {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  margin: .55rem 0 0; max-width: none; font-size: .92rem; color: var(--mist);
}
.progress-pct { font-family: var(--font-display); color: var(--rune-teal); font-variant-numeric: tabular-nums; }
.progress-track { height: 10px; border-radius: 999px; background: rgba(139,147,184,.16); overflow: hidden; }
.progress-fill {
  height: 100%; border-radius: 999px; background: var(--hologram);
  /* Animates up from zero to whatever width the markup already set, so the bar
     reads as filling without JS deciding where it stops. */
  animation: progress-fill 1.1s cubic-bezier(.22,.8,.3,1) both;
}
@keyframes progress-fill { from { width: 0; } }
@media (prefers-reduced-motion: reduce) { .progress-fill { animation: none; } }

/* The claim ----------------------------------------------------------- */
.claim {
  margin-top: 2rem; padding: 1.5rem 1.5rem 1.35rem; border-radius: var(--radius);
  background: var(--deeper); border: 1px solid rgba(61,242,211,.35); text-align: center;
}
.claim-kicker {
  font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--rune-teal); margin: 0 0 .5rem; font-weight: 500; max-width: none;
}
.claim-line {
  font-family: var(--font-display); font-weight: 700; line-height: 1.15;
  font-size: clamp(1.4rem, 4.2vw, 2.1rem); letter-spacing: -0.01em;
  margin: 0 0 .6rem; max-width: none; text-wrap: balance;
}
.claim-sub { color: var(--mist); font-size: .92rem; margin: 0 auto; max-width: 52ch; }

/* The value stack ----------------------------------------------------- */
.stack-list { list-style: none; padding: 0; margin: 0; }
.stack-list li {
  display: grid; grid-template-columns: 1fr auto; gap: .35rem 1rem; align-items: baseline;
  padding-block: .75rem; border-bottom: 1px solid var(--line);
}
.stack-list li:first-child { padding-top: 0; }
.stack-list .what strong { display: block; font-weight: 600; }
.stack-list .what > span { display: block; color: var(--mist); font-size: .85rem; line-height: 1.5; }
.stack-value {
  font-family: var(--font-display); font-size: .95rem; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.stack-list li.hero {
  background: rgba(61,242,211,.06); border-radius: 10px; border-bottom-color: transparent;
  margin-inline: -.6rem; padding-inline: .6rem;
}
.stack-list li.hero strong, .stack-list li.hero .stack-value { color: var(--rune-teal); }
.stack-total {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  font-family: var(--font-display); font-weight: 700; font-size: 1.05rem;
  margin: .9rem 0 0; max-width: none;
}
.stack-total span:last-child { font-variant-numeric: tabular-nums; }

/* Day artwork --------------------------------------------------------- */
/* Full-bleed to the card's edges, which means cancelling the card's own
   padding rather than fighting it. */
.day-art {
  display: block; width: calc(100% + 3rem); aspect-ratio: 16 / 9; object-fit: cover;
  /* height:auto is load-bearing. The height="450" attribute is a presentational
     hint that sets the CSS height, so without this the box is 358x450, portrait,
     and object-fit:cover crops the sides off a landscape image. The attributes
     stay because they are what stops the page reflowing as images arrive. */
  height: auto;
  margin: -1.5rem -1.5rem 1.1rem;
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
  background: var(--void);
}

/* The mascot ---------------------------------------------------------- */
/* Transparent cut-outs, so no plate behind them: just a soft glow so the
   character does not float on a flat panel. */
.mascot {
  display: block; width: 100%; max-width: 160px; aspect-ratio: 1 / 1;
  object-fit: contain; height: auto; margin: 0 auto .5rem;
  background: radial-gradient(closest-side, rgba(123,92,255,.22), transparent 72%);
}
.mascot-sm { max-width: 110px; }
.mascot-start { margin-inline: 0 auto; }

/* Progress through the funnel, so the buyer always knows where they are. */
.steps { display: flex; gap: .5rem; list-style: none; padding: 0; margin: 0 0 1.5rem; font-size: .78rem; color: var(--mist); flex-wrap: wrap; }
.steps li { display: flex; align-items: center; gap: .5rem; }
.steps li[aria-current] { color: var(--rune-teal); }
.steps li + li::before { content: "→"; opacity: .5; }

footer { border-top: 1px solid var(--line); padding-block: 2rem; color: var(--mist); font-size: .85rem; }
footer a { color: var(--mist); }
/* `p { max-width: 65ch }` above caps every paragraph for reading, and a capped
   block with no auto margin hugs the left edge of the centred wrap. So the
   footer paragraphs centre the block, not just the text in it. Charles
   spotted the skew on 2026-10-21. */
footer .wrap > p { margin-inline: auto; }

/* The VSL. The video is 9:16, so the frame is narrow and centred rather than
   full width, and the ratio is on the wrapper so the box never changes height
   as the player loads. */
.vsl {
  position: relative;
  width: 100%;
  max-width: 330px;
  margin: 2.25rem auto 0;
  aspect-ratio: 9 / 16;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--void);
}
.vsl iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }

/* Transparent by design: the whole frame is the unmute target, including the
   player's own controls, until it has been used. */
.vsl-unmute {
  position: absolute;
  inset: 0;
  width: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0 0 1.1rem;
  background: transparent;
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.vsl-unmute[hidden] { display: none; }
.vsl-unmute:focus-visible { outline: 2px solid var(--rune-teal); outline-offset: -4px; }
.vsl-badge {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .5rem .85rem;
  border-radius: 999px;
  background: rgba(10, 14, 28, .74);
  border: 1px solid rgba(232, 236, 255, .22);
  color: var(--moonlight);
  font-size: .85rem;
  font-weight: 600;
  backdrop-filter: blur(3px);
}
.vsl-unmute:hover .vsl-badge { background: rgba(10, 14, 28, .88); }

/* The legal row. Links out to the policies on righttechsoft.com, plus the
   refund policy, which is short enough to live in a dialog rather than a
   page of its own. Deliberately quiet: it has to be present and reachable
   for the ad platforms and the payment provider, not competing with the
   offer. */
.legal-links {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: .4rem 1.1rem; margin: 1rem auto .6rem;
}
.legal-links a { color: var(--mist); text-decoration: underline; text-underline-offset: 2px; }
.legal-links a:hover { color: var(--moonlight); }
.legal-fine { margin: 0 auto; max-width: 54ch; color: var(--mist); opacity: .72; }

dialog.modal {
  max-width: 440px; width: calc(100% - 2rem); padding: 1.4rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--deeper); color: var(--moonlight);
}
dialog.modal::backdrop { background: rgba(5, 8, 18, .72); }
dialog.modal a { color: var(--rune-teal); }
dialog.modal .btn { margin-top: 0; }

[x-cloak] { display: none !important; }

/* The phone-only jump to the checkout. Above 980px the checkout is already
   beside the reader, so a button that scrolls to it would be nonsense. */
.cta-jump { margin-top: 1.5rem; }
@media (min-width: 980px) { .cta-jump { display: none; } }

/* Turnstile renders into this only when the server is checking tokens, and
   in interaction-only mode it stays empty for most visitors. Empty, it takes
   no space; rendered, it gets a little room above the button. */
.turnstile:empty { display: none; }
.turnstile:not(:empty) { margin: .75rem 0 .25rem; }

/* The checkout on the Offers system ---------------------------------- */
/* The honeypot: off-screen for people, present for scripts. */
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
/* Stripe's embedded checkout mounts here; until it does there is nothing to see. */
#checkout:empty { display: none; }
#checkout:not(:empty) { margin-top: 1rem; }
