/* ============================================================================
 * qv-journey — pinned-scroll device journey (shared engine)
 * ----------------------------------------------------------------------------
 * Extracted from qvickly-home.php so home / checkout / betallank / inkasso can
 * all drive the same scroll engine and only supply their own chapters + mocks.
 *
 * Contract a page must provide:
 *   section.qv-ph#<id>            the 210vh pinned section
 *     .stick > .stage
 *       .txts   > .chap[.introc|.side-l|.side-r]   one per chapter
 *       .phone  > .scr > .body > .mock[data-w][data-h]   one per screen
 *       .dots   > i                                 one per chapter
 *
 * Mocks are HTML, not images: fitMocks() scales each .mock to its .body using
 * data-w/data-h, so a screen stays crisp at any size and stays editable in
 * wp-admin as markup.
 * ========================================================================== */

.qv-ph { position:relative; height:210vh;
  background:radial-gradient(1200px 700px at 75% 12%, rgba(118,74,243,.28), transparent 60%),
             radial-gradient(900px 560px at 8% 78%, rgba(95,51,224,.18), transparent 62%),
             var(--ink); }
.qv-ph .stick { position:sticky; top:0; height:100vh; min-height:600px; overflow:hidden; }
.qv-ph .stage { position:relative; height:100%; max-width:1180px; margin-inline:auto;
  padding-inline:clamp(20px,4vw,48px); }
.qv-ph .txts { position:absolute; inset:0 clamp(20px,4vw,48px); z-index:2; pointer-events:none; }
.qv-ph .chap { position:absolute; inset-inline:0; top:50%; transform:translateY(calc(-50% + 30px));
  opacity:0; transition:opacity .45s ease, transform .45s ease; pointer-events:none; }
.qv-ph .chap.on { opacity:1; transform:translateY(-50%); pointer-events:auto; }
.qv-ph .chap.side-l { left:0; right:auto; width:min(30%,26em);
  transform:translate(-28px, calc(-50% + 10px)); }
.qv-ph .chap.side-r { right:0; left:auto; width:min(30%,26em);
  transform:translate(28px, calc(-50% + 10px)); }
.qv-ph .chap.side-l.on, .qv-ph .chap.side-r.on { transform:translate(0,-50%); }
/* The intro chapter's offset originally assumed a hero sat above the journey
   (as on the homepage). When a journey OPENS a page it sits under the fixed
   header instead - ~82px on desktop - and the eyebrow collided with the nav.
   Clear the header, then add breathing room. */
/* --header-h is declared once in base.css (82px / 80px under 1199px) and
   inherits down; this file used to declare its own --qv-header-h copy. */
.qv-ph .chap.introc { text-align:center; transform:translateY(30px);
  top:calc(var(--header-h) + clamp(28px,7vh,76px)); }
.qv-ph .chap.introc.on { transform:none; }
.qv-ph .chap.introc p { margin-inline:auto; }
.qv-ph .chap.side-r .chips { justify-content:flex-start; }
.qv-ph .chap .eyebrow { font-family:'Rubik',sans-serif; font-weight:500; font-size:13.5px;
  letter-spacing:.2em; text-transform:uppercase; color:#c9b8ff; }
.qv-ph .chap h3 { color:#fdfcff; font-size:clamp(32px,3.8vw,54px); margin-top:14px; font-weight:700; }
.qv-ph .chap p { color:#cfc6f2; font-size:clamp(16px,1.4vw,19px); margin-top:16px; max-width:26em; }
.qv-ph .chips { display:flex; gap:10px; flex-wrap:wrap; margin-top:22px; }
.qv-ph .chips span { font-family:'Rubik',sans-serif; font-size:13.5px; font-weight:500;
  color:#efeaff; background:rgba(253,252,255,.12); border:1px solid rgba(253,252,255,.22);
  border-radius:999px; padding:7px 16px; }
.qv-ph .stores { display:flex; gap:10px; flex-wrap:wrap; margin-top:20px; }
.qv-ph .stores a { display:flex; align-items:center; gap:10px; background:rgba(253,252,255,.08); color:#fdfcff !important;
  border:1px solid rgba(253,252,255,.22); border-radius:13px; padding:9px 18px 9px 14px; text-decoration:none;
  transition:transform .25s ease, background .25s ease, border-color .25s ease; }
.qv-ph .stores a:hover { transform:translateY(-2px); background:rgba(118,74,243,.22); border-color:rgba(201,184,255,.55); }
.qv-ph .stores svg { width:22px; height:22px; flex-shrink:0; fill:#fdfcff; }
.qv-ph .stores small { display:block; font-size:10px; letter-spacing:.06em; text-transform:uppercase; color:#b9b3d6; line-height:1.2; }
.qv-ph .stores b { display:block; font-family:'Rubik',sans-serif; font-size:15px; font-weight:600; line-height:1.15; }
.qv-ph .phone { position:absolute; left:50%; top:50%; transform:translateY(-50%);
  width:0; height:min(78vh,720px); z-index:1; transition:height .5s ease, top .5s ease; }
/* Fan (intro) state: the phone is centred independently of the intro text, so
   once the intro was pushed down to clear the fixed header the phone overlapped
   its paragraph. Shift the fan down by the same header allowance to keep the
   two in the relationship they had when the journey followed a hero. */
.qv-ph .phone.fanmode { height:min(58vh,540px);
  top:calc(57% + var(--header-h) + 28px); }
.qv-ph .phone .scr { position:absolute; left:50%; top:50%; height:100%; aspect-ratio:389/788;
  transform:translate(-50%,-46%) scale(.96); opacity:0; border-radius:38px;
  transform-origin:50% 130%; background:#0d0b16; padding:7px;
  box-shadow:0 60px 120px -40px rgba(10,6,30,.7), inset 0 0 0 1.5px rgba(201,184,255,.18);
  transition:opacity .5s ease, transform .5s cubic-bezier(.22,1,.36,1); }
.qv-ph .phone .scr .body { position:relative; width:100%; height:100%; border-radius:31px;
  overflow:hidden; background:#fff; }
.qv-ph .phone .scr .mock { position:absolute; left:50%; top:50%;
  transform:translate(-50%,-50%) scale(var(--s,1)); transform-origin:center; }
.qv-ph .phone .scr .mock img { max-width:none; }
.qv-ph .phone .scr img.shot { width:100%; height:100%; object-fit:cover; display:block; }
.qv-ph .phone .scr.on { opacity:1; transform:translate(-50%,-50%) scale(1); }
.qv-ph .phone .scr:nth-child(1) { z-index:4; }
.qv-ph .phone .scr:nth-child(2) { z-index:2; }
.qv-ph .phone .scr:nth-child(3) { z-index:3; }
.qv-ph .phone .scr:nth-child(4) { z-index:1; }
.qv-ph .phone.fanmode .scr { transition:none; }
.qv-ph .chap.introc h3 { font-size:clamp(36px,4.4vw,62px); }
.qv-ph .chap.introc p { font-size:clamp(17px,1.5vw,20px); color:#c9b8ff; }
.qv-desk { position:absolute; left:clamp(4px,2vw,28px); top:50%; z-index:0;
  width:min(44vw,600px); opacity:0; transform:translate(70vw,-50%);
  transition:transform .95s cubic-bezier(.22,1,.36,1), opacity .55s ease; pointer-events:none; }
.qv-desk.on { opacity:1; transform:translate(0,-50%); }
.qv-desk .mba-screen { position:relative; background:#0b0a12; border-radius:16px 16px 0 0;
  padding:16px 12px 12px; border:1.5px solid rgba(201,184,255,.14); border-bottom:0;
  box-shadow:0 50px 110px -30px rgba(10,6,30,.8); }
.qv-desk .mba-cam { position:absolute; top:6px; left:50%; transform:translateX(-50%);
  width:5px; height:5px; border-radius:50%; background:#2c2a3a; }
.qv-desk .mba-base { position:relative; height:13px; margin:0 -4.5%;
  background:linear-gradient(#33303f, #17141f 70%, #0b0a12); border-radius:2px 2px 14px 14px;
  box-shadow:0 24px 50px -18px rgba(10,6,30,.8); }
.qv-desk .mba-base::before { content:""; position:absolute; left:50%; transform:translateX(-50%);
  top:0; width:13%; height:5px; background:#0b0a12; border-radius:0 0 7px 7px; }
.qv-desk .dbody { position:relative; width:100%; aspect-ratio:1000/640; overflow:hidden;
  background:#eef0fa; border-radius:5px; }
.qv-desk .dmock { position:absolute; left:0; top:0; width:1000px; height:640px;
  /* The phone overlaps the laptop's right side. Without a fade the dashboard
     cards cut mid-number at an invisible boundary and read as a rendering
     bug; dissolving them before the overlap makes the occlusion deliberate. */
  -webkit-mask-image:linear-gradient(to right, #000 38%, transparent 64%);
  mask-image:linear-gradient(to right, #000 38%, transparent 64%);
  transform-origin:top left; transform:scale(var(--ds,1)); }
@media (max-width:920px){ .qv-desk { display:none; } }
.qv-ph .dots { position:absolute; left:50%; transform:translateX(-50%); bottom:clamp(28px,5vh,54px);
  display:flex; gap:10px; }
.qv-ph .dots i { width:26px; height:4px; border-radius:2px; background:rgba(253,252,255,.25);
  transition:background .3s; }
.qv-ph .dots i.on { background:#fdfcff; }
@media (max-width:920px){
  /* Narrow screens: shrink the fan. journey.js multiplies the ±10/±30° fan by
     --fan-scale, and the phone height is capped by viewport width so the
     spread (about 1.0 phone-heights wide at this scale) stays inside the
     screen instead of being clipped by .stick's overflow:hidden. */
  .qv-ph { --fan-scale:.4; }
  .qv-ph .stage { display:grid; align-content:center; gap:14px; }
  .qv-ph .phone { position:relative; left:auto; top:auto; transform:none; width:auto; height:min(52vh,94vw); order:1; }
  .qv-ph .phone.fanmode { height:min(52vh,94vw); top:auto; }
  .qv-ph .txts { position:relative; inset:auto; order:2; min-height:240px; pointer-events:auto; }
  .qv-ph .chap.side-l, .qv-ph .chap.side-r { left:0; right:0; width:auto;
    transform:translateY(calc(-50% + 30px)); }
  .qv-ph .chap.side-l.on, .qv-ph .chap.side-r.on { transform:translateY(-50%); }
  .qv-ph .chap h3 { font-size:clamp(26px,7vw,34px); }
}
@media (prefers-reduced-motion:reduce){
  .qv-ph { height:auto; }
  .qv-ph .stick { position:static; height:auto; }
  .qv-ph .txts { position:relative; inset:auto; pointer-events:auto; }
  .qv-ph .phone { position:relative; left:auto; top:auto; transform:none; width:auto; }
  .qv-ph .chap.side-l, .qv-ph .chap.side-r { left:0; right:0; width:auto; }
}

/* ============ MASK — knockout text over color film ============ */
.qv-mask { position:relative; height:150vh; background:var(--ink); }
.qv-mask .stick { position:sticky; top:0; height:100vh; min-height:560px; overflow:hidden; }
.qv-mask video { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  filter:blur(25px); }
.qv-mask svg.knock { position:absolute; inset:0; width:100%; height:100%; display:block; }
.qv-mask .knock text { font-family:'Rubik',sans-serif; font-weight:800; letter-spacing:-0.03em; }
.qv-mask .mcopy { position:absolute; inset-inline:0; bottom:clamp(28px,6vh,70px); text-align:center;
  opacity:0; transform:translateY(20px); transition:opacity .6s ease, transform .6s ease; }
.qv-mask .mcopy .mh { color:#fdfcff; font-size:clamp(30px,3.6vw,52px); margin-top:14px; }
.qv-mask .mcopy .mact { margin-top:26px; }
.qv-mask .mcopy .maddr { font-size:13.5px; color:#8d86ad; margin-top:22px; }
.qv-mask .mcopy.on { opacity:1; transform:none; }
.qv-mask .mcopy .eyebrow { font-family:'Rubik',sans-serif; font-weight:500; font-size:14px;
  letter-spacing:.18em; text-transform:uppercase; color:#c9b8ff; }
.qv-mask .mcopy p { color:#b9b3d6; font-size:clamp(17px,1.5vw,20px); max-width:34em;
  margin:14px auto 0; padding-inline:24px; }
.qv-mask .mcopy p b { color:#fdfcff; font-weight:600; }
@media (prefers-reduced-motion:reduce){
  .qv-mask { height:100vh; }
  .qv-mask .mcopy { opacity:1; transform:none; }
}

/* ============ KVITTO MARQUEE — quotes as receipts ============ */

/* ============================================================================
 * Full-bleed canvas
 * ----------------------------------------------------------------------------
 * The theme reserves space for its fixed header with padding-top:100px on
 * #pxl-main. The homepage renders at y=0 because its hero fills that area, but
 * on a journey page the gap exposes the white <body> above the dark canvas as
 * a white block. Journey pages draw their own top spacing, so drop it.
 *
 * Scoped to .qv-journey-page (set by the loader) so ordinary pages keep the
 * theme's spacing.
 * ========================================================================== */
/* Spacing is handled by the page's own theme meta (content_spacing with zero
   padding, set by the page builder) rather than by fighting the theme from CSS.
   Verified: with this stylesheet disabled, #pxl-main still computes
   padding-top/bottom = 0 on a journey page.

   Note: never null #pxl-main's margin-bottom. Nexros' footer is
   position:fixed; bottom:0; z-index:-1 and sits behind the page; that inline
   margin (theme.js:966) is the scroll distance that reveals it. */

/* The dark canvas is the page ground here; keep <body> from flashing white
   behind it (e.g. during overscroll). */
body.qv-journey-page { background: #14121f; }
