.nav-mobile{display:none}
@media(max-width:700px){
  .nav-desktop{display:none}
  .nav-mobile{display:inline}
  .header{top:max(8px,env(safe-area-inset-top));width:calc(100% - 24px);padding:8px 14px 9px;border-radius:24px;gap:4px 10px;flex-wrap:wrap}
  .header>.brand{font-size:0;min-height:32px;gap:0}
  .header>.brand .logo{height:32px;width:25px;transform:scale(.75);transform-origin:left center;overflow:visible}
  .header .header-counter{top:25px;left:50%;transform:translate(-50%,-50%);padding:0;margin:0}
  .header-counter .saved-number{font-size:18px;line-height:1.1}
  .header-counter .saved-unit{font-size:12px;margin:2px 0 0;line-height:1.1}
  .header .theme-toggle{margin-left:auto;width:32px;height:32px}
  .header nav{display:flex;flex:0 0 100%;order:5;justify-content:space-between;align-items:center;flex-wrap:nowrap;gap:8px;margin:4px 0 0;font-size:14px;line-height:1.3}
  .header nav a{padding:5px 0;white-space:nowrap}
  .hero{min-height:0;padding:128px 20px 24px;justify-content:flex-start;gap:0}
  .hero h1{font-size:clamp(36px,9vw,52px);line-height:1.05}
  .hero .store-buttons{margin-top:22px;gap:8px}
  .hero .proof{margin-top:12px;gap:8px}
  .hero-base{margin-top:16px;padding:0}
  .section{padding:48px 22px}
  .section-label{margin-bottom:14px}
  .video-section{padding:28px 22px 0}
  .video-heading{margin-bottom:24px}
  .video-heading h2{font-size:clamp(28px,7vw,37px);line-height:1.12;margin-top:0;margin-bottom:0}
  .professionals{padding:40px 22px}
  .professionals h2{margin-bottom:22px}
  .reading-section{height:175svh}
  .reading-stage{padding:16px 22px 20px}
  .reading-note{margin-top:24px}
  .reading-progress{margin-top:14px}
  .difference{padding-block:46px}
  .second-feature{padding-top:36px;padding-bottom:24px;gap:0}
  .feature-visual{height:410px}
  .second-device{width:300px;left:calc(50% - 150px);top:0}
  .numbers{padding:24px 22px 44px}
  .number-grid{margin-top:20px}
  .closing{padding:45px 22px 50px}
  .closing h2{margin-top:22px}
  .closing .store-buttons{margin-top:22px}
  .site-footer{padding:40px 22px;gap:28px 22px}
  .info-page{padding-top:132px;padding-bottom:44px}
  .parents-page{padding-top:0;padding-left:22px;padding-right:22px}
  .parents-hero{min-height:0;padding:130px 0 32px}
  .parents-hero h1{font-size:clamp(40px,10vw,58px);margin-bottom:18px}
  .parents-hero .parents-eyebrow{margin-bottom:16px}
  .parents-lead{margin:18px auto 22px}
  .parents-hero-actions{gap:16px}
  .parents-availability{margin-top:14px}
  .parents-photo-section{padding-bottom:0}
  .parents-section{padding-top:44px;padding-bottom:44px}
  .parents-section-heading{margin-bottom:26px}
  .parents-compare>.parents-section-heading{margin-bottom:24px}
  .parents-noargue{margin-bottom:40px}
  .simple-comparison-heading{margin-bottom:24px}
  .parents-download{padding:44px 0}
  .parents-questions{padding-bottom:44px}
  .parents-setup-short ol{margin-top:26px;gap:16px}
  .faq-list details{scroll-margin-top:112px}
  #film,#difference,#compare,#parent-download{scroll-margin-top:110px}
}
@media(max-width:360px){.header nav{font-size:13px;gap:5px}.hero h1{font-size:35px}}
@media(max-width:700px) and (prefers-reduced-motion:reduce){.reading-section{height:auto}.reading-stage{height:auto;padding:40px 22px}}

/* Keep five destination links on a single compact mobile row. */
@media(min-width:1201px){.header nav{gap:12px;font-size:12px}.header nav a{letter-spacing:-.015em}}
@media(max-width:700px){.header nav{font-size:13px;gap:6px}.header nav a{letter-spacing:-.02em}}
@media(max-width:360px){.header nav{font-size:12px;gap:4px}}
@media(min-width:1201px) and (max-width:1400px){.header{flex-wrap:wrap}.header nav{order:5;flex:0 0 100%;justify-content:center;margin:0;gap:24px;font-size:14px}.header .header-counter{top:33px}.header .theme-toggle{margin-left:auto}}

/* One continuous liquid-glass surface; navigation first, counter on the right.
   Less opaque than the old flat frost (.82/.84), with a diagonal sheen and a
   specular top edge so it reads as glass rather than fog. The heavier blur and
   saturation are what keep text legible at this transparency, so lower the
   alpha and the blur together or not at all. backdrop-filter is repeated on
   the light rule because style.css sets it at a higher specificity there. */
.header{background:linear-gradient(135deg,#ffffff18,#ffffff08),rgba(24,24,24,.36);border:0;flex-wrap:nowrap;gap:24px;padding:14px 22px 14px 25px;border-radius:60px;backdrop-filter:blur(44px) saturate(210%);-webkit-backdrop-filter:blur(44px) saturate(210%);box-shadow:0 10px 34px #00000026,inset 0 1px 0 #ffffff20}
html[data-theme=light] .header{background:linear-gradient(135deg,#ffffff6b,#ffffff36),rgba(252,252,252,.24);backdrop-filter:blur(44px) saturate(210%);-webkit-backdrop-filter:blur(44px) saturate(210%);box-shadow:0 10px 30px #0000001a,inset 0 1px 0 #ffffffcc}
.header>.brand{order:0;margin:0;flex-shrink:0}
.header nav{order:1;flex:1 1 auto;flex-wrap:nowrap;justify-content:center;gap:24px;margin:0;font-size:18px;line-height:1.4}
.header nav a{letter-spacing:-.02em}
.header .header-counter{position:static;inset:auto;transform:none;order:2;flex:0 0 auto;margin:0;padding:0;gap:0}
.header-counter-total{min-width:112px}
.header-counter .saved-number{font-size:22px}
.header-counter .saved-unit{font-size:12px}
.header .theme-toggle{order:3;margin:0;flex-shrink:0}
@media(min-width:701px) and (max-width:1100px){.header{flex-wrap:wrap;gap:12px 20px;border-radius:30px}.header>.brand{margin-right:auto}.header nav{order:4;flex:0 0 100%;font-size:17px;gap:26px}.header .header-counter{margin-left:auto}.header .theme-toggle{margin-left:0}}
@media(max-width:700px){.header{padding:8px 14px 9px;flex-wrap:wrap;gap:4px 10px;border-radius:24px}.header>.brand{margin-right:auto}.header .header-counter{position:static;transform:none;flex:0 0 auto;margin:0;padding:0}.header-counter-total{min-width:104px}.header-counter .saved-number{font-size:18px}.header-counter .saved-unit{font-size:12px}.header .theme-toggle{margin:0}.header nav{order:4;flex:0 0 100%;justify-content:space-between;font-size:13px;gap:6px;margin:4px 0 0}}
@media(max-width:360px){.header nav{font-size:12px;gap:4px}}

.video-growth .video-shell{transform:scale(var(--video-scale,1));transform-origin:center top;will-change:transform}
@media(prefers-reduced-motion:reduce){.video-growth .video-shell{transform:none;will-change:auto}}

/* Logos auto-scroll continuously (the logo-drift marquee in style.css).
   Previously these rules killed the animation so logo-scroll.js could
   drive the belts from page scroll; that script is gone. The duplicate
   list must stay visible - it is what makes the loop seamless. */
.logo-belt{will-change:transform}
@media(prefers-reduced-motion:reduce){.logo-belt{animation:none!important;transform:none!important;will-change:auto}.logo-lane{overflow-x:auto}}

/* Compact mobile proof and bring the reading section closer to the logos. */
@media(max-width:700px){
  .professionals{padding-bottom:14px}
  .reading-stage{justify-content:flex-start;padding-top:24px;padding-bottom:20px}
  .store-buttons{zoom:.85}
  .hero .proof{zoom:.85;margin-top:8px}
  .hero .store-buttons{margin-top:18px}
  .hero-base{margin-top:12px}
}

/* On phones, keep the reading animation in the normal page flow. */
@media(max-width:700px){
  .reading-section{height:auto}
  .reading-stage{position:relative;top:auto;height:auto;min-height:0;padding:24px 22px}
}

/* A focused mobile reading moment, released as soon as the sentence fills. */
@media(max-width:700px){
  .reading-section{height:calc(150svh - var(--header-clearance,110px))}
  .reading-stage{position:sticky;top:var(--header-clearance,110px);height:calc(100svh - var(--header-clearance,110px));min-height:0;justify-content:center;padding:28px 26px}
  .reading-stage h2{font-size:clamp(26px,7vw,34px);font-weight:700;line-height:1.35;letter-spacing:-.8px;max-width:490px}
  .reading-note,.reading-progress{display:none}
}
@media(max-width:700px) and (prefers-reduced-motion:reduce){.reading-section{height:auto}.reading-stage{position:relative;top:auto;height:auto;padding:40px 26px}}

/* Hold the completed sentence while the following section closes the space. */
@media(max-width:700px){
  .reading-stage{position:relative;top:0;z-index:2;will-change:transform;pointer-events:none}
  .reading-section{overflow:visible}
  .second-feature{position:relative;z-index:1}
}
@media(max-width:700px) and (prefers-reduced-motion:reduce){.reading-stage{transform:none!important;will-change:auto}}

/* Native sticky positioning avoids scroll-frame lag and mobile text jitter. */
@media(max-width:700px){
 .reading-section{height:calc(150svh - var(--header-clearance,110px) + var(--reading-pull-gap,0px));margin-bottom:calc(-1 * var(--reading-pull-gap,0px))}
 .reading-stage{position:sticky;top:var(--header-clearance,110px);transform:none;will-change:auto}
}
@media(max-width:700px) and (prefers-reduced-motion:reduce){.reading-section{height:auto;margin-bottom:0}.reading-stage{position:relative;top:auto}}

.mobile-menu-toggle{display:none}
@media(max-width:700px){
 .header{display:grid;grid-template-columns:1fr auto;gap:0;padding:11px 18px;border-radius:28px}
 .header>.brand{grid-column:1;grid-row:1;font-size:21px;gap:1px;margin:0;min-height:38px}
 .header>.brand .logo{transform:scale(.8);width:25px;height:34px}
 .header .mobile-menu-toggle{display:flex;grid-column:2;grid-row:1;flex-direction:column;justify-content:center;align-items:center;gap:5px;width:42px;height:42px;background:transparent;color:inherit;border:0;border-radius:12px;cursor:pointer}
 .mobile-menu-toggle span{display:block;width:21px;height:2px;background:currentColor;border-radius:2px;transition:transform .2s,opacity .2s}
 .mobile-menu-toggle:focus-visible{outline:2px solid currentColor;outline-offset:3px}
 .header nav,.header .header-counter,.header .theme-toggle{display:none}
 .header.menu-open nav{display:flex;grid-column:1/-1;grid-row:2;flex-direction:column;align-items:stretch;gap:0;margin:12px 0 10px;font-size:18px}
 .header.menu-open nav a{padding:12px 4px;letter-spacing:0}
 .header.menu-open .header-counter{display:flex;grid-column:1;grid-row:3;justify-content:flex-start;padding:12px 4px;margin:0}
 .header.menu-open .header-counter-total{text-align:left}
 .header.menu-open .theme-toggle{display:grid;grid-column:2;grid-row:3;margin:0;align-self:center;width:42px;height:42px}
 .header.menu-open .mobile-menu-toggle span:nth-child(1){transform:translateY(7px) rotate(45deg)}
 .header.menu-open .mobile-menu-toggle span:nth-child(2){opacity:0}
 .header.menu-open .mobile-menu-toggle span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
}
@media(prefers-reduced-motion:reduce){.mobile-menu-toggle span{transition:none}}

/* Respect the iPhone status area, including embedded full-screen browsers. */
@media(max-width:700px){
 .header{top:calc(env(safe-area-inset-top,0px) + 12px)}
}
/* Header floor dropped 54px -> 8px, so the bar sits 46px higher. app.js keeps
   the homepage hero aligned via --header-clearance, but it only runs on the
   homepage - these subpage headers are hardcoded, so they come down by the
   same 46px (160 -> 114) or they would gain a matching gap. */
@supports(-webkit-touch-callout:none){
 @media(max-width:700px){
  .header{top:calc(max(env(safe-area-inset-top,0px),8px) + 12px)}
  .hero{padding-top:114px}
  .parents-hero{padding-top:114px}
  .school-hero{padding-top:114px}
  .info-page{padding-top:114px}
 }
}

/* Let the product image lead: name, phone, then a short explanation. */
.second-feature.product-reveal{display:flex;flex-direction:column;align-items:center;text-align:center;gap:0;padding-top:48px;padding-bottom:65px}
.product-reveal>h2{font-size:clamp(64px,8vw,112px);font-weight:750;letter-spacing:-.065em;line-height:1.05;margin:0;order:0}
.product-phone-stage{position:relative;width:100%;max-width:620px;height:670px;order:1;margin:12px auto 0}
.product-phone-stage .product-phone{position:absolute;width:460px;max-width:none;left:50%;top:0;transform:translateX(-50%);transform-origin:center;will-change:transform,opacity}
.product-description{order:2;max-width:620px;margin:12px auto 0}
/* It is a top-level child of <main> now, between the removes sequence and
   the demo video, so it has no section around it to inherit width, centring
   or rhythm from — it supplies all three itself. The order:2 above is inert
   here for the same reason it was inert in the film section: neither parent
   is a flex container. */
main > .product-description{max-width:min(92%,760px);margin:0 auto;padding:clamp(44px,7vw,96px) 0;text-align:center}
.product-description h3{font-size:clamp(22px,2.3vw,30px);line-height:1.25;font-weight:650;letter-spacing:-.035em;margin:0 0 16px}
.product-description p{font-size:18px;line-height:1.6;color:#999;margin:0}
html[data-theme=light] .product-description p{color:#656565}
@media(max-width:700px){.second-feature.product-reveal{padding-top:32px;padding-bottom:32px}.product-reveal>h2{font-size:clamp(54px,14vw,72px)}.product-phone-stage{height:470px;margin-top:8px}.product-phone-stage .product-phone{width:320px}.product-description{margin-top:8px}.product-description h3{font-size:23px;margin-bottom:12px}.product-description p{font-size:16px}}
@media(prefers-reduced-motion:reduce){.product-phone-stage .product-phone{will-change:auto}}

/* Preserve the image ratio and let the phone reserve its own layout height. */
.device img{height:auto}
.product-phone-stage{height:auto;padding-bottom:12px}
.product-phone-stage .product-phone{position:relative;top:auto;width:460px;max-width:100%}
.product-phone-stage .product-phone img{width:100%;height:auto;aspect-ratio:2/3;object-fit:contain}
@media(max-width:700px){.product-phone-stage{height:auto}.product-phone-stage .product-phone{width:320px;max-width:100%}}

/* The trio, at every width. The side phones used to be desktop-only; the
   fan offsets in product-reveal.js are now scaled by the centre phone's real
   width, so the same three-phone reveal works on a 390px screen. */
.product-phone-side{display:none}
@media(max-width:700px){
  /* Smaller than the single phone this replaces (290px), because there are
     three of them now and the outer two have to stay on screen.

     z-index:2 so the centre sits in FRONT of the pair. The desktop rule that
     does this lives in the min-width:701px block, so on phones the centre was
     `auto` against side phones at 1 and the fan painted over the hero shot. */
  .product-phone-stage .product-phone{width:min(186px,42svh);z-index:2}
  .product-phone-stage .product-phone-side{
    display:block;position:absolute;width:min(186px,42svh);
    left:50%;top:0;max-width:none;z-index:1;
    transform-origin:center;will-change:transform,opacity}
  .product-phone-side img{width:100%;height:auto;aspect-ratio:2/3;object-fit:contain}
  /* The fan deliberately runs a little past the content column — it reads as
     three phones continuing rather than three phones in a box.
     BOTH axes are respecified. style.css sets `.second-feature{overflow:hidden}`,
     and overriding only overflow-x left overflow-y as hidden from that
     shorthand, which sheared the tops off the phones as they rose. clip and
     visible are a legal pair; the coercion to hidden only happens when one
     axis is a scrolling value. */
  .second-feature.product-reveal{overflow-x:clip;overflow-y:visible}
  .product-phone-stage{height:auto;min-height:calc(min(186px,42svh) * 1.5 + 26px)}
}
@media(min-width:701px){
 .product-phone-stage{max-width:1100px;padding-bottom:45px}
 .product-phone-stage .product-phone{z-index:2}
 .product-phone-stage .product-phone-side{display:block;position:absolute;width:460px;left:50%;top:0;max-width:none;z-index:1;transform-origin:center;will-change:transform,opacity}
 .product-phone-side img{width:100%;height:auto;aspect-ratio:2/3;object-fit:contain}
}
@media(min-width:701px) and (max-width:1000px){.product-phone-stage .product-phone,.product-phone-stage .product-phone-side{width:350px}}
@media(prefers-reduced-motion:reduce){.product-phone-stage .product-phone-side{will-change:auto}}

/* A transparent lower edge blends naturally into either page theme. */
.product-phone-stage .device img,.parent-phone-visual .device img{
 -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 70%,transparent 96%);
 mask-image:linear-gradient(to bottom,#000 0%,#000 70%,transparent 96%);
 -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
}

/* Fade the entire group before any bottom bezel becomes visible. */
.product-phone-stage .device img{-webkit-mask-image:none;mask-image:none}
.product-phone-stage{
 -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 53%,rgba(0,0,0,.65) 64%,transparent 80%,transparent 100%);
 mask-image:linear-gradient(to bottom,#000 0%,#000 53%,rgba(0,0,0,.65) 64%,transparent 80%,transparent 100%);
 -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
}
.parent-phone-visual .device img{
 -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 53%,transparent 80%,transparent 100%);
 mask-image:linear-gradient(to bottom,#000 0%,#000 53%,transparent 80%,transparent 100%);
}

/* Bring the phone reveal directly beneath the landing content. */
.second-feature.product-reveal{padding-top:0}
.product-reveal .product-phone-stage{margin-top:-24px}
@media(max-width:700px){.second-feature.product-reveal{padding-top:0}.product-reveal .product-phone-stage{margin-top:-16px}}

/* Keep one fixed mobile header position throughout the page. */
@media(max-width:700px){
 .header{position:fixed;top:var(--mobile-header-top,calc(env(safe-area-inset-top,0px) + 12px));left:12px;right:12px;width:auto;max-width:none;transform:none;transition:none;z-index:1000;margin:0}
}
/* The iOS floor was 54px, which sat the bar ~66px down even though Safari
   reports safe-area-inset-top: 0 in normal browsing (and with the Smart App
   Banner showing, the banner already offsets the viewport). Dropped to 8px,
   so the bar clears the Dynamic Island when the toolbar collapses but is not
   pushed down by dead space. app.js derives --header-clearance from the
   header's real bottom edge, so the hero moves up with it. */
@supports(-webkit-touch-callout:none){@media(max-width:700px){.header{top:var(--mobile-header-top,calc(max(env(safe-area-inset-top,0px),8px) + 12px))}}}

/* Schools use a seamless repeat to travel at the same speed as companies. */
.logo-lane:nth-child(2) .logo-belt .logo-duplicate{display:flex}
@media(prefers-reduced-motion:reduce){.logo-lane:nth-child(2) .logo-belt .logo-duplicate{display:none}}

.footer-socials{display:flex;align-items:center;gap:18px;margin:23px 0 12px}
.footer-socials>a,.footer-socials>.social-pending{position:relative;display:grid;place-items:center;width:36px;height:40px;color:inherit}
.footer-socials svg{width:27px;height:27px}
.footer-socials>a:hover{opacity:.65}
.footer-socials>a:focus-visible{outline:2px solid currentColor;outline-offset:3px;border-radius:5px}
.footer-socials>.social-pending{opacity:.42;cursor:default}
.social-tooltip{position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);white-space:nowrap;font-size:12px;display:none}
.social-pending:hover .social-tooltip{display:block}

/* Quiet, accessible App Store links on product and social-proof touch points. */
.download-touchpoint{display:block;color:inherit;text-decoration:none;cursor:pointer}
.download-proof{display:flex;flex-direction:column;align-items:center}
.download-touchpoint:focus-visible{outline:2px solid currentColor;outline-offset:5px;border-radius:8px}
.closing-logo .download-touchpoint{display:inline-block}

/* Keep linked proof identical in size to the original unwrapped artwork. */
.rating-laurel.supplied-rating>.download-touchpoint{position:relative;width:100%;min-width:0}
.rating-laurel.supplied-rating>.download-touchpoint>img{position:static;display:block;width:100%;max-width:100%;height:auto;object-fit:contain}
.download-proof{gap:5px}
.proof .download-proof>strong{font-family:Arial,Helvetica,sans-serif;font-size:19px;font-weight:700;letter-spacing:-.025em}
.proof .download-proof>span{color:#737373;font-size:12px}
html[data-theme=light] .proof .download-proof>span{color:#656565}

/* A single, video-ready phone after the professional logo rows. */
/* ── The demo video's takeover ───────────────────────────────────────────
   A tall runway with a viewport-tall stage pinned inside it. demo-zoom.js
   scales the frame up to fill the screen and back down across the runway.

   The stage clips, so the frame can scale past the viewport without the page
   gaining a scrollbar. The runway's height IS the duration of the effect —
   300svh gives roughly two screens of scrolling for grow, hold and shrink.

   The stage is 100dvh and NOT 100svh, which is what it was and what left a
   white band under the video on iOS. svh is the SMALL viewport — the height
   with Safari's URL bar expanded. The bar collapses as you scroll, the
   visible viewport grows to lvh, and a stage fixed at the smaller number
   stops ~100pt short of the bottom with page background showing through.
   dvh tracks the viewport as it changes; the 100vh before it is the fallback
   and errs the safe way, since on iOS 100vh is the LARGE height and
   overflows into the clip rather than leaving a gap.

   The runway stays in svh deliberately. It is the scroll distance, and a
   runway that changed height as the URL bar collapsed would move the
   progress mapping under the effect while it played.

   The frame is sized by HEIGHT with an aspect-ratio, not by width. The video
   is portrait, so its height is what decides whether it fits, and 58svh
   leaves real room to grow into — sized by width it already stood ~85% of a
   laptop screen tall at rest and the zoom had nowhere to go.

   Reduced motion drops the whole mechanism: no runway, no pinning, the video
   just sits at its resting size in normal flow. */
.demo-showcase{position:relative;overflow:clip;padding:32px 0 0}
.demo-zoom{position:relative;height:300svh}
.demo-zoom-sticky{position:sticky;top:0;height:100vh;height:100dvh;display:grid;place-items:center;overflow:clip}
.demo-zoom-frame{height:min(58svh,620px);aspect-ratio:9/16;transform-origin:center center;will-change:transform;border-radius:26px;overflow:hidden;background:#f0ede9}
.demo-zoom-frame .demo-video{display:block;width:100%;height:100%;object-fit:cover}
html[data-theme=light] .demo-zoom-frame{box-shadow:0 18px 50px #00000014}
@media(max-width:700px){.demo-showcase{padding-top:12px}.demo-zoom-frame{height:min(54svh,560px)}}
@media(prefers-reduced-motion:reduce){
  .demo-zoom{height:auto}
  .demo-zoom-sticky{position:static;height:auto;padding:36px 0}
  .demo-zoom-frame{transform:none!important;will-change:auto}
}

/* Give the landing social proof the same visual weight as the rating wreath. */
/* Centred on itself, and sized against the badge beside it. "Trusted by" and
   "people" are short lines sitting under a long "1 Million+", so aligning the
   column left left them ragged and made the group lean away from the laurel.
   Measured at 1280px the pair was 152x66 against the laurel's 220x108, which
   is why one side read heavy and the other light; the icon and the figure are
   up a step to close that without matching it outright — the laurel carries a
   lot of empty space inside its wreath, so equal boxes would overshoot. */
.proof .download-proof{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:14px;text-align:center}
.download-proof .trusted-people-icon{flex:0 0 43px;width:43px;height:36px;color:#c7c7c7}
.proof .download-proof .trusted-people-copy{display:flex;flex-direction:column;align-items:center;gap:2px;white-space:nowrap;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:1.2;color:#bcbcbc}
.proof .download-proof .trusted-people-copy strong{font-family:Arial,Helvetica,sans-serif;font-size:23px;font-weight:700;letter-spacing:-.045em;line-height:1.25;color:#fff}
/* The step up in size is held back to the widest layout. Below 901px the row
   is capped at 356px for two badges, and the laurel alone is 220 of that, so
   there is no room to grow into — the centring above is the whole fix there. */
@media(min-width:901px){
  .proof .download-proof{gap:15px}
  .download-proof .trusted-people-icon{flex-basis:52px;width:52px;height:44px}
  .proof .download-proof .trusted-people-copy strong{font-size:27px}
}
html[data-theme=light] .download-proof .trusted-people-icon{color:#555}
html[data-theme=light] .proof .download-proof .trusted-people-copy{color:#656565}
html[data-theme=light] .proof .download-proof .trusted-people-copy strong{color:#171717}
@media(max-width:700px){.proof .download-proof{gap:9px}.download-proof .trusted-people-icon{flex-basis:34px;width:34px;height:30px}.proof .download-proof .trusted-people-copy{font-size:12px}.proof .download-proof .trusted-people-copy strong{font-size:20px}}

/* Two quiet crayon accents frame the headline without shifting its layout. */
.hero-title-art{position:relative;isolation:isolate}
.hero-crayon{position:absolute;top:-8px;width:124px;height:124px;object-fit:contain;pointer-events:none;user-select:none}
.hero-crayon-reels{left:calc(50% - 365px);transform:rotate(-12deg)}
.hero-crayon-shorts{right:calc(50% - 365px);transform:rotate(10deg)}
@media(max-width:1000px){.hero-crayon{width:86px;height:86px}.hero-crayon-reels{left:0}.hero-crayon-shorts{right:0}}
@media(max-width:700px){.hero-crayon{top:0;width:44px;height:44px}.hero-crayon-reels{left:0}.hero-crayon-shorts{right:0}}

/* Scroll story is an independent layer; existing hero content retains its layout. */
.hero-story{position:relative;height:auto}
.hero-story>.hero{position:relative;top:auto}
.hero-doodle-layer{position:absolute;inset:0;overflow:clip;pointer-events:none;z-index:1}
.hero-story .hero-copy,.hero-story .hero-base{position:relative;z-index:2}
.distraction{position:absolute;width:clamp(64px,8vw,120px);aspect-ratio:1;will-change:transform,opacity}
.distraction img{display:block;width:100%;height:100%;object-fit:contain;animation:doodle-drift 7s ease-in-out infinite alternate}
.doodle-reels{left:5%;top:24%}.doodle-shorts{right:5%;top:30%}.doodle-snapchat{left:3%;top:53%}.doodle-tiktok{right:4%;top:58%}.doodle-facebook{left:14%;top:76%}
.doodle-shorts img{animation-delay:-2s}.doodle-snapchat img{animation-delay:-4s}.doodle-tiktok img{animation-delay:-6s}.doodle-facebook img{animation-delay:-3s}
.connection-world{position:absolute;width:120px;height:120px;right:14%;top:76%;opacity:.55;--connection-reveal:0}
.world-art{width:100%;height:100%;object-fit:contain}
.world-routes{position:absolute;inset:-12%;width:124%;height:124%;opacity:var(--connection-reveal);color:#a0a0a0}
.world-routes path{stroke:currentColor;stroke-width:1;stroke-linecap:round;stroke-dasharray:3 4}
.world-routes circle{fill:currentColor}
.connection-symbols{position:absolute;width:150%;height:150%;max-width:none;left:-25%;top:-25%;object-fit:contain;opacity:var(--connection-reveal)}
@keyframes doodle-drift{from{transform:translate(-2px,-3px) rotate(-1deg)}to{transform:translate(3px,3px) rotate(1deg)}}
@media(max-width:700px){.distraction{width:43px}.doodle-reels{left:2%;top:30%}.doodle-shorts{right:2%;top:35%}.doodle-snapchat{left:2%;top:66%}.doodle-tiktok,.doodle-facebook{display:none}.connection-world{width:52px;height:52px;right:3%;top:74%}}
@media(prefers-reduced-motion:reduce){.hero-story{height:auto}.hero-story>.hero{position:relative;top:auto}.distraction img{animation:none}.distraction{will-change:auto}.world-routes circle{display:none}}

.connection-symbols{filter:brightness(2)}
html[data-theme=light] .connection-symbols{filter:none}

/* Let the globe take center stage during the additional connection scroll. */
.connection-world{transform-origin:center;will-change:transform,opacity}
.world-art{transform-origin:center;filter:brightness(1.35)}
html[data-theme=light] .world-art{filter:none}
.world-routes path{stroke-width:1.25;stroke-dasharray:4 3}
.world-routes circle{r:2.5}
@media(prefers-reduced-motion:reduce){.connection-world{will-change:auto}}

/* Keep the connection moment at the edge, clear of the original hero content. */
.connection-world{right:4%;top:76%;width:100px;height:100px}
@media(max-width:700px){.connection-world{right:3%;top:auto;bottom:5px;width:44px;height:44px}}

/* Use more of the globe corner while preserving the headline clearance. */
.connection-world{right:6%;width:145px;height:145px}
@media(max-width:700px){.connection-world{right:5%;width:58px;height:58px}}

.connection-world{width:205px;height:205px;right:7%;top:auto;bottom:38px}
@media(max-width:700px){.connection-world{width:68px;height:68px;right:6%;bottom:8px}}

/* A short clearing gesture hands straight back to ordinary page scrolling. */
.connection-world{--arrival:0}
.connection-symbols{opacity:var(--arrival)}
.connection-caption{position:absolute;top:calc(100% + 6px);left:50%;transform:translateX(-50%);white-space:nowrap;font:italic 17px/1.2 Georgia,serif;color:#b8b8b8;opacity:var(--arrival)}
html[data-theme=light] .connection-caption{color:#656565}
.travelling-message{position:absolute;z-index:3;width:26px;height:26px;background:url('/crayon-connections.png') right center/130px 130px no-repeat;filter:brightness(2.5);opacity:0;pointer-events:none}
html[data-theme=light] .travelling-message{filter:none}
.world-routes path{stroke-dasharray:2 3;stroke-width:1.1}
@media(max-width:700px){.connection-caption{font-size:11px;top:100%;left:35%}.connection-world{bottom:23px}.travelling-message{width:16px;height:16px;background-size:80px 80px}}

/* The paper plane carries the story to its final destination. */
.journey-plane{position:fixed;left:0;top:0;width:40px;height:40px;background:url('/crayon-connections.png') right center/200px 200px no-repeat;filter:brightness(2.7);z-index:20;pointer-events:none;opacity:0;will-change:transform}
html[data-theme=light] .journey-plane{filter:none}
.connection-finale{display:flex;flex-direction:column;align-items:center;text-align:center;gap:0;padding-top:60px;padding-bottom:90px}
.finale-globe{position:relative;width:min(330px,65vw);aspect-ratio:1;margin:0 auto 22px;--landed:0}
.finale-globe>img{display:block;width:100%;height:auto;filter:brightness(1.3)}
html[data-theme=light] .finale-globe>img{filter:none}
.landing-ring{position:absolute;left:69%;top:32%;width:18px;height:18px;border:1px solid #aaa;border-radius:50%;transform:translate(-50%,-50%) scale(calc(.6 + var(--landed)*.7));opacity:var(--landed)}
.connection-finale h2{font-size:clamp(36px,5vw,66px);font-weight:700;line-height:1.08;margin:0}
.connection-finale p{margin:20px 0 0;color:#999;font-size:18px}
/* THE authoritative gap under the closing headline. .closing .store-buttons
   exists in both style.css and earlier in this file, and neither one wins:
   this rule ties on specificity (0,2,0) and is later in the last stylesheet,
   so it decides at every width. Change it here or nothing happens.

   Widened because the paragraph and the Download button that used to sit
   between the headline and the badges are gone, and 28px left the badges
   sitting straight under an 80px headline. */
.connection-finale .store-buttons{margin-top:clamp(30px,4vw,46px)}
@media(max-width:700px){.connection-finale{padding-top:32px;padding-bottom:48px}.connection-finale p{font-size:16px}.connection-finale .store-badge{zoom:.8}}
@media(prefers-reduced-motion:reduce){.journey-plane{will-change:auto}}

/* Three crossed-out social icons on either side of the desktop hero. */
.doodle-reels{left:5%;top:24%}.doodle-shorts{right:5%;top:24%}
.doodle-snapchat{left:3%;top:53%}.doodle-tiktok{right:3%;top:53%}
.doodle-facebook{left:10%;top:76%}.doodle-x{right:10%;top:76%}
.doodle-x img{animation-delay:-5s}
.landing-ring{display:none}
@media(max-width:700px){.doodle-reels{left:2%;top:30%}.doodle-shorts{right:2%;top:30%}.doodle-snapchat{left:2%;top:53%}.doodle-tiktok{display:block;right:2%;top:53%}.doodle-facebook{display:block;left:2%;top:76%}.doodle-x{right:2%;top:76%}.distraction{width:32px}}

html[data-theme=light] .doodle-x img{filter:brightness(.55)}
html[data-theme=light] .logo-x-video img{filter:brightness(.55)}

/* Keep the phone clear until its lower edge, then blend away the bottom bezel. */
.product-phone-stage,html[data-theme=light] .product-phone-stage{
 -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 68%,rgba(0,0,0,.96) 73%,rgba(0,0,0,.78) 78%,rgba(0,0,0,.42) 82%,rgba(0,0,0,.1) 86%,transparent 89%,transparent 100%);
 mask-image:linear-gradient(to bottom,#000 0%,#000 68%,rgba(0,0,0,.96) 73%,rgba(0,0,0,.78) 78%,rgba(0,0,0,.42) 82%,rgba(0,0,0,.1) 86%,transparent 89%,transparent 100%);
}

/* Extend the hand-drawn identity to parents and schools without changing copy. */
.parents-hero{position:relative;isolation:isolate}
.parents-hero-copy{position:relative;z-index:2}
.parents-doodle-layer{position:absolute;inset:0;overflow:clip;pointer-events:none;z-index:1}
.parents-doodle-layer .distraction{width:clamp(65px,7.5vw,110px)}
.school-hero{position:relative;isolation:isolate}
.school-hero>h1,.school-hero>p,.school-hero>a{position:relative;z-index:2}
.school-doodle-layer{position:absolute;top:0;bottom:0;left:calc(50% - 50vw);width:100vw;overflow:clip;pointer-events:none}
.school-doodle{position:absolute;width:clamp(85px,10vw,150px);height:auto;object-fit:contain;animation:doodle-drift 8s ease-in-out infinite alternate}
.school-doodle-book{left:2%;top:36%;rotate:-8deg}
.school-doodle-notebook{right:2%;top:46%;rotate:8deg;animation-delay:-4s}
.student-capabilities{position:relative}
.school-cap-doodle{display:block;width:145px;height:145px;object-fit:contain;margin:20px 0 24px;rotate:-6deg}
@media(max-width:700px){.parents-doodle-layer .distraction{width:32px}.school-doodle{width:48px}.school-doodle-book{top:auto;bottom:14px;left:3%}.school-doodle-notebook{top:auto;bottom:14px;right:3%}.school-cap-doodle{width:90px;height:90px;margin:16px 0}}
@media(prefers-reduced-motion:reduce){.school-doodle,.parents-doodle-layer .distraction img{animation:none}}

/* Consistent download calls to action at key decision points. */
.try-free-row{display:flex;justify-content:center;margin:24px 0;position:relative;z-index:2}
a.try-free{display:inline-flex;align-items:center;justify-content:center;gap:16px;min-height:50px;padding:14px 28px;border:1px solid transparent;border-radius:999px;background:#f5f5f5;color:#111;font-family:inherit;font-size:16px;font-weight:600;line-height:1.2;text-decoration:none;white-space:nowrap;transition:opacity .2s,transform .2s}
a.try-free:hover{opacity:.85;transform:translateY(-1px)}
a.try-free:focus-visible{outline:2px solid currentColor;outline-offset:5px}
html[data-theme="light"] a.try-free{background:#171717;color:#fff}
.demo-showcase>.try-free-row{margin-top:0}
.student-capabilities>.try-free-row{justify-content:flex-start}
@media(max-width:700px){.try-free-row{margin:18px 0}a.try-free{min-height:46px;padding:12px 24px;font-size:15px}}
@media(prefers-reduced-motion:reduce){a.try-free{transition:none}a.try-free:hover{transform:none}}

/* Mobile: compact flow, scattered doodles, and selective reveal holds. */
@media(max-width:700px){
 .hero-story>.hero{min-height:0;height:auto;justify-content:flex-start;padding:calc(var(--header-clearance,130px) + 16px) 22px 24px;gap:0}
 .hero-story .hero-copy{margin-top:0;padding-top:0;flex:none}
 .hero-story .hero h1{margin-top:0}
 .hero .distraction{width:28px}
 .hero .doodle-reels{left:3%;right:auto;top:calc(var(--mobile-icons-top,150px) + 8px);rotate:-17deg;width:31px}
 .hero .doodle-shorts{right:4%;left:auto;top:calc(var(--mobile-icons-top,150px) + 38px);rotate:13deg;width:26px}
 .hero .doodle-snapchat{left:1%;right:auto;top:calc(var(--mobile-icons-top,150px) + var(--mobile-icons-span,180px)*.62);rotate:12deg;width:25px}
 .hero .doodle-tiktok{right:1%;left:auto;top:calc(var(--mobile-icons-top,150px) + var(--mobile-icons-span,180px)*.82);rotate:-14deg;width:31px}
 .hero .doodle-facebook{left:7%;right:auto;top:calc(var(--mobile-icons-top,150px) + var(--mobile-icons-span,180px) + 36px);rotate:-10deg;width:24px}
 .hero .doodle-x{right:10%;left:auto;top:calc(var(--mobile-icons-top,150px) + var(--mobile-icons-span,180px) + 67px);rotate:19deg;width:26px}
}
@media(max-width:700px) and (prefers-reduced-motion:no-preference){
 .mobile-scenes-active{isolation:isolate}
 .mobile-scene{position:relative;padding-bottom:18svh;margin-bottom:-18svh}
 .mobile-scene>.mobile-scene-content{position:sticky;top:var(--header-clearance,110px);min-height:0;box-sizing:border-box;background:#000;display:flex;flex-direction:column;justify-content:flex-start;padding:16px 22px 24px;margin-top:0;margin-bottom:0}
 html[data-theme=light] .mobile-scene>.mobile-scene-content{background:#fff}
 .mobile-scene>.video-section .video-growth{width:100%}
 .mobile-scene>.product-reveal .product-phone-stage{width:100%;margin:0 auto}
 /* Three phones now, not one, so each is smaller. Matched to the
    .product-phone-stage rule above — both have to move together or the
    side phones fan out around a centre phone of a different size. */
   .mobile-scene>.product-reveal .product-phone,
   .mobile-scene>.product-reveal .product-phone-side{width:min(186px,42svh)}
 .mobile-scenes-active>.professionals,.mobile-scenes-active>.numbers,.mobile-scenes-active>.connection-finale{position:relative;z-index:4;background:#000}
 html[data-theme=light] .mobile-scenes-active>.professionals,html[data-theme=light] .mobile-scenes-active>.numbers,html[data-theme=light] .mobile-scenes-active>.connection-finale{background:#fff}
 .mobile-scenes-active>.reading-section{z-index:8;background:#000}
 html[data-theme=light] .mobile-scenes-active>.reading-section{background:#fff}
 .mobile-scenes-active>.connection-finale{z-index:9}
}

/* [COUNTER-ODOMETER] Rolling digits for the hours-saved counter.
   --odo-h must match the counter's line-height so a cell is exactly one
   line tall; the header counter runs a tighter line-height, hence the
   override. Overrides `.saved-number span{display:inline-block}` in
   style.css, which would otherwise collapse the columns. */
.saved-number{--odo-h:1.2em;align-items:center}
.saved-number .odo{display:block;height:var(--odo-h);overflow:hidden}
.saved-number .odo-track{display:block;transform:translateY(calc(var(--p,0) * var(--odo-h) * -1))}
.saved-number .odo-track i{display:flex;align-items:center;justify-content:center;height:var(--odo-h);font-style:normal}
.saved-number .odo-sep{display:block}
.header-counter .saved-number{--odo-h:1.15em}

/* "60 full days" reads in the crayon strike-through red, sampled from the
   hero doodles (#f03c30) so the site's one accent colour is already part of
   its vocabulary. --read-ink is the filled half of the two-gradient
   background-clip fill in style.css, and .reading-underline takes its colour
   from the same variable, so setting it on the phrase colours both the words
   and the hand-drawn underline. Everything else keeps --read-ink from :root.
   Light mode uses a darkened variant of the same hue: the crayon red is
   3.89:1 on white, this is 5.00:1. */
.reading-phrase{--read-ink:#f03c30}
html[data-theme=light] .reading-phrase{--read-ink:#d32f21}

/* Store badges were in two equal 1fr columns up to 442px wide, centring
   inside each column, so the visible space between them was the gap plus
   whatever each column had spare - about 84px on a phone, despite gap:8px.
   Content-sized columns sit them side by side with only the gap between.
   Left as grid (not flex) so justify-items and the existing width caps in
   style.css keep working. */
.hero .store-buttons{grid-template-columns:repeat(2,auto);justify-content:center}
/* Side by side, the pair needs ~294px; a 320px viewport only offers 280px
   inside the hero's 20px padding. Trim the badge scale on the narrowest
   phones so they stay on one row instead of overflowing. */
@media(max-width:360px){.hero .store-buttons .store-badge{zoom:.78}}

/* [SHORTS-SLASH] Every crayon doodle is struck through from top-right to
   bottom-left except the YouTube Shorts one, which was drawn the other way and
   read as a mistake next to the other five.

   Flipped vertically rather than horizontally: both reverse the slash, but a
   horizontal flip also reverses the play triangle so it points backwards,
   which is worse than a mirrored petal. Done in CSS rather than by
   re-exporting because the asset ships as WebP with a PNG fallback and there
   is no cwebp on this machine - a re-export would mean dropping the WebP and
   serving a 208KB PNG in place of a 38KB one.

   The transform sits on the wrapper, not the <img>: doodle-drift animates the
   image's own transform and would overwrite a static one set there. */
.doodle-shorts{transform:scaleY(-1)}

/* [PRODUCT-SHOTS] Real app screenshots composited into the phone frame.
   Two <img> per phone rather than <picture>: the site switches theme with a
   data-theme attribute, which media queries cannot see, so the swap has to be
   a CSS rule. Both files are ~35KB WebP - the spare fetch costs less than the
   696KB phone.png this replaces.
   Specificity note: style.css sets .device img{display:block} (0,1,1), so
   these two-class selectors win without !important. */
.device .shot-light{display:none}
html[data-theme=light] .device .shot-dark{display:none}
html[data-theme=light] .device .shot-light{display:block}

/* [APPS-INSIDE] Real social apps running in SocialLite, with a crayon ring
   drawn around what is missing. */
.apps-inside{padding:clamp(34px,6vw,70px) 22px clamp(20px,3vw,40px);max-width:1180px;margin:0 auto;text-align:center}
.apps-inside h2{margin:0 0 clamp(26px,4vw,46px);font-size:clamp(26px,5.4vw,44px);font-weight:650;letter-spacing:-.03em;line-height:1.12}
/* Three fixed tracks cannot fit a phone each on a handset - they stack.
   This has to sit AFTER the rule above, not in the max-width:700px block
   near the top of the file: same specificity, and that block is ~260 lines
   earlier, so it lost and the grid stayed three columns at 114px each. */
/* Stay three-across on phones. Stacked, each tilted phone is ~360px tall
   and the section became three screens of scrolling for one idea. The
   tilt is what makes a row work at this width — the phones read as a set
   rather than three separate things. */
/* Stacked one per row, a 320px-wide tilted phone stands ~500px tall and eats
   most of a handset screen — and the tilt makes the silhouette wider than the
   phone itself, so it reads bigger than the straight mockups did at the same
   width. This has to come AFTER the rule above: same specificity, so the
   later one wins, and putting it in the media block a few lines up did
   nothing at all. */
/* .device brings the clip-path that cuts the frame's black background away;
   its absolute positioning and fixed width are not wanted here. */
.apps-inside .app-device{position:static;width:auto;will-change:auto}
html[data-theme=light] 
/* The ring sits exactly over the phone: same box, and a viewBox of
   1024x1536 so its coordinates are the composite's own pixels. */
.crayon-note{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.crayon-ring{fill:none;stroke:#f03c30;stroke-width:14;stroke-linecap:round;stroke-linejoin:round;
  filter:url(#crayon-rough)}
/* Undrawn only once JS has confirmed it can animate; without JS the ring is
   simply visible, never stuck hidden. */
.apps-inside.crayon-ready .crayon-ring{stroke-dasharray:1;stroke-dashoffset:1}
.apps-inside.is-drawn .crayon-ring{stroke-dashoffset:0;transition:stroke-dashoffset 1.15s cubic-bezier(.65,.02,.35,1) .15s}
/* stagger so the rings draw one after another rather than in unison */
.apps-inside.is-drawn .removes-card:nth-child(2) .crayon-ring{transition-delay:.45s}
.apps-inside.is-drawn .removes-card:nth-child(3) .crayon-ring{transition-delay:.9s}
@media(prefers-reduced-motion:reduce){.apps-inside .crayon-ring{stroke-dashoffset:0!important;transition:none}}

/* [DEMO-VIDEO] The film replaces the big phone in the demo showcase.
   It is a finished promo with its own device frames and title cards, so it
   is shown at size rather than nested inside another phone - the cards would
   be a third the size and unreadable. */
.demo-zoom-frame .demo-video[controls]{background:#0d0d0d;object-fit:contain}

/* ── Phone hero: fewer things ────────────────────────────────────────────
   Phones only. The desktop hero keeps all three — there is room for them
   there, and on a 390px screen they were competing with the headline.

   .hero-doodle-layer is position:absolute, so hiding it reclaims no space
   and shifts nothing; the six crayon app icons simply stop crowding the
   type. Scoped to the hero layer, so the parents page's own doodles stay.

   .try-free-row is scoped to .hero on purpose: the SAME class carries the
   closing section's "Try SocialLite" at the bottom of the page, and that
   one stays. It is the only remaining link to /start/ from a phone, since
   the header nav has none. */
@media(max-width:700px){
  .hero-doodle-layer{display:none}
  .hero .try-free-row{display:none}
  /* Matches the selector in style.css that sets display:block on this —
     .proof .supplied-rating .rating-count is three classes, so a bare
     .rating-count loses on specificity no matter that this file loads
     later. Same specificity plus later source order wins it cleanly,
     without reaching for !important. */
  .proof .supplied-rating .rating-count{display:none}
}

/* ── Phone hero: tighter headline, stacked badges ───────────────────────
   Phones only, continuing the block above.

   The headline is "Stay connected" over "without the distractions.", one
   hard <br> between them. It used to open with "SocialLite," on a line of
   its own, which this file then folded into line two on phones; both the
   fragment and the rule that hid its <br> are gone. The break that remains
   is load-bearing and is NOT a wrap hint: line two is the .silver span, so
   breaking anywhere else splits the white/silver treatment mid-line.

   Not text-wrap:balance. Balance evens the lines by making them all
   shorter, which is the opposite of fitting more words on a line — measured
   at 28px it filled about 60% of the available width. The type is sized so
   the longer of the two lines fills the column instead.

   The badges stack. grid-template-columns is respecified rather than
   switching to flex because an earlier rule in this file sets
   repeat(2,auto), and one column is the smallest change that undoes it. */
@media(max-width:700px){
  /* The size is set by one constraint: the longest line has to stay on one
     line, or the two-line composition collapses into three ragged ones.

     The copy has changed twice and the size follows it each time, because
     the constraint is the LONGEST line, not the headline as a whole:

       "SocialLite, stay connected"   11.39em   ceiling 8.12vw @320
       "without the distractions."    10.431em  ceiling 8.87vw
       "short-form content."           8.367em  ceiling 11.06vw

     So the current copy is 20% narrower than the last, and at the old 8.6vw
     it only filled 77% of the column. 10.7vw sits ~3% under the ceiling,
     enough that a metric-compatible fallback for Arial cannot push the line
     over. Verified 320-430.

     Line one is deliberately much shorter than line two — that is the
     composition, not slack to be taken up. Sizing to fill on line one would
     overflow line two immediately.

     The tracking is not arbitrarily tight: the desktop headline in style.css
     runs -6px at 105px, or -.057em, so this is still looser than the same
     words set large. And the negative margin only pulls the headline out to a
     14px gutter while the proof row and badges keep the hero's 24px — a
     display line running nearer the edge than the body beneath it. */
  .hero h1{font-size:clamp(33px,10.7vw,52px);line-height:1.06;letter-spacing:-.045em;margin-inline:-10px}

  .hero .store-buttons{grid-template-columns:minmax(0,1fr);justify-content:center;gap:10px}

  /* Same two-class selector as the sizing rule earlier in this file, so
     later source order decides it. No !important needed. */
  .download-proof .trusted-people-icon{display:none}
}

/* ── Phone hero: the proof row ───────────────────────────────────────────
   Phones only, continuing the block above.

   Stacked, the same one-column change the badges got — .hero .proof is
   already a two-column grid in style.css, so this is the smallest edit that
   puts the count above the rating rather than beside it.

   "Trusted by / 1 Million+ / people" was three stacked lines in two sizes
   and two colours: 14px #bcbcbc labels around a 23px white number. It is
   now one line in one treatment. The number keeps the ink rather than the
   labels keeping their grey, because "1 Million+" is the claim and a row
   set entirely in muted grey would read as a caption.

   "people" is hidden rather than cut from the markup: the desktop hero
   still reads "Trusted by / 1 Million+ / people" and is not part of this. */
@media(max-width:700px){
  .hero .proof{grid-template-columns:minmax(0,1fr);gap:12px}

  .proof .download-proof .trusted-people-copy{
    flex-direction:row;align-items:baseline;justify-content:center;
    gap:5px;font-size:14px;line-height:1.3;color:#fff}
  html[data-theme=light] .proof .download-proof .trusted-people-copy{color:#171717}

  /* Inherit everything the strong otherwise overrides, so "1 Million+" sits
     in the same font, size and colour as the words either side of it. */
  .proof .download-proof .trusted-people-copy strong{
    font-size:inherit;font-weight:600;letter-spacing:-.01em;
    line-height:inherit;color:inherit}
  html[data-theme=light] .proof .download-proof .trusted-people-copy strong{color:inherit}

  .proof .download-proof .trusted-people-copy>span:last-child{display:none}
}

/* ── Phone hero: proof above the badges, and bigger ──────────────────────
   Phones only, continuing the block above.

   The social proof now sits between the headline and the download buttons,
   so the claim is read before the ask rather than after it.

   Done with order rather than by moving the markup, because the desktop
   hero wants the badges first and shares this HTML. .hero-copy is not a
   flex container of its own, so it becomes one here — its children are
   block-level and full width already, so the column reflows identically
   and only the sequence changes.

   Bigger: the row carried zoom:.85 from an earlier pass. That is dropped
   and the parts are sized directly, which is why the numbers below are
   larger than they look — 1/.85 of the old size is the starting point, and
   these go past it. */
@media(max-width:700px){
  .hero-copy{display:flex;flex-direction:column}
  .hero-copy>.hero-title-art{order:1}
  .hero-copy>.proof{order:2}
  .hero-copy>.try-free-row{order:3}
  .hero-copy>.store-buttons{order:4}

  .hero .proof{zoom:1;margin-top:22px;gap:16px}
  .hero .store-buttons{margin-top:22px}

  .proof .download-proof .trusted-people-copy{font-size:17px;gap:6px}
  /* .hero-scoped: style.css caps this at 180px through
     .hero .proof .rating-laurel.supplied-rating, which is four classes and
     outranks a three-class selector however late this file loads. */
  .hero .proof .rating-laurel.supplied-rating{width:min(100%,250px)}
}

/* ── Phone hero: the counter inside the proof line ───────────────────────
   hero-counter.js moves #time-saved into .trusted-people-copy at this
   breakpoint and adds .in-proof, so the line reads

     Saving 1 Million+ people 37,771,565 hours

   It replaces a glass nub pinned under the header. Sitting in the proof line
   it scrolls away with the hero by itself, so the fixed positioning, the
   IntersectionObserver collapse and the frozen clearance variable are all
   gone with it.

   Almost every property here is a reset: the counter carries styling from its
   header home that has to be undone. What it keeps is inherit, so it takes
   the proof line's own type and colour. */
@media(max-width:700px){
  .header-counter.in-proof{
    display:inline-flex;align-items:baseline;gap:4px;
    position:static;transform:none;inset:auto;
    margin:0;padding:0;border:0;border-radius:0;
    background:none;backdrop-filter:none;-webkit-backdrop-filter:none;
    box-shadow:none;max-height:none;overflow:visible;
    font-size:inherit;line-height:inherit;color:inherit;
  }
  .in-proof .header-counter-total{
    display:inline-flex;flex-direction:row;align-items:baseline;gap:4px;
    min-width:0;white-space:nowrap}
  /* Weighted like the "1 Million+" beside it, not like the muted label. */
  .in-proof .saved-number{font-size:inherit;line-height:inherit;font-weight:600;
    color:inherit;white-space:nowrap}
  .in-proof .saved-unit{font-size:inherit;line-height:inherit;margin:0;
    font-weight:400;white-space:nowrap}
}

/* ── Phone hero: bigger badges, "people" restored ────────────────────────
   The badges were carrying two stacked zooms — .85 on the container and .85
   on each badge — so they were rendering at .72 of their already-reduced
   mobile size. Both are reset and one zoom above 1 replaces them.

   zoom rather than width, because the badge art is a sprite: the image sits
   in a ::before with a fixed background-size, so scaling the box alone
   leaves the artwork at its old size. zoom scales both together. */
@media(max-width:700px){
  .hero .store-buttons{zoom:1}
  .hero .store-buttons .store-badge{zoom:1.2}

  /* "people" back, and the whole line up again. */
  .proof .download-proof .trusted-people-copy>span:last-child{display:inline}
  .proof .download-proof .trusted-people-copy{font-size:clamp(15px,4.4vw,19px);gap:7px}
  .hero .proof .rating-laurel.supplied-rating{width:min(100%,270px)}
}

/* ── Phone hero: clearance for the fixed pill, and one width for both CTAs ──
   The pill is out of flow now, so the hero has to reserve the room it used to
   take: it sits 84..128, and the headline starts clear of that. */
@media(max-width:700px){

  /* One knob. The badge art is a sprite at a fixed 168px, so its size comes
     from zoom; the laurel is a plain image sized in px. Deriving the laurel
     from the same number is what keeps the two blocks exactly as wide as each
     other — change this and both move together.

     .88 is what lets two sit side by side: 2 x 168 x .88 + 10px of gap is
     306px, against 316px of content width at a 360px viewport, which is the
     narrowest phone worth targeting. Larger and the pair wraps there. */
  .hero{--cta-zoom:.88;--cta-gap:10px}
  .hero .store-buttons{grid-template-columns:repeat(2,auto);justify-content:center;gap:var(--cta-gap)}
  .hero .store-buttons .store-badge{zoom:var(--cta-zoom)}
  /* No longer tied to the badge pair's width. Matching it made the laurel
     306px wide and, because the artwork is far taller relative to its width
     than a store badge is, that made it the largest thing in the hero — it
     read as the headline rather than as supporting proof. It is sized on its
     own now, deliberately smaller than the CTA pair it sits above. */
  .hero .proof .rating-laurel.supplied-rating{width:min(100%,196px)}
}

/* ── Phone: bring the product phone up under the hero ────────────────────
   55px of dead space sat between the hero's last line and the phone: the
   hero's own bottom padding, then the section's padding-top, then the
   stage's offset. The section padding goes and the stage pulls up, which
   closes most of it without touching the hero. */
@media(max-width:700px){
  .second-feature.product-reveal{padding-top:0}
  .second-feature.product-reveal .product-phone-stage{margin-top:-24px}
}

/* ── Header wordmark ─────────────────────────────────────────────────────
   One authoritative size for the mark. .header>.brand .logo is set five
   times across breakpoints with conflicting widths, heights and transforms;
   this file loads after style.css, so a final rule at matching specificity
   settles it rather than adding a sixth to the pile.

   The mark is a 28x39 window onto a 55x55 image offset by -13.5/-8. All four
   numbers scale together off --k, so resizing is one value, not four that
   can drift apart. transform is cleared because the older rules scaled it
   that way, which changes what you see without changing the box — the text
   then sits against a gap rather than against the glyph.

   align-items:baseline is what puts the wordmark on the mark's bottom edge.
   .logo is an inline-block with overflow:hidden, and such a box's baseline
   IS its bottom margin edge, so its underside lands on the text baseline. */
/* min-height is cleared, not overridden to a number. An earlier rule sets
   38px while the mark-plus-wordmark only inks 28, and baseline alignment
   parks that content at the TOP of the taller box — so the box centred
   perfectly while the glyphs sat ~7px high. The header's height comes from
   the 42px hamburger, not from this, so letting the brand hug its content
   costs nothing.

   padding-top is the rest of it. Even hugging, the box keeps the wordmark's
   descender space BELOW the baseline while nothing is drawn there, so
   centring the box still left the ink ~3px high. .24em matches that descent
   at both 21px and 24px, so the empty space is mirrored above and the ink
   lands centred. Measured, not assumed — see the commit. */
/* The wordmark is sized FROM the mark, not independently, because the two
   drifting apart is exactly what went wrong: the mark inked 1.5x the cap
   height of the type beside it, so "ocialLite" read as a caption next to a
   badge rather than as the rest of the word.

   45.8 is that ratio solved for. The mark inks 39*k tall and the cap height
   of this face is .709em, so a target of mark = 1.2x cap gives
   39k / (1.2 * .709) = 45.8k. Rendered 1.5 / 1.3 / 1.2 / 1.1 / 1.0 and
   compared: 1.2 is where the S reads as the capital of the word. It is not
   1.0 because a round letterform has to overshoot flat-topped caps like L
   and t slightly to look the same size, and below about 1.1 the mark starts
   looking undersized instead. 1.0 also pushes the bar past 64px — the brand
   overtakes the 42px hamburger as the tallest thing in it.

   --k now lives here rather than on .logo so the mark and the type scale off
   one number. Change --k and the ratio survives. */
.header>.brand{
  --k:.66;
  align-items:baseline;align-self:center;min-height:0;padding-top:.24em;
  font-size:calc(45.8px * var(--k));
}
.header>.brand .logo{
  transform:none;
  overflow:hidden;
  width:calc(28px * var(--k));
  height:calc(39px * var(--k));
}
.header>.brand .logo img{
  width:calc(55px * var(--k));
  height:calc(55px * var(--k));
  left:calc(-13.5px * var(--k));
  top:calc(-8px * var(--k));
}
@media(max-width:700px){
  .header>.brand{--k:.60}
}

/* ── The footer's reading column ─────────────────────────────────────────
   These are article titles, not one-word nav labels, so they wrap. The
   tighter line-height keeps a two-line title reading as one item, and the
   extra row-gap keeps two wrapped titles from looking like four links.

   The column exists because the landing page's "Worth reading" section was
   three large cards for three posts. The links are worth more than the
   space: in the footer they appear on every page instead of one, which is
   more internal linking to the blog, not less. */
.footer-reading a{line-height:1.35}
.footer-reading{gap:15px}

/* ── The film's poster ───────────────────────────────────────────────────
   The frame holds a self-hosted still until film-facade.js swaps Vimeo in
   on intent. Absolute so the injected iframe, which is in flow at 100%/100%
   like it always was, lands on top of it rather than below it — and so the
   poster is still there underneath while the player paints. */
.video-frame .film-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border:0;display:block}
.video-frame.film-live .film-poster{z-index:0}
.video-frame iframe{position:relative;z-index:1}

/* ── "Switch off Reels", arched under the phone trio ─────────────────────
   The three phones' bottom edges are not level: measured at the end of the
   reveal the centre sits at 690 and both sides hang at 727, so the line they
   make bulges UPWARD in the middle. The text follows that, which is why it
   reads as a rainbow arc rather than a sag.

   The curve is matched to theirs rather than eyeballed: they rise 37px over a
   490px span, a ratio of .0755, and this quadratic rises 57 over 660 in the
   viewBox — the same shape one step more pronounced, so it reads as an arch
   rather than a slightly bent line.

   The section is a flex column and .product-description is order:2, so
   order:1 drops this between the phones and that line without touching the
   markup order of either.

   viewBox units, not px: the SVG scales with its container, so the arc keeps
   its shape and the type scales with the phones instead of needing its own
   breakpoints. */
.switch-off{order:1;width:min(100%,1000px);margin:-14px auto 0;pointer-events:none}
.switch-off svg{display:block;width:100%;height:auto;overflow:visible}
/* currentColor, not #000: the page ink is black in the light appearance
   and near-white in the dark one, and a literal black would vanish on
   the dark theme, which is the default. This is the same treatment every
   other heading on the page gets. */
.switch-off text{font-weight:800;font-size:100px;letter-spacing:-.025em;text-anchor:middle;fill:currentColor}
@media(max-width:700px){.switch-off{width:min(100%,500px);margin-top:-6px}}

/* ── "SocialLite removes …" — a pinned, scroll-driven sequence ───────────
   Four beats: Reels, Shorts, Spotlight, then the other apps. The section is
   a tall runway with a viewport-tall stage pinned inside it, the same shape
   as the demo video's takeover, so one scroll gesture advances one beat and
   the page carries on normally once the runway is spent.

   The deck is a 3D carousel: every card sits in the same absolute box and
   removes.js places it by how far it is from the current beat, so the
   incoming card swings in from the right while the outgoing one turns away
   to the left. perspective lives on the deck, not the cards, so they share
   one vanishing point rather than each having their own.

   The phone images keep the .device img clip-path from style.css — these are
   the flat mockups again, and that silhouette is what hides their black
   background. Do not disable it here; the angled composites needed that and
   these are the opposite case.

   Height, not width, sizes the deck: the viewport is the constraint when a
   stage is pinned to it, and aspect-ratio derives the width from the
   mockup's own 1024x1536. */
.removes-runway{position:relative;height:300svh}
.removes-stage{position:sticky;top:0;height:100vh;height:100dvh;display:grid;place-items:center;overflow:clip}
/* The layout moved off the stage and onto this so removes.js has one
   element to lift and fade on the way out. Transforming the sticky stage
   itself would mean animating the element whose position the pin depends
   on. */
.removes-inner{display:flex;flex-direction:column;align-items:center;gap:clamp(16px,3vh,40px);will-change:transform,opacity}
.removes-title{margin:0;text-align:center;font-weight:800;letter-spacing:-.04em;line-height:1.05;font-size:clamp(31px,6.2vw,76px);display:flex;flex-wrap:wrap;align-items:baseline;justify-content:center;gap:.28em}
/* Each part breaks as a unit, never mid-phrase. Without this the heading
   came out 1 line on "Reels" and 3 on "Spotlight" at 412px, so the block
   changed height between beats and the phone under it jumped. */
.removes-brand,.removes-lead,.removes-word{white-space:nowrap}
/* Below 700 the longest beat cannot share a line, so every beat gets the
   same two-line shape rather than some getting one and some three. */
@media(max-width:700px){.removes-word{flex-basis:100%}}
.removes-brand,.removes-lead{color:inherit}

/* The mark stands in for the S, the same lockup as the header: [S]ocialLite.
   Everything is in em so it scales with the heading instead of needing its
   own sizes — the window is 28x39 onto a 55x55 image offset -13.5/-8, and
   all four numbers derive from one width so they cannot drift apart.

   .61em comes from the header's ratio: the mark inks 1.2x the cap height
   there, cap height is .709em, so the mark stands .851em tall and 28/39 of
   that is .611 wide. Matching it keeps the two lockups the same shape.

   inline-block with overflow:hidden puts its baseline at the bottom margin
   edge, which is what drops the mark onto the text baseline. */
/* vertical-align, not baseline. An inline-block with overflow:hidden puts
   its baseline at the BOTTOM margin edge, so the mark sat exactly on the
   text baseline — measured, 0px off — and a mark this tall then towers
   upward from it and reads as floating above the word.
   -.19em drops it so its centre matches the cap band's instead: the mark
   is 1.086em tall, caps are .709em, so its centre is .543em above the
   baseline against the caps' .355em, and the difference is the shift. */
.removes-brand .logo{--w:.78em;display:inline-block;position:relative;overflow:hidden;width:var(--w);height:calc(var(--w) * 39 / 28);vertical-align:-.19em}
.removes-brand .logo img{position:absolute;max-width:none;width:calc(var(--w) * 55 / 28);height:calc(var(--w) * 55 / 28);left:calc(var(--w) * -13.5 / 28);top:calc(var(--w) * -8 / 28)}

/* Use the header's mark-to-type ratio and baseline in desktop headings.
   The old negative vertical-align placed the S below the word. */
@media(min-width:701px){
  .removes-brand .logo{--w:.61135em;vertical-align:baseline;transform:none}
}

/* The footer used a full-size mark next to 22px type, centred vertically.
   Scale its crop with the type and seat the bottom edge on the baseline. */
.footer-identity>.brand{align-items:baseline}
.footer-identity>.brand .logo{--w:.61135em;transform:none;width:var(--w);height:calc(var(--w) * 39 / 28)}
.footer-identity>.brand .logo img{width:calc(var(--w) * 55 / 28);height:calc(var(--w) * 55 / 28);left:calc(var(--w) * -13.5 / 28);top:calc(var(--w) * -8 / 28)}

/* Each removed feature carries its own app's colour. Instagram is a gradient
   rather than a flat pink because that is what the brand actually is.

   Snapchat is the exception and it is deliberate: #FFFC00 on the light
   appearance is about 1.1:1 against white, which is unreadable. The dark
   appearance keeps the real yellow; light drops to an amber that still reads
   as Snapchat but can actually be read. */
.removes-word[data-app="instagram"]{background:linear-gradient(88deg,#f9ce34 0%,#ee2a7b 46%,#6228d7 100%);-webkit-background-clip:text;background-clip:text;color:transparent}
.removes-word[data-app="youtube"]{color:#ff0033}
.removes-word[data-app="snapchat"]{color:#fffc00}
/* One yellow, no outline, both appearances. Flagging rather than fixing:
   Snapchat yellow is about 1.1:1 against white, so on the light theme
   this word is decorative more than readable. The stroke that bought
   that back read as an outline and is gone by request. */
.removes-word[data-app="more"]{color:inherit}
.removes-deck{position:relative;height:min(54svh,600px);aspect-ratio:1024/1536;perspective:1150px}
.removes-card{position:absolute;inset:0;margin:0;display:grid;place-items:center;will-change:transform,opacity;backface-visibility:hidden}
.removes-phone{position:relative;width:100%}
.removes-phone .app-device{position:static;width:100%}
/* No display here. style.css already sets .device img{display:block} and
   the theme pair is switched by .device .shot-light{display:none} at
   (0,2,0) — declaring display:block at (0,2,1) beat that rule and put
   BOTH the dark and light shot on screen, one under the other. */
.removes-phone img.shot{width:100%;height:auto}
.removes-phone .crayon-note{position:absolute;inset:0;width:100%;height:100%}

/* The other apps. They scale in on a stagger once this beat is reached. */
.removes-more{display:grid;grid-template-columns:repeat(3,1fr);align-content:center;gap:clamp(8px,2.2vh,26px);padding:0 2%}
.removes-logo{display:block;opacity:0;transform:scale(.45);transition:transform .55s cubic-bezier(.2,.8,.2,1),opacity .4s ease}
.removes-more.is-live .removes-logo{opacity:1;transform:scale(1);transition-delay:calc(var(--n) * .075s)}
.removes-logo img{display:block;width:100%;height:auto}

/* Let the next line use the empty lower part of the desktop stage.
   The last card remains visible while the sticky section releases. */
@media(min-width:701px) and (prefers-reduced-motion:no-preference){
  .apps-inside.removes{padding-bottom:0}
  .removes-runway{height:260svh;margin-bottom:clamp(-180px,-18svh,-100px)}
  main>.product-description{position:relative;padding:24px 0 40px}
}

/* No pinning, no carousel: every beat laid out in normal flow. */
@media(prefers-reduced-motion:reduce){
  .removes-runway{height:auto}
  .removes-stage{position:static;height:auto;padding:36px 0}
  .removes-inner{transform:none!important;opacity:1!important}
  .removes-deck{height:auto;aspect-ratio:auto;display:grid;gap:34px;perspective:none}
  .removes-card{position:static;transform:none!important;opacity:1!important}
  .removes-logo{opacity:1;transform:none}
}
