/* ==========================================================
   /promo/ — dedicated unlisted ad-landing pages.
   Shared by manual-tester-ai-toolkit.html and manual-to-ai-augmented-qa.html.

   Brand tokens and the .book cover-mockup rules below are copied verbatim
   from qa-guides/index.html's inline <style> (same dark navy / cyan system,
   same guide-cover component) -- not redesigned, per spec. Everything under
   "promo page layout" and "carousel" is new, since neither exists on the
   storefront.
   ========================================================== */

:root {
  --bg-0: #0a1a31;
  --bg-1: #0c2040;
  --bg-2: #0e2549;
  --panel-edge: rgba(120,180,235,.14);
  --cyan: #16c6e6;
  --cyan-2: #00bcd4;
  --cyan-deep: #0a99b8;
  --ink: #ffffff;
  --ink-mute: #92a8c8;
  --ink-dim: #6981a4;
  --line: rgba(255,255,255,.10);
  --bracket: #2c5f93;
  --maxw: 1240px;
  --display: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, Menlo, monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg-0);
  color: var(--ink);
  font-family: var(--display);
  font-size: 16px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
a { color: var(--cyan); text-decoration: none; }
.mono { font-family: var(--mono); }
.wrap { max-width: 560px; margin: 0 auto; padding: 0 24px; }

/* ───────── corner-bracket frame (copied verbatim) ───────── */
.framed { position: relative; }
.framed > .frame {
  position: absolute; inset: 26px; pointer-events: none; z-index: 1;
  --b: var(--bracket); --len: 22px; --w: 2px;
  background:
    linear-gradient(var(--b),var(--b)) left 0 top 0 / var(--len) var(--w) no-repeat,
    linear-gradient(var(--b),var(--b)) left 0 top 0 / var(--w) var(--len) no-repeat,
    linear-gradient(var(--b),var(--b)) right 0 top 0 / var(--len) var(--w) no-repeat,
    linear-gradient(var(--b),var(--b)) right 0 top 0 / var(--w) var(--len) no-repeat,
    linear-gradient(var(--b),var(--b)) left 0 bottom 0 / var(--len) var(--w) no-repeat,
    linear-gradient(var(--b),var(--b)) left 0 bottom 0 / var(--w) var(--len) no-repeat,
    linear-gradient(var(--b),var(--b)) right 0 bottom 0 / var(--len) var(--w) no-repeat,
    linear-gradient(var(--b),var(--b)) right 0 bottom 0 / var(--w) var(--len) no-repeat;
}

/* ───────── book cover mockup (copied verbatim from qa-guides/index.html,
   same classes so the hero cover is pixel-identical to the storefront) ───────── */
.book {
  position: relative; display: flex; flex-direction: column;
  width: 100%; aspect-ratio: 0.76;
  border-radius: 4px;
  padding: 36px 34px 128px;
  color: #fff;
  background:
    radial-gradient(120% 90% at 78% 12%, rgba(40,120,170,.55) 0%, rgba(20,70,115,.2) 38%, transparent 66%),
    linear-gradient(155deg, #1a456c 0%, #143a5f 40%, #0f2a4a 78%, #0c2340 100%);
  box-shadow:
    inset 0 0 0 1px var(--panel-edge),
    0 40px 70px -30px rgba(0,0,0,.7),
    0 18px 36px -22px rgba(0,0,0,.5);
  overflow: hidden;
}
.book .tick {
  position: absolute; inset: 16px; pointer-events: none;
  --b: rgba(22,198,230,.55); --len: 16px; --w: 1.5px;
  background:
    linear-gradient(var(--b),var(--b)) left 0 top 0 / var(--len) var(--w) no-repeat,
    linear-gradient(var(--b),var(--b)) left 0 top 0 / var(--w) var(--len) no-repeat,
    linear-gradient(var(--b),var(--b)) right 0 top 0 / var(--len) var(--w) no-repeat,
    linear-gradient(var(--b),var(--b)) right 0 top 0 / var(--w) var(--len) no-repeat,
    linear-gradient(var(--b),var(--b)) left 0 bottom 0 / var(--len) var(--w) no-repeat,
    linear-gradient(var(--b),var(--b)) left 0 bottom 0 / var(--w) var(--len) no-repeat,
    linear-gradient(var(--b),var(--b)) right 0 bottom 0 / var(--len) var(--w) no-repeat,
    linear-gradient(var(--b),var(--b)) right 0 bottom 0 / var(--w) var(--len) no-repeat;
}
.book .b-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.book .b-pill {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em;
  color: var(--cyan); text-transform: uppercase;
  border: 1px solid rgba(22,198,230,.5); border-radius: 100px;
  padding: 5px 11px;
}
.book .b-edition { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.16em; color: var(--ink-mute); text-transform: uppercase; }
.book .b-top-right { display: flex; align-items: center; gap: 10px; }
.book .b-badge {
  display: flex; align-items: center; gap: 12px; width: fit-content;
  background: rgba(22,198,230,0.09); border: 0.5px solid rgba(22,198,230,0.32);
  border-radius: 5px; padding: 10px 14px; margin: 18px 0 0;
}
.book .b-badge .num {
  width: 40px; height: 40px; flex: none; border-radius: 50%;
  background: var(--cyan); color: #0c2340;
  font-family: var(--display); font-weight: 800; font-size: 19px;
  display: grid; place-items: center; line-height: 1;
}
.book .b-badge .bl { font-family: var(--mono); font-weight: 700; font-size: 9.5px; color: var(--cyan); text-transform: uppercase; letter-spacing: 0.1em; line-height: 1.2; }
.book .b-badge .bs { font-family: var(--mono); font-size: 8.5px; color: rgba(255,255,255,0.55); margin-top: 3px; }
.book .b-pill2 {
  display: inline-block; width: fit-content; margin-top: 16px;
  font-family: var(--mono); font-weight: 700; font-size: 9px; color: var(--cyan);
  border: 0.5px solid var(--cyan); border-radius: 20px; padding: 5px 13px;
  letter-spacing: 0.14em; text-transform: uppercase;
}
.book.step { --cyan: #00BCD4; }
.book.step .tick { --b: rgba(0,188,212,.55); }
.book.step .b-rule { background: linear-gradient(90deg, rgba(0,188,212,.5), rgba(255,255,255,.08)); }
.book.step .b-badge { background: rgba(0,188,212,0.09); border-color: rgba(0,188,212,0.32); }
.book .b-rule { height: 1px; background: linear-gradient(90deg, rgba(22,198,230,.5), rgba(255,255,255,.08)); margin: 16px 0 0; }
.book .b-rule.thin { margin-top: 5px; opacity: .4; }
.book .b-intro { font-style: italic; font-weight: 400; color: #aebfd8; font-size: 22px; margin-top: auto; line-height: 1.2; }
.book .b-title { font-family: var(--display); font-weight: 700; font-size: 39px; line-height: 1.08; letter-spacing: -0.02em; margin-top: 8px; color: #fff; }
.book .b-title .cy { color: var(--cyan); display: block; }
.book .b-feature {
  margin-top: 24px; padding-left: 15px; border-left: 2px solid var(--cyan);
  font-size: 13.5px; line-height: 1.45; color: #c4d2e8;
  display: flex; gap: 9px; max-width: 380px; margin-bottom: auto;
}
.book .b-feature .plus { color: var(--cyan); font-weight: 700; }
.book .b-foot {
  position: absolute; left: 34px; right: 34px; bottom: 28px;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  padding-top: 16px;
}
.book .b-foot::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: rgba(255,255,255,.12); }
.book .b-by .lbl { font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.16em; color: var(--ink-dim); text-transform: uppercase; }
.book .b-by .nm { font-weight: 700; font-size: 15px; color: #fff; margin-top: 4px; }
.book .b-by .rl { font-size: 10.5px; color: var(--ink-mute); margin-top: 2px; }
.book .b-vol { font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.12em; color: var(--ink-dim); text-transform: uppercase; text-align: right; line-height: 1.7; }
.book .b-vol b { color: var(--ink-mute); font-weight: 500; display: block; }

/* ───────── outcome bullets, buy actions (copied verbatim) ───────── */
.path-bullets { list-style: none; margin: 0 0 22px; padding: 0; }
.path-bullets li { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 14px; }
.path-bullets li .plus { color: var(--cyan); font-weight: 700; flex: none; line-height: 1.45; }
.path-bullets .pb-text { display: flex; flex-direction: column; gap: 3px; }
.path-bullets .pb-headline { font-size: 14px; font-weight: 500; color: #fff; line-height: 1.4; }
.path-bullets .pb-sub { font-size: 13.5px; line-height: 1.5; color: #B8C4DC; }
.path-bullets .pb-sub .tech { color: #00BCD4; font-weight: 500; }

.actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-bottom: 4px; }
.instant-pdf { font-family: var(--mono); font-weight: 700; font-size: 14px; letter-spacing: 0.04em; color: var(--cyan); display: flex; align-items: center; gap: 7px; flex-basis: 100%; }
.btn-buy {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--cyan); color: var(--bg-0);
  font-family: var(--mono); font-weight: 700; font-size: 13px;
  letter-spacing: 0.04em; text-transform: uppercase;
  padding: 15px 22px; border-radius: 4px;
  transition: background .15s ease, transform .15s ease;
  width: 100%; justify-content: center;
}
.btn-buy:hover { background: #fff; transform: translateY(-1px); }
.btn-buy .price { opacity: .85; }

/* ───────── promo page layout (new) ─────────
   Carousel is full-width and alone at the top (no text beside it, matching
   the real Gumroad ?layout=profile page), dot indicators overlaid directly
   on the image. Below it, one two-column grid begins: left ~65% normal
   flow (title, copy, TOC), right ~35% normal flow -- explicitly not
   sticky/pinned. align-items:start is what lets the shorter right column
   end on its own content instead of being stretched to match the left. */
/* extra bottom padding reserves room for .promo-sticky-bar below so it
   never overlaps the last real content once it slides into view */
.promo-page { padding: 40px 0 100px; }

/* ───────── sticky bottom bar (new) ─────────
   Hidden by default (translateY past the viewport edge), slides in once
   the main Buy button scrolls out of view (promo.js) and stays reachable
   for the rest of the scroll -- required on mobile since most traffic to
   these pages is mobile, kept on desktop too for consistency. */
.promo-sticky-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
  background: rgba(10,26,49,.94);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-top: 1px solid var(--line);
  padding: 12px 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  transform: translateY(100%);
  transition: transform .25s ease;
}
.promo-sticky-bar.visible { transform: translateY(0); }
.promo-sticky-bar .sb-price { font-family: var(--mono); font-weight: 700; font-size: 15px; color: #fff; flex: none; }
.promo-sticky-bar .btn-buy { width: auto; padding: 12px 20px; flex: none; }

/* min-width:0 overrides the grid item default of min-width:auto -- without
   it, a wide child (the spec table, with unwrapped values like "Claude,
   ChatGPT, Gemini") forces its min-content size onto the shared track,
   which widens the whole single-column mobile layout instead of just
   wrapping that child's text. */
.promo-content-grid {
  display: grid;
  grid-template-areas: "left" "right";
  grid-template-columns: 1fr;
  gap: 8px 0;
}
.body-left { grid-area: left; min-width: 0; }
.body-right { grid-area: right; min-width: 0; }

@media (min-width: 900px) {
  .promo-content-grid {
    grid-template-areas: "left right";
    grid-template-columns: minmax(0, 65%) minmax(0, 1fr);
    align-items: start;
    gap: 0 48px;
  }
}

.price-author-row {
  display: flex; align-items: center; gap: 10px; margin: 0 0 26px;
  font-family: var(--mono); font-size: 12.5px; color: var(--ink-mute);
}
.price-author-row .par-price { color: var(--cyan); font-weight: 700; }
.price-author-row .par-sep { color: var(--ink-dim); }

.promo-copy p { font-size: 15.5px; line-height: 1.65; color: #C4D2E8; margin: 0 0 16px; }
.promo-copy p:last-child { margin-bottom: 0; }

/* purchase card -- accent border draws from the same cyan-tinted border
   treatment already used on .regional-badge/.b-badge elsewhere in this
   design system, not a new visual language */
.promo-purchase-panel {
  border: 1px solid rgba(22,198,230,.35); border-radius: 8px;
  background: linear-gradient(160deg, rgba(22,198,230,.05), transparent 60%);
  padding: 22px; margin: 0 0 28px;
}
.promo-purchase-panel .promo-summary { font-size: 13.5px; line-height: 1.55; color: var(--ink-mute); margin: 0 0 16px; }
.promo-purchase-panel .promo-spec { margin: 0; }

/* buy button -> [instant-pdf, price line, guarantee: a tight reassurance
   group, instant-pdf first since it reads as delivery detail right under
   the CTA] -> boxed spec panel -> FAQ. 28px marks a break between distinct
   blocks (matches .promo-purchase-panel's own margin-bottom below); 10px
   keeps the three closely-related one-line facts feeling like one group
   instead of drifting apart -- the base .instant-pdf rule (shared with
   qa-guides, where it sits inside a flex .actions row) has no bottom
   margin of its own, so it needs one here now that it stands alone. */
.body-right .btn-buy { margin: 0 0 28px; }
/* all three lines share one flex row + fixed-width icon column, so the
   readable text lines up on a common left edge whether or not that line
   has an emoji icon (price-line's is an empty same-width spacer) -- gap
   alone doesn't do this, since an icon glyph's own width still shifts
   where its following text starts relative to a line with no icon. */
.body-right .promo-price-line,
.body-right .promo-guarantee,
.body-right .instant-pdf { display: flex; align-items: center; gap: 8px; text-align: left; justify-content: flex-start; }
.body-right .li-icon { display: inline-flex; align-items: center; justify-content: center; width: 18px; flex: none; }
.body-right .instant-pdf { margin: 0 0 10px; }
.body-right .promo-price-line { margin: 0 0 10px; }
.body-right .promo-guarantee { margin: 0 0 28px; }
.body-right .promo-section-label { margin-top: 4px; }

.promo-headline {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(28px, 5vw, 38px); line-height: 1.12; letter-spacing: -0.02em;
  color: #fff; margin: 0 0 16px; text-wrap: balance;
}
.promo-body { color: var(--ink-mute); font-size: 17px; line-height: 1.6; margin: 0 0 36px; }

.promo-faq { margin: 0 0 36px; }
.faq-item { border-bottom: 1px solid var(--line); padding: 16px 0; }
.faq-item:first-child { border-top: 1px solid var(--line); }
.faq-q { font-weight: 700; font-size: 15px; color: #fff; margin: 0 0 8px; }
.faq-a { font-size: 14.5px; line-height: 1.55; color: var(--ink-mute); margin: 0; }
.faq-a .pending { color: var(--amber, #ffb454); font-style: italic; }

.promo-price-line { text-align: center; font-size: 15px; color: #fff; font-weight: 500; margin: 0 0 12px; }
.promo-price-line .pending { color: var(--amber, #ffb454); font-style: italic; font-weight: 400; }
.promo-guarantee {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  text-align: center; font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em;
  color: var(--cyan); margin: 0 0 18px;
}

/* ───────── real table of contents, pulled from the live product page
   (details/summary -- same collapsible pattern as .concept-trust on
   qa-guides -- so the full real structure is present without making the
   page unscannably long by default) ───────── */
.promo-toc { margin: 0 0 36px; border: 1px solid var(--line); }
.toc-item { border-bottom: 1px solid var(--line); }
.toc-item:last-child { border-bottom: none; }
.toc-item summary {
  cursor: pointer; list-style: none; padding: 14px 16px;
  display: flex; align-items: baseline; gap: 10px; font-weight: 600; font-size: 14px; color: #fff;
}
.toc-item summary::-webkit-details-marker { display: none; }
.toc-item summary .toc-num { font-family: var(--mono); font-size: 11px; color: var(--cyan); flex: none; }
.toc-item summary::after {
  content: "+"; margin-left: auto; color: var(--ink-dim); font-family: var(--mono); font-size: 16px; flex: none;
}
.toc-item[open] summary::after { content: "−"; }
.toc-item .toc-hook { padding: 0 16px 16px 40px; font-size: 13.5px; line-height: 1.55; color: var(--ink-mute); margin: 0; }

/* ───────── spec table, values pulled from the live Gumroad page only ───────── */
.promo-spec { width: 100%; table-layout: fixed; border-collapse: collapse; margin: 0 0 36px; }
.promo-spec td { padding: 10px 4px; border-bottom: 1px solid var(--line); font-size: 13.5px; overflow-wrap: break-word; }
.promo-spec td:first-child { color: var(--ink-dim); font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; width: 38%; }
.promo-spec td:last-child { color: #fff; text-align: right; font-weight: 500; }

.promo-author {
  display: flex; align-items: center; justify-content: flex-start; gap: 18px;
  margin: 0 0 24px; padding: 18px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  text-align: left;
}
.promo-author .lbl { font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.16em; color: var(--ink-dim); text-transform: uppercase; }
.promo-author .nm { font-weight: 700; font-size: 15px; color: #fff; margin-top: 4px; }
.promo-author .rl { font-size: 10.5px; color: var(--ink-mute); margin-top: 2px; }
.promo-author .meta { font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.12em; color: var(--ink-dim); text-transform: uppercase; text-align: right; line-height: 1.7; }
.promo-author .meta b { color: var(--ink-mute); font-weight: 500; display: block; }

.promo-section-label {
  font-family: var(--mono); font-size: 15px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--cyan); margin: 28px 0 16px;
}

.promo-buy { margin-top: 8px; }

/* ───────── image carousel (new) ─────────
   Full-width, alone, at the top of the page -- no text beside it, matching
   the real Gumroad page. Fixed 16:9 frame (confirmed from the real Gumroad
   ?layout=profile HTML) with letterboxed contents, not a container that
   just takes whatever shape the image happens to be -- that's what makes
   it read as "wide" the way Gumroad's does. One slide fills the frame at a
   time; dots and prev/next are overlaid directly on the image instead of
   sitting in a control row below it. */
.promo-carousel-wrap { margin: 0 0 40px; }
.carousel { position: relative; }
.carousel-track {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; border-radius: 6px;
}
.carousel-track::-webkit-scrollbar { display: none; }
.carousel-slide {
  flex: 0 0 100%; width: 100%; aspect-ratio: 1280 / 720;
  scroll-snap-align: start;
  border: 1px solid var(--panel-edge); border-radius: 6px;
  background: var(--bg-1);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
/* letterboxed, not cropped -- a portrait or square preview image keeps its
   own shape inside the wide 16:9 frame instead of being cover-cropped */
.carousel-slide img { width: 100%; height: 100%; object-fit: contain; display: block; }
.carousel-slide .placeholder-box {
  width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  color: var(--ink-dim); font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  background: linear-gradient(160deg, rgba(22,198,230,.06), transparent 60%);
}
.carousel-slide .placeholder-box svg { opacity: .35; }
/* first slide is the real cover -- .book isn't an <img> so object-fit
   doesn't apply to it; letterboxing it inside the wide 16:9 frame means
   keeping its own portrait aspect-ratio and constraining by height (the
   slide's flex centering does the rest), instead of stretching it to fill
   the whole frame the way a plain image would with object-fit:cover. */
.carousel-slide.cover-slide { border: none; background: none; }
.carousel-slide.cover-slide .book { width: auto; height: 100%; aspect-ratio: 0.76; border-radius: 6px; }
.carousel-btn {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  border: 1px solid rgba(255,255,255,.18); background: rgba(10,26,49,.55);
  backdrop-filter: blur(3px); color: #fff;
  display: grid; place-items: center; cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.carousel-btn.prev { left: 10px; }
.carousel-btn.next { right: 10px; }
.carousel-btn:hover { background: rgba(10,26,49,.8); border-color: rgba(22,198,230,.5); }
.carousel-btn:disabled { opacity: .3; cursor: default; }
.carousel-controls { position: absolute; left: 0; right: 0; bottom: 14px; z-index: 2; display: flex; align-items: center; justify-content: center; }
.carousel-dots {
  display: flex; gap: 7px; background: rgba(10,26,49,.55); backdrop-filter: blur(3px);
  border: 1px solid rgba(255,255,255,.14); border-radius: 100px; padding: 6px 9px;
}
.carousel-dots .dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,.35); border: none; padding: 0; cursor: pointer; }
.carousel-dots .dot.active { background: var(--cyan); }

/* ───────── responsive ───────── */
@media (min-width: 900px) {
  /* wide enough for the two-column layout (~65/35 split) to have real
     room -- the narrower single-column .wrap widths above are too tight
     for the right column to sit next to body copy */
  .wrap { max-width: 1080px; }
}
@media (max-width: 420px) {
  .book { aspect-ratio: unset; padding: 26px 26px 108px; }
  .book .b-intro { font-size: 13px; margin-top: 16px; }
  .book .b-title { font-size: 22px; }
  .book .b-feature { font-size: 10px; margin-top: 12px; }
  .book .b-foot { left: 26px; right: 26px; bottom: 24px; }
  .book .b-badge { padding: 7px 10px; margin-top: 12px; }
  .book .b-badge .num { width: 28px; height: 28px; font-size: 13px; }
  .book.step .b-intro { margin-top: 16px; }
}
