/* The Catalyst offer page (/offer)
 *
 * Loaded *after* marketing.css, never instead of it. Everything here is either
 * a component the homepage does not have (the value stack, the fit table, the
 * step rail) or a deliberate override for the offer page's one-decision layout.
 * Tokens, buttons, sections, cards, pricing and the mobile CTA bar all come
 * from marketing.css so the two pages cannot drift apart visually.
 *
 * Class prefix is `offer-` so nothing here can leak onto the homepage if the
 * file is ever loaded there by accident.
 */

/* ── Urgency ribbon ──
   Off unless OFFER_URGENCY_TEXT is set. It sits above the fixed nav, so the
   nav and the hero both get pushed down by --offer-ribbon-h. */
:root { --offer-ribbon-h: 0px; }
body.has-offer-ribbon { --offer-ribbon-h: 40px; }

.offer-ribbon {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 101;
    height: var(--offer-ribbon-h);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 0 16px;
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
    color: #06121f;
    background: linear-gradient(90deg, var(--accent), #7bc0ff);
}
.offer-ribbon a { text-decoration: underline; }
body.has-offer-ribbon .site-nav { top: var(--offer-ribbon-h); }

/* ── Nav: one destination ──
   Hormozi's rule for a landing page is that the header should not be an exit.
   The links are gone; what is left is the mark and the same button as every
   other CTA on the page. */
.offer-nav .nav-actions { margin-left: auto; }
.offer-nav .nav-cta-note {
    display: none;
    font-size: 0.78rem;
    color: var(--text-dim);
    margin-right: 12px;
}
@media (min-width: 900px) {
    .offer-nav .nav-cta-note { display: inline; }
}

/* marketing.css centres section intros only inside .section-education and
   .section-vault, which on the homepage is most of them. Here the sections are
   a different mix, and half-centred/half-left reads as an accident. One rule,
   whole page. */
.offer-page .section-intro {
    max-width: 620px;
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

/* ── Hero ──
   Padding, video width and CTA margins below are all tuned to one constraint:
   the button has to be on screen at 1440x900 without scrolling, with the VSL
   above it. Widen the video and the CTA falls off the fold. */
.offer-hero { padding-top: calc(var(--nav-h) + var(--offer-ribbon-h) + 32px); }
.offer-hero .hero-content { max-width: 860px; }
.offer-callout {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px;
    margin-bottom: 18px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--text);
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}
.offer-hero h1 { max-width: 20ch; }
.offer-hero .hero-subhead { max-width: 54ch; }

/* The VSL. One player exists on this page and this is it, at every width,
   unlike the homepage, which swaps between a hero player and a Vault player. */
.offer-hero-video {
    position: relative;
    max-width: 640px;
    margin: 22px auto 18px;
    border: 1px solid var(--border-light);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--bg-panel);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}
.offer-hero-video wistia-player { display: block; }
/* Top right: the trailer burns its captions in along the bottom left and puts
   its data-point counter bottom right, so a bottom-centre pill sat on the words
   a muted viewer is reading. */
.offer-video-sound {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 16px;
    border: none;
    border-radius: 999px;
    background: rgba(12, 12, 14, 0.9);
    color: var(--text);
    font: 600 0.82rem/1 var(--font);
    cursor: pointer;
}

.offer-cta-stack {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    margin: 18px 0 14px;
}
.offer-cta-stack .btn-primary { min-width: 280px; }
.offer-cta-micro {
    font-size: 0.85rem;
    color: var(--text-dim);
}
.offer-cta-micro strong { color: var(--text-muted); font-weight: 600; }
.offer-walkthrough { margin-top: 4px; }

/* Repeated CTA block. Every major section ends in one, so the page never leaves
   a reader more than a screen or two from the button. */
.offer-cta-block {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    margin-top: 56px;
    text-align: center;
}
.offer-cta-block p {
    color: var(--text-muted);
    font-size: 0.95rem;
    max-width: 44ch;
}

/* ── Proof bar ── */
.offer-proof-bar {
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    background: var(--bg-elevated);
    padding: 22px 0;
}
.offer-proof-bar-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 14px 40px;
}
.offer-proof-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}
.offer-proof-stat b {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: -0.02em;
}
.offer-proof-stat span {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-dim);
}

/* ── Review wall ──
   Explicit columns, not CSS multi-column. Multi-column fills top to bottom
   before moving across and cannot split a card, so the last column ran out
   early and left a card-shaped hole. wall_layout() in whop_reviews.py deals
   the cards into balanced columns server-side and each one is rendered as its
   own flex stack, which puts the bottom edge close to level.

   Card styling is inherited from .review-marquee-card so the wall and the
   homepage marquee cannot drift; only the marquee's fixed width is overridden. */
/* The member before/after leads this section, so it loses the top margin it
   had when it followed the three steps, and gains a gap before the wall. The
   max-width goes too: at 940px against the wall's full container it sat
   visibly inset, which read as two sections rather than one. */
.review-wall-section .member-proof {
    max-width: none;
    margin: 0 0 28px;
}

.review-wall {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 18px;
    align-items: start;
    margin-top: 8px;
}
.review-wall-col {
    display: flex;
    flex-direction: column;
    gap: 18px;
    min-width: 0;
}
.review-wall .review-marquee-card {
    width: auto;
    flex: 0 0 auto;
}
.review-wall-section {
    padding: 88px 0;
    background: linear-gradient(180deg, var(--bg) 0%, var(--bg-elevated) 100%);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.review-wall-more {
    margin-top: 22px;
    text-align: center;
    font-size: 0.92rem;
}
.review-wall-more a {
    color: var(--accent);
    font-weight: 600;
}
.review-wall-more a:hover { text-decoration: underline; }

/* No two-column step. The columns are dealt into three server-side, so a
   two-column grid would wrap the third onto its own row and undo the balance
   that dealing them was for. Three holds down to about 760px, where each
   column is still around 250px, and below that it goes to one. */
@media (max-width: 760px) {
    /* One column, and the column wrappers stop being boxes so every card
       becomes a direct child of the grid and they interleave in dealt order
       rather than running column by column. */
    .review-wall { grid-template-columns: 1fr; }
    .review-wall-col { display: contents; }
    .review-wall-section { padding: 56px 0; }
    /* Eight cards stacked put three thousand pixels between the hero and the
       argument at the width most ad traffic arrives on. wall_layout flags the
       shortest ones, so what survives here is the substantial reviews rather
       than whichever five happened to be dealt first. */
    .review-wall .review-card--overflow { display: none; }
}

/* ── Problem / agitation ── */
.offer-pain-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px;
    max-width: 900px;
    margin: 0 auto;
}
.offer-pain {
    display: flex;
    gap: 14px;
    padding: 22px 24px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-left: 3px solid var(--red);
    border-radius: var(--radius-sm);
}
.offer-pain-mark {
    flex: none;
    color: var(--red);
    font-size: 1.05rem;
    line-height: 1.5;
}
.offer-pain p { color: var(--text-muted); margin-top: 4px; }
.offer-pain strong { color: var(--text); font-weight: 600; }
.offer-pain-turn {
    max-width: 46ch;
    margin: 36px auto 0;
    text-align: center;
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--text);
    line-height: 1.5;
}

/* ── How it works ── */
.offer-steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    counter-reset: offer-step;
}
.offer-step {
    position: relative;
    padding: 30px 26px 26px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.offer-step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin-bottom: 16px;
    border-radius: 50%;
    background: var(--accent-soft);
    border: 1px solid var(--accent);
    color: var(--accent);
    font-family: var(--font-display);
    font-weight: 700;
}
.offer-step h3 { font-family: var(--font-display); font-size: 1.15rem; margin-bottom: 8px; }
.offer-step p { color: var(--text-muted); font-size: 0.97rem; }
.offer-step-time {
    display: inline-block;
    margin-top: 14px;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(74, 222, 128, 0.1);
    color: var(--green);
    font-size: 0.78rem;
    font-weight: 600;
}

/* ── Value stack ──
   The itemised list with a comparable-cost column, a total, and the price
   underneath it. The numbers are estimates of what the pieces cost separately;
   the footnote says so, and it stays. */
.offer-stack {
    max-width: 820px;
    margin: 0 auto;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.offer-stack-head {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 26px;
    background: var(--bg-panel);
    border-bottom: 1px solid var(--border);
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-dim);
}
.offer-stack-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
    padding: 20px 26px;
    border-bottom: 1px solid var(--border);
}
.offer-stack-row:last-of-type { border-bottom: none; }
.offer-stack-item h3 {
    font-family: var(--font-display);
    font-size: 1.02rem;
    font-weight: 700;
    margin-bottom: 4px;
}
.offer-stack-item p { color: var(--text-muted); font-size: 0.93rem; }
.offer-stack-value {
    flex: none;
    font-family: var(--font-mono);
    font-size: 0.95rem;
    color: var(--text-muted);
    white-space: nowrap;
    padding-top: 2px;
}
.offer-stack-row--bonus { background: rgba(74, 158, 255, 0.05); }
.offer-stack-badge {
    display: inline-block;
    margin-bottom: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    background: var(--accent);
    color: #06121f;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.offer-stack-total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
    padding: 22px 26px;
    background: var(--bg-panel);
    border-top: 1px solid var(--border-light);
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1.1rem;
}
.offer-stack-total-value { font-family: var(--font-mono); }

.offer-anchor {
    max-width: 820px;
    margin: 24px auto 0;
    padding: 28px;
    text-align: center;
    background: var(--bg-panel);
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    box-shadow: 0 0 0 6px var(--accent-glow);
}
.offer-anchor-strike {
    color: var(--text-dim);
    text-decoration: line-through;
    font-size: 1rem;
}
.offer-anchor-price {
    display: block;
    margin: 6px 0 4px;
    font-family: var(--font-display);
    font-size: clamp(2rem, 4vw, 2.8rem);
    font-weight: 800;
    letter-spacing: -0.03em;
}
.offer-anchor-note { color: var(--text-muted); font-size: 0.95rem; }
.offer-stack-fine {
    max-width: 820px;
    margin: 16px auto 0;
    color: var(--text-dim);
    font-size: 0.8rem;
    line-height: 1.6;
    text-align: center;
}

/* ── Member proof: one curve, before and after ──
   The two crops come from one screenshot and their shapes do not match: the
   before is wide and short, the after is nearly square. Letting each keep its
   natural height shrank the before to a sliver beside a tall after and left a
   hole under it, which undersells the very chart the comparison depends on.

   So both sit in boxes of equal height with object-fit: contain. Nothing is
   cropped, because cropping a chart changes what the chart appears to say, and
   the letterboxing is invisible: the padding is white and so is the chart. */
.member-proof {
    max-width: 940px;
    margin: 64px auto 0;
    padding: 32px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.member-proof-head { text-align: center; margin-bottom: 26px; }
.member-proof-head h3 {
    font-family: var(--font-display);
    font-size: clamp(1.3rem, 2.6vw, 1.7rem);
    font-weight: 800;
    letter-spacing: -0.02em;
    margin-bottom: 8px;
}
.member-proof-dek { color: var(--text-muted); font-size: 0.97rem; }
.member-proof-pair {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
}
.member-proof-panel {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.member-proof-label {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--text-muted);
}
.member-proof-tag {
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.member-proof-tag--before { background: rgba(248, 113, 113, 0.14); color: var(--red); }
.member-proof-tag--after { background: rgba(74, 222, 128, 0.14); color: var(--green); }
.member-proof-img {
    display: block;
    width: 100%;
    height: 230px;
    object-fit: contain;
    object-position: center;
    background: #fff;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
}
.member-proof-quote {
    max-width: 46ch;
    margin: 26px auto 0;
    text-align: center;
}
.member-proof-quote p {
    font-size: 1.08rem;
    line-height: 1.55;
    color: var(--text);
}
.member-proof-by {
    margin-top: 10px;
    font-size: 0.85rem;
    color: var(--text-dim);
}
.member-proof-disclaimer {
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
    color: var(--text-dim);
    font-size: 0.76rem;
    line-height: 1.6;
    text-align: center;
}
@media (max-width: 768px) {
    .member-proof { padding: 22px 18px; margin-top: 44px; }
    .member-proof-pair { grid-template-columns: 1fr; }
    .member-proof-img { height: 165px; }
}

/* ── Risk reversal ── */
.offer-guarantee {
    max-width: 760px;
    margin: 0 auto;
    padding: 34px 32px;
    text-align: center;
    background: var(--bg-card);
    border: 1px solid var(--green);
    border-radius: var(--radius);
}
.offer-guarantee-icon { color: var(--green); margin-bottom: 12px; }
.offer-guarantee h2 {
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 3vw, 2rem);
    font-weight: 800;
    letter-spacing: -0.02em;
    margin-bottom: 14px;
}
.offer-guarantee p { color: var(--text-muted); margin-bottom: 12px; }
.offer-guarantee p:last-child { margin-bottom: 0; }
.offer-guarantee strong { color: var(--text); }

/* ── Fit / not-fit ── */
.offer-fit {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
    max-width: 940px;
    margin: 0 auto;
}
.offer-fit-col {
    padding: 28px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.offer-fit-col--yes { border-top: 3px solid var(--green); }
.offer-fit-col--no { border-top: 3px solid var(--red); }
.offer-fit-col h3 {
    font-family: var(--font-display);
    font-size: 1.15rem;
    margin-bottom: 16px;
}
.offer-fit-list { list-style: none; display: grid; gap: 12px; }
/* The tick is absolutely positioned rather than a flex sibling. As a flex
   container the li turned every inline child into its own flex item, so an
   <em> mid-sentence became a column of its own and the line broke into three
   ragged stacks. Same technique .pricing-includes uses in marketing.css. */
.offer-fit-list li {
    position: relative;
    padding-left: 22px;
    color: var(--text-muted);
    font-size: 0.97rem;
    line-height: 1.55;
}
.offer-fit-list li::before {
    position: absolute;
    left: 0;
    top: 0;
    font-weight: 700;
}
.offer-fit-col--yes .offer-fit-list li::before { content: '✓'; color: var(--green); }
.offer-fit-col--no .offer-fit-list li::before { content: '✕'; color: var(--red); }

/* ── Mobile ── */
@media (max-width: 900px) {
    .offer-pain-grid,
    .offer-steps,
    .offer-fit { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
    .offer-hero { padding-top: calc(var(--nav-h) + var(--offer-ribbon-h) + 28px); }
    .offer-hero-video { margin: 22px auto 20px; }
    .offer-cta-stack .btn-primary { width: 100%; min-width: 0; }
    .offer-stack-row { flex-direction: column; gap: 6px; }
    .offer-stack-value { padding-top: 0; }
    .offer-stack-head { display: none; }
    .offer-proof-bar-inner { gap: 16px 24px; }
    .offer-proof-stat b { font-size: 1.25rem; }
    /* The sticky bar covers the last ~72px of the page on mobile. */
    .site-footer { padding-bottom: 96px; }
}
