/* Demo game pages (/demos/<game>/, project 3 action #102 cycle 29): the game's own world behind the page, changing
   world by world as the reader moves down it. Keyed on the data-world-* attributes the React page carries
   (src/pages/DemoGame in bles-clutch); template.py loads this file and adds .tworld to <body> only on a page that has
   a [data-world-stage], so nothing here can reach another page.
   Locked on scroll: no position is written from scroll. The stage is one fixed box behind the page; worlds.js only
   flips which scene it shows (data-at, data-prev) when a chapter comes on screen, and the new scene opens inside that
   box as a portal. Text never fades: only the pictures and the decorative layers change opacity. */

.tworld{background:#03060f}
.tworld main#main{position:relative;isolation:isolate}

/* ---- the stage: five real frames of the game, one shown at a time ---- */
.tworld .thero-copy [data-world-stage]{all:unset;position:fixed;inset:0;z-index:-2;display:block;overflow:hidden;
 background:#03060f;pointer-events:none;margin:0}
.tworld [data-world-shot]{position:absolute;inset:0;display:block;margin:0!important;opacity:0;z-index:0;
 clip-path:circle(0% at 50% 62%);scale:1.16;
 transition:clip-path 1.3s cubic-bezier(.7,0,.2,1),scale 2.4s cubic-bezier(.2,.7,.2,1),opacity .5s ease .9s}
.tworld .thero-copy [data-world-shot] img{width:100%;height:100%;max-width:none;object-fit:cover;border-radius:0;margin:0;
 animation:wdrift 28s ease-in-out infinite alternate;animation-play-state:paused}
.tworld [data-world-stage]:not([data-at]) [data-world-shot="1"],
.tworld [data-world-stage][data-at="1"] [data-world-shot="1"],
.tworld [data-world-stage][data-at="2"] [data-world-shot="2"],
.tworld [data-world-stage][data-at="3"] [data-world-shot="3"],
.tworld [data-world-stage][data-at="4"] [data-world-shot="4"],
.tworld [data-world-stage][data-at="5"] [data-world-shot="5"],
.tworld [data-world-stage][data-at="6"] [data-world-shot="6"]{opacity:1;z-index:2;clip-path:circle(150% at 50% 62%);scale:1;
 transition:clip-path 1.3s cubic-bezier(.7,0,.2,1),scale 2.4s cubic-bezier(.2,.7,.2,1),opacity 0s}
.tworld [data-world-stage]:not([data-at]) [data-world-shot="1"] img,
.tworld [data-world-stage][data-at="1"] [data-world-shot="1"] img,
.tworld [data-world-stage][data-at="2"] [data-world-shot="2"] img,
.tworld [data-world-stage][data-at="3"] [data-world-shot="3"] img,
.tworld [data-world-stage][data-at="4"] [data-world-shot="4"] img,
.tworld [data-world-stage][data-at="5"] [data-world-shot="5"] img,
.tworld [data-world-stage][data-at="6"] [data-world-shot="6"] img{animation-play-state:running}
/* the world being left stays whole under the portal until the new one has opened over it */
.tworld [data-world-stage][data-prev="1"] [data-world-shot="1"],
.tworld [data-world-stage][data-prev="2"] [data-world-shot="2"],
.tworld [data-world-stage][data-prev="3"] [data-world-shot="3"],
.tworld [data-world-stage][data-prev="4"] [data-world-shot="4"],
.tworld [data-world-stage][data-prev="5"] [data-world-shot="5"],
.tworld [data-world-stage][data-prev="6"] [data-world-shot="6"]{opacity:1;z-index:1;clip-path:circle(150% at 50% 62%);scale:1;transition:opacity .4s ease 1.3s}
@keyframes wdrift{from{transform:scale(1.03) translate3d(-1.2%,.6%,0)}to{transform:scale(1.11) translate3d(1.2%,-1%,0)}}

/* the living layer over every world: drifting motes (islands, lake) or streaks of air (the two flight games) */
.tworld [data-world-stage]::before{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;opacity:.5;
 background-repeat:repeat;will-change:transform}
.tworld [data-world-fx=motes]::before{inset:-260px 0 0;background-size:260px 260px;
 background-image:radial-gradient(2px 2px at 30px 40px,rgba(255,255,255,.9),transparent 60%),radial-gradient(1.5px 1.5px at 180px 90px,rgba(255,240,250,.85),transparent 60%),
  radial-gradient(3px 3px at 110px 200px,rgba(255,255,255,.55),transparent 60%),radial-gradient(1.5px 1.5px at 230px 230px,rgba(220,240,255,.8),transparent 60%),
  radial-gradient(2.5px 2.5px at 70px 150px,rgba(255,230,245,.6),transparent 60%);
 animation:wmotes 34s linear infinite}
.tworld [data-world-fx=streaks]::before{inset:0 -480px 0 0;background-size:480px 220px;opacity:.38;
 background-image:linear-gradient(90deg,transparent 0 12%,rgba(255,255,255,.55) 22%,transparent 34%),linear-gradient(90deg,transparent 52%,rgba(220,235,255,.4) 64%,transparent 76%);
 background-position:0 38px,0 150px;background-size:480px 220px,480px 220px;
 -webkit-mask:repeating-linear-gradient(180deg,transparent 0 37px,#000 37px 38.5px,transparent 38.5px 149px,#000 149px 150px,transparent 150px 220px);
 mask:repeating-linear-gradient(180deg,transparent 0 37px,#000 37px 38.5px,transparent 38.5px 149px,#000 149px 150px,transparent 150px 220px);
 animation:wstreaks 2.6s linear infinite}
@keyframes wmotes{to{transform:translate3d(0,260px,0)}}
@keyframes wstreaks{to{transform:translate3d(-480px,0,0)}}
/* the shade that keeps words readable over any world, darker toward the bottom and the edges */
.tworld [data-world-stage]::after{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;
 background:linear-gradient(180deg,rgba(3,6,15,.62) 0,rgba(3,6,15,.08) 16%,rgba(3,6,15,0) 40%,rgba(3,6,15,.5) 72%,rgba(3,6,15,.86) 100%),
  radial-gradient(130% 95% at 50% 42%,transparent 58%,rgba(3,6,15,.5))}

/* ---- the hero: the game itself, the words over it ---- */
/* the shade behind the hero's words rides with the hero itself, so the worlds further down keep their full colour */
.tworld .thero{min-height:100vh;min-height:100svh;display:flex;align-items:flex-end;padding:118px 0 clamp(56px,10vh,110px);overflow:visible}
/* :root[data-theme] outranks the template's own day and night hero glow, which would sit over the game */
:root[data-theme] .tworld .thero{background:linear-gradient(90deg,rgba(3,6,15,.74) 0,rgba(3,6,15,.42) 36%,rgba(3,6,15,0) 64%),linear-gradient(0deg,rgba(3,6,15,.7) 0,rgba(3,6,15,0) 48%)}
.tworld .thero::after{display:none}
.tworld .thero-in{grid-template-columns:minmax(0,1fr);width:100%}
.tworld .thero-copy{max-width:780px;--txt:#F5F9FF;--mut:#D3E0F5;--ice2:#BFE1FF;text-shadow:0 2px 18px rgba(3,6,15,.55)}
.tworld .thero-copy .crumb{color:#C9D8F2!important}
.tworld .thero-copy .crumb a{color:#BFE1FF}
.tworld .thero-copy [data-world-stage]+p{display:inline-flex;align-items:center;gap:10px;margin-top:16px;padding:7px 14px 7px 12px;border-radius:999px;
 font-family:var(--disp);font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:#F5F9FF;
 background:rgba(6,12,30,.42);border:1px solid rgba(207,232,255,.32);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);text-shadow:none}
.tworld .thero-copy [data-world-stage]+p::before{content:"";flex:none;width:8px;height:8px;border-radius:50%;background:#7CF2C2;
 box-shadow:0 0 0 0 rgba(124,242,194,.7);animation:wping 2.2s ease-out infinite}
.tworld .thero h1{font-size:clamp(46px,7.4vw,108px);line-height:.96;letter-spacing:-.025em;margin:14px 0 20px;
 background:linear-gradient(100deg,#FFFFFF 18%,#DDEEFF 52%,#BDB4FF 92%);-webkit-background-clip:text;background-clip:text;color:transparent;
 filter:drop-shadow(0 8px 32px rgba(3,6,15,.45));text-shadow:none}
.tworld .thero h1+p{font-size:clamp(17.5px,1.5vw,21px);line-height:1.6;color:#E6EEFB;max-width:56ch}
.tworld .thero-copy .tctas{margin:28px 0 12px}
.tworld .thero-copy .tctas .btn{text-shadow:none}
.tworld .thero-copy .tctas .btn-main{padding:18px 30px;font-size:17px;box-shadow:0 0 0 0 rgba(155,208,255,.55),0 16px 40px -12px rgba(111,168,255,.85);animation:wglow 2.8s ease-out infinite}
.tworld .thero-copy .tctas .btn-main::before{content:"";width:0;height:0;border-style:solid;border-width:7px 0 7px 11px;border-color:transparent transparent transparent currentColor;margin-right:2px}
.tworld .thero-copy .tctas .btn-ghost{background:rgba(6,12,30,.38);border-color:rgba(207,232,255,.38);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
:root[data-theme=day] .tworld .thero-copy .tctas .btn-ghost{color:#F5F9FF!important}
.tworld .thero-copy .tctas+p{font-size:14px;color:#C9D8F2}
/* a quiet cue that there is more below, drawn, not written */
.tworld .thero::before{content:"";position:absolute;left:50%;bottom:22px;width:22px;height:34px;margin-left:-11px;border-radius:12px;
 border:1.5px solid rgba(232,241,255,.6);background:radial-gradient(circle at 50% 30%,#F5F9FF 2.5px,transparent 3px) no-repeat 50% 6px/100% 100%;
 animation:wcue 2.2s ease-in-out infinite;z-index:1}

/* ---- the chapters: glass windows with the world between them ---- */
.tworld .tbody{padding:0 0 4vh;position:relative}
.tworld .tdoc{gap:0}
.tworld .tcard:has(>[data-world-scene]){margin-top:58vh;background:linear-gradient(155deg,rgba(14,26,58,.7),rgba(5,10,23,.56));
 border-color:rgba(200,225,255,.24);backdrop-filter:blur(20px) saturate(150%);-webkit-backdrop-filter:blur(20px) saturate(150%);
 box-shadow:inset 0 1px 0 rgba(255,255,255,.16),0 40px 90px -40px rgba(0,0,0,.85)}
.tworld .tdoc>.tcard:has(>[data-world-scene]):first-child{margin-top:34vh}
/* the card still rises out of its tilted plane (premium3d), but never fades on the way: an element's opacity fades
   its blurred backdrop with it, and a phone-tall card stays part faded until its top reaches the screen's top, so the
   game's own frame would read sharp through the words being read */
.p3-live .tworld .tcard:has(>[data-world-scene]){opacity:1}
:root[data-theme=day] .tworld .tcard:has(>[data-world-scene]){background:linear-gradient(155deg,rgba(255,255,255,.84),rgba(240,245,255,.72));border-color:rgba(255,255,255,.7);
 box-shadow:inset 0 1px 0 #fff,0 40px 90px -40px rgba(8,18,50,.55)}
/* the hero's "How it was built" jumps to a chapter: land it clear of the fixed header */
.tworld [data-world-scene]{scroll-margin-top:112px}
.tworld [data-world-scene]>h2{font-size:clamp(28px,3.6vw,48px);line-height:1.08;margin:14px 0 18px}
.tworld [data-world-label]{display:inline-flex;align-items:center;gap:10px;margin:0!important;padding:7px 14px 7px 12px;border-radius:999px;
 font-family:var(--disp);font-size:11.5px!important;line-height:1.3!important;letter-spacing:.2em;text-transform:uppercase;color:var(--ice2)!important;
 border:1px solid var(--line);background:rgba(127,150,255,.1)}
.tworld [data-world-label]::before{content:"";flex:none;width:7px;height:7px;border-radius:50%;background:currentColor;opacity:.9}
.tworld [data-world-stats]{list-style:none;padding:0!important;margin:26px 0 24px!important;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.tworld [data-world-stats] li{margin:0;padding:18px 16px 16px;border-radius:18px;border:1px solid var(--line);display:flex;flex-direction:column;gap:6px;
 background:linear-gradient(160deg,rgba(207,232,255,.12),rgba(207,232,255,.02))}
.tworld [data-world-stats] strong{font-family:var(--disp);font-weight:600;font-size:clamp(28px,3.2vw,44px);line-height:1;letter-spacing:-.02em;
 background:linear-gradient(100deg,var(--txt),var(--ice2));-webkit-background-clip:text;background-clip:text;color:transparent}
.tworld [data-world-stats] span{font-size:14.5px;line-height:1.35;color:var(--mut)}
:root[data-theme=day] .tworld [data-world-stats] li{background:linear-gradient(160deg,rgba(63,140,255,.1),rgba(63,140,255,.02))}
.tworld [data-world-points]{list-style:none;padding:0!important;margin:20px 0 4px!important;counter-reset:wp}
.tworld [data-world-points] li{counter-increment:wp;position:relative;margin:0;padding:16px 0 16px 56px;border-top:1px solid var(--line)}
.tworld [data-world-points] li::before{content:counter(wp,decimal-leading-zero);position:absolute;left:0;top:15px;width:38px;height:38px;border-radius:50%;
 display:grid;place-items:center;font-family:var(--disp);font-size:12.5px;color:var(--ice2);border:1px solid var(--line);background:rgba(127,150,255,.08)}
.tworld [data-world-cta]{display:flex;flex-wrap:wrap;gap:12px;margin-top:24px}
.tworld [data-world-cta] a{display:inline-flex;align-items:center;justify-content:center;padding:15px 24px;border-radius:999px;font-weight:700;text-decoration:none;
 font-size:16px;color:var(--txt);background:rgba(207,232,255,.06);border:1px solid rgba(207,232,255,.3);word-break:normal}
.tworld [data-world-cta] a:first-child{color:#061230;border:0;background:linear-gradient(120deg,#EAF5FF,#9BD0FF 55%,#6FA8FF);box-shadow:0 12px 34px -10px rgba(111,168,255,.7)}
:root[data-theme=day] .tworld [data-world-cta] a:not(:first-child){color:#0B1736;border-color:rgba(11,23,54,.25)}

/* the page end sits on the last world: the booking card first, then a solid footer */
.tworld .tend{padding-top:34vh}
.tworld footer.tfoot{position:relative;background:var(--ink);margin-top:70px}
.tworld footer.tfoot::before{content:"";position:absolute;left:0;right:0;bottom:100%;height:120px;background:linear-gradient(transparent,var(--ink));pointer-events:none}

@keyframes wping{0%{box-shadow:0 0 0 0 rgba(124,242,194,.7)}80%,100%{box-shadow:0 0 0 10px rgba(124,242,194,0)}}
@keyframes wglow{0%{box-shadow:0 0 0 0 rgba(155,208,255,.55),0 16px 40px -12px rgba(111,168,255,.85)}70%,100%{box-shadow:0 0 0 16px rgba(155,208,255,0),0 16px 40px -12px rgba(111,168,255,.85)}}
@keyframes wcue{0%,100%{transform:translateY(0);opacity:.85}50%{transform:translateY(7px);opacity:.45}}

@media(max-width:900px){
 .tworld .thero{padding:104px 0 112px}
 :root[data-theme] .tworld .thero{background:linear-gradient(0deg,rgba(3,6,15,.9) 0,rgba(3,6,15,.72) 42%,rgba(3,6,15,.22) 66%,rgba(3,6,15,0) 80%)}
 .tworld .thero::before{display:none}
 .tworld .tcard:has(>[data-world-scene]){margin-top:50vh}
 .tworld .tdoc>.tcard:has(>[data-world-scene]):first-child{margin-top:26vh}
}
@media(max-width:700px){
 .tworld .thero h1{font-size:clamp(40px,11.5vw,58px)}
 .tworld .thero-copy .tctas{gap:10px}
 .tworld .thero-copy .tctas .btn{flex:1 1 100%}
 .tworld .thero-copy .tctas .btn-main{padding:17px 22px}
 .tworld [data-world-stats]{grid-template-columns:repeat(2,minmax(0,1fr))}
 .tworld [data-world-points] li{padding-left:50px}
 .tworld [data-world-cta] a{flex:1 1 100%}
 .tworld [data-world-fx]::before{opacity:.32}
}
/* still: no portal, no drift, no particles; the scene still follows the chapter */
@media(prefers-reduced-motion:reduce){
 .tworld [data-world-shot],.tworld [data-world-stage] [data-world-shot]{transition:none!important;scale:1}
 .tworld .thero-copy [data-world-shot] img{animation:none}
 .tworld [data-world-stage]::before,.tworld .thero::before{animation:none;display:none}
 .tworld .thero-copy .tctas .btn-main,.tworld .thero-copy [data-world-stage]+p::before{animation:none}
}
/* lite (no GPU, premium3d.js): software painting, so no blur behind glass and no moving layers */
.lite .tworld [data-world-stage]::before{display:none}
/* without the blur a frame's own words (a start screen, a HUD) read sharp through any see-through fill: white game
   lettering still showed as a ghost through a 95% card, so here the card is solid */
.lite .tworld .tcard:has(>[data-world-scene]){backdrop-filter:none;-webkit-backdrop-filter:none;background:#050A17}
:root.lite[data-theme=day] .tworld .tcard:has(>[data-world-scene]){background:#FFFFFF}
.lite .tworld .thero-copy [data-world-shot] img{animation:none}
