/* ==========================================================================
   Subtitl — TEMPLATES "constellation" (index.html only)
   --------------------------------------------------------------------------
   Desktop: the live 9:16 preview in the middle; every other style floats
   around it as a poster card at its own depth. --depth (0.7–1) drives size,
   stacking, a pale veil (far = paler — no blur: a filter on a bobbing card
   would re-raster every frame) and how far it drifts with the pointer
   (--px/--py, set on the stage by app.js initTemplateCloud). Each card bobs
   on its own period (--bd, --bdl, --r0/--r1). Clicking one flies it into the
   phone while the playing style flies out to its slot (WAAPI, same file).
     .tc (slot: left/top %, centred, scaled by depth)
       .tc-par (pointer parallax)  > .tc-bob (idle float)  > .tc-card
   Phones (≤820px): the preview on top, the cards as a swipeable filmstrip.
   Reduced motion: no float, no parallax, no flight — swaps are instant.
   ========================================================================== */
.tcloud{position:relative;max-width:1192px;height:clamp(600px,48vw,680px);margin:var(--stack-gap) auto 0;
  --px:0;--py:0}
/* a soft blue light behind the phone */
.tcloud::before{content:"";position:absolute;left:50%;top:50%;width:62%;height:96%;translate:-50% -50%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(75,166,241,.16),rgba(75,166,241,0))}
/* faint orbit rings behind everything — static on purpose (animating dashes
   repaints the whole SVG every frame) */
.tc-orbits{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;
  fill:none;stroke:rgba(18,134,230,.16);stroke-width:1.2;stroke-dasharray:2 7;vector-effect:non-scaling-stroke}
.tc-orbits ellipse{vector-effect:non-scaling-stroke}
.tc-orbits ellipse:nth-child(2){stroke:rgba(18,134,230,.11)}
.tc-orbits ellipse:nth-child(3){stroke:rgba(18,134,230,.07)}

.tcloud .styles-gallery{position:absolute;inset:0}

/* a card in its slot */
.tc{
  position:absolute;left:calc(var(--x) * 1%);top:calc(var(--y) * 1%);
  width:clamp(100px,8.6vw,124px);padding:0;margin:0;border:0;background:none;
  transform:translate(-50%,-50%) scale(var(--depth));
  cursor:pointer;-webkit-tap-highlight-color:transparent;text-align:center;color:inherit;
}
.tc.is-in{visibility:hidden;pointer-events:none}          /* the style playing in the phone */
.tc.is-emerging{visibility:hidden}                        /* the old style, until it peels off the phone */
.tc-par{display:block;
  transform:translate3d(calc(var(--px) * var(--depth) * -30px),calc(var(--py) * var(--depth) * -20px),0)}
/* Keyframes hold LITERAL values on purpose: var() inside keyframes kept these
   loops off the compositor (measured: 12 cards cost ~6–10% of the main
   thread). Variety comes from three fixed variants + per-card --bd/--bdl. */
.tc-bob{display:block;animation:tcBobA var(--bd,7s) ease-in-out var(--bdl,0s) infinite alternate}
.tc:nth-child(3n+1) .tc-bob{animation-name:tcBobB}
.tc:nth-child(3n+2) .tc-bob{animation-name:tcBobC}
@keyframes tcBobA{from{transform:translate3d(0,-8px,0) rotate(-1deg)}to{transform:translate3d(0,8px,0) rotate(.8deg)}}
@keyframes tcBobB{from{transform:translate3d(0,-7px,0) rotate(1.2deg)}to{transform:translate3d(0,9px,0) rotate(-.9deg)}}
@keyframes tcBobC{from{transform:translate3d(0,-9px,0) rotate(.5deg)}to{transform:translate3d(0,6px,0) rotate(-.6deg)}}
.tc.is-in .tc-bob{animation:none}   /* the hidden card in the phone needn't float */

.tc-card{position:relative;display:block;padding:5px;border-radius:20px;
  background:linear-gradient(180deg,#fff,#EEF1F6);
  box-shadow:inset 0 1px 0 #fff,0 0 0 1px rgba(20,30,60,.08),
    0 calc(var(--depth) * 34px) calc(var(--depth) * 50px) calc(var(--depth) * -26px) rgba(10,30,70,.5);
  transition:transform .35s cubic-bezier(.2,.8,.2,1),box-shadow .35s ease}
/* depth veil: far cards sink into the page */
.tc-card::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:#F6F8FB;opacity:calc((1 - var(--depth)) * 1.45);transition:opacity .35s ease}
.tc .sci-thumb{position:relative;display:block;aspect-ratio:9/16;border-radius:15px;overflow:hidden;background:#0c0c10}
.tc .sci-thumb img{display:block;width:100%;height:100%;object-fit:cover}
.tc .sci-name{position:absolute;left:50%;bottom:-12px;translate:-50% 0;z-index:1;white-space:nowrap;
  padding:5px 10px;border-radius:999px;font:600 11.5px/1 var(--sans);color:var(--ink);
  background:#fff;box-shadow:0 0 0 1px rgba(20,30,60,.09),0 8px 16px -10px rgba(10,30,70,.5)}
@media (hover:hover) and (pointer:fine){
  .tc:hover{z-index:40 !important}
  .tc:hover .tc-card{transform:translateY(-8px) scale(1.07);
    box-shadow:inset 0 1px 0 #fff,0 0 0 1px rgba(18,134,230,.35),0 40px 60px -28px rgba(10,30,70,.6)}
  .tc:hover .tc-card::after{opacity:0}
}
.tc:focus-visible{outline:none}
.tc:focus-visible .tc-card{box-shadow:0 0 0 3px var(--blue),0 30px 50px -26px rgba(10,30,70,.5)}
.tc:focus-visible .tc-card::after{opacity:0}

/* the "+23" card: the rest of the 35+ live in the editor */
.tc-more{cursor:default}
.tc-more .tc-card{aspect-ratio:9/16.9;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:18px 14px;
  background:
    radial-gradient(90% 60% at 50% 0%,rgba(75,166,241,.45),transparent 70%),
    linear-gradient(170deg,#16223C,#0A0E18);color:#fff}
.tc-more .tc-card::after{opacity:0}
.tc-more b{font:700 2.6rem/1 var(--sans);letter-spacing:-.04em}
.tc-more span span,.tc-more .tc-card > span{font:500 .82rem/1.3 var(--body);color:rgba(230,240,255,.78);max-width:12ch}

/* the live preview, centred on the stage */
.tcloud .styles-preview{position:absolute;left:50%;top:50%;translate:-50% -50%;z-index:20;
  width:clamp(240px,20vw,280px)}
.styles-card{position:relative;aspect-ratio:9/16;border-radius:26px;overflow:hidden;background:#0c0c10;width:100%;
  box-shadow:0 0 0 6px #fff,0 0 0 7px rgba(20,30,60,.08),0 60px 90px -40px rgba(9,28,66,.6),0 16px 30px -16px rgba(9,28,66,.3)}
.styles-card video.pv{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:inherit}
/* ---- the merge (app.js initTemplateCloud) ------------------------------
   the ghost: a flying copy of a card's poster, sized as the phone's video and
   scaled down onto the card, so it lands pixel-crisp; origin top-left, since
   the JS positions it by its corner */
.tc-ghost{position:absolute;left:0;top:0;z-index:35;pointer-events:none;transform-origin:0 0;
  border-radius:26px;overflow:hidden;background:#0c0c10;will-change:transform;
  box-shadow:0 24px 44px -22px rgba(10,30,70,.55)}
.tc-ghost img{display:block;width:100%;height:100%;object-fit:cover}
/* the playing copy sits over the poster and appears once it's actually playing */
.tc-ghost video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .12s linear}
.tc-ghost video.is-live{opacity:1}


@media (min-width:1600px){
  .tcloud{max-width:1320px;height:740px}
  .tc{width:136px}
  .tcloud .styles-preview{width:300px}
}
/* between tablet and small laptop the side columns get tight: smaller cards */
@media (max-width:1100px) and (min-width:821px){
  .tc{width:clamp(84px,9vw,104px)}
  .tc .sci-name{font-size:11px;padding:5px 9px}
}

/* ==========================================================================
   COMPARISON LAYOUTS (desktop; app.js initTemplateCloud → LAYOUTS). The
   preview-only switcher sets data-layout on the stage. Shared: no bob, no
   parallax, no depth veil, and the playing style stays visible, ringed.
   ========================================================================== */
.tl-switch{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:6px;margin:18px auto 0;width:max-content;max-width:100%;
  padding:5px;border-radius:999px;background:#F2F4F7;box-shadow:inset 0 0 0 1px rgba(20,30,60,.07)}
.tl-switch span{font:600 11px/1 var(--body);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint);padding:0 8px 0 10px}
.tl-switch button{font:600 13px/1 var(--sans);color:var(--ink-soft);padding:8px 14px;border-radius:999px;background:none;border:0;cursor:pointer}
.tl-switch button[aria-checked="true"]{background:#fff;color:var(--ink);box-shadow:0 1px 0 #fff inset,0 0 0 1px rgba(20,30,60,.08),0 4px 10px -6px rgba(10,30,70,.4)}
@media (max-width:820px){ .tl-switch{display:none} }

@media (min-width:821px){
  .tcloud:not([data-layout="cloud"]) .tc-orbits{display:none}
  .tcloud:not([data-layout="cloud"]):not([data-layout="globe"]) .tc-bob{animation:none}
  .tcloud:not([data-layout="cloud"]) .tc-par{transform:none}
  .tcloud:not([data-layout="cloud"]) .tc-card::after{opacity:0}
  .tcloud:not([data-layout="cloud"]) .tc.is-in{visibility:visible;pointer-events:auto}
  .tcloud:not([data-layout="cloud"]) .tc.is-active .tc-card{box-shadow:0 0 0 3px var(--blue),0 24px 40px -22px rgba(18,134,230,.6)}
  .tcloud:not([data-layout="cloud"]) .tc.is-active .sci-name{color:var(--blue-deep)}

  /* WALL: four endless columns; each track is two identical halves, so
     -50% loops seamlessly (items carry their gap as margin, not gap) */
  .tcloud[data-layout="wall"] .styles-gallery{
    -webkit-mask-image:linear-gradient(180deg,transparent,#000 13%,#000 87%,transparent);
            mask-image:linear-gradient(180deg,transparent,#000 13%,#000 87%,transparent)}
  .tw-col{position:absolute;top:0;bottom:0;width:clamp(104px,9vw,128px);translate:-50% 0;overflow:hidden;padding-top:8px}
  .tw-col-0{left:8%} .tw-col-1{left:24%} .tw-col-2{left:76%} .tw-col-3{left:92%}
  .tw-track{display:flex;flex-direction:column;animation:twUp 34s linear infinite}
  .tw-col-1 .tw-track,.tw-col-3 .tw-track{animation-name:twDown;animation-duration:40s}
  .tw-col-2 .tw-track{animation-duration:38s}
  .tw-col:hover .tw-track{animation-play-state:paused}
  @keyframes twUp{from{transform:translate3d(0,0,0)}to{transform:translate3d(0,-50%,0)}}
  @keyframes twDown{from{transform:translate3d(0,-50%,0)}to{transform:translate3d(0,0,0)}}
  .tcloud[data-layout="wall"] .tc{position:relative;left:auto;top:auto;width:100%;transform:none;margin:0 0 34px;flex:none}
  .tcloud[data-layout="wall"] .tc-more .tc-card{aspect-ratio:9/15}


}
/* GLOBE: JS places every card (transform/opacity/z-index); the card facing
   front is hidden behind the phone at rest; .is-front shows a card while it
   hands over to/from the phone. Name pills fade as a card grows (--lab). */
@media (min-width:821px){
  .tcloud[data-layout="globe"] .tc{will-change:transform,opacity}
  .tcloud[data-layout="globe"] .tc.is-in:not(.is-front){visibility:hidden;pointer-events:none}
  .tcloud[data-layout="globe"] .tc.is-front{visibility:visible}   /* stacking comes from the animation */
  .tcloud[data-layout="globe"] .tc-bob{animation-play-state:running}   /* float in free air, like the constellation */
  .tcloud[data-layout="globe"] .tc.is-front .tc-bob{animation:none}
  .tcloud[data-layout="globe"] .tc.is-active .sci-name{color:var(--ink)}
  .tcloud[data-layout="globe"] .tc.is-active .tc-card{box-shadow:inset 0 1px 0 #fff,0 0 0 1px rgba(20,30,60,.08),0 20px 30px -20px rgba(10,30,70,.5)}
}
/* the leaving copy of the phone (app.js globeExchange) — pointer-transparent */
.tcloud .gl-ghost{pointer-events:none;will-change:transform,opacity}
/* the leaving copy is a still of the phone's frame (app.js globeExchange) */
.gl-still{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:inherit;display:block}
/* the arriving style's poster, worn by the phone while its caption swaps
   underneath; crossfades to the live clip mid-flight */
.gl-cover{position:absolute;inset:0;z-index:3;border-radius:inherit;overflow:hidden;pointer-events:none;opacity:0;transition:opacity .22s ease}
.gl-cover.is-on{opacity:1;transition:none}
.gl-cover img{display:block;width:100%;height:100%;object-fit:cover}
.styles-card .style-chip{z-index:4}
/* drag to spin */
.tcloud[data-layout="globe"] .styles-gallery{cursor:grab;touch-action:pan-y;-webkit-user-select:none;user-select:none}
.tcloud[data-layout="globe"].gl-dragging .styles-gallery{cursor:grabbing}
/* while the globe is free (dragging / coasting) the cards ignore the pointer:
   sliding under the cursor they flickered their hover lift every frame */
.tcloud[data-layout="globe"].gl-dragging .tc{pointer-events:none}
.tcloud[data-layout="globe"] .tc .sci-name{opacity:var(--lab,1)}
/* the phone rides the globe while dragging: no ring shadow lag */
.tcloud[data-layout="globe"].gl-dragging .styles-preview{will-change:transform,opacity}
.tcloud[data-layout="globe"].gl-dragging .tc-card{transition:box-shadow .18s ease,transform .18s ease}
.tc .sci-thumb .tc-live{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .15s linear}
.tc .sci-thumb .tc-live.is-live{opacity:1}

@media (min-width:821px) and (prefers-reduced-motion:reduce){
  .tw-track{animation:none}
}

/* ---- phones/tablets: preview on top, the cards as a filmstrip ----------- */
@media (max-width:820px){
  .tcloud{height:auto;display:flex;flex-direction:column;gap:22px;max-width:460px}
  .tc-orbits,.tc-more{display:none}
  .tcloud .styles-preview{position:relative;left:auto;top:auto;translate:none;order:-1;width:min(300px,76vw);margin-inline:auto}
  .styles-card{max-height:58svh;width:auto}
  .tcloud .styles-gallery{position:relative;inset:auto;display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x proximity;
    padding:10px 16px 26px;scrollbar-width:none;scroll-padding-inline:16px;
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 26px),transparent);
            mask-image:linear-gradient(to right,#000 calc(100% - 26px),transparent)}
  .tcloud .styles-gallery::-webkit-scrollbar{display:none}
  .tc{position:relative;left:auto;top:auto;flex:0 0 auto;width:92px;transform:none;scroll-snap-align:center}
  .tc.is-in{visibility:visible;pointer-events:auto}       /* in the strip the playing one stays, highlighted */
  .tc-par,.tc-bob{transform:none;animation:none}
  .tc-card{padding:4px;border-radius:16px;box-shadow:inset 0 1px 0 #fff,0 0 0 1px rgba(20,30,60,.08),0 14px 22px -16px rgba(10,30,70,.5)}
  .tc-card::after{opacity:0}
  .tc .sci-thumb{border-radius:12px}
  .tc .sci-name{font-size:10.5px;padding:4px 8px;bottom:-11px}
  /* a loosely dealt strip rather than a ruler-straight one; the playing card sits straight */
  .tc:nth-child(odd) .tc-card{rotate:-2.5deg}
  .tc:nth-child(even) .tc-card{rotate:2deg}
  .tc.is-active .tc-card{rotate:0deg}
  .tc.is-active .tc-card{box-shadow:0 0 0 2.5px var(--blue),0 14px 22px -14px rgba(18,134,230,.6)}
  .tc.is-active .sci-name{color:var(--blue-deep)}
}
@media (prefers-reduced-motion:reduce){
  .tc-bob{animation:none}
  .tc-par{transform:none}
  .tc-card,.tc-card::after{transition:none}
}
