/* ============================================================
   Nellie homepage, built to the V4 design comp (the Illustrator
   artboard in Nellie-Website-V4_Folder, 1366px wide). Single
   file, no build step. Brand: deep purple #3d076b -> #8735cb
   (footer gradient), heading ink #43106f, accent #842fd1, soft
   lavender surfaces #fff0ff / #f7defd. Type Nunito (display) +
   Nunito Sans (body) as full variable ranges.
   V4 notes that differ from earlier comps: section headings are
   INK not bright purple, kickers carry a thin underline, the
   features bar is a fully-rounded pill with filled icon circles,
   who-is-nellie-for is a full-bleed background photo, the key
   features slider has SIX slides with its nav overlaid on the
   image, and the footer is square-cornered with no column
   headings.
   Motion: transform and opacity only, reveals via
   IntersectionObserver, rAF-damped mouse parallax, everything
   gated behind prefers-reduced-motion.
   ============================================================ */

:root{
  /* ---- Brand palette (v2) ----
     Primary Dark #3e0a6e  headings + body copy on light backgrounds
     Primary Light #ffffff text on dark / on accent buttons
     Secondary Light #fef0fe
     Accent 1 #5c1a8c · Accent 2 #c866e9 (also highlight word colour)
     Accent 3 #7e37ca · Light gradient #e4b8f5 -> #fef0fe */
  --ink:#3e0a6e;
  --ink-deep:#2c0a4d;
  --accent1:#5c1a8c;
  --accent2:#c866e9;
  --accent3:#7e37ca;
  --accent:#5c1a8c;
  --accent-soft:#c866e9;
  --accent-bright:#c866e9;     /* highlighted words */
  --sec-light:#fef0fe;
  --light-grad:linear-gradient(90deg,#e4b8f5,#fef0fe);
  --icon-grad:linear-gradient(135deg,#c866e9,#7e37ca);
  /* headings and body copy both sit at Primary Dark on light bg */
  --display:#3e0a6e;
  --body-purple:#3e0a6e;
  --muted:#5c1a8c;
  --lav-0:#fef0fe;
  --lav-1:#fff6ff;
  --lav-2:#f3ddfb;
  --lav-3:#fbeefe;
  --hairline:#ecd3f7;
  --footer-grad:linear-gradient(105deg,#3d076b,#52128d 45%,#8735cb);
  /* tighter shadows: the old 50px/70px blur was huge, and a very soft shadow is
     what the compositor re-rasterises as a HARD offset copy during scroll. A
     smaller blur keeps the premium lift but makes any scroll re-raster tiny and
     imperceptible. */
  --card-shadow:0 10px 28px rgba(67,16,111,.13);
  --card-shadow-hover:0 18px 42px rgba(67,16,111,.22);
  --radius-lg:28px;
  --radius-pill:999px;
  --font-display:'Nunito','Nunito Sans',sans-serif;
  --font-body:'Nunito Sans','Segoe UI',sans-serif;
  --header-h:76px;
  /* top safe-area inset (iOS notch / status bar). 0 on devices without one, so
     it is a no-op off iOS. Added to the fixed header (its purple fills the inset)
     and to every content offset that clears the header. */
  --safe-top:env(safe-area-inset-top, 0px);
}

*{box-sizing:border-box;margin:0;padding:0}
/* smooth scrolling is enabled by JS after load, so refreshes and
   hash restores land instantly in the right place */
html.smooth{scroll-behavior:smooth}
html,body{overflow-x:clip}
/* deep brand purple on the root canvas so the area BEHIND/above the fixed nav
   never shows white on mobile: the browser's top inset (notch / status-bar) and
   any rubber-band overscroll at the top reveal this instead of the white canvas,
   matching the purple header. Paired with the <meta name="theme-color">. The
   lavender body paints over it for the page itself; the dark footer blends with
   it at the bottom. */
html{background:#3d076b}
body{
  font-family:var(--font-body);
  color:var(--ink);
  /* iOS Safari tints the top safe-area (status bar / notch) from the BODY's
     background, ignoring the fixed header painted over it. So the body carries a
     purple base with the lavender page laid over everything BELOW the safe-area
     inset: the top strip (behind the header) is purple -> the status bar reads
     purple, the visible page stays lavender. Off iOS --safe-top is 0, so the
     lavender covers 100% and purple never shows (page unchanged). */
  background:linear-gradient(var(--lav-1),var(--lav-1)) left var(--safe-top)/100% calc(100% - var(--safe-top)) no-repeat, #3d076b;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
ul{list-style:none}
button{font-family:inherit;cursor:pointer;border:0;background:none}

/* Fluid type. v2: every heading is Primary Dark (#3e0a6e) in Nunito
   Semibold (600) by default; large headings bumped +5%. */
h1,h2,h3{font-family:var(--font-display);line-height:1.16;color:var(--ink);font-weight:600}
h1{font-size:clamp(2rem,3.47vw,2.99rem);font-weight:600}
h2{font-size:clamp(1.68rem,2.94vw,2.73rem);font-weight:600;color:var(--display)}
h3{font-size:clamp(1.2rem,2vw,1.5rem);font-weight:600}

.wrap{max-width:1152px;margin:0 auto;padding:0 clamp(20px,4vw,32px)}
section{position:relative}
/* anchored jumps (#faqs, #about...) land clear of the fixed header */
section[id],footer[id]{scroll-margin-top:calc(var(--safe-top) + var(--header-h) + 12px)}
/* horizontal overflow from animation pre-states stays contained */
main section{overflow-x:clip}
::selection{background:#caa0e8;color:#2c0a4d}
:focus-visible{outline:3px solid var(--accent-bright);outline-offset:2px;border-radius:6px}

/* V4 kicker: small caps ink with a short underline beneath */
.kicker{
  display:inline-block;
  /* pre-heading scales down with everything else on smaller screens */
  font-size:clamp(.74rem,2.1vw,.92rem);letter-spacing:.18em;text-transform:uppercase;
  font-weight:600;color:var(--ink);margin-bottom:12px;
  border-bottom:1.5px solid var(--accent-soft);padding-bottom:5px;
}
.t-center{text-align:center}
.nowrap{white-space:nowrap}
/* mobile-only line break: forces a heading to wrap at a chosen point on
   phones while staying on one flow on desktop */
.m-br{display:none}
@media (max-width:760px){.m-br{display:inline}}

/* ---------- Reveal-on-scroll primitives ----------
   Elements start shifted and transparent; the .in class (added by
   IntersectionObserver) animates them home. data-delay staggers
   siblings. With reduced motion, or without JS, everything is
   simply visible: the base state only applies under .js + ok-motion. */
.reveal{transition:opacity .8s cubic-bezier(.22,1,.36,1),transform .8s cubic-bezier(.22,1,.36,1)}
.js.ok-motion .reveal{opacity:0;transform:translateY(34px)}
/* capped sideways offsets so pre-reveal states never widen the
   document's paintable canvas on small screens */
.js.ok-motion .reveal.r-left{transform:translateX(clamp(-44px,-4vw,-20px))}
.js.ok-motion .reveal.r-right{transform:translateX(clamp(20px,4vw,44px))}
.js.ok-motion .reveal.r-pop{transform:scale(.86)}
/* r-drop: a slower, softer fall from above that settles with a gentle
   landing (used by the step cards so they drop in one at a time) */
.reveal.r-drop{transition:opacity 1s ease,transform 1.05s cubic-bezier(.18,.7,.24,1.05)}
.js.ok-motion .reveal.r-drop{opacity:0;transform:translateY(-42px) scale(.96)}
/* r-rise: a slower, weightier rise for large cards (the carousel) */
.reveal.r-rise{transition:opacity 1.1s ease,transform 1.15s cubic-bezier(.22,1,.36,1)}
.js.ok-motion .reveal.r-rise{opacity:0;transform:translateY(56px) scale(.97)}
.js.ok-motion .reveal.in{opacity:1;transform:none}
/* Hold a card's box-shadow OFF until its reveal has SETTLED. As a card fades /
   moves in (the reveal), its opacity/transform animate, which composites the card
   onto a GPU layer, and the compositor renders its soft box-shadow as a HARD,
   offset copy for the duration of that animation. Because reveals only fire as
   elements scroll INTO view, this shows on scroll DOWN only, on exactly the white
   shadowed shapes (pills bar, banner, step cards). With no shadow present during
   the animation there is nothing to render hard; JS adds .sh once the card is
   static and de-composited, and the element's own soft shadow fades back in and
   stays locked to the page. Non-shadowed reveals are unaffected (none -> none). */
.js.ok-motion .reveal:not(.sh){box-shadow:none}

/* ============================ HEADER ============================ */
.site-header{
  position:fixed;top:0;left:0;right:0;z-index:100;
  color:#fff;
  /* the purple fills the iOS top safe-area (notch/status bar) so it never cuts
     to white above the nav; the bar's own content sits below the inset. 0 off iOS. */
  padding-top:var(--safe-top);
  /* solid, no backdrop-filter: the blur re-rendered the content behind the
     fixed header every frame while scrolling, and combined with the header's
     box-shadow it flashed a shadow band along the header's bottom edge on
     scroll. At 92% opacity the blur was barely visible anyway, so the header
     is now a clean flat colour with no per-frame cost. */
  /* Flat #3d076b, NOT a gradient: it matches the iOS safe-area / status-bar
     strip, the page background and the theme-color exactly, so the bar reads as
     one continuous purple up into the notch. The old 105deg gradient clashed
     with that solid strip along the top edge on iOS. */
  background:#3d076b;
  /* NO drop shadow. The header auto-hides on scroll (transform: translateY),
     and any drop shadow on a fixed element that slides in/out SWEEPS across the
     content on every scroll-up, which read as a shadow "appearing/glitching" on
     scroll, site-wide. The bold purple gradient separates cleanly from the pale
     content on its own, so the shadow is dropped entirely. Only transform is
     transitioned now (no box-shadow to animate). */
  transition:transform .4s ease;
}
.site-header.hidden-up{transform:translateY(-100%)}
.header-inner{
  max-width:1152px;margin:0 auto;height:var(--header-h);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 clamp(20px,4vw,32px);
}
.logo{height:48px;width:160px;position:relative;flex-shrink:0}
.logo img{height:100%;width:100%;object-fit:contain;object-position:left center}
.nav-desktop{display:flex;align-items:center;gap:clamp(20px,3.2vw,44px);font-weight:700;font-size:1.05rem}
.nav-desktop a{opacity:.9;position:relative;padding:6px 0;transition:opacity .25s,color .25s}
.nav-desktop a::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--accent-bright);border-radius:2px;
  transform:scaleX(0);transform-origin:left;transition:transform .3s ease;
}
.nav-desktop a:hover{opacity:1}
.nav-desktop a:hover::after{transform:scaleX(1)}
/* scrollspy: the section currently in view tints its link pink, the
   active state the comp shows on "about" */
.nav-desktop a.active{color:var(--accent-bright);opacity:1}

/* Hamburger: three bars that morph into a cross when open. */
.burger{display:none;width:44px;height:44px;position:relative;z-index:130}
.burger span{
  position:absolute;left:10px;right:10px;height:3px;border-radius:3px;
  background:#fff;transition:transform .35s ease,opacity .25s ease,top .35s ease;
}
.burger span:nth-child(1){top:14px}
.burger span:nth-child(2){top:21px}
.burger span:nth-child(3){top:28px}
.menu-open .burger span:nth-child(1){top:21px;transform:rotate(45deg)}
.menu-open .burger span:nth-child(2){opacity:0}
.menu-open .burger span:nth-child(3){top:21px;transform:rotate(-45deg)}

/* Mobile menu: full-screen overlay, links stagger in. */
.nav-mobile{
  position:fixed;inset:0;z-index:120;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:10px;
  background:var(--footer-grad);
  opacity:0;pointer-events:none;transition:opacity .35s ease;
}
.menu-open .nav-mobile{opacity:1;pointer-events:auto}
/* the burger lives inside the header, whose z-index would otherwise
   trap it beneath the overlay; lift the whole header while open so
   the logo and the close cross stay visible and clickable */
.menu-open .site-header{z-index:130;background:transparent;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none}
.nav-mobile a{
  color:#fff;font-family:var(--font-display);font-weight:600;
  font-size:2rem;padding:10px 24px;
  opacity:0;transform:translateY(22px);
  transition:opacity .4s ease,transform .4s ease;
}
.menu-open .nav-mobile a{opacity:1;transform:none}
.menu-open .nav-mobile a:nth-child(1){transition-delay:.08s}
.menu-open .nav-mobile a:nth-child(2){transition-delay:.14s}
.menu-open .nav-mobile a:nth-child(3){transition-delay:.2s}
.menu-open .nav-mobile a:nth-child(4){transition-delay:.26s}
.menu-open .nav-mobile a:nth-child(5){transition-delay:.32s}

@media (max-width:860px){
  .nav-desktop{display:none}
  .burger{display:block}
}

/* ============================ BUTTONS ============================ */
.btn{
  display:inline-flex;align-items:center;gap:.55em;
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(.9rem,.85vw,1.02rem);
  padding:.72em 1.5em;border-radius:var(--radius-pill);
  position:relative;overflow:hidden;
  transition:transform .25s cubic-bezier(.34,1.56,.64,1),box-shadow .25s ease;
  /* no permanent will-change: it parked every button on its own GPU layer
     whose soft shadow dragged/jittered on scroll. The hover transform still
     composites fine on its own; the shadow now rides with the page. */
}
.btn img{width:1.25em;height:1.25em}
.btn:hover{transform:translateY(-3px) scale(1.03)}
.btn:active{transform:translateY(0) scale(.98)}
.btn-primary{
  color:#fff;background:linear-gradient(120deg,#c692ec,#b06ce0);
  box-shadow:0 10px 24px rgba(150,80,200,.32);
}
.btn-primary:hover{box-shadow:0 16px 34px rgba(150,80,200,.42)}
/* deep solid secondary, per the comp's "how it works" */
.btn-deep{
  color:#fff;background:linear-gradient(120deg,#9c4fe0,#7f2fd0);
  box-shadow:0 10px 26px rgba(110,30,180,.35);
}
/* V4 secondary: solid white pill, ink text */
.btn-ghost{
  color:var(--ink);background:#fff;
  box-shadow:0 10px 26px rgba(67,16,111,.18);
}
/* lighter primary used on the white CTA band */
.btn-soft{
  color:#fff;background:linear-gradient(120deg,#bf7ce8,#a55ddd);
  box-shadow:0 12px 30px rgba(160,80,210,.35);
}
/* v2 pricing accent buttons: a bright accent-2 pill and a deep accent-3
   pill. Declared after btn-primary so the modifier wins the solid colour
   when both classes sit on the element. */
.btn-bright{color:#fff;background:#c866e9;box-shadow:0 10px 24px rgba(200,102,233,.34)}
.btn-bright:hover{box-shadow:0 16px 34px rgba(200,102,233,.44)}
.btn-grape{color:#fff;background:#7e37ca;box-shadow:0 10px 26px rgba(126,55,202,.36)}
.btn-grape:hover{box-shadow:0 16px 34px rgba(126,55,202,.46)}
/* A light streak that sweeps across filled buttons on hover. */
.btn-primary::after,.btn-soft::after{
  content:'';position:absolute;top:0;bottom:0;left:-80%;width:50%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.45),transparent);
  transform:skewX(-20deg);transition:left .55s ease;
}
.btn-primary:hover::after,.btn-soft:hover::after{left:130%}

/* ============================ HERO ============================ */
/* V4 shows the hero photo (hero-v4.jpg, 2.17:1) essentially in full:
   tablet and phone right of centre, copy on the pale left. Height
   tracks the image aspect so nothing important crops away. */
.hero,.page-hero{
  /* soft brand wash from beneath the nav down into the photo's own
     pale tone, so the space above the photo never reads as white */
  background:linear-gradient(180deg,#e9cdf4,#f9e8fb 34%,#fdf0fd 60%);
}
.hero{
  /* the hero locks to the photo: header height plus the image's
     aspect height (1229/2663), so the photo's top break aligns just
     beneath the nav and the fold lands at the straddling bar */
  min-height:max(580px,calc(var(--safe-top) + var(--header-h) + 46.17vw));
  /* the wash stays LIGHT down the whole hero, then HARD-STEPS to the solid
     block colour on one line. That line is calc(100% - 64px): the exact guide
     where the photo hard-cuts on the right and where the lozenge centres
     (features-dock sits at heroBottom-64). The step is a hard edge (two stops
     at the same position), NOT a smooth ramp: a smooth gradient has no visible
     line, so the left half (which carries almost no photo, just wash) read as
     a soft fade while the right had the photo's crisp wood->lilac edge. Meeting
     the light wash and #ecd8f6 at the same calc gives the block a clean
     horizontal start right across the width, so the left matches the photo cut
     on the right at every viewport height. The above-line tone is a near-white
     lilac (#fcf1fe), deliberately lighter than the block, so the step reads
     with some contrast on the left where there is no photo to define it (a
     pale-on-pale step was too faint). Below the line the hero is solid #ecd8f6,
     flush into the features band. */
  background:linear-gradient(180deg,#e9cdf4,#fcf1fe 40%,#fcf1fe calc(100% - 64px),#ecd8f6 calc(100% - 64px),#ecd8f6 100%);
  display:flex;align-items:center;
  padding:calc(var(--safe-top) + var(--header-h) + clamp(14px,2.6vh,34px)) 0 clamp(70px,7vw,104px);
  overflow:hidden;
  /* no perspective: it was only for 3D float chips (.note), which the home hero
     does not use, and a perspective context put the hero's shadowed CTA buttons
     on GPU layers whose shadows drifted on scroll. Dropping it de-promotes them.
     (how-it-works uses .page-hero, not .hero, so its float chips are unaffected.) */
}
/* the block's top edge as ONE clean line across the FULL width, on the same
   guide the photo cuts and the lozenge centres (bottom:64px = calc(100%-64px)).
   The right side gets this line for free from the photo's wood->lilac cut; the
   left is pale-lilac-on-pale-lilac and colour alone can't make it read, so a
   soft grounding shadow defines it: the scene "sits on" the block and casts a
   gentle shadow onto it, giving the left the same visible straight edge as the
   right. It is a STATIC shadow on an in-flow layer (scrolls with the page), so
   it never sweeps or glitches like the old fixed-header shadow did. */
.hero::after{
  content:'';position:absolute;left:0;right:0;bottom:64px;height:1px;z-index:1;
  pointer-events:none;
  background:rgba(96,42,150,.16);
  box-shadow:0 7px 20px -1px rgba(96,42,150,.17);
}
.hero-photo{
  position:absolute;inset:0;z-index:0;
  /* natural aspect, pinned to the photo's bottom edge: at normal
     windows the image spans the full width and grows with it; on
     short-wide (letterbox) windows min() scales it down to fit the
     height instead, so the scene never chops. Any gap falls on the
     pale left, under the copy wash. The faint top mask blends the
     wall edge into the section gradient without touching the
     product colours. */
  /* lifted off the floor; the features lozenge below is lifted by the
     same amount (.features-dock) so the desk still meets the lozenge and
     the whole pair sits higher, with more space opening beneath it */
  background:url('../nellie/images/hero-v4.webp') center calc(100% - 64px)/100% auto no-repeat;
  /* the top edge blends the wall into the wash. The bottom edge is a defined
     line at the LOZENGE'S MIDDLE (the photo's own foot, 100% - 64px, which by
     design sits half-way up the straddling lozenge): the lozenge is the line
     break, so the photo meets the lilac at its own vertical centre, level
     across the whole width, with the table edge on the right meeting it there. */
  -webkit-mask-image:linear-gradient(180deg,transparent 76px,#000 165px,#000 calc(100% - 64px),transparent calc(100% - 64px));
  mask-image:linear-gradient(180deg,transparent 76px,#000 165px,#000 calc(100% - 64px),transparent calc(100% - 64px));
  /* no compositor layer: with the zoom and the scroll parallax both gone,
     will-change:transform kept the masked photo on its own GPU layer, whose
     sub-pixel re-raster on scroll flickered a faint shadow at the mask edge.
     Rendering it inline (auto) keeps the fade rock-steady while scrolling. */
  transform-origin:right bottom;
  will-change:auto;
}
/* header zoom removed per amends: the hero photo holds still */
@keyframes kenburns{
  from{transform:scale(1)}
  to{transform:scale(1.045)}
}
/* gentle left wash so the copy always reads. It STOPS at the block line
   (bottom:64px = calc(100%-64px)): covering the full height meant this near-white
   wash painted over the hero's own #ecd8f6 block on the left, lightening it, so
   the dark colour only appeared BELOW the hero at the band, a good 64px under the
   line. Ending the tint on the line lets the block show its true dark tone right
   up to the line, so the darker colour meets the line across the width. */
.hero-tint{
  position:absolute;top:0;left:0;right:0;bottom:64px;z-index:1;
  background:linear-gradient(90deg,rgba(255,240,255,.96),rgba(255,240,255,.88) 30%,rgba(255,240,255,.4) 38%,rgba(255,240,255,0) 45%);
}
/* below desktop the hero stacks: copy on top in fully clear space,
   photo framing the bottom with the devices untinted below the text.
   No horizontal wash fighting full-width copy. */
@media (max-width:1020px){
  .hero{min-height:max(640px,96svh);align-items:flex-start;padding-bottom:56px}
  .hero-content{max-width:none}
  .hero-ctas{max-width:none}
  .hero-tint{background:linear-gradient(180deg,rgba(255,240,255,.99),rgba(255,240,255,.97) 42%,rgba(255,240,255,.55) 50%,rgba(255,240,255,0) 58%)}
  .hero-photo{
    background-size:auto 50%;background-position:65% bottom;
    -webkit-mask-image:linear-gradient(180deg,transparent 49%,#000 54%);
    mask-image:linear-gradient(180deg,transparent 49%,#000 54%);
  }
}
@media (max-width:760px){
  .hero{min-height:max(640px,100svh)}
  .hero-photo{background-position:78% bottom}
}
/* narrow column: the V4 photo's phone sits at ~34% of the frame, so
   the copy must hold to the pale strip left of it */
/* the hero is a flex container, so without an explicit width the
   wrap shrink-wraps and auto-margins centre it; force full width so
   the copy sits at the container's left edge. The slight upward bias
   reads better than true centre against the bottom-framed photo. */
.hero .wrap,.page-hero .wrap{width:100%;margin-top:-5svh}
.hero-content{position:relative;z-index:3;max-width:clamp(330px,26vw,520px)}
.hero h1,.page-hero h1{
  font-size:clamp(2.2rem,3.36vw,4.2rem);font-weight:600;
  color:var(--display);line-height:1.16;
}
/* measure tuned so the homepage headline breaks after "way" */
.hero h1{max-width:6.2em;}
@media (max-width:760px){.hero-content{max-width:none}}
/* Headline words rise in one by one (spans injected by JS). */
h1 .w{display:inline-block;overflow:hidden;vertical-align:bottom}
h1 .w i{display:inline-block;font-style:normal}
.js.ok-motion h1 .w i{transform:translateY(110%);animation:wordup .9s cubic-bezier(.22,1,.36,1) forwards;animation-delay:var(--d,0s)}
@keyframes wordup{to{transform:translateY(0)}}
.hero-sub{
  font-size:clamp(1rem,1.3vw,1.6rem);max-width:23em;
  margin:clamp(18px,3vh,40px) 0 clamp(20px,3.2vh,42px);
  font-weight:500;color:var(--body-purple);line-height:1.62;
}
.hero-sub strong{font-weight:800;color:#3e0a6e}
/* allowed to run wider than the copy column, per the comp */
.hero-ctas{display:flex;flex-wrap:wrap;gap:13px;width:max-content;max-width:60vw}

/* Floating notification chips: product-UI moments drifting at
   different 3D depths over the photo. Mouse parallax shifts each by
   its data-depth; a gentle float keeps them alive when the pointer
   is still. Kept clear of the tablet and phone screens. */
.float-layer{position:absolute;inset:0;z-index:2;pointer-events:none;transform-style:preserve-3d}
.note{
  position:absolute;display:flex;gap:10px;align-items:center;
  /* solid white, NO backdrop-filter and NO will-change: the blur re-rendered
     the content behind this shadowed floating chip every frame while scrolling,
     and the permanent GPU layer let its big soft shadow drag, both flickering a
     shadow on scroll. Solid fill + inline rendering keep it rock-steady. */
  background:#fff;
  border:1px solid rgba(255,255,255,.8);
  border-radius:18px;padding:10px 16px;
  box-shadow:0 14px 38px rgba(67,16,111,.22);
  font-size:.86rem;font-weight:700;color:var(--ink);
  white-space:nowrap;
}
.note-inner{display:flex;gap:10px;align-items:center;transition:opacity .35s ease,transform .35s ease}
.note.swapping .note-inner{opacity:0;transform:translateY(10px) rotateX(55deg)}
.note .emoji{
  width:34px;height:34px;border-radius:12px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;font-size:1.05rem;
  background:linear-gradient(135deg,#f3d4fb,#e2b1f4);
}
.note small{display:block;font-weight:600;color:var(--muted);font-size:.74rem;line-height:1.2}
.js.ok-motion .note{animation:floaty 6s ease-in-out infinite alternate;animation-delay:var(--fd,0s)}
@keyframes floaty{from{margin-top:0}to{margin-top:-14px}}
.note-1{top:16%;right:3%}
.note-2{bottom:28%;right:18%}
@media (max-width:1020px){
  .note-2{display:none}
  .note-1{top:12%;right:6%}
}
@media (max-width:760px){
  .note{font-size:.78rem;padding:8px 12px}
  .note-1{top:auto;bottom:13%;left:auto;right:5%}
}

/* ================== FEATURES BAR (under the hero) ==================
   V4: one fully-rounded white pill pulled up over the photo's bottom
   edge, four items with hairline dividers, filled lavender icon
   circles, and the small gradient pill perched on its top-left. */
/* the Why section's lilac rises to meet the hero photo, so this band
   carries the same lilac and the lozenge straddles the seam (per the
   join mockup). The next section (.why) continues the same tone. */
/* starts LIGHT (= the hero wash bottom, so the photo edge blends away) and
   deepens to the brand lilac, which continues into the Why section */
.features-band{background:#ecd8f6;padding:0 0 clamp(28px,3.5vw,48px)}
/* the -64px matches the hero photo's lift so the lozenge rises with the
   desk (stays docked to it); the existing -50% keeps it straddling. The
   matching negative margin-bottom pulls the next section up by the same
   64px so the lift doesn't open an oversized gap below the lozenge. */
/* lift the straddling lozenge with position, NOT transform. A permanent
   transform put this card (and its dark-purple box-shadow) on its own GPU
   layer, which desynced from the page on scroll: the shadow appeared to shift
   behind the pills. position:relative + top lifts it identically with no layer,
   so the shadow scrolls locked to the content. (Mobile already did this.) The
   top value is ~ half the dock height + 64, matching the old -50%-64 ride-up;
   the dock is a stable single row on desktop so a fixed value tracks it. */
.features-dock{position:relative;top:-124px;margin-bottom:-64px}
.features-bar{
  position:relative;
  background:#fff;border-radius:999px;   /* perfect lozenge, not a rounded rectangle */
  box-shadow:var(--card-shadow);
  transition:box-shadow .6s ease;   /* so the post-reveal shadow fades in, not pops */
  display:grid;grid-template-columns:repeat(4,1fr);
  padding:clamp(13px,1.7vw,24px) clamp(20px,2.6vw,38px);   /* slimmer lozenge */
  z-index:5;
}
.fb-pill{
  /* centred on the bar's top edge with a negative top, NOT transform: this
     lozenge carries a purple shadow, and a transform put it on a GPU layer whose
     shadow drifted on scroll. top:-24px (~half its ~49px height) sits it the same
     place with no layer, so the shadow stays locked to the page. */
  position:absolute;left:clamp(16px,3vw,34px);top:-24px;
  background:#e4b8f5;
  color:#3e0a6e;font-family:var(--font-display);font-weight:600;
  font-size:clamp(.85rem,.95vw,1.12rem);
  padding:.6em 1.5em;border-radius:var(--radius-pill);
  box-shadow:0 12px 28px rgba(123,46,198,.22);
  white-space:nowrap;
}
.fb-item{
  display:flex;align-items:center;gap:11px;
  padding:4px clamp(8px,1.2vw,16px);
  /* features copy, held to 3 lines per item */
  font-weight:700;font-size:clamp(.86rem,.96vw,1.05rem);line-height:1.3;color:var(--ink);
}
.fb-item > span:last-child{max-width:14em}
.fb-item + .fb-item{border-left:1px solid var(--hairline)}
.fb-ico{
  width:clamp(42px,2.8vw,54px);height:clamp(42px,2.8vw,54px);border-radius:50%;flex-shrink:0;
  background:var(--icon-grad);
  display:flex;align-items:center;justify-content:center;
}
/* per-badge brand colours (v2) */
.fb-ico.fb-msg{background:#5c1a8c}
.fb-ico.fb-photo{background:#c866e9}
.fb-ico.fb-music{background:#7e37ca}
.fb-ico.fb-cal{background:#e4b8f5}
/* the icon set ships white; on the light calendar badge tint it dark
   so it stays legible */
.cap-ico img{filter:brightness(0) invert(1)}
.fb-ico img{width:46%;height:46%}
/* calendar icon stays white per amends (was tinted dark on the light badge) */
@media (max-width:980px){
  .features-bar{grid-template-columns:1fr 1fr;row-gap:18px}
  .fb-item:nth-child(odd){border-left:0}
  .fb-item:nth-child(3){border-left:0}
  .fb-item:nth-child(4){border-left:1px solid var(--hairline)}
}
@media (max-width:560px){
  /* SOFT FEATURE ROWS: the "with nellie..." line reads as a clean header
     (in-flow, never overlapping the photo, so it can't hide on scroll),
     and each benefit sits in its own soft lavender rounded row. */
  .features-bar{
    grid-template-columns:1fr;margin-top:0;gap:9px;
    padding:18px clamp(13px,3.5vw,18px);border-radius:24px;
  }
  .fb-pill{
    position:static;transform:none;justify-self:start;
    background:none;box-shadow:none;padding:0;
    margin:2px 4px 9px;white-space:normal;
    color:var(--display);font-family:var(--font-display);font-weight:800;
    font-size:1.04rem;line-height:1.25;
  }
  .fb-pill b{color:var(--accent-bright)}
  .fb-item{
    border:0 !important;
    background:var(--lav-2);border-radius:15px;
    padding:12px 14px;gap:13px;align-items:center;
  }
  .fb-item + .fb-item{border-top:0}
  .fb-ico{width:42px;height:42px}
  .fb-item > span:last-child{font-size:.94rem;line-height:1.3}
}

/* ============================ WHY NELLIE ============================ */
.why{
  padding:clamp(44px,6vw,80px) 0;
  /* continuous flow from the features band (its bottom is #eed6f6): no radial
     glow (it read as a saturated horizontal band at the join) */
  background:linear-gradient(180deg,#ecd8f6,#fbeefe);
  overflow:hidden;
}
.why-grid{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(32px,5vw,72px);align-items:center}
@media (max-width:900px){.why-grid{grid-template-columns:1fr;justify-items:center}.why-copy{justify-self:stretch}}
/* Circular portrait with a fine offset ring. */
.why-circle{
  position:relative;width:min(350px,75vw);aspect-ratio:1;
  border-radius:50%;overflow:hidden;
  box-shadow:var(--card-shadow);
  /* no permanent GPU layer (nothing animates it on scroll now), so its
     shadow no longer jitters while scrolling */
}
.why-circle img{width:100%;height:100%;object-fit:cover;object-position:72% 50%}
.why-circle-wrap{position:relative;width:fit-content;margin:0 auto}
/* stroke in accent 2, with the gap to the image tightened by 30% (-12 -> -8) */
.why-circle-wrap::after{
  content:'';position:absolute;inset:-8px;border-radius:50%;
  border:2px solid #c866e9;pointer-events:none;
}
.why-list{margin-top:18px;display:flex;flex-direction:column;gap:0}
/* key points align flush with the headline's left edge, no hover */
.why-item{
  display:flex;gap:13px;align-items:center;
  padding:8px 0;border-radius:14px;
}
.why-item .ico{
  width:38px;height:38px;border-radius:50%;flex-shrink:0;
  background:#c866e9;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 10px 22px rgba(123,46,198,.3);
}
.why-item .ico img{width:20px;height:20px;filter:brightness(0) invert(1)}
.why-item p{font-weight:700;font-size:clamp(1rem,1.25vw,1.15rem);line-height:1.45}
.why-item .stat{color:var(--accent2);font-weight:800}
/* designed lozenge: as wide as the with-nellie lozenge, semibold, +15% */
.why-pill{
  margin:clamp(40px,5vw,56px) auto 0;max-width:none;
  background:#fff;border-radius:var(--radius-pill);
  padding:clamp(16px,2.4vw,24px) clamp(28px,5vw,56px);
  text-align:center;box-shadow:var(--card-shadow);
  transition:box-shadow .6s ease;   /* so the post-reveal shadow fades in, not pops */
  font-family:var(--font-display);font-weight:600;
  font-size:clamp(1.21rem,2.3vw,1.93rem);color:var(--display);
}

/* ============================ WHO FOR ============================
   V4: the photo IS the section, full-bleed, with the copy sitting on
   the image's own pale left side over a soft wash. */
.who{
  padding:clamp(56px,7vw,96px) 0;
  min-height:clamp(420px,44vw,620px);
  display:flex;align-items:center;
  background:url('../nellie/images/Who-is-nellie-for.webp') right center/cover no-repeat;
  background-color:#fef0fe;
  overflow:hidden;
}
/* #e4b8f5 wash backs the copy and fades smoothly into the photo, so the
   colour and the image meet with no hard seam (the photo's own pale left
   carries the blend through to #fef0fe) */
.who::before{
  content:'';position:absolute;inset:0;
  /* one continuous fade from the #e4b8f5 copy side into the photo, no
     colour stops, so there is no perceptible seam */
  background:linear-gradient(90deg,#e4b8f5 8%,rgba(228,184,245,0) 64%);
}
@media (max-width:900px){
  /* stacked: copy on a solid wash, then a dedicated MOBILE image as a full-width
     band at the section's foot (a portrait composition, shown whole at 100%
     width, no zoom-crop). padding-bottom reserves the band's height (82vw for
     the 1080x889 image) PLUS a gap, so the simple/familiar/comforting chips sit
     clear of the image and never overlap it. The wash covers the copy area and
     fades out just above the image. */
  .who{
    background-image:url('../nellie/images/who-is-nellie-for-mobile.webp');
    background-size:100% auto;background-position:center bottom;
    padding-bottom:calc(82vw + 48px);
  }
  .who::before{
    top:0;left:0;right:0;bottom:auto;height:calc(100% - 82vw - 24px);
    background:linear-gradient(180deg,#fbeefe,#fbeefe 84%,rgba(251,238,254,0));
  }
}
.who .wrap{position:relative;width:100%}
.who-copy{max-width:440px}
.who-copy p{margin-top:14px;font-weight:600;font-size:clamp(1rem,1.2vw,1.15rem);line-height:1.55;color:#3e0a6e}
.who-copy p strong{color:var(--ink);font-weight:800}
.who-list{margin:12px 0 4px;display:flex;flex-direction:column;gap:8px}
/* round dot markers, per V4 */
.who-list li{display:flex;align-items:center;gap:12px;font-weight:700;font-size:clamp(1rem,1.2vw,1.15rem)}
.who-list li::before{
  content:'';width:8px;height:8px;border-radius:50%;flex-shrink:0;
  background:linear-gradient(135deg,#c95dea,#842fd1);
}
.chips{display:flex;flex-wrap:wrap;gap:12px;margin-top:22px}
.chip{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--font-display);font-weight:800;color:#fff;font-size:.9rem;
  padding:8px 18px;border-radius:var(--radius-pill);
  transition:transform .3s cubic-bezier(.34,1.56,.64,1);
}
.chip:hover{transform:translateY(-4px) rotate(-1deg)}
.chip img{width:16px;height:16px}
.chip-1{background:#41056e}
.chip-2{background:#5c1a8c}
.chip-3{background:#7b2ec6}
@media (max-width:560px){
  /* keep the three who-for chips on one row per amends */
  .who .chips{flex-wrap:nowrap;gap:8px;justify-content:flex-start}
  .who .chip{padding:8px 12px;font-size:.78rem;gap:6px}
  .who .chip img{width:14px;height:14px}
}

/* ==================== KEY FEATURES (full-bleed slider) ====================
   White heading band, then an edge-to-edge slider. Captions sit in
   each image's baked-in pale zone (.cap-left / .cap-right). The nav
   overlays the image bottom centre, per V4. */
.features-slider{background:#fff;padding:clamp(44px,6vw,76px) 0 clamp(34px,4.5vw,60px)}
.slider{
  position:relative;margin-top:clamp(26px,3.6vw,44px);
  max-width:1240px;margin-left:auto;margin-right:auto;
  padding:0 clamp(20px,4vw,32px);
}
.slides{
  position:relative;height:clamp(300px,36vw,520px);overflow:hidden;
  border-radius:clamp(28px,3vw,44px);
  box-shadow:var(--card-shadow);
}
.slide{
  position:absolute;inset:0;opacity:0;pointer-events:none;
  transition:opacity .9s ease;
}
.slide.on{opacity:1;pointer-events:auto}
.slide img{width:100%;height:100%;object-fit:cover}
.js.ok-motion .slide.on img{animation:slidedrift 7s ease-out forwards}
.js.ok-motion .slide:nth-child(odd).on img{transform-origin:32% 42%}
.js.ok-motion .slide:nth-child(even).on img{transform-origin:68% 58%}
@keyframes slidedrift{from{transform:scale(1.06)}to{transform:scale(1)}}
.slide-cap{
  /* vertically centred with top/bottom:0 + margin:auto, NOT translateY(-50%):
     a permanent transform kept the caption (and its shadow) on a GPU layer that
     drifted on scroll. margin-auto centring lets the settled caption be
     transform:none, so it de-promotes; the slide-in below animates a small
     translateY that resolves to none. */
  position:absolute;top:0;bottom:0;height:max-content;margin-block:auto;
  max-width:min(26ch,40%);
  font-family:var(--font-display);font-weight:700;color:var(--display);
  font-size:clamp(1rem,1.9vw,1.6rem);line-height:1.35;
  /* solid-ish fill, NO backdrop-filter: the blur re-rendered every frame on
     scroll and, with this caption's shadow, flickered a shifting shadow. A
     higher-opacity fill keeps the caption legible over the slide with no
     per-frame cost. */
  background:rgba(255,246,255,.94);
  border:1px solid rgba(255,255,255,.65);
  padding:clamp(16px,2vw,28px) clamp(18px,2.2vw,30px);
  border-radius:22px;
  box-shadow:0 14px 36px rgba(67,16,111,.16);
}
.slide-cap .cap-ico{
  width:52px;height:52px;border-radius:50%;margin-bottom:14px;
  background:var(--icon-grad);
  display:flex;align-items:center;justify-content:center;
}
/* carousel icon float removed per amends */
@keyframes capfloat{from{transform:translateY(0)}to{transform:translateY(-8px)}}
/* thin accent rule grows in under the caption once the slide lands */
.slide-cap::after{
  content:'';display:block;width:64px;height:3px;border-radius:2px;
  background:linear-gradient(90deg,#c95dea,#842fd1);margin-top:14px;
  transform:scaleX(0);transform-origin:left;
  transition:transform .6s cubic-bezier(.22,1,.36,1) .55s;
}
.slide.on .slide-cap::after{transform:scaleX(1)}
.slide-cap .cap-ico img{width:25px;height:25px}
.cap-left .slide-cap{left:clamp(20px,7vw,110px)}
.cap-right .slide-cap{right:clamp(20px,7vw,110px)}
/* caption text slides up as its slide becomes active */
.js.ok-motion .slide .slide-cap{opacity:0;transform:translateY(18px);transition:opacity .7s ease .25s,transform .7s ease .25s}
.js.ok-motion .slide.on .slide-cap{opacity:1;transform:none}
@media (max-width:760px){
  .slides{height:66vw;min-height:250px}
  .slide-cap{max-width:62%;padding:12px 16px;font-size:.95rem}
  .slide-cap .cap-ico{width:38px;height:38px;margin-bottom:8px}
  .slide-cap .cap-ico img{width:19px;height:19px}
  .cap-left .slide-cap{left:14px}
  .cap-right .slide-cap{right:14px}
}
/* nav beneath the image on the white band, per the reference */
.slider-nav{
  display:flex;align-items:center;justify-content:center;gap:18px;
  padding:clamp(18px,2.6vw,30px) 0 clamp(8px,1.2vw,14px);
}
.slider-btn{
  width:40px;height:40px;border-radius:50%;position:relative;
  background:linear-gradient(135deg,#9a4ae0,#7b2ec6);
  box-shadow:0 8px 20px rgba(44,10,77,.35);
  transition:transform .3s;
}
.slider-btn:hover{transform:scale(1.12);box-shadow:0 8px 20px rgba(44,10,77,.35),0 0 0 7px rgba(255,255,255,.16)}
.slider-btn::before{
  content:'';position:absolute;top:50%;left:50%;width:9px;height:9px;
  border-top:2.5px solid #fff;border-right:2.5px solid #fff;
  transform:translate(-65%,-50%) rotate(45deg);
}
.slider-btn.prev::before{transform:translate(-35%,-50%) rotate(-135deg)}
.slider-dots{display:flex;gap:9px}
.slider-dots button{
  position:relative;width:8px;height:8px;border-radius:6px;overflow:hidden;
  background:#e2c6f3;
  transition:width .35s cubic-bezier(.22,1,.36,1),background .3s;
}
.slider-dots button.on{width:34px;background:#ecd8f8}
.slider-dots button.on::after{
  content:'';position:absolute;inset:0;border-radius:6px;
  background:linear-gradient(90deg,#9a4ae0,#7b2ec6);
  transform:translateX(-101%);
}
/* autoplay: the fill sweeps across over the advance interval */
.slider-nav.auto .slider-dots button.on::after{animation:dotfill 5.2s linear forwards}
@keyframes dotfill{to{transform:translateX(0)}}
/* manual: solid fill, no sweep */
.slider-nav.manual .slider-dots button.on::after{transform:translateX(0)}

/* ============================ HELPS ============================ */
.helps{
  padding:clamp(44px,6vw,80px) 0;
  background:#fef0fe;
}
/* Each column owns its photo, so the image sits directly above the list
   it illustrates (alone -> for your loved one, family -> for you & your
   family). Side by side on desktop, a clean photo-then-list stack on
   phones. */
.helps-cols{
  display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(28px,4.5vw,64px);margin-top:clamp(26px,3.6vw,44px);
}
.helps-col{display:flex;flex-direction:column}
.helps-col .ph{
  overflow:hidden;box-shadow:var(--card-shadow);
  height:clamp(200px,26vw,320px);border-radius:clamp(20px,2.4vw,32px);
  margin-bottom:clamp(20px,2.4vw,30px);
}
.helps-col .ph img{width:100%;height:100%;object-fit:cover;transition:transform .8s ease}
.helps-col .ph:hover img{transform:scale(1.05)}
.helps-col h3{font-size:clamp(1.5rem,2.8vw,2.4rem);margin-bottom:16px;color:var(--display);font-weight:600}
.ticks li{
  display:flex;gap:11px;align-items:flex-start;
  padding:6px 0;font-weight:600;font-size:clamp(1rem,1.25vw,1.15rem);line-height:1.4;
}
/* tick badge: tick-pink.svg is already a #c866e9 circle with a white
   check, so no recolour filter (a filter would flatten the white tick
   into the pink fill and it would read as a plain dot) */
.ticks img{width:22px;height:22px;margin-top:3px;flex-shrink:0}
@media (max-width:860px){
  .helps-cols{grid-template-columns:1fr;row-gap:clamp(36px,8vw,48px);max-width:520px;margin-left:auto;margin-right:auto}
}

/* ============================ STEPS ============================ */
.steps{
  padding:clamp(44px,6vw,80px) 0;
  /* vertical brand gradient so it reads distinct from the helps section */
  background:linear-gradient(180deg,#e4b8f5,#fef0fe);
}
.steps-grid{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(18px,2.6vw,30px);margin-top:clamp(26px,3.6vw,44px);
}
@media (max-width:980px){.steps-grid{grid-template-columns:1fr;max-width:560px;margin-left:auto;margin-right:auto}}
.step-card{
  background:#fff;border-radius:var(--radius-lg);overflow:hidden;
  box-shadow:var(--card-shadow);position:relative;
  /* NO transform-style:preserve-3d. It was only for the raised (translateZ)
     step number, which is gone; a 3D context on a shadowed card makes its soft
     shadow render as a HARD offset copy during scroll. The hover tilt (rotateX/Y
     on the card itself) is a flat plane rotating and does not need preserve-3d. */
  transition:box-shadow .35s ease;
  display:flex;flex-direction:column;
}
.step-card:hover{box-shadow:var(--card-shadow-hover)}
.step-card .photo{height:clamp(150px,16vw,190px);overflow:hidden}
.step-card .photo img{width:100%;height:100%;object-fit:cover}
.step-num{
  position:absolute;top:12px;left:12px;z-index:2;
  width:38px;height:38px;border-radius:50%;
  background:linear-gradient(135deg,#9a4ae0,#7b2ec6);color:#fff;
  font-family:var(--font-display);font-weight:900;font-size:1.05rem;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 10px 24px rgba(123,46,198,.45);
  /* no translateZ: the 3D push put this shadowed badge on a compositor layer
     whose shadow drifted on scroll, and the badge is placed by top/left so the
     3D added nothing but the layer. */
}
.step-card .body{padding:clamp(16px,2.1vw,22px);text-align:center;flex:1}
.step-card .body h3{font-size:clamp(1.12rem,1.5vw,1.3rem);font-weight:700}
.step-card .body h3 b{color:#c866e9;font-weight:700}
.step-card .body p{margin-top:8px;font-weight:600;color:#3e0a6e;font-size:clamp(.95rem,1.05vw,1.02rem);line-height:1.5}
/* desktop: reserve a uniform 3-line block for each step's title and
   body so the three cards align row-for-row regardless of copy length */
@media (min-width:981px){
  /* reserve a uniform block so the bodies align row-for-row; no flex
     here (it would split the inline "nellieconnect" lockup) */
  .step-card .body h3{min-height:2.6em}
  .step-card .body p{min-height:4.5em}
}

/* ============================ CTA ============================ */
/* V4: clean white band, ink heading, soft purple button */
.cta{
  text-align:center;
  padding:clamp(52px,7vw,96px) 0;
  background:#fff;
}
.cta h2{max-width:24em;margin:0 auto 28px;font-weight:700}
/* phones: hold the closing nellie line to 3 lines, not 4, per amends */
@media (max-width:560px){.cta h2{font-size:clamp(1.4rem,6vw,1.5rem)}}

/* ============================ FOOTER ============================ */
/* V4: square corners, no column headings, pink brand suffixes */
.site-footer{
  background:var(--footer-grad);color:#fff;
  padding:clamp(44px,6vw,64px) 0;
  /* keep footer content above the iOS home indicator (viewport-fit=cover) */
  padding-bottom:calc(clamp(44px,6vw,64px) + env(safe-area-inset-bottom, 0px));
}
.footer-grid{display:grid;grid-template-columns:1.3fr 1fr 1fr 1fr;gap:clamp(24px,4vw,48px);align-items:start}
@media (max-width:860px){.footer-grid{grid-template-columns:1fr 1fr}}
/* phones: brand on top, the three link columns stay side by side so the
   footer is short instead of one tall stack */
@media (max-width:520px){
  .footer-grid{grid-template-columns:repeat(3,1fr);gap:20px 12px}
  .footer-brand{grid-column:1 / -1}
  .footer-col a{font-size:.82rem;padding:4px 0}
}
/* logo sized to the same width as the 'powered by' lozenge below it */
.footer-brand img.lg{width:210px;height:auto;max-width:100%}
.powered{margin-top:14px;display:block;width:210px;max-width:100%;background:#fff6ff;border-radius:var(--radius-pill);padding:8px 16px;text-align:center}
.powered img{height:20px;width:auto}
.footer-col a{display:block;padding:5px 0;font-weight:700;font-size:.88rem;opacity:.92;transition:opacity .25s,transform .25s}
.footer-col a:hover{opacity:1;transform:translateX(4px)}
.footer-col a span{color:var(--accent-bright)}
/* "coming soon" footer items: read like the links but muted + not clickable */
.footer-col .soon{display:block;padding:5px 0;font-weight:700;font-size:.88rem;color:rgba(255,255,255,.45);cursor:default}
.footer-col .soon span{color:rgba(255,255,255,.45)}
.footer-col .foot-head{display:block;padding:5px 0;font-family:var(--font-display);font-weight:800;font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--accent-bright);opacity:.85}
/* legal + copyright strip under the columns */
.footer-legal{margin-top:clamp(28px,4vw,44px);padding-top:20px;border-top:1px solid rgba(255,255,255,.15);display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px 24px}
.footer-legal-links{display:flex;flex-wrap:wrap;gap:18px}
.footer-legal-links a{color:rgba(255,255,255,.7);font-weight:600;font-size:.82rem;transition:color .2s}
.footer-legal-links a:hover{color:#fff}
.footer-copy{color:rgba(255,255,255,.55);font-weight:600;font-size:.8rem}
/* company registration line (required on a UK trading site) */
.footer-company{margin-top:14px;color:rgba(255,255,255,.42);font-weight:500;font-size:.76rem;line-height:1.55}
@media (max-width:520px){.footer-legal{justify-content:center;text-align:center}.footer-company{text-align:center}}

/* ---------- legal pages (terms / privacy / cookies) ---------- */
.legal-main{background:#fff;padding:calc(var(--safe-top) + var(--header-h,76px) + clamp(26px,4vw,48px)) 0 clamp(56px,8vw,88px)}
.legal-wrap{width:min(760px,92vw);margin:0 auto}
.legal-wrap .kicker{margin-bottom:6px}
.legal-wrap h1{font-size:clamp(2rem,4vw,2.8rem)}
.legal-updated{color:#8a6db0;font-weight:600;font-size:.9rem;margin:6px 0 24px}
.legal-note{background:#faf2ff;border:1.5px solid #ead9f7;border-radius:14px;padding:14px 18px;margin-bottom:26px;color:#5c1a8c;font-weight:600;font-size:.92rem;line-height:1.55}
.legal-wrap h2{font-size:clamp(1.2rem,2vw,1.5rem);margin:30px 0 10px;color:var(--ink)}
.legal-wrap h3{font-size:1.04rem;margin:18px 0 6px;color:var(--ink)}
.legal-wrap p,.legal-wrap li{color:#3e0a6e;font-weight:500;line-height:1.65;font-size:1rem}
.legal-wrap p{margin:0 0 12px}
.legal-wrap ul{margin:0 0 14px;padding-left:22px}
.legal-wrap li{margin-bottom:6px}
.legal-wrap a{color:#7e37ca;font-weight:700}
.legal-wrap strong{color:var(--ink);font-weight:800}

/* gentle hover-in-space for transparent product renders */
@keyframes hoverfloat{from{transform:translateY(0)}to{transform:translateY(-14px)}}
/* float removed from both the how-it-works tablet and the pricing FAQs
   image per the v2 brief, so nothing carries the hoverfloat now */
.js.ok-motion .vibe-float-none{animation:hoverfloat 5.5s ease-in-out infinite alternate}

/* ============================ COOKIE CONSENT ============================
   A gentle bottom bar (assets/analytics.js injects it). Brand white card,
   soft purple shadow, ink copy, the site's primary pill to accept and a
   soft lilac button to decline. Slides up on show, slides away on choice. */
.cookie-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:200;
  display:flex;justify-content:center;
  padding:clamp(12px,2vw,20px);pointer-events:none;
  /* clear the iOS home indicator (viewport-fit=cover reaches the screen edge) */
  padding-bottom:calc(clamp(12px,2vw,20px) + env(safe-area-inset-bottom, 0px));
  transform:translateY(130%);
  transition:transform .45s cubic-bezier(.22,1,.36,1);
}
.cookie-bar.show{transform:none}
.cookie-bar-inner{
  pointer-events:auto;
  display:flex;align-items:center;gap:clamp(14px,2.5vw,28px);flex-wrap:wrap;
  width:min(920px,100%);
  background:#fff;border:1px solid #f0ddfa;border-radius:20px;
  box-shadow:0 24px 60px rgba(67,16,111,.28);
  padding:clamp(14px,2vw,20px) clamp(16px,2.4vw,26px);
}
.cookie-bar-text{
  flex:1 1 300px;margin:0;color:#3e0a6e;font-weight:600;
  font-size:clamp(.9rem,1.05vw,1rem);line-height:1.5;
}
.cookie-bar-text a{color:#7e37ca;font-weight:800;text-decoration:underline}
.cookie-bar-actions{display:flex;gap:10px;flex-shrink:0}
.cookie-bar .cookie-accept{padding:.6em 1.5em}
.cookie-decline{
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(.9rem,.85vw,1.02rem);
  color:var(--ink);background:#f3ddfb;
  border:0;cursor:pointer;border-radius:var(--radius-pill);
  padding:.6em 1.4em;transition:background .25s ease;
}
.cookie-decline:hover{background:#eccdf8}
/* "Manage cookie preferences" reads as a link inside the cookie policy copy */
.cookie-prefs-link{
  background:none;border:0;padding:0;cursor:pointer;
  color:#7e37ca;font-family:inherit;font-weight:700;font-size:inherit;
  text-decoration:underline;
}
.cookie-prefs-link:hover{color:#c866e9}
@media (max-width:560px){
  /* stack the copy over the buttons. The text must reset to its natural
     height: the desktop flex:1 1 300px basis becomes a 300px COLUMN height
     here, which forced the card ~380px tall with a big empty gap. */
  .cookie-bar-inner{flex-direction:column;align-items:stretch;text-align:center;gap:12px;padding:15px}
  .cookie-bar-text{flex:0 0 auto;font-size:.86rem;line-height:1.45}
  .cookie-bar-actions{justify-content:center;gap:8px}
  .cookie-bar-actions button{flex:1;padding:.7em 1em}
}

/* ============================ MOTION SAFETY ============================ */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none !important;transition:none !important}
}

/* ================================================================
   Components for the inner pages (how-it-works.html, pricing.html),
   built to the V4 ABOUT and PRICING artboards.
   ================================================================ */

/* ---------- inner-page hero (photo right, copy left or right) ---------- */
.page-hero{
  min-height:max(620px,100svh);
  display:flex;align-items:center;
  padding:calc(var(--safe-top) + var(--header-h) + clamp(14px,2.6vh,34px)) 0 clamp(56px,6vw,88px);
  overflow:hidden;
}
.page-hero .wrap{width:100%}
.page-hero .hero-photo{animation:none}
/* inner-page header zoom removed per amends: the hero photo holds still */
/* copy on the RIGHT (how-it-works) */
.hero-copy-right{position:relative;z-index:3;max-width:clamp(340px,26vw,460px);margin-left:auto}
/* tablet and below: the inner heroes stack like the homepage one,
   copy at the top in clear space, photo framing the bottom, so the
   headline never overlaps the device */
@media (max-width:960px){
  .page-hero{align-items:flex-start;min-height:max(640px,100svh)}
  .hero-copy-right{margin-left:0;max-width:none}
}
/* get started leads on its own row, the two app-store badges sit
   together on the row beneath, both phone and desktop, so the set reads
   as one tidy block at matched heights */
.store-badges{display:flex;flex-direction:column;align-items:flex-start;gap:14px;margin-top:18px}
/* how-it-works hero: the get-started button and the two app-store badges
   all sit on one row per the mockup (desktop only, mobile keeps the
   stack). width:max-content lets the row size to its three items and
   spill into the clean right space rather than wrapping inside the
   narrower copy column. */
@media (min-width:761px){
  .hiw-hero .store-badges{flex-direction:row;flex-wrap:nowrap;align-items:center;width:max-content}
}
.store-badges .btn{flex-shrink:0;height:54px;padding-top:0;padding-bottom:0}
.store-badges .btn img{height:1.25em;width:auto}
.badge-row{display:flex;gap:12px;flex-wrap:wrap}
@media (max-width:760px){
  .store-badges{align-items:stretch}
  .store-badges .btn{justify-content:center}
  .badge-row{flex-wrap:nowrap}
  .badge-row .badge-dark{flex:1 1 0;justify-content:center;padding:0 12px}
}
/* nellieconnect lockup */
.nc-lockup{display:flex;align-items:center;gap:0;margin:18px 0 6px;font-family:var(--font-display);font-weight:800;font-size:1.3rem;color:var(--ink)}
.nc-lockup img{height:34px;width:auto}
.nc-lockup span{color:var(--accent-bright)}

/* ---------- app feature grid (6 phone screens) ---------- */
.app-features{background:linear-gradient(180deg,#e4b8f5,#fef0fe);padding:clamp(44px,6vw,76px) 0}
.app-grid{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(18px,2.6vw,30px);margin-top:clamp(26px,3.6vw,44px);
}
@media (max-width:980px){.app-grid{grid-template-columns:1fr 1fr}}
@media (max-width:600px){
  .app-grid{grid-template-columns:1fr;max-width:360px;margin-left:auto;margin-right:auto}
  /* single column: drop the row-alignment min-heights so cards aren't padded out */
  .app-card h3,.app-card p{min-height:0}
}
/* horizontal lozenge cards per the reference: copy left, phone right */
/* the phone UI now sits flush against the card's bottom inner edge, so
   the card aligns its children to the bottom and drops its own bottom
   padding; the copy keeps its breathing room via its own pad-bottom */
.app-card{
  display:flex;align-items:flex-end;gap:14px;
  background:#fff;border-radius:clamp(26px,2.6vw,40px);
  box-shadow:var(--card-shadow);
  padding:14px 14px 0 clamp(16px,1.8vw,24px);
  text-align:left;overflow:hidden;
  transition:transform .35s ease,box-shadow .35s ease;
}
.app-card:hover{transform:translateY(-5px);box-shadow:var(--card-shadow-hover)}
.app-card .copy{flex:1;min-width:0;padding-bottom:clamp(16px,1.9vw,24px)}
/* no drop shadow, square bottom (no rounded crop) so the screen meets the
   card edge cleanly, and nudged slightly left */
.app-card .screen{
  width:clamp(86px,7.6vw,104px);height:clamp(128px,11.4vw,158px);flex-shrink:0;
  border-radius:14px 14px 0 0;overflow:hidden;box-shadow:none;
  transform:translateX(-6px);
}
.app-card .screen img{width:100%;height:100%;object-fit:cover;object-position:top}
/* hold titles to two lines and body to three so the cards stay even */
.app-card h3{font-size:clamp(1.05rem,1.35vw,1.2rem);min-height:2.4em;font-weight:800}
.app-card p{margin-top:4px;font-weight:600;color:#3e0a6e;font-size:clamp(.92rem,1.05vw,1rem);line-height:1.5;min-height:4.5em}

/* ---------- family connection (image left, copy right) ----------
   white section, the photo full-bleeds the left half, three photo
   bubbles sit centred over the seam, and the copy fills the right half.
   No icons on the bubbles, just a thin accent stroke. */
.family{
  background:#fff;display:grid;grid-template-columns:1fr 1fr;
  align-items:stretch;position:relative;overflow:hidden;
}
.family-media{position:relative;min-height:clamp(420px,46vw,620px)}
.family-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* the bubbles stack vertically and sit centred on the column seam */
.family-bubbles{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  z-index:3;display:flex;flex-direction:column;gap:clamp(16px,2.2vw,30px);
  pointer-events:none;
}
.fbub{
  width:clamp(124px,12.5vw,180px);aspect-ratio:1;border-radius:50%;
  overflow:hidden;background:#fff;border:2px solid #c866e9;
  box-shadow:0 18px 36px rgba(67,16,111,.26);
}
.fbub img{width:100%;height:100%;object-fit:cover;border-radius:50%}
.family-copy{
  display:flex;flex-direction:column;justify-content:center;
  padding:clamp(44px,6vw,84px) clamp(28px,5vw,72px) clamp(44px,6vw,84px) clamp(96px,9vw,150px);
}
/* keep the pre-heading underline to the text width, not the flex column
   width (a stretched flex item made the rule run the full column) */
.family-copy .kicker{align-self:flex-start}
@media (max-width:900px){
  .family{grid-template-columns:1fr}
  .family-media{min-height:clamp(280px,66vw,420px)}
  /* stacked: the bubbles become an in-flow, centred row tucked under the
     photo (source order is media -> bubbles -> copy) rather than floating
     across the section seam, which read as misaligned on phones */
  .family-bubbles{position:static;transform:none;flex-direction:row;justify-content:center;gap:clamp(14px,4vw,24px);margin:-42px auto clamp(24px,6vw,36px)}
  .fbub{width:clamp(84px,21vw,112px)}
  /* centre the family-connection copy on phones per amends */
  .family-copy{padding:0 clamp(22px,6vw,40px) clamp(36px,8vw,52px);text-align:center}
  .family-copy .kicker{align-self:center}
  /* let the heading wrap naturally on phones (the desktop line breaks
     leave an awkward stranded middle line) */
  .d-br{display:none}
}

/* ---------- gentle insights (quote bubbles over photo) ---------- */
.insights{
  padding:clamp(44px,6vw,76px) 0 0;
  background:linear-gradient(#f7defd,#fbeefe);
  text-align:center;overflow:hidden;
}
.insights-sub{max-width:46em;margin:10px auto 0;font-weight:600;color:#3e0a6e;font-size:clamp(1rem,1.15vw,1.12rem);line-height:1.55}
.quotes{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(12px,2vw,24px);max-width:1060px;
  margin:clamp(30px,4vw,48px) auto calc(clamp(60px,7vw,100px) * -1);
  position:relative;z-index:4;padding:0 clamp(20px,4vw,32px);
}
@media (max-width:860px){.quotes{grid-template-columns:1fr 1fr;margin-bottom:-40px}}
.quote{
  background:#fff;border-radius:50%;aspect-ratio:1;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
  padding:clamp(18px,2.6vw,34px);
  box-shadow:var(--card-shadow);
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(.72rem,1.05vw,.92rem);line-height:1.45;color:var(--ink);
  text-align:center;
}
.quote .q-ico{
  width:clamp(30px,2.4vw,40px);height:clamp(30px,2.4vw,40px);border-radius:50%;flex-shrink:0;
  background:var(--icon-grad);
  display:flex;align-items:center;justify-content:center;
}
.quote .q-ico img{width:50%;height:50%}
/* slightly larger badges, and per-insight colours: messages keep the
   gradient, music #c866e9, calendar #7e37ca, photos #e4b8f5 (light, so
   its white glyph is recoloured dark to stay legible) */
.quote .q-ico{width:clamp(36px,2.9vw,48px);height:clamp(36px,2.9vw,48px)}
.insights .quotes > div:nth-child(1) .q-ico{background:#5c1a8c}
.insights .quotes > div:nth-child(2) .q-ico{background:#c866e9}
.insights .quotes > div:nth-child(3) .q-ico{background:#7e37ca}
.insights .quotes > div:nth-child(4) .q-ico{background:#e4b8f5}
/* photo icon stays white per amends (was tinted dark on the light badge) */
@media (max-width:560px){
  /* keep the insight bubbles as circles on phones per amends */
  .quotes{grid-template-columns:1fr 1fr;gap:10px}
  .quote{border-radius:50%;aspect-ratio:1;padding:12px;font-size:clamp(.62rem,2.6vw,.8rem)}
  .quote .q-ico{width:32px;height:32px}
}
.insights-photo{height:clamp(280px,38vw,520px)}
.insights-photo img{width:100%;height:100%;object-fit:cover}

/* ---------- intentionally simple (tablet cutout + ticks) ---------- */
.simple{background:var(--lav-0);padding:clamp(44px,6vw,80px) 0}
.simple-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(32px,5vw,64px);align-items:center}
@media (max-width:900px){
  .simple-grid{grid-template-columns:1fr}
  /* stacked: text FIRST, the tablet image beneath it (per amends). The image
     is DOM-first for the desktop left column, so order:2 drops it below. */
  .simple-grid .cutout{order:2}
}
.simple-grid .cutout{will-change:auto}
/* the tablet no longer floats (animation removed per the v2 brief) */
.simple .cutout img{animation:none!important;transform:none!important}
.simple-sub{margin:14px 0 18px;font-weight:600;color:#3e0a6e;font-size:clamp(1rem,1.15vw,1.12rem);line-height:1.55}
.simple-sub strong{color:var(--ink);font-weight:800}

/* ---------- pricing hero two-tone headline ---------- */
.h1-two-tone em{font-style:normal;color:var(--accent)}

/* ---------- purchase columns ---------- */
.purchase{background:var(--lav-0);padding:clamp(44px,6vw,80px) 0}
.purchase-grid{
  display:grid;grid-template-columns:1fr auto 1fr;
  gap:clamp(16px,2.4vw,36px);margin-top:clamp(26px,3.6vw,44px);
  align-items:stretch;
}
@media (max-width:900px){
  .purchase-grid{grid-template-columns:1fr;max-width:560px;margin-left:auto;margin-right:auto}
  .purchase-arrow{transform:rotate(90deg);justify-self:center;padding:0}
}
.purchase-arrow{
  align-self:center;font-family:var(--font-display);font-weight:900;
  font-size:clamp(2rem,3.4vw,3rem);color:var(--accent-bright);
}
/* one card = one purchase: image, step, price, what you get, CTA and
   perks all live together, in the site's lozenge language */
.plan-card{
  background:#fff;border-radius:clamp(28px,3vw,44px);overflow:hidden;
  box-shadow:var(--card-shadow);
  display:flex;flex-direction:column;
  transition:transform .35s ease,box-shadow .35s ease;
}
.plan-card:hover{transform:translateY(-6px);box-shadow:var(--card-shadow-hover)}
.plan-photo{height:clamp(180px,16vw,250px);overflow:hidden}
.plan-photo img{width:100%;height:100%;object-fit:cover;transition:transform .8s ease}
.plan-card:hover .plan-photo img{transform:scale(1.04)}
.plan-body{padding:clamp(22px,2.6vw,36px);display:flex;flex-direction:column;flex:1}
.step-pill{
  align-self:flex-start;
  background:#efd9fa;color:var(--display);
  font-family:var(--font-display);font-weight:800;
  font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  padding:6px 14px;border-radius:var(--radius-pill);margin-bottom:14px;
}
.plan-card h3{font-size:clamp(1.25rem,1.8vw,1.6rem);font-weight:800}
.plan-card h3 b{color:var(--accent)}
.plan-card h3 span{color:var(--accent-bright)}
.price-big{
  font-family:var(--font-display);font-weight:800;color:var(--display);
  font-size:clamp(1.6rem,2.6vw,2.3rem);line-height:1.2;
  margin:10px 0 16px;
}
.price-big s{color:var(--muted);font-weight:700;font-size:.58em;margin-right:8px}
.price-big small{font-size:.42em;font-weight:700;color:#3e0a6e;margin-left:6px}
.plan-card .ticks{margin-bottom:16px}
/* the purchase cards run tall; trim the photo, padding and list text so a
   card fits inside the visible browser area without scrolling the section */
.plan-photo{height:clamp(150px,12vw,196px)}
.plan-body{padding:clamp(18px,2vw,28px)}
.plan-card h3{font-size:clamp(1.15rem,1.6vw,1.42rem)}
.price-big{margin:8px 0 12px}
.plan-card .ticks li{font-size:clamp(.84rem,.98vw,.94rem);line-height:1.28;padding:4px 0}
.plan-card .ticks img{width:18px;height:18px;margin-top:2px}
.perks{display:flex;flex-wrap:wrap;gap:10px;justify-content:center}
.perk{
  display:inline-flex;align-items:center;gap:8px;
  background:var(--lav-1);border:1.5px solid #eedcf7;
  border-radius:var(--radius-pill);
  font-weight:700;font-size:.78rem;color:var(--ink);
  padding:7px 13px;
}
.perk img{width:15px;height:15px}
.plan-card .btn{align-self:flex-start;margin-top:auto}
.plan-card .perks{justify-content:flex-start;margin-top:18px}

/* ---------- FAQs accordion ---------- */
.faqs{background:#fef0fe;padding:clamp(44px,6vw,80px) 0}
.faqs-grid{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(32px,5vw,64px);align-items:start}
/* heading held to two lines (desktop). Declared BEFORE the mobile block so the
   mobile max-width:none actually wins by source order (it did not before, which
   left the heading a narrow, left-biased block on phones). */
.faqs-intro h2{max-width:7em}
@media (max-width:900px){
  .faqs-grid{grid-template-columns:1fr}
  /* centre the FAQ intro (kicker, heading, copy, image) on phones per amends */
  .faqs-intro{text-align:center}
  .faqs-intro .kicker{border-bottom-color:var(--accent-soft)}
  .faqs-intro h2{max-width:none;margin-left:auto;margin-right:auto}
}
.faqs-intro p{margin-top:14px;font-weight:600;color:#3e0a6e;max-width:30em;font-size:clamp(1rem,1.15vw,1.12rem);line-height:1.55}
.faqs-intro .art{margin-top:clamp(20px,4vw,44px)}
/* larger image, and the gentle float is removed */
.faqs-intro .art img{max-width:100%;animation:none}
.faq-item{
  background:#fff;border:1.5px solid #eedcf7;border-radius:16px;margin-bottom:9px;
  box-shadow:0 6px 16px rgba(67,16,111,.06);
  overflow:hidden;
}
.faq-q{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:11px 16px;text-align:left;
  font-family:var(--font-display);font-weight:800;font-size:clamp(.98rem,1.2vw,1.1rem);
  color:var(--ink);
}
.faq-q::after{
  content:'+';flex-shrink:0;width:26px;height:26px;border-radius:50%;
  background:#c866e9;color:#fff;
  display:flex;align-items:center;justify-content:center;
  font-weight:800;font-size:1.1rem;line-height:1;
  transition:transform .3s ease;
}
.faq-item.open .faq-q::after{content:'\2013';transform:rotate(180deg)}
.faq-a{
  max-height:0;overflow:hidden;
  transition:max-height .45s cubic-bezier(.22,1,.36,1);
}
.faq-item.open .faq-a{max-height:420px}
.faq-a p{padding:0 16px 16px;font-weight:600;color:#3e0a6e;font-size:1rem;line-height:1.55}

/* ---------- photo CTA band (bring your family closer) ---------- */
.photo-cta{
  position:relative;overflow:hidden;
  padding:clamp(60px,8vw,110px) 0;
  background:url('../nellie/images/Pricing-Bring_Family_Closer.webp') 72% center/cover no-repeat;
}
.photo-cta::before{
  content:'';position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(251,238,254,.94),rgba(251,238,254,.65) 38%,rgba(251,238,254,0) 62%);
}
.photo-cta .wrap{position:relative}
.photo-cta .copy{max-width:420px}
.photo-cta .copy p{margin:14px 0 24px;font-weight:600;color:#3e0a6e;font-size:clamp(1rem,1.15vw,1.12rem);line-height:1.55}
@media (max-width:760px){
  /* mobile (per amends): the IMAGE comes FIRST (a full-width band at the top,
     dedicated mobile composition), with the copy CENTRE-aligned beneath it.
     The image is 1080x664 (0.615 h/w), so its band is 61.5vw tall. */
  .photo-cta{
    background-image:url('../nellie/images/pricing-bring_family_closer-mobile.webp');
    background-position:center top;
    background-size:100% auto;
    background-repeat:no-repeat;
    padding-top:calc(61.5vw + 30px);
    padding-bottom:clamp(40px,9vw,64px);
    text-align:center;
  }
  .photo-cta::before{
    inset:0;
    /* transparent over the top image, solid wash below it behind the copy */
    background:linear-gradient(180deg,rgba(251,238,254,0) calc(61.5vw - 8px),#fbeefe calc(61.5vw + 6px));
  }
  .photo-cta .copy{max-width:none;margin:0 auto}
}

/* ---------- responsive bar flow ----------
   Below desktop the half-height ride-up would bury the photo and the
   CTAs, so the bar flows after the hero with a slight overlap. */
@media (max-width:1020px){
  .features-dock{top:-26px}   /* position-based (see base rule), not transform */
  /* stacked hero: copy sits at the top, not biased above centre */
  .hero .wrap{margin-top:4svh}
}

/* ---------- phones: the hero is an integrated OVERLAY (copy over photo) ----------
   Copy sits over the photo like the desktop, NOT a separate band. The
   trick that keeps the buttons off the devices on any screen height: the
   device zone is reserved at the foot with padding-bottom (--band), and
   the copy is ordinary flow content above it, so it physically cannot
   reach the devices, the hero just grows taller if the copy needs more
   room. The photo is pinned into that foot zone (devices clear, no fade
   on the product); only its top edge fades into the wash behind the
   words. will-change/transform are cleared (with parallax off on phones
   in site.js) so the photo never becomes a compositor layer that paints
   over the "with nellie..." pill. Appended last so it wins the cascade. */
@media (max-width:760px){
  /* CLEAN STACK on phones: copy, then the photo as a real in-flow block.
     No absolute positioning, no mask, no zoom-crop, no compositor layer,
     so the phone renders exactly like the preview (the masked overlay
     was painting the device image over the value-props pill on real
     Safari). The block's aspect shows the full scene with only a sliver
     trimmed off the sides, so nothing key is cropped away. */
  /* IMMERSIVE OVERLAY on phones: the copy sits over the top of a
     full-bleed device photo, the photo's top edge fading up into the
     copy. The fade is a GRADIENT LAYER baked into the background (pale
     hero colour -> transparent), NOT a CSS mask, so it never promotes
     the photo to a compositor layer (that was what painted the photo
     over the value-props pill on real Safari). The devices sit in the
     lower, clear part of the photo, so nothing covers them. */
  .hero{
    display:flex;flex-direction:column;align-items:stretch;
    min-height:0;overflow:visible;
    padding:calc(var(--safe-top) + var(--header-h) + 14px) 0 0;
  }
  .hero .wrap{order:1;margin-top:0;width:100%}
  /* mobile: copy CENTRE-aligned (heading, sub, button) above the image */
  .hero-content{max-width:none;text-align:center}
  .hero h1{max-width:none}
  .hero .hero-sub{margin:12px auto 0;max-width:none}
  .hero .hero-ctas{margin:22px auto 0;justify-content:center}
  /* the secondary "how it works" button stays hidden on the pricing
     hero, which still carries a .btn-deep */
  .hero-ctas .btn-deep{display:none}
  /* scoped to .hero so the home photo never leaks onto the inner-page
     heroes (.page-hero), which set their own photo */
  .hero .hero-photo,
  .js.ok-motion .hero .hero-photo{
    order:2;position:relative;inset:auto;
    width:100%;height:auto;aspect-ratio:1080/749;
    /* dedicated MOBILE hero image (a portrait composition with no baked-in text
       gradient - the heading sits above it). aspect-ratio matches the image so
       cover shows the whole scene; a short top fade blends its pale top into
       the copy above. */
    background:
      linear-gradient(180deg,#fbeefe 0%,rgba(251,238,254,.6) 7%,rgba(251,238,254,0) 20%),
      url('../nellie/images/homepage-header-mobile.webp') center bottom/cover no-repeat;
    -webkit-mask-image:none;mask-image:none;
    margin-top:-8px;
    animation:none;transform:none;will-change:auto;
  }
  .hero-tint{display:none}
  .note-1{display:none}
  /* the value-props card rides UP to overlap the bottom of the photo
     slightly. Safe now: the card is an opaque, in-flow block (z-index:2)
     and the "with nellie" pill lives INSIDE it, so neither can be hidden
     behind the photo on scroll. */
  .features-band{position:relative;padding-bottom:clamp(30px,5vw,48px)}
  /* Lift the card with position:relative + top, NOT a transform. A
     transform promoted the card to its own GPU layer, which iOS Safari
     dropped intermittently while scrolling (the card flickered away).
     position:relative offsets it without a compositor layer; the
     matching negative margin-bottom closes the gap below. No z-index is
     needed, so it simply paints on top in document order (the card
     section comes after the hero). */
  .features-dock{transform:none;position:relative;top:-46px;margin-top:0;margin-bottom:-46px}
  .features-bar{margin-top:0}
  /* keep the card always visible on phones (no reveal fade): the reveal
     pattern flashes every element visible for a frame on load, then hides
     it (opacity:0) until it scrolls into view, which on this prominent
     overlapping card read as "hides on load, then again on scroll" */
  .js.ok-motion .features-bar.reveal{opacity:1;transform:none;transition:none}
}

/* phones: the inner-page heroes (how it works, pricing) use the same
   clean in-flow stack as the home hero. Each page's <style> sets its own
   photo url + framing for the block. */
@media (max-width:760px){
  .page-hero{
    display:flex;flex-direction:column;align-items:stretch;
    min-height:0;overflow:visible;
    padding:calc(var(--safe-top) + var(--header-h) + 14px) 0 0;
  }
  .page-hero .wrap{order:1;margin-top:0;width:100%}
  .page-hero .hero-copy-right,
  .page-hero .hero-content{margin-left:0;max-width:none}
  /* single primary CTA, natural width, left aligned (not a full-width
     lozenge); the secondary button is hidden by the shared rule above */
  .page-hero .hero-ctas{flex-wrap:wrap;width:auto;max-width:none;gap:12px;justify-content:flex-start}
  .page-hero .hero-ctas .btn{flex:0 0 auto}
  .page-hero .hero-photo,
  .js.ok-motion .page-hero .hero-photo{
    order:2;position:relative;inset:auto;
    width:100%;height:auto;aspect-ratio:1.5;
    -webkit-mask-image:none;mask-image:none;
    /* full-bleed photo band, its top fading into the copy (the per-page
       <style> sets the gradient + photo). Same immersive overlay as home. */
    margin-top:-8px;
    animation:none;transform:none;will-change:auto;
  }
  .page-hero .hero-tint{display:none}
}

/* ====================== PRE-LAUNCH / MARKET MODE ======================
   The public "register your interest" build sets SITE_MODE=market, which
   makes netlify-build.sh stamp <html data-mode="market"> on every page.
   The pre-launch note is shipped hidden in the source (pricing.html) and
   only revealed here, so the full ordering site (the password-protected
   dev build) never shows it. */
.prelaunch-note{display:none}
html[data-mode="market"] .prelaunch-note{
  display:block;max-width:44em;margin:clamp(24px,3.4vw,38px) auto 0;text-align:center;
  font-family:var(--font-display);font-weight:700;color:#6b2e9e;
  font-size:clamp(1rem,1.5vw,1.14rem);line-height:1.5;
  background:#fff;border:1.5px solid #ecd9fb;border-radius:18px;
  padding:clamp(16px,2.4vw,22px) clamp(20px,3.4vw,30px);
  box-shadow:0 14px 34px rgba(67,16,111,.1);
}
