/* Engraving art direction for the home page (navbar, hero, step 1 art, footer).
   Palette per the proposed DESIGN.md: --sky #27238F, --cream #F4EAD5, --amber #F5B841 (accent only, on --sky only).
   Contrast: cream on sky 10.20, sky on cream 10.20, amber dot on sky 6.86, cream focus ring on sky 10.20. */
/* Zero layout shift from font loading: the font is preloaded; if it is not there for the first paint the page keeps the
   fallback for that view instead of swapping later (font-display: optional). Home page only. */
@font-face{font-family:'Anuphan';src:url('/assets/vendor/fonts/Anuphan-VF.woff2') format('woff2');font-weight:300 700;font-style:normal;font-display:optional}


/* ---------- hero ---------- */
.art-hero{position:relative;background:var(--sky);color:var(--cream);overflow:hidden;isolation:isolate;display:flex;flex-direction:column;min-height:clamp(560px,100vh,1400px);min-height:clamp(560px,100svh,1400px);--hero-lift:40px}
/* the hero is exactly one screen (100svh, 100vh where svh is unknown), never taller than the screen: no paper strip or card shows under it */
/* the art starts 40px below the top of the hero (the top row of the picture is the same indigo as the hero, so there is no seam): sky above the lantern, clear of the navbar */
.art-hero-media{position:absolute;inset:var(--hero-lift) 0 0 0;z-index:0;overflow:hidden}
.art-hero picture{display:block;height:100%}
.art-hero-img{display:block;width:100%;height:100%;object-fit:cover;object-position:84% 0%}
/* sky scrim behind the text column so cream stays AA over the water hatching */
.art-hero-media::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,rgba(39,35,143,.62) 0,rgba(39,35,143,.38) 34%,transparent 62%)}
/* the text group sits in the vertical middle of the free space under the navbar and above the "see a preview" pointer */
.art-hero-in{position:relative;z-index:2;flex:1 0 auto;width:100%;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:var(--sp-5);padding-top:calc(var(--pnav-h) + var(--sp-4));padding-bottom:calc(var(--sp-8) + var(--sp-2))}
.art-hero h1{margin:0;font-size:clamp(2.75rem,calc(1.6rem + 4.2vw),5.5rem);line-height:1.3;font-weight:700;letter-spacing:-.01em;color:var(--cream);-webkit-text-stroke:.01em currentColor;text-wrap:balance}
.art-hero .ph{display:block;position:relative;clip-path:inset(-.5em -.25em)}
.art-hero .hero-sub{margin:0;max-width:30em;font-size:clamp(1.25rem,1.1rem + .4vw,1.375rem);line-height:1.55;color:var(--cream)}
.art-hero .nb{display:inline-block}
.art-hero .hero-sub{text-wrap:pretty}
@media (min-width:1280px){.art-hero .hero-sub{max-width:none}}   /* one line on wide screens: keeps the button and small note above the demo card at 1280x720 */
.art-hero .hero-cta{flex-direction:row;align-items:center;width:auto;margin-top:0}
.hero-cta{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-wrap:nowrap;white-space:nowrap;min-height:60px;padding:0 var(--sp-6);font-size:1.25rem;font-weight:700;gap:12px;margin-top:var(--sp-2)}
.hero-cta .ico{transition:transform var(--dur-base,250ms) var(--ease-glide,ease)}
.hero-cta:hover .ico,.hero-cta:focus-visible .ico{transform:translateX(5px)}
.art-hero .hero-note{margin:0;font-size:var(--fs-base);color:var(--cream)}
/* small pointer at the bottom edge of the hero: scrolls to the demo card */
.hero-more{position:absolute;z-index:3;left:50%;bottom:20px;transform:translateX(-50%);display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 18px;border-radius:999px;background:rgba(39,35,143,.9);border:1.5px solid color-mix(in srgb,var(--cream) 45%,transparent);color:var(--cream);font-size:var(--fs-sm);font-weight:700;text-decoration:none;white-space:nowrap}
.hero-more:hover{background:var(--sky);border-color:var(--cream)}
@keyframes fx-bob{0%,100%{transform:translateY(-2px)}50%{transform:translateY(3px)}}
.fx-go .hero-more .ico{animation:fx-bob 1.8s ease-in-out infinite}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}

/* hero motion: transform and opacity only; paused out of view (.fx-off, one IntersectionObserver), off under reduced motion */
.hero-fx{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .4s linear}
.hero-fx.ready{opacity:1}
.fx-beam,.fx-lamp,.fx-gull{position:absolute;display:block}
.fx-beam{width:calc(var(--hs,1)*640px);height:calc(var(--hs,1)*240px);left:calc(var(--lx,0px) - var(--hs,1)*640px);top:calc(var(--ly,0px) - var(--hs,1)*120px);transform-origin:100% 50%;opacity:0;background:conic-gradient(from 261deg at 100% 50%,rgba(245,184,65,0),rgba(245,184,65,.3) 9deg,rgba(245,184,65,0) 18deg);-webkit-mask-image:linear-gradient(270deg,#000 4%,rgba(0,0,0,.55) 50%,transparent);mask-image:linear-gradient(270deg,#000 4%,rgba(0,0,0,.55) 50%,transparent)}
.fx-lamp{width:calc(var(--hs,1)*96px);height:calc(var(--hs,1)*96px);left:calc(var(--lx,0px) - var(--hs,1)*48px);top:calc(var(--ly,0px) - var(--hs,1)*48px);border-radius:50%;background:radial-gradient(circle,rgba(245,184,65,.5),rgba(245,184,65,0) 68%)}
.fx-gull{fill:none;stroke:var(--cream);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;opacity:.9}
.fx-gull.g1{left:calc(var(--lx,0px) - var(--hs,1)*250px);top:calc(var(--ly,0px) - var(--hs,1)*34px)}
.fx-gull.g2{left:calc(var(--lx,0px) + var(--hs,1)*110px);top:calc(var(--ly,0px) - var(--hs,1)*74px)}
@keyframes fx-beam{0%{opacity:0;transform:rotate(40deg)}8%{opacity:1}36%{opacity:.85;transform:rotate(18deg)}46%,100%{opacity:0;transform:rotate(16deg)}}
@keyframes fx-lamp{0%{opacity:.5;transform:scale(.92)}10%{opacity:1;transform:scale(1.14)}34%{opacity:.9;transform:scale(1.07)}46%,100%{opacity:.5;transform:scale(.92)}}
@keyframes fx-drift{from{transform:translate(0,0)}to{transform:translate(10px,-5px)}}
/* light sweeping through the headline one phrase at a time (a warm bar on top of the phrase, 26 % at most, AA kept) */
.art-hero .ph::after{content:"";position:absolute;inset:0 auto 0 0;width:38%;pointer-events:none;background:linear-gradient(100deg,transparent,rgba(245,184,65,.26) 50%,transparent);-webkit-mask-image:linear-gradient(transparent,#000 28%,#000 72%,transparent);mask-image:linear-gradient(transparent,#000 28%,#000 72%,transparent);opacity:0;transform:translateX(-130%) skewX(-12deg)}
/* the effects start about a second after load (home-fx.js adds .fx-go), so they never compete with the first paint */
.fx-go .fx-beam{animation:fx-beam 8s cubic-bezier(.45,0,.2,1) infinite}
.fx-go .fx-lamp{animation:fx-lamp 8s cubic-bezier(.45,0,.2,1) infinite}
.fx-go .fx-gull.g1{animation:fx-drift 6s ease-in-out infinite alternate}
.fx-go .fx-gull.g2{animation:fx-drift 7.5s ease-in-out -2s infinite alternate}
.fx-go .ph::after{animation:fx-sweep 8s ease-in-out infinite}
.fx-go .ph + .ph::after{animation-delay:1.3s}
@keyframes fx-sweep{0%{opacity:0;transform:translateX(-130%) skewX(-12deg)}3%{opacity:1}15%{opacity:1;transform:translateX(330%) skewX(-12deg)}17%,100%{opacity:0;transform:translateX(330%) skewX(-12deg)}}
/* amber light runs once around the button edge on first load, then rests */
@supports (offset-path:inset(0 round 30px)){
  .hero-cta::after{content:"";position:absolute;left:0;top:0;width:10px;height:10px;margin:-5px 0 0 -5px;border-radius:50%;background:var(--amber);box-shadow:0 0 12px 4px rgba(245,184,65,.75);offset-path:inset(0 round 30px);offset-distance:0%;opacity:0;pointer-events:none}
  .fx-go .hero-cta::after{animation:fx-lap 2s ease-in-out .5s 1 both}
  @keyframes fx-lap{0%{offset-distance:0%;opacity:1}92%{opacity:1}100%{offset-distance:100%;opacity:0}}
}
.art-hero.fx-off .fx-beam,.art-hero.fx-off .fx-lamp,.art-hero.fx-off .fx-gull,.art-hero.fx-off .ph::after,.art-hero.fx-off .hero-cta::after,.art-hero.fx-off .hero-more .ico,
.art-hero.fx-tab .fx-beam,.art-hero.fx-tab .fx-lamp,.art-hero.fx-tab .fx-gull,.art-hero.fx-tab .ph::after,.art-hero.fx-tab .hero-cta::after,.art-hero.fx-tab .hero-more .ico{animation-play-state:paused}
/* frame rate guard (home-fx.js): under 40 fps for 2 s in a row, the decorative motion switches off for good, like reduced motion */
.art-hero.fx-lite .fx-beam,.art-hero.fx-lite .fx-gull,.art-hero.fx-lite .ph::after,.art-hero.fx-lite .hero-cta::after{display:none}
.art-hero.fx-lite .fx-lamp{animation:none;opacity:.8}
.art-hero.fx-lite .hero-more .ico{animation:none}
@media (prefers-reduced-motion:reduce){
  .fx-beam,.fx-gull,.art-hero .ph::after,.hero-cta::after{display:none}
  .fx-go .hero-more .ico{animation:none}
  .fx-lamp{animation:none;opacity:.8}
  .hero-cta .ico{transition:none}
}
@media (max-width:899px){
  /* phone: text first, art under it. The hero is still one screen at least: the art box grows to take the free height (cover, bottom aligned) */
  .art-hero-media{position:relative;inset:auto;order:2;flex:1 0 auto;aspect-ratio:4/3}
  .art-hero-media::after{background:linear-gradient(180deg,var(--sky),transparent 22%)}
  .art-hero-img{object-position:88% 100%}
  .art-hero-in{order:1;flex:none;justify-content:flex-start;width:100%;box-sizing:border-box;padding-top:calc(var(--pnav-h) + var(--sp-6));padding-bottom:var(--sp-5)}
  .art-hero h1{font-size:clamp(2.75rem,calc(1.6rem + 4.2vw),3.25rem);line-height:1.25}
  .art-hero .ph + .ph{margin-top:4px}   /* a little air between the two phrases on a phone */
}
@media (max-width:599px){.art-hero-media{aspect-ratio:1/1}}


/* ---------- dashboard demo card (starts under the hero, no overlap) ---------- */
.preview{position:relative;z-index:3;padding-top:var(--sp-7);padding-bottom:var(--sp-4)}
.dash-card{position:relative;margin:0 auto;max-width:1100px;background:#FBF8F3;border:1px solid color-mix(in srgb,var(--sky) 16%,transparent);border-radius:28px;padding:10px;box-shadow:0 2px 4px rgba(31,26,23,.06),0 24px 48px -16px rgba(22,18,90,.34),0 64px 96px -48px rgba(22,18,90,.40)}
.dash-card picture{display:block;border-radius:19px;overflow:hidden}
.dash-card img{display:block;width:100%;height:auto;aspect-ratio:1650/840}
/* clickable demo: the still image is only a placeholder with the same size, the demo (demo-home.js) replaces it inside the same box, so nothing moves */
.dash-card .demo-stage{position:relative;isolation:isolate;border-radius:19px;overflow:hidden;background:#FBF8F3;aspect-ratio:1078/560;min-height:560px;min-width:0;width:100%}
@media (max-width:899px){.dash-card .demo-stage{aspect-ratio:829/640;min-height:640px;min-width:0;width:100%}}
.dash-card .demo-still{position:absolute;z-index:2;inset:0;border-radius:0;opacity:0;transition:opacity 200ms ease}
.dash-card .demo-stage[data-img=ok] .demo-still{opacity:1}
.dash-card .demo-still img{color:transparent;font-size:0}   /* the alt text must never show while the picture loads or fails */
.dash-card .demo-stage noscript img{aspect-ratio:auto}   /* the no-JS copy (inside noscript) keeps the picture's own ratio */
.dash-card .demo-still img{height:100%;aspect-ratio:auto;object-fit:cover;object-position:top}
.demo-stage.live .demo-still{display:none}
.demo-cap{max-width:1100px;margin:var(--sp-4) auto 0;text-align:center;font-size:var(--fs-sm);color:var(--text-muted)}
.sample-badge{position:absolute;z-index:2;top:-15px;right:28px;padding:5px 14px;background:var(--cream);color:var(--sky);border:1.5px dashed var(--sky);border-radius:var(--r-pill);font-size:var(--fs-sm);font-weight:700;box-shadow:0 4px 12px -4px rgba(31,26,23,.3)}
@media (max-width:719px){
  .dash-card{max-width:420px;padding:8px;border-radius:22px}
  .dash-card picture{border-radius:15px}
  .dash-card img{aspect-ratio:780/1520}
  .dash-card .demo-stage{aspect-ratio:402/760;min-height:760px;min-width:0;width:100%}
  .sample-badge{right:20px}
}


/* ---------- feature cards: paper with grain, engraving hatch in one corner, thin indigo ink edge; three featured cards on indigo ---------- */
.feat .fc{--hatch:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 120'><g stroke='%2327238F' stroke-opacity='.3' stroke-width='1' stroke-opacity='.5' stroke-linecap='round' fill='none'><path d='M2 118L52 68M2 104L38 68M2 90L24 68M2 76L10 68M2 118L72 48M16 118L88 46M36 118L102 52M60 118L112 66M84 118L116 88'/></g></svg>");border:1px solid color-mix(in srgb,var(--sky) 28%,transparent);
  background:var(--hatch) left -8px bottom -8px/112px 112px no-repeat,var(--grain-tile) 0 0/96px 96px,var(--glow-corner) right -90px top -90px/320px 320px no-repeat,#FFFDF8;
  transition:opacity var(--dur-reveal) var(--ease-glide),transform var(--dur-reveal) var(--ease-glide),box-shadow var(--dur-base) var(--ease-glide);transition-delay:calc(var(--i,0)*60ms)}
.feat .fc.in{transition-delay:0s}
.feat .fc.fc-feat{--hatch:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 120'><g stroke='%23F4EAD5' stroke-opacity='.28' stroke-width='1' stroke-opacity='.5' stroke-linecap='round' fill='none'><path d='M2 118L52 68M2 104L38 68M2 90L24 68M2 76L10 68M2 118L72 48M16 118L88 46M36 118L102 52M60 118L112 66M84 118L116 88'/></g></svg>");color:var(--cream);border-color:var(--sky);
  background:var(--hatch) left -8px bottom -8px/112px 112px no-repeat,var(--grain-tile) 0 0/96px 96px,var(--sky)}
.fc-feat h3,.fc-feat p,.fc-feat .caveat{color:var(--cream)}
.fc-feat h3::before{background:var(--amber)}
.fc-feat .num-tag{color:var(--cream)}
.fc-feat .icon-tile{background:rgba(244,234,213,.14);color:var(--cream)}
.feat .fc-feat::after{color:rgba(244,234,213,.10)}
.feat .fc.spot::before{background:radial-gradient(300px circle at var(--mx,50%) var(--my,50%),rgba(245,184,65,.20),transparent 70%)}
.feat .fc-feat.spot::before{background:radial-gradient(300px circle at var(--mx,50%) var(--my,50%),rgba(245,184,65,.28),transparent 70%)}
.feat .fc.w6{flex-direction:row;align-items:center;gap:var(--sp-5)}
.feat .fc.w6 .head{gap:var(--sp-3);justify-content:flex-start}
.feat .fc.w6 .fc-body{flex:1;min-width:0}
@media (max-width:767px){.feat .fc.w6{flex-direction:column;align-items:flex-start}}
@media (hover:hover) and (pointer:fine){
  .feat .fc.in:hover{transform:translateY(-4px);box-shadow:var(--sh-3);transition-delay:0s}
  .feat:has(.fc:hover)>.fc.in:not(:hover){opacity:1;transform:none}
}
/* one small effect per card, tied to what the card says. They run only while the card is hovered/focused (mouse)
   or while it is on screen (touch, at most two at a time), a few times, and never under reduced motion. */
.fxi *{transform-box:fill-box}
.fc .h{opacity:0}
.fc.fx-on .h{opacity:1;stroke-dasharray:.3 1;animation:fx-run 1.5s ease-in-out 2 both}
.fc.fx-on .b{animation:fx-dim 3s linear 1 both}
.fc.fx-on .fly{animation:fx-fly 1.5s cubic-bezier(.2,.8,.3,1) 1 both}
.fc.fx-on .wing{transform-origin:50% 100%;animation:fx-flap .28s ease-in-out 5 alternate}
.fc.fx-on .lens{animation:fx-scan 1.1s ease-in-out 4 alternate both}
.fc.fx-on .flag{transform-origin:0 50%;animation:fx-wave .7s ease-in-out 5 alternate}
.sand-t,.sand-b{transform-origin:50% 100%}
.sand-b{transform:scaleY(.35)}.stream{opacity:0}
.fc.fx-on .sand-t{animation:fx-sand-t 3s ease-in-out 1 both}
.fc.fx-on .sand-b{animation:fx-sand-b 3s ease-in-out 1 both}
.fc.fx-on .stream{animation:fx-stream 3s linear 1 both}
.fc.fx-on .shackle{animation:fx-lock 1.6s ease-in-out 1 both}
.fc.fx-on .kh{transform-origin:center;animation:fx-pop 1.2s ease-in-out 1 .9s both}
.fc.fx-on .bino{transform-origin:50% 60%;animation:fx-rot 2s ease-in-out 1 both}
.ring{fill:none;opacity:0;transform-origin:center}
.fc.fx-on .ring{animation:fx-ring 1.3s ease-out 3 both}.fc.fx-on .ring.r2{animation-delay:.45s}
.fc.fx-on .sh1{transform-origin:0 100%;animation:fx-fan 1.6s ease-in-out 1 both}
.fc.fx-on .sh2{transform-origin:0 100%;animation:fx-fan 1.6s ease-in-out .15s 1 both;--fa:-16deg}
.fc.fx-on .shb{transform-origin:center;animation:fx-pop 1s ease-in-out 2 both}
.fc.fx-on .mk{animation:fx-blink .5s ease-in-out 4 alternate both}
@keyframes fx-run{from{stroke-dashoffset:.3}to{stroke-dashoffset:-1}}
@keyframes fx-dim{0%,96%{opacity:.3}100%{opacity:1}}
@keyframes fx-fly{from{opacity:0;transform:translate(18px,-8px)}to{opacity:1;transform:none}}
@keyframes fx-flap{from{transform:scaleY(1)}to{transform:scaleY(.55)}}
@keyframes fx-scan{from{transform:translateY(-6px)}to{transform:translateY(4px)}}
@keyframes fx-wave{from{transform:skewY(-6deg) scaleX(.96)}to{transform:skewY(6deg) scaleX(1.03)}}
@keyframes fx-sand-t{from{transform:scaleY(1)}to{transform:scaleY(.12)}}
@keyframes fx-sand-b{from{transform:scaleY(.35)}to{transform:scaleY(1)}}
@keyframes fx-stream{0%{opacity:0}10%,85%{opacity:.9}100%{opacity:0}}
@keyframes fx-lock{0%{transform:translateY(-4px) rotate(-8deg)}55%{transform:translateY(-4px) rotate(-8deg)}80%{transform:translateY(1px)}100%{transform:none}}
@keyframes fx-pop{0%,100%{transform:scale(1)}50%{transform:scale(1.18)}}
@keyframes fx-rot{0%{transform:rotate(0)}30%{transform:rotate(-14deg)}70%{transform:rotate(14deg)}100%{transform:rotate(0)}}
@keyframes fx-ring{0%{opacity:.7;transform:scale(1)}100%{opacity:0;transform:scale(3.4)}}
@keyframes fx-fan{0%,100%{transform:rotate(0)}50%{transform:rotate(var(--fa,-9deg))}}
@keyframes fx-blink{from{opacity:1}to{opacity:.25}}
@media (prefers-reduced-motion:reduce){.fxi *{animation:none!important}.fc .h{opacity:0!important}}

/* ---------- step 1 art ---------- */
.step-art{display:block;width:200px;max-width:100%;height:auto;margin:calc(44px - var(--sp-5) + var(--sp-3)) 0 0}
.step .step-art + h3{margin-top:var(--sp-3)}


/* Thai line breaks: balanced headings, no one-word last lines */
.sec-head h2,.final-in h2,.persona h3,.feat h3,.step h3{text-wrap:balance}
.sec-head p,.persona .pain,.persona .fix,.feat p,.step p,.acc-p p{text-wrap:pretty}

/* ---------- feature cards: paper with grain, a small engraved hatch in the corner, hairline indigo edge;
   three featured cards on --sky. Texture is code only (grain tile + two inline SVG hatches, under 1 KB). ---------- */
.feat .fc{--hatch:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 120'><g stroke='%2327238F' stroke-opacity='.3' stroke-width='1' stroke-opacity='.5' stroke-linecap='round' fill='none'><path d='M2 118L44 76M2 104L30 76M2 90L16 76M2 118L68 52M24 118L84 58M48 118L100 66M74 118L112 80'/></g></svg>");--hop:.30;border:1px solid color-mix(in srgb,var(--sky) 26%,transparent);
  background:var(--hatch) left -8px bottom -8px/112px 112px no-repeat,var(--grain-tile) 0 0/96px 96px,var(--glow-corner) right -90px top -90px/320px 320px no-repeat,#FFFDF8;
  transition:opacity var(--dur-reveal) var(--ease-glide),transform var(--dur-reveal) var(--ease-glide),box-shadow var(--dur-base) var(--ease-glide);transition-delay:calc(var(--i,0)*60ms)}
.feat .fc-feat{--hatch:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 120'><g stroke='%23F4EAD5' stroke-opacity='.28' stroke-width='1' stroke-opacity='.5' stroke-linecap='round' fill='none'><path d='M2 118L44 76M2 104L30 76M2 90L16 76M2 118L68 52M24 118L84 58M48 118L100 66M74 118L112 80'/></g></svg>");color:var(--cream);border-color:var(--sky);
  background:var(--hatch) left -8px bottom -8px/112px 112px no-repeat,var(--grain-tile) 0 0/96px 96px,var(--sky)}
.fc-feat h3,.fc-feat p,.fc-feat .caveat,.fc-feat .num-tag{color:var(--cream)}
.fc-feat h3::before{background:var(--amber)}
.fc-feat .icon-tile{background:rgba(244,234,213,.14);color:var(--cream)}
.feat .fc-feat::after{color:rgba(244,234,213,.12)}
.feat .fc .fc-body{flex:1}
.fc.spot::before{background:radial-gradient(300px circle at var(--mx,50%) var(--my,50%),rgba(245,184,65,.22),transparent 70%)}
.fc-feat.spot::before{background:radial-gradient(300px circle at var(--mx,50%) var(--my,50%),rgba(245,184,65,.30),transparent 70%)}
/* hover: lift 4px with a soft shadow (fine pointers only). Replaces the older scale-and-dim hover. */
@media (hover:hover) and (pointer:fine){
  .feat .fc.in:hover{transform:translateY(-4px);box-shadow:var(--sh-3);transition-delay:0s}
  .feat:has(.card:hover)>.card.fc.in:not(:hover){opacity:1;transform:none}
}
/* per-card motion: one small effect each, tied to the meaning. Played while .fx-on is set (hover on fine pointers,
   in view on touch, at most 2 at a time, see home-cards.js), finite, transform/opacity (one stroke-dash line), off for reduced motion. */
.fxi *{transform-box:fill-box}
.fx-on .fxi .h{opacity:1;stroke-dasharray:.34 1;animation:fx-run 1.5s ease-in-out 1 both}
.fxi .h{opacity:0}
.fx-on .fxi .b{animation:fx-dim 1.5s linear 1 both}
@keyframes fx-run{from{stroke-dashoffset:.34}to{stroke-dashoffset:-1}}
@keyframes fx-dim{0%,95%{opacity:.35}100%{opacity:1}}
.fx-on .fxi .fly{animation:fx-fly 1.5s cubic-bezier(.2,.8,.2,1) 1 both}
.fx-on .fxi .wing{transform-origin:50% 100%;animation:fx-flap .28s ease-in-out 5 alternate}
@keyframes fx-fly{from{transform:translate(14px,-7px);opacity:0}30%{opacity:1}to{transform:none;opacity:1}}
@keyframes fx-flap{from{transform:scaleY(1)}to{transform:scaleY(.55)}}
.fx-on .fxi .lens{animation:fx-scan 1.7s ease-in-out 2 alternate both}
@keyframes fx-scan{from{transform:translateY(-6px)}to{transform:translateY(5px)}}
.fx-on .fxi .flag{transform-origin:0 50%;animation:fx-wave .8s ease-in-out 4 alternate}
@keyframes fx-wave{from{transform:skewY(-6deg) scaleX(1)}to{transform:skewY(6deg) scaleX(.94)}}
.fxi .sand-t{transform-origin:50% 100%}.fxi .sand-b{transform-origin:50% 100%;transform:scaleY(.4)}.fxi .stream{opacity:0}
.fx-on .fxi .sand-t{animation:fx-sand-t 2.6s ease-in-out 1 both}
.fx-on .fxi .sand-b{animation:fx-sand-b 2.6s ease-in-out 1 both}
.fx-on .fxi .stream{animation:fx-stream 2.6s linear 1 both}
@keyframes fx-sand-t{from{transform:scaleY(1)}to{transform:scaleY(.12)}}
@keyframes fx-sand-b{from{transform:scaleY(.15)}to{transform:scaleY(1)}}
@keyframes fx-stream{0%{opacity:0}10%,85%{opacity:.9}100%{opacity:0}}
.fx-on .fxi .shackle{animation:fx-lock 1.5s ease-in-out 1 both}
.fx-on .fxi .kh{transform-origin:center;animation:fx-key 1.5s ease-in-out 1 both}
@keyframes fx-lock{0%,55%{transform:translateY(-4px)}80%{transform:translateY(1px)}100%{transform:none}}
@keyframes fx-key{0%,70%{transform:scale(1)}85%{transform:scale(1.7)}100%{transform:scale(1)}}
.fx-on .fxi .bino{transform-origin:center;animation:fx-rot 1.8s ease-in-out 1 both}
@keyframes fx-rot{0%{transform:rotate(0)}30%{transform:rotate(-14deg)}65%{transform:rotate(12deg)}100%{transform:rotate(0)}}
.fxi .ring{fill:none;opacity:0;transform-origin:center}
.fx-on .fxi .ring{animation:fx-ring 1.3s ease-out 2 both}.fx-on .fxi .ring.r2{animation-delay:.45s}
@keyframes fx-ring{from{transform:scale(1);opacity:.75}to{transform:scale(3.6);opacity:0}}
.fxi .sh1,.fxi .sh2{transform-origin:6px 22px;opacity:.55}
.fx-on .fxi .sh1{animation:fx-fan1 1.6s ease-in-out 1 both}.fx-on .fxi .sh2{animation:fx-fan2 1.6s ease-in-out 1 both}
@keyframes fx-fan1{0%,100%{transform:rotate(0)}45%{transform:rotate(-9deg)}}
@keyframes fx-fan2{0%,100%{transform:rotate(0)}45%{transform:rotate(-17deg)}}
.fx-on .fxi .shb{transform-origin:center;animation:fx-pop 1.1s ease-in-out 2 both}
.fx-on .fxi .mk{animation:fx-blink .55s ease-in-out 3 both}
@keyframes fx-pop{0%,100%{transform:scale(1)}50%{transform:scale(1.12)}}
@keyframes fx-blink{0%,100%{opacity:1}50%{opacity:.2}}
@media (prefers-reduced-motion:reduce){.fxi *{animation:none!important}.fxi .h,.fxi .stream,.fxi .ring{opacity:0!important}.fxi .sand-b{transform:scaleY(.4)}}
@media (max-width:767px){.feat .fc-body{width:100%}}

/* ---------- scrollbar: one look at every scroll position. Capsule thumb in sky (#27238F) with a thin cream edge on a solid pale cream track.
   Thumb/track contrast 10:1, above the 3:1 UI minimum. Chrome, Edge, Safari use ::-webkit-scrollbar (Chrome ignores it when
   scrollbar-color is set, so it stays on auto there); Firefox gets scrollbar-color and scrollbar-width:auto. ---------- */
:root{--sb-thumb:#27238F;--sb-thumb-hover:#3B36C9;--sb-track:#F0E7D3;--sb-edge:#F4EAD5}
html{scrollbar-width:auto;scrollbar-color:auto}   /* cancels the older thin/colour rules in art.css and landing.css, otherwise Chrome ignores ::-webkit-scrollbar */
::-webkit-scrollbar{width:16px;height:16px}
::-webkit-scrollbar-track{background:var(--sb-track)}
::-webkit-scrollbar-thumb{background:var(--sb-thumb);border:2px solid var(--sb-edge);border-radius:999px;min-height:56px}
::-webkit-scrollbar-thumb:hover{background:var(--sb-thumb-hover)}
::-webkit-scrollbar-corner{background:var(--sb-track)}
@supports (-moz-appearance:none){html{scrollbar-width:auto;scrollbar-color:var(--sb-thumb) var(--sb-track)}}

/* ---------- page rhythm: paper / sky / paper / paper / sky, sky stays under half of the page ---------- */
.band-sky{background:var(--sky);color:var(--cream);padding:var(--sp-9) 0;margin-top:var(--sp-9);position:relative;isolation:isolate}
.band-sky .eyebrow,.band-sky .sec-head h2,.band-sky .sec-head p,.band-sky .step h3,.band-sky .step p{color:var(--cream)}
.band-sky .step .sn{background:var(--cream);color:var(--sky)}
.band-sky .step:not(:last-child)::after{background:var(--cream);opacity:.45}
.band-sky .line-id code{background:rgba(244,234,213,.14);color:var(--cream);border-color:rgba(244,234,213,.4)}
.band-sky .btn-secondary{background:var(--cream);color:var(--sky);border-color:var(--cream)}
.band-sky .btn-ghost{color:var(--cream)}
.band-sky :focus-visible{outline:3px solid var(--cream);outline-offset:3px}
.band-sky .pulse-track{display:none}
.step-ico{display:grid;place-items:center;width:72px;height:72px;margin:calc(44px - var(--sp-5) + var(--sp-3)) 0 0;border:2px solid var(--cream);border-radius:50%;color:var(--cream)}
.ico-32{width:32px;height:32px}
.step .step-ico + h3{margin-top:var(--sp-3)}
.stats{padding:var(--sp-7) 0 var(--sp-5)}
.stats-in{display:grid;grid-template-columns:repeat(3,1fr);list-style:none;margin:0;padding:0;border-block:1px solid color-mix(in srgb,var(--sky) 22%,transparent)}
.stats-in li{display:flex;flex-direction:column;align-items:center;gap:var(--sp-1);padding:var(--sp-5) var(--sp-3);text-align:center}
.stats-in li + li{border-left:1px solid color-mix(in srgb,var(--sky) 22%,transparent)}
.st-l,.st-u{font-size:var(--fs-base);color:var(--text-muted)}
.st-n{font-size:clamp(3rem,7vw,4.75rem);line-height:1;font-weight:700;color:var(--sky);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.squig{height:18px;margin:var(--sp-7) auto 0;max-width:var(--container-wide);background:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 18'><path d='M0 9Q7.5 0 15 9T30 9T45 9T60 9' fill='none' stroke='%2327238F' stroke-opacity='.5' stroke-width='2' stroke-linecap='round'/></svg>") repeat-x center/60px 18px}
.squig.on-sky{margin:var(--sp-7) auto 0;background-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 18'><path d='M0 9Q7.5 0 15 9T30 9T45 9T60 9' fill='none' stroke='%23F4EAD5' stroke-opacity='.55' stroke-width='2' stroke-linecap='round'/></svg>")}
.cta-band{background:var(--sky);color:var(--cream);margin-top:var(--sp-9);padding:var(--sp-9) 0 var(--sp-6);text-align:center}
.cta-band h2{margin:0 auto var(--sp-5);max-width:16em;font-size:clamp(2.25rem,5.2vw,3.75rem);line-height:1.12;color:var(--cream);text-wrap:balance}
.cta-btn{min-height:60px;padding:0 var(--sp-6);font-size:1.25rem;font-weight:700;gap:12px;white-space:nowrap}
.cta-btn .ico{transition:transform var(--dur-base,250ms) var(--ease-glide,ease)}
.cta-btn:hover .ico{transform:translateX(5px)}
.cta-note{margin:var(--sp-3) 0 0;font-size:var(--fs-base);color:var(--cream)}
.cta-band :focus-visible{outline:3px solid var(--cream);outline-offset:3px}
.art-footer{margin-top:0;padding-top:var(--sp-6)}
@media (max-width:719px){
  .stats-in{grid-template-columns:1fr}
  .stats-in li{flex-direction:row;flex-wrap:wrap;justify-content:center;align-items:baseline;gap:var(--sp-2) var(--sp-3)}
  .stats-in li + li{border-left:0;border-top:1px solid color-mix(in srgb,var(--sky) 22%,transparent)}
  .st-n{font-size:3.25rem}
  .band-sky{padding:var(--sp-8) 0}
}
@media (prefers-reduced-motion:reduce){.cta-btn .ico{transition:none}}

/* Demo card loading skeleton. Pure CSS, built like the dashboard: indigo panel, 4 capsules, 4 paper cards. Shown only while the
   picture and the demo code load (home-fx.js sets data-img and data-state on the stage). Without JS the <noscript> rule in the
   page head hides it and the still picture shows as before. The sweep moves with transform and opacity only, stops when the card
   is off screen (.is-off) and never runs under reduced motion. */
.demo-skel{position:absolute;z-index:1;inset:0;display:grid;grid-template-columns:200px minmax(0,1fr);gap:12px;padding:10px;overflow:hidden;
  background:#FBF8F3;transition:opacity 200ms ease,visibility 0s linear 0s}
.demo-stage[data-img=ok] .demo-skel{opacity:0;visibility:hidden;transition:opacity 200ms ease,visibility 0s linear 200ms}
.demo-stage.live .demo-skel{display:none}
.ds-nav{display:flex;flex-direction:column;gap:4px;padding:14px 12px;border-radius:20px;background:var(--sky)}
.ds-brand{display:block;width:132px;height:28px;margin:6px 14px 14px;border-radius:var(--r-pill);background:color-mix(in srgb,var(--cream) 30%,transparent)}
.ds-cap{position:relative;display:flex;align-items:center;min-height:46px;padding:0 16px;border-radius:var(--r-pill);background:color-mix(in srgb,var(--cream) 12%,transparent)}
.ds-cap::before{content:"";display:block;width:62%;height:10px;border-radius:var(--r-pill);background:color-mix(in srgb,var(--cream) 42%,transparent)}
.ds-cap.on{background:var(--cream)}
.ds-cap.on::before{background:color-mix(in srgb,var(--sky) 38%,transparent)}
.ds-cap.on::after{content:"";position:absolute;top:50%;right:14px;width:7px;height:7px;margin-top:-3.5px;border-radius:50%;background:var(--amber)}
.ds-main{display:flex;flex-direction:column;gap:12px;min-width:0;padding:6px}
.ds-h{display:block;width:180px;max-width:60%;height:22px;margin:2px 0 4px;border-radius:var(--r-pill);background:var(--border)}
.ds-grid{flex:1;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,1fr);gap:12px}
.ds-card{display:flex;flex-direction:column;gap:10px;padding:16px;border-radius:20px;background:#FFFDF8;border:1px solid color-mix(in srgb,var(--sky) 24%,transparent)}
.ds-card i{display:block;height:12px;border-radius:var(--r-pill);background:var(--border)}
.ds-card i:nth-child(1){width:52%}
.ds-card i:nth-child(2){width:86%}
.ds-card i:nth-child(3){width:38%}
.ds-card b{display:block;flex:1;min-height:24px;max-height:90px;border-radius:12px;background:color-mix(in srgb,var(--sky) 7%,#FFFDF8)}
.demo-skel::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,transparent 30%,rgba(244,234,213,.5) 50%,transparent 70%);
  transform:translateX(-100%);opacity:0;animation:demo-sweep 1.8s ease-in-out infinite;will-change:transform,opacity}
@keyframes demo-sweep{0%{transform:translateX(-100%);opacity:0}20%{opacity:1}80%{opacity:1}100%{transform:translateX(100%);opacity:0}}
.demo-stage.is-off .demo-skel::after,.demo-stage[data-state=error] .demo-skel::after{animation-play-state:paused}
.demo-stage[data-state=error] .demo-skel{opacity:.55}
.demo-stage[data-state=error][data-img=ok] .demo-skel{opacity:0}
@media (prefers-reduced-motion:reduce){.demo-skel::after{animation:none;opacity:0}}
/* status pill: sits over the card, outside the stage (aria-busy lives on the stage, the live region must not be inside it) */
.demo-status{position:absolute;z-index:3;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;align-items:center;gap:var(--sp-3);
  max-width:calc(100% - 32px);padding:10px 18px;border-radius:var(--r-pill);background:var(--cream);color:var(--sky);border:1.5px solid var(--sky);
  font-size:var(--fs-base);font-weight:700;line-height:1.4;box-shadow:0 8px 22px -10px rgba(31,26,23,.45)}
.demo-status .ds-load,.demo-status .ds-err{text-wrap:balance}
.demo-status .ds-err,.demo-status .ds-retry{display:none}
.demo-stage[data-state=error] ~ .demo-status .ds-load{display:none}
.demo-stage[data-state=error] ~ .demo-status .ds-err{display:inline}
.demo-stage[data-state=error] ~ .demo-status .ds-retry{display:inline-flex}
.demo-stage.live ~ .demo-status{display:none}
.ds-retry{align-items:center;justify-content:center;min-height:44px;padding:0 18px;border:0;border-radius:var(--r-pill);background:var(--sky);color:var(--cream);font:inherit;font-weight:700;cursor:pointer}
.ds-retry:hover{background:#1c1970}
.ds-retry:focus-visible{outline:3px solid var(--sky);outline-offset:3px}
@media (max-width:719px){
  .demo-skel{display:block;padding:8px 8px 84px}
  .ds-nav{position:absolute;left:8px;right:8px;bottom:8px;display:grid;grid-template-columns:repeat(4,1fr);gap:4px;padding:6px;border-radius:28px}
  .ds-brand{display:none}
  .ds-cap{justify-content:center;min-height:52px;padding:0}
  .ds-cap::before{width:46%}
  .ds-cap.on::after{top:8px;right:calc(50% - 22px);margin-top:0}
  .ds-main{height:100%;padding:4px 2px}
  .ds-grid{grid-template-columns:minmax(0,1fr)}
  .ds-h{display:none}
  .ds-card b{max-height:64px}
  .demo-status{flex-wrap:wrap;justify-content:center;text-align:center}
}
