/* gettofu.app homepage styles, shared by index.html and sk.html (TOF-631).
   The host caches by URL: never edit a published file in place. Rename it with
   git mv to the next version number, change that, and point both pages at it. */

/* ========================================
   FONTS
   ======================================== */
/* WOFF2, named by the hash of the source .otf (scripts/fonts-to-woff2.py): half
   the bytes of the OTFs they come from, and a name that changes only when the
   font does, so they ship through the normal deploy and can be cached for a
   year. The .otf files stay in landing/fonts as the source; nothing loads them. */
@font-face {
    font-family: 'Clash Display';
    src: url('../fonts/ClashDisplay-Bold-cbf5670a.woff2') format('woff2');
    font-weight: 700;
    font-display: swap;
}
@font-face {
    font-family: 'Clash Display';
    src: url('../fonts/ClashDisplay-Semibold-e70dce86.woff2') format('woff2');
    font-weight: 600;
    font-display: swap;
}
@font-face {
    font-family: 'General Sans';
    src: url('../fonts/GeneralSans-Regular-f5cfd05c.woff2') format('woff2');
    font-weight: 400;
    font-display: swap;
}
@font-face {
    font-family: 'General Sans';
    src: url('../fonts/GeneralSans-Medium-a4c6067d.woff2') format('woff2');
    font-weight: 500;
    font-display: swap;
}
@font-face {
    font-family: 'General Sans';
    src: url('../fonts/GeneralSans-Semibold-6ad3ed96.woff2') format('woff2');
    font-weight: 600;
    font-display: swap;
}

/* ========================================
   TOKENS
   ======================================== */
:root {
    --primary: #2C6E46;
    --primary-light: rgba(44, 110, 70, 0.08);
    --primary-dark: #1E5233;
    --secondary: #D68C45;
    --tertiary: #FFE8B9;
    --bg: #F6F4EF;
    --bg-warm: #EDE9E0;
    --surface: #FFFFFF;
    --surface-2: #DDD9D0;
    --text: #0F1F0F;
    --text-2: #4A5A4A;
    --white: #FFFFFF;

    --font-display: 'Clash Display', Georgia, serif;
    --font-body: 'General Sans', -apple-system, sans-serif;

    /* Spacing: the app's TofuSpacing scale (xs 4 ... xxxl 48), plus the two
       section gaps the page needs and the app doesn't. */
    --space-xs: 4px; --space-sm: 8px; --space-md: 12px; --space-lg: 16px;
    --space-xl: 24px; --space-xxl: 32px; --space-xxxl: 48px;
    --space-section-sm: 64px; --space-section: 96px;

    /* Motion: linear() approximations of the app's springs. --spring is
       .spring(duration: 0.45, bounce: 0.3) from TofuAnimations.swift, for
       small things; --spring-soft overshoots less, for whole containers. */
    --spring: linear(0, 0.012, 0.047 2.2%, 0.19 4.6%, 0.738 13.4%, 0.95 17.6%, 1.05 21.2%, 1.1 24.6%, 1.108 27.2%, 1.1 30%, 1.064 35.4%, 1.012 44%, 0.99 51.4%, 0.987 58%, 0.998 72%, 1);
    --spring-soft: linear(0, 0.036 1.6%, 0.192 5.4%, 0.506 12.2%, 0.772 19.4%, 0.93 26.2%, 1.012 33%, 1.036 39.2%, 1.03 45.8%, 1.008 58%, 0.998 72%, 1);
    --out: cubic-bezier(0.16, 1, 0.3, 1);

    /* The journey stage's background, one tone per chapter (TOF-630). */
    --tone-oat: #EEE6D6;
    --tone-butter: #F8E4BC;
    --tone-sage: #DCE7DB;
    --tone-peach: #F7D9C4;
}

/* ========================================
   RESET & BASE
   ======================================== */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html {
    scroll-behavior: smooth;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    font-family: var(--font-body);
    color: var(--text);
    background: var(--bg);
    overflow-x: hidden;
}

a { color: var(--primary); text-decoration: none; }
img { max-width: 100%; display: block; }

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 24px;
}

/* ========================================
   SCROLL REVEAL
   ======================================== */
.reveal {
    opacity: 0;
    transform: translateY(40px);
    transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.visible {
    opacity: 1;
    transform: translateY(0);
}

/* ========================================
   NAV
   ======================================== */
.nav {
    position: fixed;
    top: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1000;
    padding: 0 8px 0 24px;
    height: 56px;
    width: calc(100% - 48px);
    max-width: 1100px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(24px);
    -webkit-backdrop-filter: blur(24px);
    border-radius: 100px;
    box-shadow: 0 2px 16px rgba(0,0,0,0.06), 0 0 0 1px rgba(0,0,0,0.03);
    transition: box-shadow 0.3s ease;
}

.nav-logo {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    color: var(--primary);
    letter-spacing: -0.5px;
}

.nav-center { flex: 1; display: flex; align-items: center; justify-content: center; gap: 36px; }
/* In flow, not absolutely centred. Absolute centring took the anchors
   out of the flex row, so the destinations added to the right zone
   rendered straight on top of them. */
.nav-link {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-2);
    transition: color 0.2s;
}
.nav-link:hover { color: var(--text); }

.nav-right {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}
.lang-switcher {
    display: inline-flex;
    align-items: center;
    background: rgba(0, 0, 0, 0.04);
    border-radius: 100px;
    padding: 3px;
    gap: 2px;
}
.lang-option {
    padding: 6px 11px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-2);
    border-radius: 100px;
    text-decoration: none;
    line-height: 1;
    letter-spacing: 0.3px;
    transition: color 0.2s, background 0.2s, box-shadow 0.2s;
}
.lang-option.active {
    background: #fff;
    color: var(--text);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
    cursor: default;
    pointer-events: none;
}
.lang-option:not(.active):hover {
    color: var(--text);
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 14px;
    border: none;
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.btn-primary {
    background: var(--primary);
    color: var(--white);
    padding: 12px 24px;
    border-radius: 100px;
}
.btn-primary:hover {
    background: var(--primary-dark);
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(44, 110, 70, 0.25);
}
/* Apple mark on the App Store CTA. currentColor so it tracks the button's
   text colour; the -1px lifts it into optical centre against the cap height. */
.btn-icon {
    width: 15px;
    height: 15px;
    flex-shrink: 0;
    margin-top: -1px;
}

/* ========================================
   JOURNEY (TOF-630)
   Chapter text on the left carries every word; one pinned stage on the
   right shows the same thing in the app's own UI. The stage is drawn at a
   540 x 640 design size; CSS sizes its box (--fit-w) and the shared
   homepage script scales the drawing to fill it (--s). Each chapter's
   layout is a `.stage[data-step="N"]` rule; timed sequences (the recipe
   counter) live in the script.
   ======================================== */
.journey {
    max-width: 1200px;
    margin: 0 auto;
    padding: 104px 24px 0;          /* clears the fixed nav pill */
    display: flex;
    align-items: flex-start;
    gap: clamp(40px, 6vw, 96px);
    position: relative;
    z-index: 1;
}
.chapters { flex: 1 1 0; min-width: 0; }
.chapter {
    min-height: calc(var(--len, 85) * 1vh);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--space-section-sm);
}
.chapter-hero { min-height: calc(100svh - 104px); padding-block: var(--space-xxxl); }
/* Every chapter after the hero is a stretch of scroll that its stage changes
   are spread over (TOF-633, the Journey section of the shared script): the
   copy holds still near the middle of the screen while the reader scrolls
   through the chapter, then moves on with it. The more a chapter changes, the
   longer it is. */
.chapter:not(.chapter-hero) { justify-content: flex-start; }
.chapter-copy { position: sticky; top: max(120px, 50vh - 170px); }
/* in vh; phones take 15 less, in svh */
#library { --len: 95; }
#kitchen { --len: 110; }
#one-recipe { --len: 85; }
#adapt, #shop { --len: 155; }
#cook, #keep { --len: 125; }
/* The stage stays pinned only while the journey is on screen; room under the
   last chapter keeps it pinned until that chapter's sequence has played.
   Margin, not padding: chapters are border-box with a min-height, so extra
   padding would be absorbed and add nothing, and on phones `.chapters` is
   `display: contents`, so padding there would be ignored too. */
.chapter:last-child { margin-bottom: 40vh; }
.chapter h2, .section-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(30px, 3.3vw, 46px);
    line-height: 1.04;
    letter-spacing: -1px;
    color: var(--text);
    margin: 0 0 var(--space-xl);
    text-wrap: balance;
}
.chapter h2 { max-width: 15ch; }
.section-title { max-width: 24ch; }
.chapter-body, .hero-sub, .section-subtitle {
    font-size: 17px;
    line-height: 1.65;
    color: var(--text-2);
    max-width: 42ch;
}

/* ---- hero copy ---- */
/* Phones show her photo behind the headline. Desktop shows her on the stage,
   which is hidden from assistive tech, so here the photo stays in the page,
   visually hidden, for its description. Same file as the stage's: one download. */
.hero-photo { position: absolute; width: 1px; height: 1px; clip-path: inset(50%); }
.chapter-hero h1 {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(44px, 5.2vw, 74px);
    line-height: 0.98;
    letter-spacing: -2.4px;
    color: var(--text);
    margin: 0 0 var(--space-xl);
    text-wrap: balance;
    animation: rise 0.8s cubic-bezier(0.2, 0.8, 0.3, 1) 0.05s both;
}
/* Slovak headline: smaller and looser so the longer words keep to three lines. */
:where(:lang(sk)) .chapter-hero h1 {
    font-size: clamp(38px, 4.3vw, 62px);
    line-height: 1.0;
    letter-spacing: -1.9px;
}
.chapter-hero h1 em, .about-text blockquote em {
    position: relative;
    font-style: normal;
    color: var(--primary);
    white-space: nowrap;
}
/* the hand-drawn underline under the accent phrase, drawn once on load */
.u-line {
    position: absolute;
    left: -2%;
    bottom: -0.16em;
    width: 104%;
    height: 0.3em;
    overflow: visible;
    pointer-events: none;
}
.u-line path {
    fill: none;
    stroke: var(--secondary);
    stroke-width: 4;
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation: draw 1.1s var(--out) 0.5s forwards;
}
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.hero-sub { animation: rise 0.7s cubic-bezier(0.2, 0.8, 0.3, 1) 0.42s both; }
.hero-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-md);
    margin-top: var(--space-xxl);
    animation: rise 0.7s cubic-bezier(0.2, 0.8, 0.3, 1) 0.54s both;
}
.hero-actions .app-store-link img { height: 56px; }
.hero-actions .android-badge { --badge-h: 56px; }
/* TOF-578: the Android waitlist is a second store-style badge beside
   the App Store one, and the App Store one stays first on every device.
   Built in HTML rather than as an SVG file so it uses the page font and
   localises like any other text. Google's Play badge is a trademark that
   may not be modified, so this uses the CC BY Android robot (attribution
   in the footer). Everything is derived from --badge-h. */
.android-badge {
    --badge-h: 64px;
    display: inline-flex;
    align-items: center;
    gap: calc(var(--badge-h) * 0.11);
    height: var(--badge-h);
    padding: 0 calc(var(--badge-h) * 0.22) 0 calc(var(--badge-h) * 0.18);
    border-radius: calc(var(--badge-h) * 0.165);
    background: #000;
    color: var(--white);
    border: 1px solid #a6a6a6;
    font-family: var(--font-body);
    text-decoration: none;
    cursor: pointer;
    transition: transform 0.2s ease;
}
.android-badge:hover { transform: scale(1.04); text-decoration: none; }
.android-badge-icon { width: calc(var(--badge-h) * 0.47); height: calc(var(--badge-h) * 0.47); fill: #3DDC84; flex-shrink: 0; }
.android-badge-text { display: flex; flex-direction: column; line-height: 1.05; text-align: left; }
.android-badge-text small { font-size: calc(var(--badge-h) * 0.18); font-weight: 500; letter-spacing: 0.01em; opacity: 0.92; }
.android-badge-text strong { font-size: calc(var(--badge-h) * 0.34); font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; }

/* real App Store reviews, above the fold */
.hero-proof {
    margin: var(--space-xxl) 0 0;
    max-width: 30rem;
    animation: rise 0.7s cubic-bezier(0.2, 0.8, 0.3, 1) 0.66s both;
}
.hero-proof-top {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-md);
}
.hero-proof .stars { color: var(--secondary); font-size: 16px; letter-spacing: 3px; }
.hero-proof-src { font-size: 13px; font-weight: 500; color: var(--text-2); }
/* quotes are grid-stacked so swapping one for another can't shift the page */
.hero-quotes { display: grid; }
.hero-quotes blockquote {
    grid-area: 1 / 1;
    margin: 0;
    font-size: 18px;
    font-weight: 500;
    line-height: 1.5;
    color: var(--text);
    opacity: 0;
    /* outgoing quote leaves immediately... */
    transition: opacity 0.32s ease;
}
/* ...and the incoming one waits for it to clear */
.hero-quotes blockquote.is-on {
    opacity: 1;
    transition: opacity 0.38s ease 0.36s;
}

/* ---- the stage ----
   --fit-w is the stage's on-screen width: as big as the height under the nav
   pill (88px) allows once the progress segments above it (30px, with their
   gap) and a margin (32px) are in, at most half the width beside the text,
   never under 0.42 of the design size. Past the design size (540px) it grows
   only while the margin stays 62px, up to 640px (1.19x): on a tall enough
   screen the phone's text reads better (TOF-747), without the stage running
   to the screen's bottom edge. The column is centred in the height left under
   the nav.
   --tone is the chapter's colour: the disc behind the phone paints it, on phones the band. */
.stage-col {
    --fit-w: max(226.8px, min(640px, max(540px, (100svh - 180px) * 540 / 640), (100svh - 150px) * 540 / 640, 50vw));
    --tone: var(--tone-oat);
    flex: none;
    position: sticky;
    top: max(88px, (100svh + 42px - var(--fit-w) * 640 / 540) / 2);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-lg);
    padding-block: var(--space-sm);
}
.stage-fit { width: var(--fit-w); height: calc(var(--fit-w) * 640 / 540); contain: layout size style; }
.stage {
    position: relative;
    width: 540px;
    height: 640px;
    transform: scale(var(--s, 1));
    transform-origin: 0 0;
    border-radius: 32px;
}
/* the photo clips itself; past the hero the phone's shadow and the disc may
   reach past the stage's edge on desktop (phones clip the band, below) */
/* one line per chapter's tone */
.stage-col[data-step="2"] { --tone: var(--tone-sage); }
.stage-col[data-step="3"] { --tone: var(--tone-butter); }
.stage-col[data-step="4"] { --tone: var(--tone-peach); }
.stage-col[data-step="6"], .stage-col[data-step="7"] { --tone: var(--primary); }
/* on a phone's green band the progress segments go white; above the desktop
   stage they sit on the page, so they stay green */
@media (max-width: 699px) {
    .stage-col[data-step="6"], .stage-col[data-step="7"] { --rail: rgba(255, 255, 255, 0.28); --rail-on: var(--white); }
}

/* Nikoleta: the hero; the phone takes the stage after it */
.st-nika {
    position: absolute;
    z-index: 2;
    left: 0;
    top: 0;
    width: 540px;
    height: 640px;
    border-radius: 32px;
    overflow: hidden;
    background: #2B3A2E;
    transition: left 0.85s var(--spring-soft), top 0.85s var(--spring-soft),
                width 0.85s var(--spring-soft), height 0.85s var(--spring-soft),
                border-radius 0.6s var(--out), opacity 0.4s ease;
}
.st-nika img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 26%; }
.st-nika::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(10, 24, 14, 0.74) 0%, rgba(10, 24, 14, 0) 44%);
    transition: opacity 0.4s ease;
}
.stage:not([data-step="0"]) .st-nika { opacity: 0; transform: scale(0.96); }
.st-nika { transition: opacity 0.5s ease, transform 0.8s var(--spring-soft); }
/* the caption leaves the right side to the phone */
.st-nika-cap {
    position: absolute;
    z-index: 3;
    left: 36px;
    right: 226px;
    bottom: 36px;
    color: var(--white);
    transition: opacity 0.25s ease;
}
.st-nika-name { font-family: var(--font-display); font-weight: 700; font-size: 34px; line-height: 1; letter-spacing: -0.5px; }
.st-nika-line { margin-top: var(--space-md); font-size: 14px; line-height: 1.5; color: rgba(255, 255, 255, 0.85); }
.stage:not([data-step="0"]) .st-nika-cap { opacity: 0; }

/* TOF-642, TOF-745: the app beside her, so the hero reads as an app and not a
   cookbook; past the hero the phone is the stage. The app is drawn by
   scripts/landing-phone/build.mjs, styled by assets/phone-v1.css and posed by
   the script below (translate + scale on .st-phone, in stage units): beside
   Nikoleta in the hero, whole and centred after it, and on phones as big as
   reads well, cut off by the band's sheet edge. */
.st-phone {
    position: absolute;
    z-index: 4;
    left: 0;
    top: 0;
    transform-origin: 0 0;
    transform: translate(342.9px, 256.9px) scale(0.62);  /* the hero's pose (pose() in home-v{N}.js), before the script runs */
    transition: transform 0.8s var(--spring-soft);
    will-change: transform;  /* keeps its layer between poses, so the phone isn't re-rastered */
}
/* past the hero, the chapter's tone as a disc behind the phone, as on the Veganuary page */
.st-disc { position: absolute; left: 50px; top: 90px; width: 440px; height: 440px; border-radius: 50%; background: var(--tone); opacity: 0; transform: scale(0.8); transition: opacity 0.5s ease, transform 0.8s var(--spring-soft), background-color 0.8s ease; }
.stage:not([data-step="0"]) .st-disc { opacity: 1; transform: none; }

/* chapter rail under the stage */
/* The rail is the journey's progress: one thin segment per chapter, like
   stories, above the stage (on phones, along the top of the band). The
   chapters read are full and the current one fills as it goes (--p, from the
   shared script). Each segment is a button to its chapter, its label kept as
   the accessible name. */
.stage-rail { order: -1; display: flex; gap: 4px; width: var(--fit-w); }
.stage-rail button { position: relative; flex: 1; height: 14px; padding: 0; border: 0; background: none; font-size: 0; cursor: pointer; }
.stage-rail button::before { content: ""; position: absolute; left: 0; right: 0; top: 5px; height: 3px; border-radius: 2px; background: linear-gradient(to right, var(--rail-on, var(--primary)) calc(var(--p, 0) * 100%), var(--rail, rgba(15, 31, 15, 0.16)) 0); transition: top 0.2s ease, height 0.2s ease; }
.stage-rail button:hover::before { top: 4px; height: 5px; }
.stage-rail button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ---- tablets and half-screen windows: still side by side, smaller type ---- */
@media (max-width: 899px) {
    .journey { gap: 40px; }
    .stage-col { --fit-w: max(226.8px, min(540px, (100svh - 150px) * 540 / 640, 46vw)); }
    .chapter-hero h1 { font-size: clamp(34px, 5.2vw, 46px); letter-spacing: -1.2px; }
    .chapter h2, .section-title { font-size: clamp(26px, 3.6vw, 34px); }
}

/* ---- phones: the stage is the top half of the screen, like the app's own
   screen, and the story is a sheet pulled up under it ---- */
@media (max-width: 699px) {
    /* --band-w: the band's stage width, which the copy's resting place under it needs too */
    .journey { --band-w: max(226.8px, min(100vw, (100svh - 366px) * 540 / 640)); flex-direction: column; align-items: stretch; gap: 0; padding: 88px 16px 0; }
    .chapters { display: contents; }
    .chapter { min-height: calc((var(--len, 85) - 15) * 1svh); justify-content: flex-start; padding-block: var(--space-xl) var(--space-xxxl); }
    /* the copy holds still just under the band's sheet edge (100px of padding + the stage + 12px of edge) */
    .chapter-copy { top: calc(112px + var(--band-w) * 640 / 540); padding-top: var(--space-md); }
    .chapter-hero { order: -2; min-height: 0; padding-block: var(--space-sm) var(--space-xxl); }
    /* a full-width band in the chapter's tone, running up behind the nav pill;
       the stage sits in it, so a short phone letterboxes it without a floating box */
    .stage-col {
        /* full width, unless that leaves under ~230px for the chapter text:
           366px = the 100px top padding + the 36px sheet edge + 230px */
        --fit-w: var(--band-w);
        order: -1;
        top: 0;
        z-index: 10;
        margin-inline: -16px;
        padding: 100px 0 0;             /* the nav pill, then the progress segments */
        gap: 0;
        background-color: var(--tone);
        transition: background-color 0.8s ease;
    }
    .stage { background-color: transparent; border-radius: 0; overflow: hidden; }
    .st-disc { display: none; }  /* the band is the chapter's tone */
    /* the sheet's top edge, with a grab handle: the chapter text scrolls under it */
    .stage-col::after {
        content: "";
        align-self: stretch;
        height: 24px;
        margin-top: -12px;
        border-radius: 22px 22px 0 0;
        background: var(--bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='5'%3E%3Crect width='36' height='5' rx='2.5' fill='%23C9C4B9'/%3E%3C/svg%3E") center 8px no-repeat;
        box-shadow: 0 -10px 24px -14px rgba(15, 31, 15, 0.35);
        position: relative;
        z-index: 2;
    }
    /* the progress segments run along the top of the band */
    .stage-rail { position: absolute; top: 82px; left: 16px; right: 16px; z-index: 3; width: auto; }
    .hero-top {
        position: relative;
        isolation: isolate;
        overflow: hidden;
        min-height: 72svh;
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
        padding: var(--space-xxl) var(--space-xl) var(--space-xl);
        border-radius: 28px;
        color: var(--white);
    }
    .hero-photo { display: block; inset: 0; z-index: -2; width: 100%; height: 100%; clip-path: none; object-fit: cover; object-position: 50% 18%; }
    .hero-top::before { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(to top, rgba(10, 24, 14, 0.88) 0%, rgba(10, 24, 14, 0.55) 46%, rgba(10, 24, 14, 0) 74%); }
    .hero-top h1 { color: var(--white); }
    .hero-top h1 em { color: var(--tertiary); }
    .hero-top .hero-sub { color: rgba(255, 255, 255, 0.88); }
}
@media (max-width: 640px) {
    .chapter-hero h1 { font-size: clamp(34px, 10vw, 44px); letter-spacing: -1px; }
    /* 48px keeps both badges on one row at 390px */
    .hero-actions .app-store-link img { height: 48px; }
    .hero-actions .android-badge { --badge-h: 48px; }
    .hero-quotes blockquote { font-size: 16px; }
}
@media (prefers-reduced-motion: reduce) {
    .chapter-hero h1, .hero-sub, .hero-actions, .hero-proof,
    .stage-col, .stage, .stage *, .stage *::after {
        animation: none !important;
        transition-duration: 0.01ms !important;
        transition-delay: 0s !important;
    }
    .u-line path { animation: none; stroke-dashoffset: 0; }
}

/* ========================================
   ABOUT NIKOLETA
   ======================================== */
.about {
    padding-block: var(--space-section);
    /* fades in from the page's ground and back out over its own padding, so
       nothing of it reaches into the sections around it */
    background: linear-gradient(to bottom, var(--bg), var(--bg-warm) var(--space-section),
                var(--bg-warm) calc(100% - var(--space-section)), var(--bg));
}

.about-content {
    display: grid;
    grid-template-columns: 1fr 1.2fr;
    gap: 80px;
    align-items: center;
}

.about-photo {
    position: relative;
}
.about-photo-frame {
    width: 360px;
    height: 440px;
    border-radius: 32px;
    overflow: hidden;
    box-shadow: 0 32px 64px rgba(26, 45, 26, 0.1);
}
.about-photo-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
}

/* One sentence of Nikoleta's, set big, and one small line under it (TOF-634) */
.about-text { margin: 0; }
.about-text blockquote {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(28px, 3.4vw, 44px);
    line-height: 1.2;
    letter-spacing: -0.5px;
    color: var(--text);
    text-wrap: balance;
    margin: 0 0 28px;
}
.about-meta {
    font-size: 15px;
    color: var(--text-2);
}
.about-meta b {
    font-family: var(--font-display);
    font-weight: 600;
    color: var(--text);
}
.about-meta a {
    color: var(--primary);
    font-weight: 500;
}
.about-meta a:hover { text-decoration: underline; }
/* The quote's last word sits on the hero's hand-drawn underline, drawn when the
   quote scrolls in; the photo settles in with it. */
.about-text .u-line path { animation: none; }
@media (prefers-reduced-motion: no-preference) {
    .about-text.visible .u-line path { animation: draw 1.1s var(--out) 0.45s forwards; }
    .about-photo.reveal { transform: translateY(40px) scale(0.96); }
    .about-photo.reveal.visible { transform: none; }
}
/* Her numbers, counted up by the script the first time they scroll in */
.about-stats {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(3, auto);
    justify-content: start;
    gap: 44px;
    margin: 0 0 32px;
    padding: 0;
}
.about-stats li { display: flex; flex-direction: column; gap: 6px; }
.about-stats b {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(30px, 3.2vw, 46px);
    line-height: 1;
    letter-spacing: -1px;
    color: var(--text);
}
.about-stats span { max-width: 10em; font-size: 14px; line-height: 1.35; color: var(--text-2); }

/* ========================================
   REVIEWS
   ======================================== */
.reviews {
    padding-block: var(--space-section);
    background: var(--bg);
}
.reviews-header {
    margin-bottom: 56px;
}
.reviews-header .section-title { margin-bottom: 24px; }
.reviews-stars {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    transition: opacity 0.2s ease;
}
.reviews-stars:hover { opacity: 0.7; }
.reviews-stars .stars {
    color: var(--secondary);
    font-size: 22px;
    letter-spacing: 3px;
}
.reviews-stars-label {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 15px;
    color: var(--text);
}
.reviews-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
    max-width: 960px;
}
.review-card {
    background: var(--white);
    border-radius: 24px;
    padding: 40px 36px;
    display: flex;
    flex-direction: column;
    gap: 18px;
    transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.review-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 24px 48px rgba(26, 45, 26, 0.08);
}
.review-stars {
    color: var(--secondary);
    font-size: 16px;
    letter-spacing: 3px;
}
.review-card blockquote {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 19px;
    line-height: 1.55;
    letter-spacing: -0.3px;
    color: var(--text);
}
.review-card figcaption {
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 600;
    color: var(--text-2);
    margin-top: auto;
}
/* an odd card out spans the row, so the two columns never end on a lone card */
.review-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
.review-card:last-child:nth-child(odd) blockquote { max-width: 72ch; }

/* ========================================
   PRICING
   ======================================== */
.pricing {
    padding-block: var(--space-section);
    position: relative;
    z-index: 2;
}
.pricing-header {
    margin-bottom: 64px;
}

.pricing-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    max-width: 780px;
}

.pricing-card {
    border-radius: 24px;
    padding: 44px 36px;
    position: relative;
    transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.pricing-card:hover {
    transform: translateY(-4px);
}
.pricing-card.free {
    background: var(--white);
}
.pricing-card.free:hover {
    box-shadow: 0 16px 40px rgba(26, 45, 26, 0.06);
}
.pricing-card.premium {
    background: var(--primary);
    color: var(--white);
    box-shadow: 0 16px 48px rgba(44, 110, 70, 0.2);
}
.pricing-card.premium:hover {
    box-shadow: 0 24px 56px rgba(44, 110, 70, 0.3);
}

.pricing-badge {
    position: absolute;
    top: -12px;
    right: 24px;
    background: var(--secondary);
    color: var(--white);
    font-weight: 600;
    font-size: 12px;
    padding: 6px 16px;
    border-radius: 100px;
    letter-spacing: 0.5px;
}

.pricing-card h3 {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 24px;
    margin-bottom: 8px;
}
.pricing-card .pricing-desc {
    font-size: 14px;
    opacity: 0.6;
    margin-bottom: 32px;
}

.pricing-features {
    list-style: none;
    margin-bottom: 32px;
}
.pricing-features li {
    font-size: 15px;
    padding: 10px 0;
    border-bottom: 1px solid rgba(0,0,0,0.05);
    display: flex;
    align-items: center;
    gap: 12px;
}
.pricing-card.premium .pricing-features li {
    border-bottom-color: rgba(255,255,255,0.12);
}
.pricing-features li::before {
    content: '\2713';
    font-weight: 700;
    font-size: 13px;
    width: 22px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    flex-shrink: 0;
}
.pricing-card.free .pricing-features li::before {
    background: var(--primary-light);
    color: var(--primary);
}
.pricing-card.premium .pricing-features li::before {
    background: rgba(255,255,255,0.15);
    color: var(--white);
}

.pricing-note {
    text-align: left;
    margin-top: 24px;
    font-size: 14px;
    color: var(--text-2);
}

/* ========================================
   FAQ
   ======================================== */
.faq {
    padding-block: var(--space-section);
}
.faq-header {
    margin-bottom: 56px;
}
.faq-list {
    max-width: 680px;
}
.faq-item {
    border-bottom: 1px solid var(--surface-2);
}
.faq-question {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 24px 0;
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 18px;
    color: var(--text);
    text-align: left;
    transition: color 0.2s;
}
.faq-question:hover { color: var(--primary); }
.faq-icon {
    font-size: 20px;
    color: var(--text-2);
    transition: transform 0.3s ease;
    flex-shrink: 0;
}
.faq-item.open .faq-icon {
    transform: rotate(45deg);
}
.faq-answer {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.faq-item.open .faq-answer {
    max-height: 40em;               /* room for the longest answer on a phone */
}
.faq-answer p {
    font-size: 15px;
    line-height: 1.7;
    color: var(--text-2);
    padding-bottom: 24px;
}

/* ========================================
   FINAL CTA
   ======================================== */
.final-cta {
    background: var(--primary);
    border-radius: 32px;
    margin: 0 24px 80px;
    padding: 96px 48px;
    text-align: center;
    position: relative;
    overflow: hidden;
}
.final-cta::before {
    content: '';
    position: absolute;
    width: 700px;
    height: 700px;
    background: radial-gradient(circle, rgba(255,255,255,0.06) 0%, transparent 60%);
    top: -250px;
    right: -150px;
    border-radius: 50%;
}
.final-cta::after {
    content: '';
    position: absolute;
    width: 500px;
    height: 500px;
    background: radial-gradient(circle, rgba(255,255,255,0.04) 0%, transparent 60%);
    bottom: -200px;
    left: -100px;
    border-radius: 50%;
}
/* everything in the box sits above the glows (TOF-643) */
.final-cta > * { position: relative; z-index: 1; }
.final-cta h2 {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(32px, 5vw, 52px);
    color: var(--white);
    margin-bottom: 16px;
    letter-spacing: -1px;
}
.final-cta p {
    font-size: 17px;
    color: rgba(255,255,255,0.7);
    margin-bottom: 40px;
}

/* ========================================
   THE ENDING (TOF-634): after the journey, static sections in its look. The
   headings and body lines are the chapters' own (the shared rules above),
   left-aligned in the same column, no eyebrows, one spacing rhythm.
   ======================================== */
.extras { padding-block: var(--space-section); }

/* scanner + supplements: two small screens in the app's own UI, one line each */
.extras-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xl); max-width: 960px; margin-top: var(--space-xxxl); }
.extra { display: flex; flex-direction: column; gap: var(--space-lg); }
.extra-screen { flex: 1; padding: 28px; border-radius: 28px; background: var(--surface); box-shadow: 0 24px 48px -28px rgba(26, 45, 26, 0.35); }
.extra figcaption { max-width: 36ch; font-size: 17px; line-height: 1.55; color: var(--text-2); }
/* the scanner's result for a vegan product, as ProductDetailView shows it */
.scan-name { font-family: var(--font-display); font-weight: 600; font-size: 22px; line-height: 1.2; text-align: center; color: var(--text); }
.scan-brand { margin-top: var(--space-xs); font-size: 15px; font-weight: 500; text-align: center; color: var(--text-2); }
.scan-verdict { display: flex; flex-direction: column; align-items: center; gap: var(--space-sm); margin-top: var(--space-xl); padding: var(--space-xl); border-radius: 16px; background: var(--primary); color: var(--white); text-align: center; transition: scale 0.6s var(--spring) 0.6s, opacity 0.3s ease 0.6s; }
.scan-verdict svg { width: 34px; height: 34px; fill: currentColor; }
.scan-verdict b { font-family: var(--font-display); font-weight: 600; font-size: 20px; }
.scan-verdict span { font-size: 13px; color: rgba(255, 255, 255, 0.7); }
/* the supplement tracker's rows: B12 taken today, D3 still to take */
.supps-title { margin-bottom: var(--space-sm); font-family: var(--font-display); font-weight: 600; font-size: 20px; color: var(--text); }
.supps-row { display: flex; align-items: center; gap: var(--space-md); margin: 0 -10px; padding: 14px 10px; border-radius: 12px; border-top: 1px solid rgba(15, 31, 15, 0.06); font-size: 16px; color: var(--text); }
.supps-row i { font-style: normal; font-size: 24px; line-height: 1; }
.supps-row span { flex: 1; }
.supps-row.is-taken span { color: var(--text-2); text-decoration: line-through; }
.supps-row svg { flex: none; width: 24px; height: 24px; }
.supps-info { fill: var(--primary); opacity: 0.85; }
.supps-done circle { fill: var(--primary); }
/* both screens play while they're on screen (the shared script); the markup
   rests on the finished state, which is what reduced motion and no script see */
.scan { position: relative; min-height: 292px; padding: 0; overflow: hidden; }
.scan-cam, .scan-result { position: absolute; inset: 0; transition: opacity 0.35s ease; }
.scan-result { padding: 28px; }
/* the camera, as the scanner tab shows it: the pack's barcode, the viewfinder's
   corner brackets pulsing, a scan line sweeping */
.scan-cam { display: grid; place-items: center; background: radial-gradient(120% 90% at 50% 40%, #3f4b40, #1b201c); }
.scan-label { padding: 12px 16px 8px; border-radius: 8px; background: #FBFAF6; rotate: -4deg; box-shadow: 0 12px 26px -12px rgba(0, 0, 0, 0.7); text-align: center; }
.scan-label svg { display: block; width: 190px; height: 70px; fill: #161616; }
.scan-label span { display: block; margin-top: 5px; font-size: 12px; font-weight: 500; line-height: 1; letter-spacing: 2px; color: #222; font-variant-numeric: tabular-nums; }
.scan-frame { position: absolute; left: 50%; top: 50%; width: 76%; aspect-ratio: 1.4; translate: -50% -50%; container-type: size; animation: scan-pulse 2s ease-in-out infinite alternate paused; }
.scan-frame i { position: absolute; width: 36px; height: 36px; border: 2.5px solid rgba(255, 255, 255, 0.8); filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.25)); transition: border-color 0.2s ease; }
.scan-frame i:nth-child(1) { left: 0; top: 0; border-right: 0; border-bottom: 0; border-top-left-radius: 6px; }
.scan-frame i:nth-child(2) { right: 0; top: 0; border-left: 0; border-bottom: 0; border-top-right-radius: 6px; }
.scan-frame i:nth-child(3) { left: 0; bottom: 0; border-right: 0; border-top: 0; border-bottom-left-radius: 6px; }
.scan-frame i:nth-child(4) { right: 0; bottom: 0; border-left: 0; border-top: 0; border-bottom-right-radius: 6px; }
.scan-line { position: absolute; left: 16px; right: 16px; top: 16px; height: 1.5px; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.15), transparent); box-shadow: 0 0 12px rgba(255, 255, 255, 0.3); animation: scan-sweep 1.25s ease-in-out infinite alternate paused; }
@keyframes scan-sweep { to { translate: 0 calc(100cqh - 32px); } }
.extras-grid.is-live .scan:not(.is-found) :is(.scan-frame, .scan-line) { animation-play-state: running; }
@keyframes scan-pulse { to { scale: 1.015; } }
/* caught: the brackets flash green, the camera gives way to the result and
   its verdict springs in, as ProductDetailView's does */
.scan.is-found .scan-frame i { border-color: #7BD49A; }
.scan.is-found .scan-cam { opacity: 0; transition: opacity 0.45s ease 0.25s; }
.scan:not(.is-found) .scan-result { opacity: 0; }
.scan.is-found .scan-result { transition-delay: 0.45s; }
.scan:not(.is-found) .scan-verdict { scale: 0.6; opacity: 0; transition: none; }
/* the tracker: a row ticked off grows for a moment and its name strikes through */
.supps-done, .supps-row.is-taken .supps-todo { display: none; }
.supps-row.is-taken .supps-done { display: block; animation: st-pop 0.45s var(--spring) both; }
.supps-row.is-taken { animation: supps-tick 0.8s ease; }
@keyframes st-pop { from { opacity: 0; scale: 0.85; } }
@keyframes supps-tick { 35% { scale: 1.03; background-color: #E8F1E7; } }
@media (prefers-reduced-motion: reduce) { .scan-frame, .scan-line, .supps-row.is-taken, .supps-row.is-taken .supps-done { animation: none; } }
@media (max-width: 699px) {
    :root { --space-section: var(--space-section-sm); }
    .extras-grid { grid-template-columns: 1fr; }
}

/* ========================================
   FOOTER
   ======================================== */
.footer {
    background: var(--text);
    color: rgba(255,255,255,0.6);
    padding: 64px 0 40px;
}
.footer-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.footer-logo {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 24px;
    color: var(--white);
}

.footer-links {
    display: flex;
    gap: 28px;
}
.footer-links a {
    font-size: 14px;
    color: rgba(255,255,255,0.5);
    transition: color 0.2s;
}
.footer-links a:hover { color: var(--white); }

.footer-legal a { color: inherit; text-decoration: underline; }   /* not colour alone */
.footer-legal {
    text-align: center;
    font-size: 12px;
    color: rgba(255,255,255,0.62);   /* 0.3 failed contrast on the dark footer */
    margin-top: 48px;
    padding-top: 24px;
    border-top: 1px solid rgba(255,255,255,0.06);
}

/* ========================================
   RESPONSIVE
   ======================================== */
@media (max-width: 900px) {

    .about-content {
        grid-template-columns: 1fr;
        text-align: center;
        gap: 48px;
    }
    .about-photo-frame {
        width: 280px;
        height: 340px;
        margin: 0 auto;
    }
    .about-stats { justify-content: center; gap: 22px; }
    .about-stats li { align-items: center; }

    .reviews-grid {
        grid-template-columns: 1fr;
        max-width: 460px;
    }

    .pricing-grid {
        grid-template-columns: 1fr;
        max-width: 400px;
    }

    .footer-inner {
        flex-direction: column;
        gap: 24px;
        text-align: center;
    }
    .footer-links { flex-wrap: wrap; justify-content: center; }

    .nav-center { display: none; }
    .nav { padding: 0 8px 0 20px; }
}

@media (max-width: 480px) {
    /* Nav pill has ~170px for the CTA at 375px — "Download Tofu" doesn't fit
       next to the logo and language switcher, so drop back to "Download". */
    .btn-label-extra { display: none; }
    .final-cta { padding: 64px 24px; margin: 0 16px 64px; border-radius: 24px; }
}

/* App Store download badge */
.app-store-link {
    display: inline-block;
    transition: transform 0.2s ease;
    line-height: 0;
}
.app-store-link:hover {
    transform: scale(1.04);
}
.app-store-link img {
    display: block;
    height: 60px;
    width: auto;
}
.final-cta .app-store-link img { height: 64px; }
.final-cta .store-badges { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 12px; }
.final-cta .android-badge { --badge-h: 64px; }
@media (max-width: 480px) {
    .app-store-link img { height: 52px; }
    .android-badge { --badge-h: 52px; }
    .final-cta .app-store-link img { height: 56px; }
    .final-cta .android-badge { --badge-h: 56px; }
}

/* TOF-538 — the shared CTA motion: a lift, and a sheen that crosses
   once on hover. Matches the app-install buttons on the recipe
   directory so every page behaves the same. */
.btn-primary { position: relative; overflow: hidden;
    transition: transform .18s cubic-bezier(.2,.8,.3,1), box-shadow .18s ease, background .18s ease; }
.btn-primary::after { content: ""; position: absolute; inset: 0; border-radius: inherit;
    pointer-events: none; transform: translateX(-120%);
    background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.30) 50%, transparent 62%); }
.btn-primary:hover::after { transform: translateX(120%); transition: transform .75s ease; }
.btn-primary:active { transform: translateY(0) scale(.985); }
@media (prefers-reduced-motion: reduce) {
    .btn-primary, .btn-primary::after { transition: none; }
    .btn-primary:hover::after { transform: translateX(-120%); }
}

/* TOF-538 — destinations live in the right-hand zone, never among the
   anchors. The left and centre of this nav scroll this page; the right
   is where things that change your context already are, the language
   switcher and the store CTA. Recipes and Guides belong with those.
   Mixing them into .nav-center would give five links that scroll and
   two that navigate, all styled the same, with no way to tell which. */
.nav-dests { display: flex; align-items: center; gap: 22px;
    padding-right: 20px; margin-right: 4px;
    border-right: 1px solid rgba(0,0,0,0.10); }
.nav-dest { font-size: 14px; font-weight: 600; color: var(--text);
    text-decoration: none; white-space: nowrap; transition: color 0.2s; }
.nav-dest:hover { color: var(--primary); }
/* Seven links plus a switcher plus a CTA do not fit a tablet. The
   anchors go first: they only scroll a page you are already on, while
   the destinations are the only route into 290 pages of content. */
@media (max-width: 1100px) { .nav-center { display: none; } }
@media (max-width: 640px) { .nav-dests { display: none; } }

/* the cue to scroll (the journey script adds it): a visitor still on the
   first screen after a moment gets a small arrow; the first scroll puts it away */
.scroll-cue { position: fixed; z-index: 20; left: 50%; bottom: calc(20px + env(safe-area-inset-bottom)); width: 44px; height: 44px; margin-left: -22px; display: grid; place-items: center; border-radius: 50%; background: var(--surface); box-shadow: 0 8px 22px -10px rgba(15, 31, 15, 0.45); color: var(--primary); opacity: 0; translate: 0 10px; pointer-events: none; transition: opacity 0.4s ease, translate 0.5s var(--out); }
.scroll-cue.is-on { opacity: 1; translate: none; }
.scroll-cue svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; animation: cue-bob 1.6s ease-in-out infinite; }
@keyframes cue-bob { 50% { transform: translateY(4px); } }
@media (prefers-reduced-motion: reduce) { .scroll-cue svg { animation: none; } }
/* phones: the badges and the review line fill the bottom centre, so it sits in the corner */
@media (max-width: 699px) { .scroll-cue { left: auto; right: 16px; bottom: calc(12px + env(safe-area-inset-bottom)); margin-left: 0; } }
