/* ============================================================
   CATEGORY SELECTOR, full-screen creative-universe picker.
   Opened from the four-square mark in the homepage header.
   Loads AFTER mobile.css, which supplies the shared design system
   (tokens, .glass, .chip, typography). Nothing here is used by the
   homepage, that layout is locked and untouched.
   ============================================================ */
/* a single-screen layout when everything fits: uscreen is a flex column
   that fills at least one viewport, and main(.ustage) grows to take
   exactly what's left. On short viewports where the card + dots + footer
   don't fit in one screen, uscreen grows past 100dvh and the page scrolls
   instead of shrinking the card and clipping it (min-height, not a fixed
   height, so flexbox never has a reason to shrink children below content). */
.uscreen{min-height:100vh;min-height:100svh;min-height:100dvh;overflow-x:hidden;
  display:flex;flex-direction:column;
  background:var(--black);position:relative;isolation:isolate}
.uscreen .ubar{flex:none}

/* ---- ambient world: one layer per category, crossfaded on change ----
   Gradients can't be tweened, so the desktop's .uni__layer trick applies:
   stack them all and animate opacity instead. Fixed, so the atmosphere
   stays put while the screen scrolls. */
.cats__atmos{position:fixed;inset:-14%;z-index:0;pointer-events:none;
  filter:blur(40px) saturate(1.12)}
.cats__layer{position:absolute;inset:0;opacity:0;
  transition:opacity .5s var(--ease);
  background:
    radial-gradient(96% 70% at 50% 4%,  var(--c1) 0%, transparent 68%),
    radial-gradient(82% 60% at 92% 44%, var(--c2) 0%, transparent 68%),
    radial-gradient(88% 64% at 6% 96%,  var(--c3) 0%, transparent 70%)}
.cats__layer.is-on{opacity:1}

/* ============ TOP BAR ============ */
.ubar{position:sticky;top:0;z-index:20;display:flex;align-items:center;justify-content:space-between;
  gap:.6rem;padding:calc(env(safe-area-inset-top) + 12px) var(--pad) 12px}
.ubar__brand{display:inline-flex;align-items:center}
.ubar__actions{display:flex;align-items:center;gap:.5rem}
.ubar__close,.ubar__profile{display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:14px;color:var(--white);flex:none;
  transition:transform .4s var(--ease)}
.ubar__close:active,.ubar__profile:active{transform:scale(.94)}

/* ============ STAGE ============
   No introductory copy: the visual selector itself is the whole screen.
   The carousel grows to fill whatever space the header/dots/footer leave,
   so the active universe stays the dominant thing on screen at any height. */
.ustage{position:relative;z-index:10;flex:1 1 auto;min-height:0;
  display:flex;flex-direction:column;
  padding-bottom:calc(env(safe-area-inset-bottom) + 18px)}

/* ============ SNAP CAROUSEL ============
   The physics are the platform's: the viewport is a genuine scroll
   container with `scroll-snap-type:x mandatory`, so momentum, flick,
   slow drag and the settle spring come from the OS compositor, they
   run off the main thread and stay at 60fps under load. JS only maps
   scroll position onto --p (1 at centre → 0 further out) for scale and
   opacity, and swaps which ambient layer is lit.

   The viewport is deliberately full-bleed while the head and dots keep
   --pad, so --side can centre the first and last card off 100vw.

   --side and --gap are deliberately the SAME value (both var(--pad)): the
   spacer formula below (side - gap) then collapses to zero, so the next
   card's leading edge lands exactly on the viewport boundary, not a pixel
   sooner. That is what keeps the neighbour fully off-screen, no sliver,
   the pagination dots are the only hint more universes exist, while the
   active card still opens flush with the header/dots inset. */
.cats{position:relative;z-index:2;flex:1 1 auto;min-height:0;
  display:flex;flex-direction:column;justify-content:center;
  padding:clamp(6px,1.2vh,14px) 0 0;
  --side:var(--pad);
  --gap:var(--pad);
  --cardw:calc(100vw - (2 * var(--side)))}
.cats__viewport{flex:0 1 auto;min-height:0;overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain;
  scrollbar-width:none;-ms-overflow-style:none}
.cats__viewport::-webkit-scrollbar{display:none}
.cats__track{display:flex;align-items:center;gap:var(--gap);width:max-content;padding:14px 0}
/* spacer flex items rather than padding, Safari drops the trailing padding
   on a horizontal flex scroller, which would make the last card un-centrable.
   Subtracting a full --gap (not half) lands the first and last card dead centre
   at scrollLeft 0 and at max scroll respectively, with no leftover slack. */
.cats__track::before,.cats__track::after{content:"";flex:0 0 max(0px, calc(var(--side) - var(--gap)))}

/* ---- card ---- */
.ucard{flex:0 0 var(--cardw);scroll-snap-align:center;
  /* --p is written per frame by universes.js: 1 at dead centre, 0 further out */
  transform:scale(calc(.9 + .1 * var(--p,1)));
  opacity:calc(.55 + .45 * var(--p,1));
  will-change:transform,opacity}
.ucard__inner{display:flex;flex-direction:column;border-radius:24px;padding:10px 10px 4px;
  border-color:rgba(255,255,255,.16);
  transition:border-color .5s var(--ease),box-shadow .5s var(--ease);
  /* entrance, kept off .ucard so it never fights the scroll-driven scale */
  opacity:0;transform:translateY(26px)}
.cats.is-in .ucard__inner{opacity:1;transform:none;
  transition:opacity .8s var(--ease),transform .9s var(--ease),
             border-color .5s var(--ease),box-shadow .5s var(--ease)}
.cats.is-in .ucard:nth-child(2) .ucard__inner{transition-delay:.07s}
.cats.is-in .ucard:nth-child(3) .ucard__inner{transition-delay:.14s}
.cats.is-in .ucard:nth-child(4) .ucard__inner{transition-delay:.21s}
.cats.is-in .ucard:nth-child(5) .ucard__inner{transition-delay:.28s}
.cats.is-in .ucard:nth-child(6) .ucard__inner{transition-delay:.35s}
/* the centred card earns the orange rim + a deeper lift */
.ucard.is-active .ucard__inner{border-color:rgba(255,90,31,.34);
  box-shadow:0 22px 50px -26px rgba(0,0,0,.66), 0 0 46px -22px rgba(255,90,31,.34)}

/* media, the preview fills its box edge-to-edge like a clipping mask: `cover`
   scales the artwork to occupy the whole 2:3 frame (no letterbox strips, no grey
   margins) and `overflow:hidden` + the border-radius clip it to the card's own
   rounded corners, so the image reads as part of the card rather than a
   rectangle sitting inside it. Aspect ratio is honoured, never stretched.
   (The gallery + fullscreen viewer still show every frame WHOLE; this cover is
   only for the small selector preview.) */
.ucard__media{position:relative;aspect-ratio:2/3;overflow:hidden;border-radius:17px;
  background:rgba(255,255,255,.03)}
.ucard__media img{width:100%;height:100%;object-fit:cover;object-position:center;display:block}

.ucard__body{display:flex;flex-direction:column;gap:.42rem;padding:.85rem .5rem .7rem}
.ucard__label{font-size:.53rem;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--dim)}
.ucard__title{font-size:1.16rem;font-weight:800;letter-spacing:-.03em;line-height:1.12}
.ucard__title em{color:var(--orange);font-weight:500;font-style:italic}
.ucard__foot{display:flex;align-items:center;justify-content:space-between;gap:.6rem;margin-top:.2rem}
.ucard__count{font-size:.65rem;letter-spacing:.09em;color:var(--faint);font-variant-numeric:tabular-nums}
/* arrow, same frosted language as every other button on the site */
.ucard__go{flex:none;width:34px;height:34px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;font-style:normal;font-size:.9rem;
  background:var(--glass-bg);border:1px solid var(--glass-bd);color:var(--white);
  transition:background .45s var(--ease),border-color .45s var(--ease),
             color .45s var(--ease),transform .45s var(--ease)}
.ucard.is-active .ucard__go{background:var(--orange);border-color:var(--orange);color:#0a0a0a}
.ucard:active .ucard__go{transform:scale(.9)}

/* ---- pagination ---- */
.cats__dots{display:flex;justify-content:center;align-items:center;gap:.3em;margin-top:1.1rem;padding:0 var(--pad)}
.cats__dot{padding:9px 5px;display:inline-flex;align-items:center;line-height:0}
.cats__dot i{display:block;width:6px;height:6px;border-radius:50%;background:rgba(246,244,240,.22);
  transition:background .45s var(--ease),width .45s var(--ease)}
.cats__dot.is-on i{background:var(--orange);width:22px;border-radius:6px}

/* ============ FOOTER, a single subtle copyright line ============ */
.ufoot{margin-top:auto;padding:clamp(14px,2.5vh,22px) var(--pad) 0;
  display:flex;justify-content:center}
.ufoot__copy{font-size:.66rem;letter-spacing:.04em;color:var(--white);opacity:.4}

/* larger phones/phablets: cap the card's own width so it doesn't sprawl,
   then re-derive --side and --gap from that capped width so the zero-peek
   identity (side === gap) still holds instead of just inheriting --pad. */
@media (min-width:560px){
  .cats{--cardw:min(68vw,420px);--side:calc((100vw - var(--cardw)) / 2);--gap:var(--side)}
}
/* tablets: the card would otherwise sit small in a wide frame, leaving the
   peeking neighbours stranded far out at the edges */
@media (min-width:720px){
  .cats{--cardw:min(56vw,460px);--side:calc((100vw - var(--cardw)) / 2);--gap:var(--side)}
  .ufoot{max-width:760px;margin-left:auto;margin-right:auto;width:100%}
}

@media (prefers-reduced-motion:reduce){
  /* the carousel still snaps and scrolls, it just stops scaling and fading */
  .ucard{transform:none;opacity:1}
  .ucard__inner,.cats.is-in .ucard__inner{opacity:1;transform:none;transition:none}
  .cats__layer{transition:none}
}
