/*
 * v4's tour (tour.php links this file right before the section: below the fold, so it never delays the hero's paint).
 *
 * Desktop/landscape (.is-staged, set by tour.php's script): one sticky stage, 100vh, holds the five scenes on top of
 * each other; the track under it gives each scene 110vh of scroll. The script sets --q on each scene (0 → 1, the
 * picture turning from A to B), .is-on on the current one and .is-b once B is in. Scene changes are class-driven
 * transitions, so the copy is never half-transparent when the reader stops scrolling. Without the class (phones,
 * portrait, no JS) every scene is its picture over its copy, in the normal flow.
 *
 * Motion is opacity and transform only, except the wipe and the sheet reveal (clip-path on one layer): no filters, no
 * animated masks. Frame sequences are drawn on a canvas.
 */

/* ---------- the tour ---------- */
.v4-tour {
    --ink: #15171a;
    --ink-2: #33363c;
    --ink-3: #50545c;
    --red-text: #9b1b21;
    --v4-bg: #eef1f6;
    --rail-h: 56px;
    --head: 72px; /* the theme's header once the page is scrolled: fixed, 60 px shrunk, 72 px full */
    position: relative;
    background: var(--v4-bg);
    color: var(--ink);
}
.v4-intro {
    max-width: 1280px;
    box-sizing: border-box;
    margin: 0 auto;
    padding: clamp(56px, 9vh, 104px) 32px clamp(32px, 5vh, 56px);
}
.v4-intro .hv3i-eyebrow {
    margin-bottom: clamp(12px, 1.8vh, 18px);
}
.v4-intro-title,
.v4-close-title {
    max-width: 19em;
    margin: 0;
    font-size: clamp(30px, min(5vh, 3.2vw), 48px);
    font-weight: 800;
    line-height: 1.08;
    letter-spacing: -.03em;
    color: var(--ink);
    text-wrap: balance;
}
.v4-intro-title em,
.v4-title em,
.v4-close-title em {
    display: block;
    font-style: normal;
    color: var(--red);
}
/* in the scenes the whole answer is black (the payoff is often its second line); red stays for the hero, the intro,
 * the close, the numbers, the pills, links and CTAs */
.v4-title em {
    color: var(--ink);
}

/* the five problems as an index: pick yours, jump to its scene */
.v4-index {
    display: grid;
    grid-template-columns: repeat(var(--n), minmax(0, 1fr));
    gap: 12px;
    margin: clamp(24px, 4vh, 40px) 0 0;
    padding: 0;
    list-style: none;
}
.v4-index a {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 6px;
    height: 100%;
    box-sizing: border-box;
    padding: 16px 16px 14px;
    border-radius: 12px;
    background: #fff;
    box-shadow: 0 1px 0 rgba(21, 23, 26, .06), 0 10px 26px -18px rgba(21, 23, 26, .35);
    color: var(--ink);
    text-decoration: none;
    transition: transform .25s var(--ease, ease), box-shadow .25s var(--ease, ease);
}
.v4-index a:hover {
    transform: translateY(-2px);
    box-shadow: 0 1px 0 rgba(21, 23, 26, .06), 0 16px 30px -18px rgba(21, 23, 26, .45);
}
.v4-index a:focus-visible {
    outline: 2px solid var(--red);
    outline-offset: 3px;
}
.v4-thumb {
    display: block;
    flex: none; /* a flex item: without this the card's row height squeezes it */
    aspect-ratio: 4 / 3;
    margin: -6px -6px 12px;
    border-radius: 9px;
    overflow: hidden;
    background: #e4e7ec;
}
.v4-thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .5s var(--ease, ease);
}
.v4-index a:hover .v4-thumb img {
    transform: scale(1.04);
}
.v4-index-t {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 6px;
}
.v4-index b {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .14em;
    color: var(--red-text);
}
.v4-index-t > span {
    flex: 1;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.35;
    text-wrap: balance;
}
.v4-index em {
    font-size: 12px;
    font-style: normal;
    font-weight: 500;
    color: var(--ink-3);
}
.v4-index em::after {
    content: " →";
    color: var(--red-text);
}
@media (max-width: 1100px) {
    .v4-index {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}
@media (max-width: 767px), (max-aspect-ratio: 979/1000) {
    .v4-index {
        grid-template-columns: 1fr;
        gap: 8px;
    }
    /* a row: thumbnail, then the number over the question; the arrow says it is a tap */
    .v4-index a {
        flex-direction: row;
        align-items: center;
        gap: 12px;
        padding: 9px 12px 9px 9px;
    }
    .v4-thumb {
        width: 64px;
        margin: 0;
        border-radius: 7px;
    }
    .v4-index-t {
        flex: 1;
        gap: 2px;
    }
    .v4-index-t > span {
        font-size: 14.5px;
    }
    .v4-index em {
        display: none;
    }
    .v4-index a::after {
        content: "→";
        flex: none;
        font-weight: 600;
        color: var(--red-text);
    }
}

/* one scene: the picture, then the copy (this is the stacked layout; the stage below overrides it) */
.v4-scene {
    --q: 0;
    /* v6: the one focal point every picture, canvas, chip and pointer of the scene uses; split and tall swap it below */
    --opos: var(--pos, 66% 50%);
    position: relative;
    /* v5: a plain anchor jump (phones, portrait: the index and the hero's cards) stops under the theme's header, which is
       60 px once the page has scrolled; the scene's own top padding is the gap */
    scroll-margin-top: 60px;
}
.v4-media {
    position: relative;
    overflow: hidden;
    background: var(--v4-bg);
}
.v4-img,
.v4-img img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}
.v4-img img {
    object-fit: cover;
    object-position: var(--opos, 66% 50%);
}
/* the slow push-in while the reader scrolls: same transform on A and B, so they stay aligned */
.v4-img {
    transform: scale(calc(1 + var(--q) * var(--push, .03)));
    transform-origin: var(--origin, var(--opos, 66% 50%));
}

/* how B arrives, all driven by --q */
.v4-b {
    opacity: 0;
}
/* a moving part (Elastlok's upper plate) would ghost in a long cross-fade, so this one is short */
.v4-fx-fade .v4-b {
    opacity: clamp(0, calc((var(--q) - .3) / .4), 1);
}
/* the line crosses the visible picture (100 % → 35 % of the width) over almost the whole scrub, and the washed
 * left part only in the last few percent, so the picture keeps changing until B */
.v4-fx-wipe {
    --wl: min(calc(35% + (1 - var(--q)) * 65%), calc((1 - var(--q)) * 700%));
}
.v4-fx-wipe .v4-b {
    opacity: 1;
    clip-path: inset(0 0 0 var(--wl));
}
.v4-scan {
    display: none;
}
.v4-fx-wipe .v4-scan {
    display: block;
    position: absolute;
    z-index: 2;
    top: 0;
    bottom: 0;
    left: var(--wl);
    width: 3px;
    margin-left: -1.5px;
    background: var(--red);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .85), 0 0 24px 6px rgba(255, 255, 255, .55);
    opacity: clamp(0, calc(min(var(--q), 1 - var(--q)) * 8), 1);
}
/* the frost: the edges of the frame freeze first (a static mask, only its opacity moves), then the whole frame */
.v4-fx-frost .v4-b {
    opacity: clamp(0, calc((var(--q) - .4) / .6), 1);
}
.v4-fx-frost .v4-b-edge {
    opacity: clamp(0, calc(var(--q) / .5), 1);
    -webkit-mask-image: radial-gradient(ellipse 70% 80% at 64% 52%, transparent 30%, #000 85%);
    mask-image: radial-gradient(ellipse 70% 80% at 64% 52%, transparent 30%, #000 85%);
}
/* a frame sequence (the clip from A to B) drawn on a canvas: shown only on the stage, once every frame is in; then the
 * stills under it stop changing */
.v4-seq {
    display: none;
}
.v4-tour.is-staged .has-seq .v4-seq {
    display: block;
}
.v4-tour.is-staged .has-seq .v4-b,
.v4-tour.is-staged .has-seq .v4-scan {
    visibility: hidden;
}
/* labels pinned over the frame (ExDroid's four spools), placed by the script; the name always, what the print did once
 * B is in. Only on the stage; phones get the same four as a list under the heading. */
.v4-pins {
    display: none;
    z-index: 4;
    pointer-events: none;
}
.v4-tour.is-staged .v4-pins {
    display: block;
}
/* on the stage the pins say it; the list stays for screen readers */
.v4-tour.is-staged .v4-compact .v4-four {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
/* one chip per spool: the name; with B, what the print just did appears above it, inside the same chip. Pinned at its
 * bottom centre; the script nudges a chip that would cross the content edge (LUX). */
.v4-pin {
    position: absolute;
    display: flex;
    flex-direction: column-reverse;
    align-items: center;
    width: max-content;
    max-width: clamp(140px, 9.5vw, 190px);
    padding: 6px 12px 5px;
    border-radius: 12px;
    background: rgba(21, 23, 26, .84);
    box-shadow: 0 10px 26px -14px rgba(21, 23, 26, .55);
    color: #fff;
    text-align: center;
    transform: translate(-50%, -100%);
    translate: var(--nudge, 0px) var(--nudge-y, 0px); /* --nudge-y: kept below the header (tour.php placePins) */
}
.v4-pin b {
    display: block;
    font-size: clamp(11.5px, .62vw, 14px);
    font-weight: 700;
    letter-spacing: .14em;
    line-height: 1.4;
}
.v4-pin i {
    display: block;
    max-height: 0;
    overflow: hidden;
    font-size: clamp(12.5px, .7vw, 15.5px);
    font-style: normal;
    font-weight: 500;
    line-height: 1.3;
    color: #e9ecf1;
    opacity: 0;
    transition: max-height .45s var(--ease, ease), opacity .4s var(--ease, ease), margin .45s var(--ease, ease);
}
.is-b .v4-pin i,
.v4-pin.is-measuring i {
    max-height: 4.6em; /* 3 lines: a longer text typed in the admin grows the chip instead of being cut off (was 3.2em) */
    margin-bottom: 4px;
    opacity: 1;
}
.v4-pin.is-measuring i {
    transition: none;
}
/* pointers: an arrow on one side (l, r) or under the text (d, the chip sits above its point) */
.v4-mark {
    position: absolute;
    z-index: 4;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 13px 7px 10px;
    border-radius: 999px;
    background: rgba(21, 23, 26, .82);
    color: #fff;
    font-size: clamp(12.5px, .72vw, 15px);
    font-weight: 600;
    white-space: nowrap;
    transform: translateY(-50%);
    translate: var(--nudge, 0px) 0;
    opacity: clamp(0, calc(1 - var(--q) * 4), 1);
}
.v4-mark::before {
    content: "←";
    font-weight: 700;
    color: #ffb4a8;
}
.v4-mark--r {
    transform: translate(-100%, -50%);
}
.v4-mark--r::before,
.v4-mark--d::before {
    content: none;
}
.v4-mark--r::after {
    content: "→";
    font-weight: 700;
    color: #ffb4a8;
}
.v4-mark--d {
    padding: 7px 13px;
    transform: translate(-50%, calc(-100% - 12px));
}
.v4-mark--d::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 100%;
    width: 2px;
    height: 12px;
    margin-left: -1px;
    background: #fff;
    box-shadow: 0 0 0 1px rgba(21, 23, 26, .35);
}
.v4-mark--at-b {
    opacity: clamp(0, calc((var(--q) - .78) * 5), 1);
}
.v4-marks {
    z-index: 4;
    pointer-events: none;
}
/* a scene whose picture starts further left (ExDroid): a narrower column, same type */
.v4-tour.is-staged .v4-compact .v4-copy > * {
    max-width: min(440px, 34vw);
}
.v4-tour.is-staged .v4-compact .v4-copy > .v4-title {
    max-width: min(600px, 40vw);
}
/* a saturated picture (the thermal frames): a longer, denser wash, so even the red accent keeps ≥ 3:1 under the copy;
 * it ends before the joint (at ~58 % of the frame) */
.v4-tour.is-staged .v4-wash-strong .v4-media::after {
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .8) 0, rgba(238, 241, 246, 0) 120px),
        linear-gradient(90deg, rgba(238, 241, 246, .97) 0%, rgba(238, 241, 246, .94) 36%, rgba(238, 241, 246, .8) 45%, rgba(238, 241, 246, .3) 52%, rgba(238, 241, 246, 0) 56%);
}
/* the light goes out, then the prints show their trick */
.v4-fx-dim .v4-b {
    opacity: var(--q);
}

/* the copy */
.v4-copy {
    box-sizing: border-box;
}
.v4-eyebrow {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 0 clamp(14px, 2.2vh, 22px);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--red-text);
}
.v4-eyebrow {
    flex-wrap: wrap;
    row-gap: 8px;
}
/* the offer, next to the brand: solid red, as heavy as the brand name (white on #BF2026 ≈ 6.1:1) */
.v4-pl {
    display: inline-flex;
    align-items: center;
    margin-left: 4px;
    padding: 5px 11px 4px;
    border-radius: 999px;
    background: var(--red);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .1em;
    line-height: 1.3;
    white-space: nowrap;
}
.v4-num {
    flex: none;
    padding-right: 12px;
    border-right: 1.5px solid currentColor;
    letter-spacing: .06em;
    font-variant-numeric: tabular-nums;
}
/* the buyer's question: big enough to land before the answer, lighter than it */
.v4-problem {
    margin: 0 0 clamp(8px, 1.4vh, 14px);
    font-size: clamp(20px, min(2.9vh, 2vw), 32px);
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -.012em;
    color: var(--ink-3);
    text-wrap: balance;
}
.v4-title {
    margin: 0 0 clamp(14px, 2.2vh, 22px);
    font-size: clamp(30px, min(5.2vh, 3.3vw), 60px);
    font-weight: 800;
    line-height: 1.06;
    letter-spacing: -.03em;
    color: var(--ink);
    text-wrap: balance;
}
/* ExDroid's four: a 2 × 2 of name over what it does */
.v4-four {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, max-content));
    gap: clamp(8px, 1.4vh, 14px) clamp(20px, 2.4vw, 36px);
    margin: 0 0 clamp(14px, 2.2vh, 22px);
    padding: 0;
    list-style: none;
}
.v4-four li {
    padding-left: 12px;
    border-left: 2px solid var(--red);
}
.v4-four b {
    display: block;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .14em;
    color: var(--ink);
}
.v4-four span {
    display: block;
    font-size: 14px;
    line-height: 1.4;
    color: var(--ink-2);
}
.v4-lead {
    margin: 0 0 clamp(14px, 2.2vh, 22px);
    font-size: clamp(15px, 1.75vh, 19px);
    line-height: 1.6;
    color: var(--ink-2);
    text-wrap: pretty;
}
.v4-more {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    align-self: flex-start;
    font-size: 15px;
    font-weight: 600;
    color: var(--red-text);
    text-decoration: none;
}
.v4-more svg {
    transition: transform .25s var(--ease, ease);
}
.v4-more:hover svg {
    transform: translateX(4px);
}
.v4-more:focus-visible,
.v4-rail a:focus-visible {
    outline: 2px solid var(--red);
    outline-offset: 3px;
    border-radius: 4px;
}
/* what B shows: a caption with a red rule, it arrives with B */
.v4-proof {
    position: relative;
    margin: 0;
    padding: 0 0 0 14px;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.5;
    color: var(--ink);
    opacity: 0;
    transform: translateY(6px);
    transition: opacity .35s var(--ease, ease), transform .35s var(--ease, ease);
}
.v4-proof::before {
    content: "";
    position: absolute;
    left: 0;
    top: .3em;
    bottom: .3em;
    width: 3px;
    border-radius: 2px;
    background: var(--red);
}
.is-b .v4-proof {
    opacity: 1;
    transform: none;
}
/* the thermal scale: on the picture from A on, so the colours read before the change, not after it */
.v4-legend {
    position: absolute;
    z-index: 4;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 12px;
    border-radius: 10px;
    background: rgba(255, 255, 255, .92);
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-3);
    right: 10px;
    top: 10px;
}
/* on the stage: top right, like a thermal camera's own scale, clear of the chips at the bottom */
.v4-tour.is-staged .v4-legend {
    top: calc(var(--head) + 20px);
    right: max(32px, calc((100% - 1280px) / 2 + 32px));
}
.v4-legend i {
    width: 120px;
    height: 6px;
    border-radius: 3px;
    background: linear-gradient(90deg, #1c1a6e 0%, #5b2aa6 25%, #b5379a 50%, #ef7a3c 75%, #fbd36b 100%);
}

/* ---------- the stage: desktop and landscape tablets ---------- */
.v4-tour.is-staged .v4-track {
    height: calc(var(--ns, var(--n)) * 110vh + 100vh);
}
.v4-tour.is-staged .v4-stage {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
}
.v4-tour.is-staged .v4-scene {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
}
.v4-tour.is-staged .v4-scene.is-on {
    z-index: 2;
    pointer-events: auto;
}
.v4-tour.is-staged .v4-media {
    position: absolute;
    inset: 0;
    /* leaving: stay put under the next scene until it has fully come in */
    visibility: hidden;
    transition: visibility 0s linear .9s;
}
.v4-tour.is-staged .is-on .v4-media {
    visibility: visible;
    transition: none;
}
/* arriving: the next picture comes in as a sheet from the side the reader scrolls toward (class-driven, so it always
 * finishes; .is-armed keeps the first scene from playing it on load) */
.v4-tour.is-staged.is-armed .is-on .v4-media {
    animation: v4-in-down .85s cubic-bezier(.65, 0, .25, 1) both;
}
.v4-tour.is-staged.is-armed.is-up .is-on .v4-media {
    animation-name: v4-in-up;
}
@keyframes v4-in-down {
    from { clip-path: inset(100% 0 0 0); }
    to { clip-path: inset(0); }
}
@keyframes v4-in-up {
    from { clip-path: inset(0 0 100% 0); }
    to { clip-path: inset(0); }
}
/* the copy side of the picture stays calm: a wash from the left (v6, Łukasz 14.10: at 50 % of its strength) */
.v4-tour.is-staged .v4-media::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    opacity: .5;
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .8) 0, rgba(238, 241, 246, 0) 120px),
        linear-gradient(90deg, rgba(238, 241, 246, .96) 0%, rgba(238, 241, 246, .93) 33%, rgba(238, 241, 246, .78) 41%, rgba(238, 241, 246, .3) 49%, rgba(238, 241, 246, 0) 55%);
    pointer-events: none;
}
.v4-tour.is-staged .v4-copy {
    position: absolute;
    z-index: 4;
    top: var(--head);
    bottom: var(--rail-h);
    left: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    max-width: 1280px;
    margin: 0 auto;
    /* the same top in every scene, so the eyebrow and the question never jump when the scene changes */
    /* --copy-top: set by the script so the tallest scene's copy is centred; the fallback is close to it */
    padding: var(--copy-top, clamp(24px, calc((100vh - var(--head) - var(--rail-h)) * .19), 270px)) 32px 0;
    pointer-events: none;
    /* leaving: out at once; arriving: only once the next picture has covered most of the old one (the sheet takes
       .85 s), so new words never sit on the old picture */
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .18s var(--ease, ease), transform .18s var(--ease, ease);
}
.v4-tour.is-staged .is-on .v4-copy {
    opacity: 1;
    transform: none;
    transition: opacity .45s var(--ease, ease) .5s, transform .6s cubic-bezier(.2, .7, .2, 1) .5s;
}
.v4-tour.is-staged:not(.is-pinned) .is-on .v4-copy {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .18s var(--ease, ease), transform .18s var(--ease, ease);
}
.v4-tour.is-staged .v4-copy > * {
    max-width: min(580px, 37vw);
    pointer-events: auto;
}
.v4-tour.is-staged .v4-copy > .v4-title {
    max-width: min(740px, 44vw);
}
/* on the stage the caption sits on the picture, bottom right under the subject, on its own light chip */
.v4-tour.is-staged .v4-proof {
    position: absolute;
    right: max(32px, calc((100% - 1280px) / 2 + 32px));
    bottom: 22px;
    max-width: min(470px, 36vw);
    padding: 12px 16px 12px 28px;
    font-size: clamp(14.5px, 1.05vw, 17px);
    border-radius: 10px;
    background: rgba(255, 255, 255, .9);
    box-shadow: 0 10px 30px -14px rgba(21, 23, 26, .35);
}
.v4-tour.is-staged .v4-proof::before {
    left: 13px;
    top: 13px;
    bottom: 13px;
}

/* at A, where the caption will be: what the scroll is about to show; it goes as soon as the picture starts to change.
 * 03.11 (no autoplay any more, Łukasz: „add some hints about scrolling so the user knows to scroll down”): „Przewiń w dół”,
 * a little larger, its arrow nudging down like the front's „next” link; still with reduced motion */
.v4-hint {
    display: none;
}
.v4-tour.is-staged .v4-hint {
    position: absolute;
    z-index: 4;
    right: max(32px, calc((100% - 1280px) / 2 + 32px));
    bottom: calc(var(--rail-h) + 22px);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: .72em 1.15em .72em 1em;
    border-radius: 999px;
    background: rgba(21, 23, 26, .78);
    color: #fff;
    font-size: clamp(14px, .8vw, 17px); /* 15 px at 1920, 17 on a 4096 px wide screen */
    font-weight: 600;
    opacity: clamp(0, calc(1 - var(--q) * 10), 1);
    pointer-events: none;
}
.v4-tour.is-staged .v4-hint svg {
    flex: none;
    width: 1em;
    height: 1em;
    animation: v4-nudge 2.4s var(--ease, ease) infinite; /* the front's „next” link nudges the same way (hero.css h6-nudge) */
}
@keyframes v4-nudge {
    0%, 60%, 100% { transform: none; }
    30% { transform: translateY(3px); }
}
@media (prefers-reduced-motion: reduce) {
    .v4-tour.is-staged .v4-hint svg {
        animation: none;
    }
}

/* the rail: where you are, and a way to jump */
.v4-rail {
    display: none;
}
.v4-tour.is-staged.is-end .v4-rail {
    opacity: 0;
    transform: translateY(100%);
}
.v4-tour.is-staged .v4-rail {
    transition: opacity .3s var(--ease, ease), transform .3s var(--ease, ease);
}
.v4-tour.is-staged .v4-rail {
    display: block;
    position: absolute;
    z-index: 6;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--rail-h);
    background: rgba(238, 241, 246, .94);
    box-shadow: 0 -1px 0 rgba(21, 23, 26, .08);
}
.v4-rail-in {
    display: flex;
    align-items: center;
    gap: 28px;
    height: 100%;
    max-width: 1280px;
    box-sizing: border-box;
    margin: 0 auto;
    padding: 0 32px;
}
.v4-rail ol {
    flex: 1;
    display: grid;
    grid-template-columns: repeat(var(--n), 1fr);
    gap: 0 20px;
    height: 100%;
    margin: 0;
    padding: 0;
    list-style: none;
}
/* the next step is never more than one click away */
.v4-rail-cta {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border-radius: 10px;
    background: var(--red);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 8px 22px -12px var(--red-glow, rgba(191, 32, 38, .6));
    transition: background .25s var(--ease, ease);
}
.v4-rail-cta:hover {
    background: var(--red-dark, #9b1b21);
}
.v4-rail-cta:focus-visible {
    outline: 2px solid var(--red);
    outline-offset: 3px;
}
.v4-rail ol a {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    height: 100%;
    font-size: 13px;
    font-weight: 600;
    color: rgba(21, 23, 26, .64); /* ≥ 4.5:1 on the rail's grey (≈ 4.9:1) */
    text-decoration: none;
    transition: color .3s;
}
.v4-rail b {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    font-variant-numeric: tabular-nums;
    color: inherit;
}
.v4-rail ol a:hover,
.v4-rail a[aria-current="true"] {
    color: var(--ink);
}
.v4-rail a[aria-current="true"] b {
    color: var(--red-text);
}
/* the line above each name fills as its scene plays */
.v4-rail i {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: rgba(21, 23, 26, .12);
}
.v4-rail i::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--red);
    transform: scaleX(var(--f, 0));
    transform-origin: left;
}

/* phones and portrait: a slim CTA bar while the scenes are on screen */
.v4-mcta {
    display: none;
}
.v4-tour:not(.is-staged) .v4-mcta {
    position: fixed;
    z-index: 40;
    left: 12px;
    right: 12px;
    bottom: max(12px, env(safe-area-inset-bottom));
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 14px 18px;
    border-radius: 14px;
    background: var(--red);
    color: #fff;
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 12px 30px -10px rgba(21, 23, 26, .5);
    opacity: 0;
    transform: translateY(140%);
    visibility: hidden;
    transition: opacity .3s var(--ease, ease), transform .35s var(--ease, ease), visibility 0s linear .35s;
}
.v4-tour:not(.is-staged).is-in:not(.is-link) .v4-mcta {
    opacity: 1;
    transform: none;
    visibility: visible;
    transition: opacity .3s var(--ease, ease), transform .35s var(--ease, ease), visibility 0s;
}
.v4-mcta:focus-visible {
    outline: 2px solid #fff;
    outline-offset: -5px;
}

/* ---------- the close: the private-label CTA after the last scene ----------
 * A bookend: the hero's own bench (v1's plate, already in the cache) seen closer, the compound, the die and the red
 * gasket on the right, so the page ends where it began: our mix, your product. */
.v4-close {
    position: relative;
    z-index: 10;
    overflow: hidden;
    background: linear-gradient(180deg, #eef1f6 0%, #e9ebef 100%);
}
.v4-close-img {
    position: absolute;
    right: 0;
    bottom: 0;
    height: 100%;
    max-width: 58%;
    overflow: hidden;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    /* the left and top edges dissolve into the section's grey */
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 28%), linear-gradient(180deg, transparent 0, #000 22%);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(90deg, transparent 0, #000 28%), linear-gradient(180deg, transparent 0, #000 22%);
    mask-composite: intersect;
    pointer-events: none;
}
.v4-close-img img {
    display: block;
    height: 100%;
    width: auto;
    max-width: none;
    margin-left: auto;
    object-fit: cover;
    object-position: 100% 100%;
}
.v4-close-in {
    position: relative;
    z-index: 1;
    max-width: 1280px;
    box-sizing: border-box;
    min-height: clamp(440px, 64vh, 680px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin: 0 auto;
    padding: clamp(64px, 10vh, 112px) 32px;
}
.v4-close-in > * {
    max-width: min(620px, 50vw);
}
.v4-close-title {
    margin-bottom: clamp(14px, 2.2vh, 22px);
}
.v4-close-lead {
    max-width: 36em;
    margin: 0 0 clamp(22px, 3.2vh, 34px);
    font-size: clamp(15.5px, 1.8vh, 18px);
    line-height: 1.6;
    color: var(--ink-2);
}

/* ---------- short and narrow landscape windows ---------- */
@media (orientation: landscape) and (max-height: 760px) {
    .v4-title {
        font-size: clamp(28px, 5vh, 40px);
    }
    .v4-problem {
        font-size: clamp(18px, 2.7vh, 22px);
    }
    .v4-lead {
        font-size: 15px;
        line-height: 1.5;
    }
}
@media (orientation: landscape) and (max-width: 1100px) {
    .v4-tour.is-staged .v4-copy > * {
        max-width: min(520px, 48vw);
    }
    .v4-tour.is-staged .v4-copy > .v4-title {
        max-width: 50vw;
    }
    .v4-tour.is-staged .v4-media::after {
        background: linear-gradient(90deg, rgba(238, 241, 246, .96) 0%, rgba(238, 241, 246, .92) 40%, rgba(238, 241, 246, .55) 54%, rgba(238, 241, 246, 0) 66%);
    }
    .v4-img img {
        object-position: var(--opos, 74% 50%);
    }
    .v4-rail ol a {
        font-size: 12px;
    }
    .v4-rail-cta {
        display: none;
    }
}

/* ---------- phone, portrait, no JS: every scene is its picture over its copy ---------- */
.v4-tour:not(.is-staged) .v4-scene {
    padding-top: 40px;
    padding-bottom: 76px; /* room for the floating CTA bar */
}
/* the hint sits on the picture, bottom left, and goes as the picture starts to change */
.v4-tour:not(.is-staged) .v4-hint {
    position: absolute;
    z-index: 3;
    left: 12px;
    bottom: 12px;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 0;
    padding: 7px 12px;
    border-radius: 999px;
    background: rgba(21, 23, 26, .72);
    color: #fff;
    font-size: 12.5px;
    font-weight: 600;
    opacity: clamp(0, calc(1 - var(--q) * 8), 1);
    pointer-events: none;
}
.v4-tour:not(.is-staged) .v4-media {
    aspect-ratio: 4 / 3;
}
.v4-tour:not(.is-staged) .v4-img img {
    object-position: var(--mpos, var(--pos, 66% 50%));
    transform: scale(var(--mzoom, 1));
    transform-origin: var(--mpos, var(--pos, 64% 50%));
}
/* stacked: the offer always on its own line under the brand, the same in every scene */
.v4-tour:not(.is-staged) .v4-eyebrow::after {
    content: "";
    order: 2;
    flex-basis: 100%;
    height: 0;
}
.v4-tour:not(.is-staged) .v4-pl {
    order: 3;
    margin-left: 0;
    font-size: 12px;
}

/* stacked: the buyer's question first, then the picture, then what it proved, the answer and the link */
.v4-tour:not(.is-staged) .v4-scene {
    display: flex;
    flex-direction: column;
}
.v4-tour:not(.is-staged) .v4-copy {
    display: contents;
}
.v4-tour:not(.is-staged) .v4-copy > * {
    margin-left: 20px;
    margin-right: 20px;
}
.v4-tour:not(.is-staged) .v4-eyebrow {
    order: 1;
    margin-top: 0;
}
.v4-tour:not(.is-staged) .v4-problem {
    order: 2;
    margin-bottom: 16px;
}
.v4-tour:not(.is-staged) .v4-media {
    order: 3;
}
.v4-tour:not(.is-staged) .v4-proof {
    order: 4;
    margin-top: 14px;
    margin-bottom: 14px;
    font-size: 13.5px;
}
.v4-tour:not(.is-staged) .v4-title {
    order: 5;
}
.v4-tour:not(.is-staged) .v4-four {
    order: 6;
}
.v4-tour:not(.is-staged) .v4-lead {
    order: 7;
}
.v4-tour:not(.is-staged) .v4-more {
    order: 8;
}
/* stacked on a big screen (a 4:3 tablet in landscape, a squarish window): the whole 16:9 picture, the copy on the
 * page grid under it */
@media (min-width: 768px) {
    .v4-tour:not(.is-staged) .v4-media {
        aspect-ratio: 16 / 9;
        max-height: 72vh;
        width: 100%;
    }
    .v4-tour:not(.is-staged) .v4-hint {
        left: 24px;
        bottom: 20px;
        font-size: 13px;
    }
    .v4-tour:not(.is-staged) .v4-proof {
        font-size: 14.5px;
    }
    .v4-tour:not(.is-staged) .v4-img img {
        transform: none;
    }
    .v4-tour:not(.is-staged) .v4-copy > * {
        max-width: 720px;
        margin-left: 32px;
        margin-right: 32px;
    }
    /* a compact pill in the corner, so it never sits on a heading */
    .v4-tour:not(.is-staged) .v4-mcta {
        left: auto;
        right: 24px;
        bottom: 24px;
        padding: 12px 18px;
        font-size: 14px;
    }
}
@media (max-width: 767px), (max-aspect-ratio: 979/1000) {
    .v4-intro {
        padding: 56px 20px 28px;
    }
    .v4-intro-title,
    .v4-close-title {
        font-size: clamp(27px, 7.2vw, 40px);
    }
    .v4-title {
        font-size: clamp(26px, 6.8vw, 38px);
    }
    /* phones and portrait: the bench under the copy, full width */
    .v4-close {
        display: flex;
        flex-direction: column;
    }
    .v4-close-in {
        order: 1;
        min-height: 0;
        padding: 56px 20px 8px;
    }
    .v4-close-in > * {
        max-width: 36em;
    }
    .v4-close-img {
        order: 2;
        position: relative;
        height: auto;
        max-width: none;
        -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 26%);
        mask-image: linear-gradient(180deg, transparent 0, #000 26%);
    }
    .v4-close-img img {
        width: 100%;
        height: auto;
    }
}

/* the scrub is the reader's own scroll, so it stays; what moves by itself goes */
@media (prefers-reduced-motion: reduce) {
    .v4-img {
        transform: none;
    }
    .v4-tour.is-staged.is-armed .is-on .v4-media {
        animation: none;
    }
    .v4-tour.is-staged .v4-copy,
    .v4-tour.is-staged .is-on .v4-copy,
    .v4-proof {
        transition: none;
        transform: none;
    }
}

/* ---------- v6 (13.10): no intro above the stage, the close carries the recap ---------- */
/* the section's name for screen readers (the visible intro is gone, the first flick lands on scene 1) */
.v4-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
/* the close's picture covers its upper part only (the copy's height); the recap runs under both */
.v4-close-img {
    top: 0;
    bottom: auto;
    height: clamp(440px, 64vh, 680px);
}
.v4-close-img img {
    object-position: 100% 50%;
}
/* the exclusivity line: Marcin's strongest private-label argument (13.10, 34:59), a red tick like the offer pills */
.v4-close-excl {
    position: relative;
    margin: calc(-1 * clamp(8px, 1.4vh, 16px)) 0 clamp(22px, 3.2vh, 34px);
    padding-left: 22px;
    font-size: clamp(15px, 1.7vh, 17px);
    font-weight: 600;
    line-height: 1.5;
    color: var(--ink);
}
.v4-close-excl::before {
    content: "";
    position: absolute;
    left: 0;
    top: .55em;
    width: 10px;
    height: 10px;
    border-radius: 2px;
    background: var(--red);
}
.v4-recap {
    position: relative;
    z-index: 1;
    max-width: 1280px;
    box-sizing: border-box;
    margin: 0 auto;
    padding: 0 32px clamp(56px, 9vh, 104px);
}
.v4-recap-title {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--red-text);
}
.v4-recap-title::before {
    content: "";
    width: 32px;
    height: 1.5px;
    background: currentColor;
}
.v4-recap .v4-index {
    margin-top: clamp(16px, 2.6vh, 24px);
}
@media (max-width: 767px), (max-aspect-ratio: 979/1000) {
    .v4-close-img {
        height: auto;
    }
    .v4-close-excl {
        margin-top: -6px;
    }
    .v4-recap {
        order: 3;
        padding: 36px 20px 64px;
    }
}


/* ---------- v6 (14.10): the stage on every screen — split (squarer landscape) and tall (portrait) ----------
 * Łukasz 14.10: the stage with the rail under it „is super cool, same for vertical ones”; the stacked fallback on
 * squarer windows (picture, then caption, then title) „is bad”. tour.php's script picks the layout from the CSS 100vh:
 * wide ≥ 1.5 : 1 (as before), split 0.98–1.5 : 1, tall below. Landscape phones and no-JS keep the stacked layout. */
.v4-tour.is-split .v4-scene,
.v4-tour.is-tall .v4-scene {
    --opos: var(--spos, var(--pos, 66% 50%));
}

/* split: the copy in a left column, the picture to its right */
.v4-tour.is-split {
    --col: clamp(340px, 40vw, 560px);
    --gut: max(28px, calc((100vw - 1280px) / 2 + 32px));
}
.v4-tour.is-split .v4-media {
    left: calc(var(--gut) + var(--col) + 8px);
}
.v4-tour.is-split .v4-media::after,
.v4-tour.is-split .v4-wash-strong .v4-media::after {
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .8) 0, rgba(238, 241, 246, 0) 120px),
        linear-gradient(90deg, rgba(238, 241, 246, 1) 0, rgba(238, 241, 246, 0) 14%);
}
.v4-tour.is-split .v4-copy {
    padding-left: var(--gut);
    padding-right: var(--gut);
    max-width: none;
}
.v4-tour.is-split .v4-copy > *,
.v4-tour.is-split .v4-copy > .v4-title,
.v4-tour.is-split .v4-compact .v4-copy > *,
.v4-tour.is-split .v4-compact .v4-copy > .v4-title {
    max-width: var(--col);
}
.v4-tour.is-split .v4-title {
    font-size: clamp(28px, min(4.8vh, 3.6vw), 54px);
}
.v4-tour.is-split .v4-problem {
    font-size: clamp(18px, min(2.6vh, 2.2vw), 28px);
}
/* the caption chip and the scroll hint sit on the picture, not across the column */
.v4-tour.is-split .v4-proof {
    right: max(20px, calc((100% - 1280px) / 2 + 32px));
    max-width: min(440px, calc(100vw - var(--gut) - var(--col) - 56px));
}
.v4-tour.is-split .v4-hint {
    right: 20px;
}
.v4-tour.is-split .v4-legend {
    right: 20px;
}

/* tall: the picture on top, the copy under it, the rail a segmented line with the CTA */
.v4-tour.is-tall {
    --mh: clamp(200px, 44vh, 100vw);
    --gut: 20px;
}
.v4-tour.is-tall .v4-stage {
    height: 100vh;
    height: 100svh; /* a phone's toolbar never hides the rail */
    height: 100dvh; /* 20.10 (#1): and with the toolbar gone, the rail moves down to the screen's edge, no empty band */
}
.v4-tour.is-tall .v4-media {
    top: var(--head);
    bottom: auto;
    height: var(--mh);
}
.v4-tour.is-tall .v4-media::after,
.v4-tour.is-tall .v4-wash-strong .v4-media::after {
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .6) 0, rgba(238, 241, 246, 0) 56px),
        linear-gradient(0deg, rgba(238, 241, 246, .9) 0, rgba(238, 241, 246, 0) 22%);
}
.v4-tour.is-tall .v4-copy {
    top: calc(var(--head) + var(--mh) + 10px);
    padding: 0 var(--gut);
    max-width: none;
}
.v4-tour.is-tall .v4-copy > *,
.v4-tour.is-tall .v4-copy > .v4-title,
.v4-tour.is-tall .v4-compact .v4-copy > *,
.v4-tour.is-tall .v4-compact .v4-copy > .v4-title {
    max-width: 40rem;
}
.v4-tour.is-tall .v4-eyebrow {
    margin-bottom: 10px;
    font-size: 11.5px;
}
.v4-tour.is-tall .v4-pl {
    padding: 4px 9px 3px;
    font-size: 11.5px;
}
.v4-tour.is-tall .v4-problem {
    margin-bottom: 6px;
    font-size: clamp(17px, 4.6vw, 24px);
}
.v4-tour.is-tall .v4-title {
    margin-bottom: 10px;
    font-size: clamp(26px, 7.4vw, 44px);
}
.v4-tour.is-tall .v4-lead {
    margin-bottom: 10px;
    font-size: clamp(14.5px, 3.8vw, 18px);
    line-height: 1.5;
}
.v4-tour.is-tall .v4-more {
    font-size: 14.5px;
}
/* ExDroid: the four names as one line under the heading (their chips would crowd a narrow picture) */
.v4-tour.is-tall .v4-pins {
    display: none;
}
.v4-tour.is-tall .v4-compact .v4-four {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    margin-bottom: 10px;
}
.v4-tour.is-tall .v4-four li {
    padding-left: 8px;
}
.v4-tour.is-tall .v4-four span {
    display: none;
}
/* the caption chip at the picture's bottom edge (it belongs to the proof); the hint at the same place before it */
.v4-tour.is-tall .v4-proof {
    left: 12px;
    right: 12px;
    top: auto;
    bottom: calc(100% + 20px);
    max-width: none;
    padding: 9px 12px 9px 24px;
    font-size: 13.5px;
}
.v4-tour.is-tall .v4-proof::before {
    left: 11px;
    top: 10px;
    bottom: 10px;
}
.v4-tour.is-tall .v4-hint {
    left: 12px;
    right: auto;
    bottom: 12px;
    padding: 7px 12px;
    font-size: 12.5px;
}
.v4-tour.is-tall .v4-legend {
    top: 10px;
    right: 10px;
}
/* short phones: the heading and the link stay, the paragraph goes */
@media (orientation: portrait) and (max-height: 740px) {
    .v4-tour.is-tall {
        --mh: clamp(180px, 40vh, 100vw);
    }
    .v4-tour.is-tall .v4-lead {
        display: none;
    }
}
/* the rail: five segments filling as the scenes play, the current group's name, the CTA */
.v4-rail-now {
    display: none;
}
.v4-tour.is-tall .v4-rail-in {
    gap: 12px;
    padding: 0 12px 0 var(--gut);
}
.v4-tour.is-tall .v4-rail ol {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    gap: 0 3px;
}
.v4-tour.is-tall .v4-rail ol a {
    height: 3px;
    padding: 0;
}
.v4-tour.is-tall .v4-rail ol a b,
.v4-tour.is-tall .v4-rail ol a span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.v4-tour.is-tall .v4-rail i {
    height: 3px;
}
.v4-tour.is-tall .v4-rail-now {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    font-size: 13.5px;
    font-weight: 600;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: var(--ink);
}
.v4-tour.is-tall .v4-rail-now b {
    font-size: 11px;
    letter-spacing: .08em;
    color: var(--red-text);
}
.v4-tour.is-tall .v4-rail-cta {
    display: inline-flex;
    padding: 9px 14px;
    font-size: 13px;
}
/* tall: B's pointers would sit on the caption chip (both at the picture's bottom edge) — the caption says it there */
.v4-tour.is-tall .v4-mark--at-b {
    display: none;
}
/* a tablet in portrait has the height for a bigger picture */
@media (orientation: portrait) and (min-width: 600px) {
    .v4-tour.is-tall {
        --mh: clamp(200px, 50vh, 100vw);
        --gut: 32px;
    }
}
/* phones: a tighter CTA, so the current group's name stays whole */
@media (max-width: 440px) {
    .v4-tour.is-tall .v4-rail-cta {
        gap: 6px;
        padding: 8px 11px;
        font-size: 12.5px;
    }
    .v4-tour.is-tall .v4-rail-cta svg {
        display: none;
    }
    .v4-tour.is-tall .v4-rail-now {
        font-size: 12.5px;
        gap: 6px;
    }
}
/* split: the picture is a narrower window, so ExDroid's chips would fall off its left edge; the four go into the
   copy column as a 2 × 2 (name over what it does), as on phones */
.v4-tour.is-split .v4-pins {
    display: none;
}
.v4-tour.is-split .v4-compact .v4-four {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
}
/* tall: each segment is a 24 px tall tap target (WCAG 2.5.8), the visible line stays 3 px at its top */
.v4-tour.is-tall .v4-rail ol {
    height: 24px;
}
.v4-tour.is-tall .v4-rail ol a {
    height: 24px;
}
/* the segments get their own 24 px row above the name and the CTA, so nothing covers them */
.v4-tour.is-tall {
    --rail-h: 74px;
}
.v4-tour.is-tall .v4-rail-in {
    padding-top: 24px;
}
/* the smallest phones (≤ 680 px tall, e.g. 360 × 640): a lower picture, so ExDroid's heading + four names clear the rail */
@media (orientation: portrait) and (max-height: 680px) {
    .v4-tour.is-tall {
        --mh: clamp(170px, 35vh, 100vw);
    }
}
/* ExDroid carries the most copy (heading on three lines + the four names): its picture is a little lower on phones */
@media (orientation: portrait) and (max-width: 599px) {
    .v4-tour.is-tall .v4-compact {
        --mh: clamp(170px, 37vh, 100vw);
    }
}
/* phones (Łukasz 14.10: bigger pictures, „60/40”): problem → answer → the caption on the picture → the link; the paragraph
   stays on tablets and up. With it the picture got ≈ 45–50 % of the screen, without it ≈ 58 % (tour.php, fitTall) */
@media (orientation: portrait) and (max-width: 599px) {
    .v4-tour.is-tall .v4-lead {
        display: none;
    }
}
/* tall: the picture starts under the fixed header, not at its assumed bottom (Łukasz 14.10: a gap between the menu and the
   picture on the phone — the theme's header is 72 px, then 60 px once the page has scrolled, so a picture placed at 72 px
   left a 12 px strip of background). Now it runs from the top edge; the header simply covers its top. */
.v4-tour.is-tall .v4-media {
    top: 0;
    height: calc(var(--mh) + var(--head));
}
.v4-tour.is-tall .v4-media::after,
.v4-tour.is-tall .v4-wash-strong .v4-media::after {
    background: linear-gradient(0deg, rgba(238, 241, 246, .9) 0, rgba(238, 241, 246, 0) 22%);
}
/* 20.10 (#2): a leaving picture never shows below the arriving one (--cut: tour.php setScene) */
.v4-tour.is-tall .v4-scene:not(.is-on) .v4-media {
    clip-path: inset(0 0 var(--cut, 0px) 0);
}

/* ---------- phones (14.10): the close as one screen, like the front; no recap ----------
 * Łukasz 14.10: „to samo z sekcją Twój problem jest inny” — picture first (flexible, the header covers its top edge), then
 * the title, the exclusivity line and the CTA, all on the first screen with Safari's bars shown (100svh); the lead goes on
 * phones. „Na telefonie usuńmy sekcję Pięć problemów, które już rozwiązujemy” — the recap is desktop/tablet only. */
@media (max-width: 767px) and (orientation: portrait) {
    .v4-close {
        min-height: 100vh;
        min-height: 100svh;
        display: flex;
        flex-direction: column;
    }
    .v4-close-img {
        order: 1;
        position: relative;
        flex: 1 1 auto;
        min-height: 30svh;
        height: auto;
        max-width: none;
        -webkit-mask-image: linear-gradient(0deg, transparent 0, #000 16%);
        mask-image: linear-gradient(0deg, transparent 0, #000 16%);
    }
    .v4-close-img img {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        object-position: 60% 50%;
    }
    .v4-close-in {
        order: 2;
        flex: none;
        min-height: 0;
        padding: 12px 20px 28px;
    }
    .v4-close-title {
        font-size: clamp(26px, min(7.4vw, 4.6svh), 38px);
        margin-bottom: 12px;
    }
    .v4-close-lead {
        display: none;
    }
    .v4-close-excl {
        margin: 0 0 16px;
        font-size: 14.5px;
    }
    .v4-close .h6-actions {
        margin-top: 0;
    }
    .v4-recap {
        display: none;
    }
}
/* portrait phones, scenes with a 3:4 frame (14.10, Łukasz: „oddalić… nie widać, że to komin”): each frame is anchored
   at its own point ('ppos'), so a short window (an iPhone with Safari's bars, wider than tall) keeps what matters */
@media (max-width: 767px) and (orientation: portrait) {
    .v4-tour.is-tall .has-phone {
        --opos: var(--ppos, 50% 50%);
    }
    .v4-tour.is-tall .has-phone .v4-img {
        transform-origin: var(--ppos, 50% 50%);
    }
}
/* preview only: ?wash=0 (hero.php) — the pictures without the light wash under the copy */
.v4-tour.is-nowash .v4-media::after {
    display: none;
}
/* phones keep their full bottom fade under the caption chip (it is not the left wash) */
.v4-tour.is-tall .v4-media::after {
    opacity: 1;
}
/* wide and split (Łukasz 14.10): the rail stands at the bottom from the first screen, so the story starts on the front;
   it leaves (.is-end) before the stage scrolls away, as before */
.v4-tour.is-wide .v4-rail,
.v4-tour.is-split .v4-rail {
    position: fixed;
}

/* 15.10, Łukasz on near-square windows (~1260 × 1200–1280): „jest taka jedna dziwna rozdziałka, co mi to wszystko psuje”.
 * The split picture started at a straight edge next to the copy column. Its fade sat in the wash, which runs at 50 %
 * since 14.10, so the seam showed. Now the picture starts a little under the column and dissolves into the stage
 * background at full strength; the wash's top band keeps its old weight. */
.v4-tour.is-split {
    --fade: clamp(240px, 28vw, 440px);
}
.v4-tour.is-split .v4-media {
    left: calc(var(--gut) + var(--col) - 32px);
}
/* the second pass the same day (Łukasz: „ten overlay biały jest za mocny, ustaw go na dużo mniej i żeby lepiej się
   rozchodził”): a quick, eased decay, so the picture shows within a few dozen px of the column and the tail is long;
   third pass („drop it to 50 %”): every stop after the edge halved, the edge itself stays solid so no seam comes back */
.v4-tour.is-split .v4-media::after,
.v4-tour.is-split .v4-wash-strong .v4-media::after {
    opacity: 1;
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .125) 0, rgba(238, 241, 246, 0) 110px),
        linear-gradient(90deg, rgba(238, 241, 246, 1) 0, rgba(238, 241, 246, .37) calc(var(--fade) * .06), rgba(238, 241, 246, .25) calc(var(--fade) * .14), rgba(238, 241, 246, .16) calc(var(--fade) * .24), rgba(238, 241, 246, .09) calc(var(--fade) * .36), rgba(238, 241, 246, .045) calc(var(--fade) * .5), rgba(238, 241, 246, .02) calc(var(--fade) * .66), rgba(238, 241, 246, .006) calc(var(--fade) * .82), rgba(238, 241, 246, 0) var(--fade));
}
.v4-tour.is-nowash.is-split .v4-media::after {
    display: block;
    background: linear-gradient(90deg, rgba(238, 241, 246, 1) 0, rgba(238, 241, 246, .5) calc(var(--fade) * .14), rgba(238, 241, 246, .09) calc(var(--fade) * .5), rgba(238, 241, 246, 0) var(--fade));
}
/* 15.10, the wide wash, much lighter and with a longer tail (Łukasz: „za mocny … dużo mniej … żeby lepiej się
   rozchodził”): under the copy ≈ .3 instead of ≈ .48, then an eased fade to nothing at ~62 % (was a cliff at 55 %).
   The thermal frame keeps a little more (≈ .44) so its red accent still reads. Split and tall have their own. */
.v4-tour.is-wide .v4-media::after {
    opacity: 1;
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .3) 0, rgba(238, 241, 246, 0) 110px),
        linear-gradient(90deg, rgba(238, 241, 246, .3) 0%, rgba(238, 241, 246, .27) 28%, rgba(238, 241, 246, .2) 38%, rgba(238, 241, 246, .11) 46%, rgba(238, 241, 246, .045) 54%, rgba(238, 241, 246, .012) 60%, rgba(238, 241, 246, 0) 64%);
}
.v4-tour.is-wide .v4-wash-strong .v4-media::after {
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .3) 0, rgba(238, 241, 246, 0) 110px),
        linear-gradient(90deg, rgba(238, 241, 246, .44) 0%, rgba(238, 241, 246, .41) 36%, rgba(238, 241, 246, .3) 45%, rgba(238, 241, 246, .14) 52%, rgba(238, 241, 246, .05) 58%, rgba(238, 241, 246, 0) 64%);
}
/* 20.10 (Łukasz: „use stronger white wash on that roof scene”): Frostbond's lead ends at 37–48 % of the frame on wide
   screens, over the dark roof edge. This holds ≈ .5–.6 under the copy and is gone before the chimney's body (~55 %). */
.v4-tour.is-wide .v4-wash-heavy .v4-media::after {
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .3) 0, rgba(238, 241, 246, 0) 110px),
        linear-gradient(90deg, rgba(238, 241, 246, .62) 0%, rgba(238, 241, 246, .58) 38%, rgba(238, 241, 246, .5) 46%, rgba(238, 241, 246, .32) 50%, rgba(238, 241, 246, .14) 55%, rgba(238, 241, 246, .04) 60%, rgba(238, 241, 246, 0) 66%);
}
@media (min-aspect-ratio: 49/50) and (max-width: 1100px) {
    .v4-tour.is-wide .v4-media::after {
        background: linear-gradient(90deg, rgba(238, 241, 246, .34) 0%, rgba(238, 241, 246, .3) 40%, rgba(238, 241, 246, .17) 50%, rgba(238, 241, 246, .07) 58%, rgba(238, 241, 246, 0) 66%);
    }
}
/* split and tall keep their own washes (above): restate them after the wide one */
.v4-tour.is-split .v4-media::after,
.v4-tour.is-split .v4-wash-strong .v4-media::after {
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .125) 0, rgba(238, 241, 246, 0) 110px),
        linear-gradient(90deg, rgba(238, 241, 246, 1) 0, rgba(238, 241, 246, .37) calc(var(--fade) * .06), rgba(238, 241, 246, .25) calc(var(--fade) * .14), rgba(238, 241, 246, .16) calc(var(--fade) * .24), rgba(238, 241, 246, .09) calc(var(--fade) * .36), rgba(238, 241, 246, .045) calc(var(--fade) * .5), rgba(238, 241, 246, .02) calc(var(--fade) * .66), rgba(238, 241, 246, .006) calc(var(--fade) * .82), rgba(238, 241, 246, 0) var(--fade));
}

/* 16.10 — split, full-bleed. Łukasz on a near-square window: „look at the left side, half of the page is white, and here
 * [the wide layout] it's fine”. The picture now runs behind the copy as in wide, from 1:1 frames whose middle band is
 * the 16:9 frame (tour.php $v4_pic, square.py), so the subject stays right of the copy. The wash is the wide one. The
 * 15.10 seam fade and the 3:4 frames in split are retired; the rules above that still set them are overridden here. */
.v4-tour.is-split .v4-scene {
    --opos: 50% 50%;
}
.v4-tour.is-split .v4-media {
    left: 0;
}
.v4-tour.is-split .v4-media::after {
    opacity: 1;
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .3) 0, rgba(238, 241, 246, 0) 110px),
        linear-gradient(90deg, rgba(238, 241, 246, .32) 0%, rgba(238, 241, 246, .29) 30%, rgba(238, 241, 246, .21) 40%, rgba(238, 241, 246, .11) 48%, rgba(238, 241, 246, .045) 56%, rgba(238, 241, 246, .012) 62%, rgba(238, 241, 246, 0) 66%);
}
.v4-tour.is-split .v4-wash-strong .v4-media::after {
    opacity: 1;
    background:
        linear-gradient(180deg, rgba(238, 241, 246, .3) 0, rgba(238, 241, 246, 0) 110px),
        linear-gradient(90deg, rgba(238, 241, 246, .46) 0%, rgba(238, 241, 246, .43) 38%, rgba(238, 241, 246, .3) 47%, rgba(238, 241, 246, .14) 54%, rgba(238, 241, 246, .05) 60%, rgba(238, 241, 246, 0) 66%);
}
.v4-tour.is-nowash.is-split .v4-media::after {
    display: none;
}
/* with a scroll sequence, the canvas covers only the middle band; the bands above and below follow A → B with the
 * scroll (fx fade), so the frost reaches the whole square together */
.v4-tour.is-split .has-seq .v4-b {
    visibility: visible;
}
/* the copy column ends by 41 % of the window, so it stays clear of subjects that start at ~45 % of the frame (the
   shadowgraph's housing, 16.10 at 1656 × 1203: „48 h, od” ran onto its bezel) */
.v4-tour.is-split {
    --col: clamp(320px, calc(41vw - var(--gut)), 560px);
}

/* 16.10 — the close's picture full width (Łukasz: „na full width, żeby to zdjęcie było na całości”): the product family
 * runs behind the copy as the scenes' pictures do, with the same light wash on the copy side; its lower edge dissolves
 * into the recap. Phones and portrait keep the picture above (or under) the copy. */
@media (min-width: 768px) and (min-aspect-ratio: 49/50) {
    .v4-close {
        --close-h: clamp(480px, 74vh, 780px);
    }
    .v4-close-in {
        min-height: var(--close-h);
    }
    /* the copy keeps to the left 44 %, clear of the products (they start at ~50 % of the frame) */
    .v4-close-in > * {
        max-width: min(600px, 44vw);
    }
    .v4-close-img {
        left: 0;
        right: 0;
        top: 0;
        bottom: auto;
        width: 100%;
        max-width: none;
        height: var(--close-h);
        -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 78%, transparent 100%);
        mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 78%, transparent 100%);
        -webkit-mask-composite: source-over;
        mask-composite: add;
    }
    .v4-close-img::after {
        content: "";
        position: absolute;
        inset: 0;
        background: linear-gradient(90deg, rgba(238, 241, 246, .5) 0%, rgba(238, 241, 246, .44) 30%, rgba(238, 241, 246, .26) 42%, rgba(238, 241, 246, .1) 52%, rgba(238, 241, 246, 0) 62%);
    }
    .v4-close-img img {
        width: 100%;
        height: 100%;
        margin: 0;
        object-fit: cover;
        object-position: 100% 62%;
    }
}
@media (max-width: 767px) and (orientation: portrait) {
    .v4-close-img img {
        object-position: 80% 60%;
    }
}

/* 16.10 — the close as the stage's last scene (tour.php .v4-scene--close): it arrives with the same sheet as the five.
 * Stacked layouts (landscape phones, no JS) keep the .v4-close below; on the stage only the recap stays there. */
.v4-scene--close {
    display: none;
}
.v4-tour.is-staged .v4-scene--close {
    display: block;
}
.v4-tour.is-staged .v4-close-in,
.v4-tour.is-staged .v4-close-img {
    display: none;
}
.v4-tour.is-staged .v4-close {
    padding-top: clamp(24px, 4vh, 48px);
}
.v4-tour.is-staged .v4-scene--close .v4-copy {
    padding-top: 0;
    justify-content: center;
}
.v4-tour.is-staged .v4-scene--close .v4-title {
    font-size: clamp(30px, min(5vh, 3.2vw), 50px);
    margin-bottom: clamp(14px, 2.2vh, 22px);
}
.v4-tour.is-staged .v4-scene--close .v4-close-excl {
    margin: 0 0 clamp(18px, 2.8vh, 30px);
}
.v4-tour.is-staged .v4-scene--close .h6-actions {
    pointer-events: auto;
}
.v4-tour.is-wide .v4-scene--close .v4-copy > *,
.v4-tour.is-split .v4-scene--close .v4-copy > * {
    max-width: min(600px, 44vw);
}
.v4-tour.is-tall .v4-scene--close .v4-close-excl {
    font-size: 14.5px;
    margin: 0 0 14px;
}

/* 16.10 — front → first scene, the same sheet as between scenes. hero.php holds the front in place (.h6-stack.is-sheet)
 * and pulls the tour up over it; until the stage pins, the tour is see-through and the stage hidden (the rail stays),
 * then the first picture comes in from below over the front; scrolling back, it leaves upward and uncovers it. */
@media (min-aspect-ratio: 49/50) and (min-height: 520px), (max-width: 767px) and (orientation: portrait) {
    /* until the tour's script runs (is-live) and while the stage is not pinned yet (is-pre), the tour is see-through and
       its scenes hidden; visibility, not opacity, so nothing under the front counts as a layout shift. The rail stays. */
    .h6-stack.is-sheet .v4-tour:not(.is-live),
    .h6-stack.is-sheet .v4-tour.is-pre,
    .h6-stack.is-sheet .v4-tour.is-enter,
    .h6-stack.is-sheet .v4-tour.is-leave {
        background: transparent;
    }
    .h6-stack.is-sheet .v4-tour:not(.is-live) .v4-track,
    .h6-stack.is-sheet .v4-tour:not(.is-live) .v4-mcta {
        visibility: hidden;
    }
    .h6-stack.is-sheet .v4-tour.is-pre .v4-scene,
    .h6-stack.is-sheet .v4-tour.is-pre .v4-scene .v4-media,
    .h6-stack.is-sheet .v4-tour.is-pre .v4-scene .v4-copy {
        visibility: hidden;
    }
    .h6-stack.is-sheet .v4-tour.is-pre {
        pointer-events: none;
    }
    .h6-stack.is-sheet .v4-tour.is-pre .v4-rail {
        pointer-events: auto;
    }
    /* 02.11 (Łukasz, a phone screenshot: the front's picture above and below the arriving one, its title under the
       scene's): the sheet is the whole scene on its own background, so picture, copy and chips move as one page. Until
       then only the picture moved: for the .85 s of the sheet the front showed around it (on tall screens the front's
       picture is taller than the scene's), and the scene's copy faded in over the front's, two titles on top of each
       other, on every layout. */
    .h6-stack.is-sheet .v4-tour .v4-scene.is-sheet-in.is-on,
    .h6-stack.is-sheet .v4-tour .v4-scene.is-sheet-out.is-on {
        background: var(--v4-bg);
        animation: v4-sheet-in .85s cubic-bezier(.65, 0, .25, 1) both;
    }
    .h6-stack.is-sheet .v4-tour .v4-scene.is-sheet-out.is-on {
        animation-name: v4-sheet-out;
    }
    .h6-stack.is-sheet .v4-tour .v4-scene.is-sheet-in.is-on .v4-media,
    .h6-stack.is-sheet .v4-tour .v4-scene.is-sheet-out.is-on .v4-media {
        animation: none;
    }
    /* the copy rides on the sheet: there from its first line, and it leaves with it */
    .h6-stack.is-sheet .v4-tour.is-staged .v4-scene.is-sheet-in.is-on .v4-copy,
    .h6-stack.is-sheet .v4-tour.is-staged .v4-scene.is-sheet-out.is-on .v4-copy {
        opacity: 1;
        transform: none;
        transition: none;
    }
}
@keyframes v4-sheet-in {
    from { clip-path: inset(100% 0 0 0); }
    to { clip-path: inset(0); }
}
@keyframes v4-sheet-out {
    from { clip-path: inset(0); }
    to { clip-path: inset(100% 0 0 0); }
}
@media (prefers-reduced-motion: reduce) {
    .h6-stack.is-sheet .v4-tour .v4-scene.is-sheet-in.is-on,
    .h6-stack.is-sheet .v4-tour .v4-scene.is-sheet-out.is-on {
        animation: none;
    }
    /* without the sheet, back on the front the scene goes at once (it would otherwise cover the front until is-pre) */
    .h6-stack.is-sheet .v4-tour .v4-scene.is-sheet-out.is-on {
        opacity: 0;
    }
}
/* the close keeps its red second line (as before 16.10); the scenes' titles stay ink */
.v4-tour .v4-scene--close .v4-title em {
    color: var(--red);
}

/* 16.10: the recap is gone, so on the stage nothing of .v4-close is left (the close is the stage's last scene) */
.v4-tour.is-staged .v4-close {
    display: none;
}
/* the red strip along the bottom of the close scene's picture (tour.php placeStrip), over the wash; on tall screens
   along the bottom of the scene, under the CTA, shown with the scene's copy */
.v4-scene--close > .hv3-marquee {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 5;
    opacity: 0;
    transition: opacity .18s ease;
}
.v4-scene--close.is-on > .hv3-marquee {
    opacity: 1;
    transition-delay: .5s;
}
.v4-scene--close .v4-media .hv3-marquee {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 5;
}
