/* Surfwise home, "future" layer (2026-10-16, lag fix the same day). Loaded AFTER assets/site.css and
   assets/iphone.css and only adds to them: the Aurora Glass design, layout, copy and colours stay as they are.
   What this file adds
   1. PHONE SLOTS: every phone on the page is the pre-rendered iPhone 16 Pro of assets/iphone.css. Its
      wrapper (.slot) may turn a little: a still base angle here, and on fine pointers assets/future.js
      writes ONE inline transform per slot (pointer tilt, the How step). One flattened layer per phone:
      no preserve-3d, no depth plates, no scroll-linked rotation, no will-change (those were the lag:
      every pointer / scroll frame re-resolved the style of whole sections and re-layerised 7 plate stacks).
   2. FUTURISTIC LAYER: HUD corner brackets + mono readouts, a scan beam over two screens, holographic
      sheen on cards, a glowing cursor ring (fine pointers only). The WebGL aurora is gone: the painted
      CSS aurora of site.css is the background (it cost GPU time on integrated graphics for no visible gain).
   PERFORMANCE (same contract as site.css): animated properties are transform / opacity only (plus clip-path
   and stroke on small elements); no backdrop-filter, no filter, no animated box-shadow / size / position;
   every infinite animation is paused unless its block is on screen (.is-in) and while the tab is hidden
   (html.pg-off); pointer effects only on (hover:hover) and (pointer:fine); custom properties that change
   per frame are written only on the element that uses them (never on a section); the whole layer is off
   under prefers-reduced-motion.
   2026-10-17: section 3 (render cost) and section 4 (fast scroll) at the end. */

:root{--mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace}
.sw-home main{position:relative;z-index:1}
.sw-home .aur{z-index:0}

/* =============================== 1. PHONE SLOTS =============================== */
/* flat at rest (2026-10-17): no perspective / rotateY on a phone that is not being tilted, so the frame and
   the screenshot are plain raster (sharp at every zoom, no 3D layer); future.js tilts a slot only while the
   pointer is over its section and removes the transform again once it has settled */
.sw-home .sp-slot{position:relative}
.sw-home .sp-stick{gap:14px}
.sw-home .sp-slot{margin-bottom:10px}
/* scan beam over a screen (future.js adds .ph-scan to the hero's centre phone + the sticky phone) */
.sw-home .ph-scan{position:absolute;left:0;right:0;top:-24%;height:22%;pointer-events:none;z-index:2;
  background:linear-gradient(180deg,rgba(22,197,232,0) 0%,rgba(22,197,232,.16) 70%,rgba(255,255,255,.6) 97%,rgba(22,197,232,0) 100%);
  animation:scanY 4.2s cubic-bezier(.45,0,.55,1) infinite;animation-play-state:paused}
.sw-home .is-in .ph-scan,.sw-home .night.is-in .ph-scan{animation-play-state:running}

/* =============================== 2. FUTURISTIC LAYER =============================== */
/* HUD corner brackets (future.js adds four .hud-c to .hud hosts) */
.sw-home .hud{position:relative}
.sw-home .hud-c{position:absolute;width:14px;height:14px;pointer-events:none;z-index:4;border:2px solid var(--cyan);opacity:0;scale:.3;transition:opacity .6s ease,scale .8s cubic-bezier(.16,1,.3,1)}
.sw-home .hud-c.tl{left:-7px;top:-7px;border-right:0;border-bottom:0;border-top-left-radius:4px}
.sw-home .hud-c.tr{right:-7px;top:-7px;border-left:0;border-bottom:0;border-top-right-radius:4px;transition-delay:.08s}
.sw-home .hud-c.bl{left:-7px;bottom:-7px;border-right:0;border-top:0;border-bottom-left-radius:4px;transition-delay:.16s}
.sw-home .hud-c.br{right:-7px;bottom:-7px;border-left:0;border-top:0;border-bottom-right-radius:4px;transition-delay:.24s}
.sw-home .hud.in .hud-c,.rv-all .sw-home .hud-c{opacity:1;scale:1}
.sw-home .linkbox .hud-c,.sw-home .rt-card .hud-c{border-color:var(--violet)}
/* no bracket pulse: 16 pulsing pseudo layers cost ~40 % of the main thread per frame in a trace (2026-10-16) */
/* mono readouts */
.sw-home .hud-tag{position:absolute;z-index:4;pointer-events:none;display:inline-flex;align-items:center;gap:6px;font:500 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--brand);white-space:nowrap}
.sw-home .hud-tag::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--cyan);box-shadow:0 0 0 3px rgba(22,197,232,.18);animation:blip 1.6s ease-in-out infinite;animation-play-state:paused}
/* runs only while its block is on screen (the hero and the report card carry data-anim -> .is-in) */
.sw-home .is-in .hud-tag::before{animation-play-state:running}
.sw-home .linkbox .hud-tag{right:14px;top:12px}
.sw-home .rt-card .hud-tag{right:16px;top:14px;display:none}
.sw-home .hud-read{display:none;font:500 11px/1.4 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:#8FE3F5;text-align:center;white-space:nowrap}
.sw-home .hud-read b{font-weight:600;color:#fff}
/* eyebrow index: "01 ——" in mono before each section label */
.sw-home .hud-n{display:inline-flex;align-items:center;gap:8px;margin-right:10px;font:600 11px/1 var(--mono);letter-spacing:.1em;color:var(--cyan);vertical-align:1px}
.sw-home .hud-n::after{content:"";width:22px;height:2px;border-radius:2px;background:linear-gradient(90deg,var(--cyan),rgba(22,197,232,0));transform-origin:0 50%;scale:0 1;transition:scale .8s cubic-bezier(.16,1,.3,1) .2s}
.sw-home .in .hud-n::after,.rv-all .sw-home .hud-n::after{scale:1 1}
.sw-home .night .hud-n{color:#8FE3F5}
.sw-home .plus .hud-n{color:#fff}.sw-home .plus .hud-n::after{background:linear-gradient(90deg,#fff,rgba(255,255,255,0))}
.sw-home .dec{text-decoration:none}
/* the dark How panel gets a faint data field (static) */
.sw-home .night::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:radial-gradient(rgba(159,142,255,.26) 1px,transparent 1.6px);background-size:26px 26px;
  -webkit-mask-image:radial-gradient(70% 60% at 85% 20%,#000,transparent 75%);mask-image:radial-gradient(70% 60% at 85% 20%,#000,transparent 75%)}
/* holographic sheen on cards (future.js adds .holo; --mx/--my come from site.js's spotlight, on the card itself) */
.sw-home .holo{position:absolute;left:-30%;top:-30%;width:160%;height:160%;z-index:-1;pointer-events:none;opacity:0;transition:opacity .5s ease;
  background:conic-gradient(from 210deg at 50% 50%,rgba(109,74,255,0) 0deg,rgba(22,197,232,.2) 70deg,rgba(255,255,255,.34) 120deg,rgba(109,74,255,.2) 170deg,rgba(47,107,255,0) 230deg,rgba(255,255,255,.22) 300deg,rgba(109,74,255,0) 360deg)}
.sw-home .hot .holo{opacity:1;transform:translate(calc(var(--mx,0px) * .18),calc(var(--my,0px) * .18))}
.sw-home .rt-card{position:relative;isolation:isolate}
/* corners drawn inside the box where the card clips its overflow (.rt-card is a .spot) */
.sw-home .hud-in .hud-c.tl{left:8px;top:8px}.sw-home .hud-in .hud-c.tr{right:8px;top:8px}
.sw-home .hud-in .hud-c.bl{left:8px;bottom:8px}.sw-home .hud-in .hud-c.br{right:8px;bottom:8px}
.sw-home .demo-panel .hud-c{display:none}
.sw-home .rt-card .holo{opacity:.55;animation:holoDrift 9s ease-in-out infinite alternate;animation-play-state:paused}
.sw-home .rt-card.played.is-in .holo,.sw-home .rt-card.played:hover .holo{animation-play-state:running}
/* hero: the link box gets a thin animated light on its top edge; chips get a glass rim */
.sw-home .linkbox{position:relative}
.sw-home .linkbox::before{content:"";position:absolute;left:12%;right:12%;top:-1px;height:2px;border-radius:2px;background:linear-gradient(90deg,rgba(109,74,255,0),#6D4AFF 30%,#16C5E8 70%,rgba(22,197,232,0));opacity:.85;transform-origin:50% 50%;animation:edgeLight 5s ease-in-out infinite;animation-play-state:paused}
.sw-home .hero.is-in .linkbox::before{animation-play-state:running}
.sw-home .chip{box-shadow:0 12px 30px rgba(79,80,255,.2),inset 0 0 0 1px rgba(255,255,255,.9),inset 0 -14px 24px rgba(109,74,255,.06)}
/* the glowing cursor (fine pointers only; future.js moves it, transform only, on two fixed layers) */
.sw-home .cur,.sw-home .cur-g{display:none;position:fixed;left:0;top:0;z-index:70;pointer-events:none;border-radius:50%;opacity:0;transition:opacity .3s ease}
.sw-home .cur{width:26px;height:26px;margin:-13px 0 0 -13px;border:1.5px solid rgba(109,74,255,.75);transform:translate3d(-100px,-100px,0)}
.sw-home .cur::after{content:"";position:absolute;left:50%;top:50%;width:4px;height:4px;margin:-2px 0 0 -2px;border-radius:50%;background:var(--cyan)}
.sw-home .cur-g{width:180px;height:180px;margin:-90px 0 0 -90px;background:radial-gradient(closest-side,rgba(22,197,232,.16),rgba(109,74,255,.07) 50%,rgba(109,74,255,0));transform:translate3d(-100px,-100px,0)}
.sw-home.cur-on .cur,.sw-home.cur-on .cur-g{opacity:1}
.sw-home .cur.big{border-color:rgba(22,197,232,.85)}

@media (hover:hover) and (pointer:fine){
  .sw-home .cur,.sw-home .cur-g{display:block}
}
@media (min-width:768px){
  .sw-home .rt-card .hud-tag{display:inline-flex}
  .sw-home .hud-c{width:18px;height:18px}
  .sw-home .demo-panel .hud-c{display:block}
  .sw-home .hud-in .hud-c.tl{left:10px;top:10px}.sw-home .hud-in .hud-c.tr{right:10px;top:10px}
  .sw-home .hud-in .hud-c.bl{left:10px;bottom:10px}.sw-home .hud-in .hud-c.br{right:10px;bottom:10px}
  .sw-home .hud-c.tl,.sw-home .hud-c.bl{left:-9px}.sw-home .hud-c.tr,.sw-home .hud-c.br{right:-9px}
  .sw-home .hud-c.tl,.sw-home .hud-c.tr{top:-9px}.sw-home .hud-c.bl,.sw-home .hud-c.br{bottom:-9px}
  .sw-home .hud-n{font-size:12px}
}
@media (min-width:960px){
  .sw-home .hud-read{display:block}
  .sw-home .sp-stick{top:max(80px,calc(50vh - 340px))}
}
@media (max-width:767px){
  .sw-home .linkbox .hud-tag{display:none}
}

@keyframes scanY{0%{transform:translateY(0)}55%,100%{transform:translateY(560%)}}
@keyframes blip{0%,100%{opacity:.35}50%{opacity:1}}
@keyframes edgeLight{0%{transform:translateX(-30%) scaleX(.6);opacity:.2}50%{transform:translateX(0) scaleX(1);opacity:.9}100%{transform:translateX(30%) scaleX(.6);opacity:.2}}
@keyframes holoDrift{from{transform:translate3d(-8%,-6%,0) rotate(-6deg)}to{transform:translate3d(8%,6%,0) rotate(8deg)}}

@media (prefers-reduced-motion:reduce){
  .sw-home .ph-scan,.sw-home .cur,.sw-home .cur-g,.sw-home .holo{display:none!important}
  .sw-home .sp-slot,.sw-home .plus-phone .slot,.sw-home .dl-phones .slot{transform:none!important;transition:none!important}
  .sw-home .hud-c,.sw-home .hud-n::after{opacity:1;scale:1}
  .sw-home .hud-tag::before,.sw-home .linkbox::before{animation:none!important}
}

/* =============================== 3. RENDER COST (every mode, 2026-10-17) ===============================
   Found with hardware acceleration OFF (WebGL "Microsoft Basic Render Driver": everything rasterised and
   composited on the CPU): the page lagged and the phones went soft while zooming. Rules for full mode too:
   - no permanent will-change (it froze the raster scale of the phones: blurry after a zoom);
   - nothing 3D or scaled on an image container at rest (tilts exist only while the pointer is over them);
   - a card's tilt transform and spotlight layer exist only while it is live (.fx from site.js), so the
     page at rest has no per-card compositor layers;
   - entrances move by translate only (no scale() on the raster). The 38 px header icon keeps its
     scale(.9) on scroll: a width transition there re-laid the header out every frame (measured jank). */
.sw-home .is-in .bobL,.sw-home .is-in .bobC,.sw-home .is-in .bobR,.sw-home .is-in .chip1,.sw-home .is-in .chip2{will-change:auto}
.sw-home .hero-phones .slot{animation-name:slotIn2}
@media (hover:hover) and (pointer:fine){
  .js .sw-home .tilt:not(.fx){transform:none}
  .js .sw-home .spot:not(.fx)::before{display:none}
  .sw-home .feat:not(.fx) .holo{display:none}
}
/* independent blocks: their layout never reaches outside (no paint containment: shadows overflow) */
.sw-home .sec,.sw-home .marquee,.sw-home .foot{contain:layout style}
@keyframes slotIn2{from{opacity:0;transform:translate(var(--fx,0px),70px)}}
/* the report card's holo sheen drifts only while the pointer is on the card, as before (its on-screen
   switch never fired then; the card now carries data-anim for its readout dot) */
.sw-home .rt-card.played.is-in:not(:hover) .holo{animation-play-state:paused}
/* the progress bar follows the scroll on the compositor (scroll-driven animation; site.js writes it only
   where this is not supported, and under reduced motion) */
@media (prefers-reduced-motion:no-preference){
  @supports (animation-timeline:scroll()){
    .sw-home .prog i{animation:progX linear both;animation-timeline:scroll(root block)}
  }
}
@keyframes progX{from{transform:scaleX(0)}to{transform:scaleX(1)}}
/* the page jumps instantly (reload / Back restore it at once); in-page links scroll smoothly by script */
html:has(>body.sw-home){scroll-behavior:auto}
/* the headline sweep on the compositor (future.js builds .shn > .shn-t; the ::after of site.css is the
   no-JS fallback). Window 60 % of the words wide; its centre runs from -50 % to 150 % of the words in the
   first 30 % of 7 s (ease-in-out), exactly the band of the old background-position sweep. */
.sw-home .shine.shn-on::after{display:none}
.sw-home .shn{position:absolute;left:0;top:0;bottom:0;width:60%;overflow:hidden;pointer-events:none;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 50%,transparent);mask-image:linear-gradient(90deg,transparent,#000 50%,transparent);
  transform:translateX(-133.333%);animation:shnW 7s ease-in-out 1.7s infinite;animation-play-state:paused}
.sw-home .shn-t{position:absolute;left:0;top:0;white-space:nowrap;color:rgba(255,255,255,.95);-webkit-text-fill-color:rgba(255,255,255,.95);
  transform:translateX(80%);animation:shnT 7s ease-in-out 1.7s infinite;animation-play-state:paused}
.sw-home .hero.is-in .shn,.sw-home .hero.is-in .shn-t{animation-play-state:running}
@keyframes shnW{0%{transform:translateX(-133.333%)}30%,100%{transform:translateX(200%)}}
@keyframes shnT{0%{transform:translateX(80%)}30%,100%{transform:translateX(-120%)}}

/* =============================== 4. FAST SCROLL (2026-10-17) ===============================
   Measured with hardware acceleration OFF (software compositing, 1536 x 695 at 125 %): the CPU blended 4.5
   compositor layers per screen pixel on every scroll frame. A running loop is a layer, and everything that
   paints after it and over it becomes one more layer. Two fixes here (site.js also rests the slow loops while
   the page scrolls, see "ambient loops" there):
   - paint order: the marquee strip paints after the How panel (the panel's shadow reaches up into the strip,
     which made the whole How section one more full-height layer) and still below the hero copy and phones;
     the sticky How phone paints after the step list beside it (a sticky element is a layer, and the list
     after it was a 2100 px layer). Nothing overlaps differently on screen.
   - 2026-10-17: the aurora / How-glow drift is no longer a CSS animation at all: assets/site.js moves the blobs in
     small painted steps (see site.css, "aurora"), so there is no blob layer and no second page layer to blend. */
.sw-home .marquee{z-index:1}
.sw-home .hero-copy,.sw-home .hero-phones{z-index:2}
.sw-home .story-phone{position:relative;z-index:1}

/* =============================== 5. SHADOWS AS IMAGES (2026-10-17) ===============================
   Measured on the owner's S25 Ultra (dpr 3.75) and on a PC with hardware acceleration off: the big blurred
   box-shadows (50-70 px blur on cards up to 358 x 1348 px) were the single largest raster cost of the page, paid
   again every time a tile or a layer was (re)built during a fling. Each one is now the SAME shadow rendered once
   with Chrome from the real box-shadow (assets/img/sh/*.webp, lossless, 2x) and drawn as a 9-slice border-image
   on a pseudo element that sits exactly where the shadow was (the inner part is transparent, like the clipped
   box-shadow). Nothing else about the cards changes. Where a card clips its overflow the image sits on its
   wrapper / section instead (.night -> #how, .plus-ring -> its .pr-in wrapper). On fine pointers .rt-card and
   .contact keep their box-shadow (their spotlight needs overflow:hidden there). */
/* link box: 0 20px 50px rgba(79,80,255,.14), radius 20 / 22 */
.sw-home .linkbox{isolation:isolate;box-shadow:none}
.sw-home .linkbox::after{content:"";position:absolute;z-index:-1;pointer-events:none;border-style:solid;border-color:transparent;inset:-30px -50px -70px -50px;border-width:100px 120px 140px 120px;border-image:url(img/sh/lb20.webp) 200 240 280 240 fill / 100px 120px 140px 120px stretch}
/* How panel: 0 30px 70px rgba(21,18,58,.22), radius 26 / 32 / 36, drawn by the section around it (the section's
   padding is 8 16 16 / 36 32 at >= 768) */
.sw-home #how::before{content:"";position:absolute;z-index:-1;pointer-events:none;border-style:solid;border-color:transparent;left:-54px;right:-54px;top:-32px;bottom:-84px;border-width:136px 166px 196px 166px;border-image:url(img/sh/n26.webp) 272 332 392 332 fill / 136px 166px 196px 166px stretch}
/* Plus card: 0 30px 70px rgba(79,80,255,.28), radius 26 / 32 */
.sw-home .plus-ring::after{content:"";position:absolute;z-index:-1;pointer-events:none;border-style:solid;border-color:transparent;inset:-40px -70px -100px -70px;border-width:136px 166px 196px 166px;border-image:url(img/sh/p26.webp) 272 332 392 332 fill / 136px 166px 196px 166px stretch}
/* report card: 0 20px 50px rgba(79,80,255,.16), radius 22 / 28 */
.sw-home .rt-card{box-shadow:none}
.sw-home .rt-card::after{content:"";position:absolute;z-index:-1;pointer-events:none;border-style:solid;border-color:transparent;inset:-30px -50px -70px -50px;border-width:102px 122px 142px 122px;border-image:url(img/sh/rt22.webp) 204 244 284 244 fill / 102px 122px 142px 122px stretch}
/* contact card: 0 10px 26px rgba(79,80,255,.1), radius 18 */
.sw-home .contact{box-shadow:none}
.sw-home .contact::after{content:"";position:absolute;z-index:-1;pointer-events:none;border-style:solid;border-color:transparent;inset:-16px -26px -36px -26px;border-width:60px 70px 80px 70px;border-image:url(img/sh/c18.webp) 120 140 160 140 fill / 60px 70px 80px 70px stretch}
@media (min-width:768px){
  .sw-home .linkbox::after{border-width:102px 122px 142px 122px;border-image:url(img/sh/lb22.webp) 204 244 284 244 fill / 102px 122px 142px 122px stretch}
  .sw-home #how::before{left:-38px;right:-38px;top:-4px;bottom:-64px;border-width:142px 172px 202px 172px;border-image:url(img/sh/n32.webp) 284 344 404 344 fill / 142px 172px 202px 172px stretch}
  .sw-home .plus-ring::after{border-width:142px 172px 202px 172px;border-image:url(img/sh/p32.webp) 284 344 404 344 fill / 142px 172px 202px 172px stretch}
  .sw-home .rt-card::after{border-width:108px 128px 148px 128px;border-image:url(img/sh/rt28.webp) 216 256 296 256 fill / 108px 128px 148px 128px stretch}
  /* the demo panel inside the How panel: 0 30px 60px rgba(0,0,0,.35), radius 28 */
  .sw-home .night .demo-panel{position:relative;isolation:isolate;box-shadow:none}
  .sw-home .night .demo-panel::after{content:"";position:absolute;z-index:-1;pointer-events:none;border-style:solid;border-color:transparent;inset:-30px -60px -90px -60px;border-width:118px 148px 178px 148px;border-image:url(img/sh/d28.webp) 236 296 356 296 fill / 118px 148px 178px 148px stretch}
}
@media (min-width:960px){
  .sw-home #how::before{border-width:146px 176px 206px 176px;border-image:url(img/sh/n36.webp) 292 352 412 352 fill / 146px 176px 206px 176px stretch}
}
@media (hover:hover) and (pointer:fine){
  .js .sw-home .rt-card{box-shadow:0 20px 50px rgba(79,80,255,.16)}
  .js .sw-home .contact{box-shadow:0 10px 26px rgba(79,80,255,.1)}
  .js .sw-home .rt-card::after,.js .sw-home .contact::after{display:none}
}
