/* =====================================================================
   NEURA — World Select (.ws-*)

   This screen used to be a standalone export: its own black, its own
   starfield, its own saturated blue/violet/pink palette, its own type scale
   and its own corner radii. It looked like a different product bolted onto
   this one.

   It is now built from the same parts as everything else in the shell. It
   declares no colours, no radii, no shadows and no easing of its own — every
   value below is a token from styles.css. The panel recipe is the one
   `.atmos-panel` / `.world-menu` use, the label voice is the chrome's
   uppercase kicker, the motion is the single house curve, and the scene is
   the workspace's own wallpaper, grain and vignette.
   ===================================================================== */

/* ---------------------------------------------------------------------
   Root overlay — sits above the always-mounted workspace
   --------------------------------------------------------------------- */
.ws-root {
  position: fixed;
  inset: 0;
  z-index: 2000;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background-color: #030304;
  color: var(--text-primary);
  font-family: "SF Pro Rounded", "SF Pro Display", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-weight: 300;
  -webkit-font-smoothing: antialiased;
}

html.is-transitioning .ws-root {
  pointer-events: none;
  overflow: hidden;
}

/* ---------------------------------------------------------------------
   Scene — wallpaper, bloom, dust, vignette, grain
   --------------------------------------------------------------------- */
.ws-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  --ws-body-size: clamp(72px, 8vw, 118px);
}

/* One palette per phase. Everything downstream reads these, so the whole scene
   is retimed by swapping a single class. */
.ws-scene--night {
  --ws-sky-top: #030304;
  --ws-sky-mid: #050607;
  --ws-sky-low: #08090b;
  --ws-horizon: rgba(206, 216, 230, 0.1);
  --ws-body-tint: rgba(228, 232, 238, 0.9);
  --ws-scrim-core: 0.16;
  --ws-scrim-edge: 0.44;
}
.ws-scene--dawn {
  --ws-sky-top: #030304;
  --ws-sky-mid: #060606;
  --ws-sky-low: #0b0a09;
  --ws-horizon: rgba(230, 196, 168, 0.1);
  --ws-body-tint: rgba(255, 214, 170, 0.9);
  --ws-scrim-core: 0.16;
  --ws-scrim-edge: 0.44;
}
.ws-scene--day {
  --ws-sky-top: #030304;
  --ws-sky-mid: #060607;
  --ws-sky-low: #0a0a0c;
  --ws-horizon: rgba(224, 230, 240, 0.1);
  --ws-body-tint: rgba(246, 247, 250, 0.92);
  --ws-scrim-core: 0.16;
  --ws-scrim-edge: 0.44;
}
.ws-scene--dusk {
  --ws-sky-top: #030304;
  --ws-sky-mid: #060606;
  --ws-sky-low: #0b0908;
  --ws-horizon: rgba(230, 184, 156, 0.1);
  --ws-body-tint: rgba(255, 196, 146, 0.9);
  --ws-scrim-core: 0.16;
  --ws-scrim-edge: 0.44;
}

/* The sky itself. Three stops rather than two, so the light gathers toward the
   horizon instead of washing the frame evenly. */
.ws-sky {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    var(--ws-sky-top) 0%,
    var(--ws-sky-mid) 46%,
    var(--ws-sky-low) 74%
  );
  transition: background 2.4s linear;
}
/* The band of light sitting on the horizon behind the ridges. Cool at night,
   warm at dawn and dusk, near-white at noon. This is what silhouettes the
   land, so it is drawn before it. */
.ws-sky__horizon {
  position: absolute;
  left: 50%;
  bottom: 28%;
  width: 160%;
  height: 46%;
  transform: translateX(-50%);
  background: radial-gradient(
    closest-side,
    var(--ws-horizon) 0%,
    transparent 76%
  );
  transition: background 2.4s linear;
}

/* Stars. The whole field is scaled by --ws-night, which the clock drives from
   1 to 0 across sunrise, so they go out as the sky comes up instead of
   switching off at an hour boundary. */
.ws-stars {
  position: absolute;
  inset: 0;
  opacity: var(--ws-night, 1);
  transition: opacity 2.4s linear;
}
.ws-star {
  position: absolute;
  width: var(--ws-star-size, 1.5px);
  height: var(--ws-star-size, 1.5px);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.8);
  /* The glow scales with the star. At a flat 2px it was wider than the smallest
     stars are, which turned the faint end of the field into smudges — fine at
     96 stars, mush at 220. */
  box-shadow: 0 0 calc(var(--ws-star-size, 1.5px) * 1.4) rgba(230, 234, 240, 0.45);
  opacity: 0;
  animation: ws-twinkle var(--ws-star-duration, 3.5s) ease-in-out var(--ws-star-delay, 0s) infinite;
}
@keyframes ws-twinkle {
  0%,
  100% {
    opacity: calc(var(--ws-star-opacity, 0.7) * 0.6);
    transform: scale(0.78);
  }
  50% {
    opacity: var(--ws-star-opacity, 0.7);
    transform: scale(1);
  }
}

/* Sun or moon. It crosses the sky once a day, left to right, staying in the
   upper band above the cards, so stepping the clock forward always moves it
   forward. On top of that it floats, so it is never a frozen sticker. */
.ws-body {
  position: absolute;
  left: var(--ws-body-x, 50%);
  top: var(--ws-body-y, 24%);
  width: var(--ws-body-size, 108px);
  height: var(--ws-body-size, 108px);
  margin: calc(var(--ws-body-size, 108px) / -2) 0 0 calc(var(--ws-body-size, 108px) / -2);
  transition: left 900ms var(--tab-anim-ease), top 900ms var(--tab-anim-ease);
  animation: ws-body-float 16s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes ws-body-float {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(0, -14px, 0);
  }
}
/* The halo. This was three box-shadows at widening radii on the disc itself,
   and that is where the seam came from: each shadow is the same silhouette
   blurred by a different amount and painted over the last, so the light stepped
   down three times and then stopped dead at the widest radius — a ring of cut
   light against a near-black sky, and three fainter ones inside it.

   One element with one falloff replaces all three, at a fraction of the reach
   and a fraction of the brightness: the moon should look lit, not like it is
   leaking into the sky. The curve is Gaussian-ish, so it has no flat top and is
   spent within about two thirds of a radius past the limb, and its tail hits
   zero at ~70% of its own box — the light ends nowhere near an edge, which is
   what keeps it from reading as cut. Carrying it on a sized element rather than
   a shadow also keeps every lit pixel inside the element's own bounds, so a
   compositor layer can't clip the outer ring. */
.ws-body__glow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--ws-glow-size);
  height: var(--ws-glow-size);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(
    closest-side,
    rgb(var(--ws-glow-rgb) / 0.5) 0%,
    rgb(var(--ws-glow-rgb) / 0.34) 20%,
    rgb(var(--ws-glow-rgb) / 0.21) 30%,
    rgb(var(--ws-glow-rgb) / 0.12) 38%,
    rgb(var(--ws-glow-rgb) / 0.07) 45%,
    rgb(var(--ws-glow-rgb) / 0.036) 52%,
    rgb(var(--ws-glow-rgb) / 0.015) 60%,
    rgb(var(--ws-glow-rgb) / 0.005) 68%,
    rgb(var(--ws-glow-rgb) / 0.002) 78%,
    rgb(var(--ws-glow-rgb) / 0.001) 88%,
    rgb(var(--ws-glow-rgb) / 0) 100%
  );
}

.ws-body__disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
}
/* Moon: the Sleep & Rhythm surface texture, scrolling so the face turns. The
   disc keeps only the inset light that shapes its own limb; everything outside
   it is the halo's job. */
.ws-body--moon {
  --ws-glow-rgb: 236 240 246;
  --ws-glow-size: 260%;
}
.ws-body--moon .ws-body__disc {
  box-shadow: inset 0 0 12px rgba(255, 255, 255, 0.3);
}
.ws-body__surface {
  position: absolute;
  inset: 0;
  background-image: url("https://cdn.builder.io/api/v1/image/assets%2F829e877d75694a02812ee63318590140%2Fac0bdea45475487d9848c78295101f7a?format=webp&width=1000");
  background-repeat: repeat-x;
  background-size: auto 100%;
  background-position: 0 center;
  filter: brightness(0.97) contrast(1.06);
  animation: ws-moon-spin 28s linear infinite;
  will-change: background-position;
}
@keyframes ws-moon-spin {
  from {
    background-position-x: 0;
  }
  to {
    background-position-x: calc(var(--ws-body-size, 108px) * -2);
  }
}
.ws-body__shade {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 46%, rgba(255, 255, 255, 0.14), transparent 55%),
    radial-gradient(circle at 50% 50%, transparent 66%, rgba(246, 247, 250, 0.26) 90%, rgba(255, 255, 255, 0.55) 100%);
  box-shadow: inset 0 0 16px 2px rgba(255, 255, 255, 0.32);
}

/* Sun: no surface texture, and gold rather than the moon's cold white. It is
   the one warm thing in the scene, which is what tells you it is daytime — the
   sky itself stays dark at every hour. Its halo reaches a little further than
   the moon's, which is the other half of what separates them. */
.ws-body--sun {
  --ws-glow-rgb: 250 200 126;
  --ws-glow-size: 300%;
}
.ws-body--sun .ws-body__disc {
  background: radial-gradient(circle at 50% 44%, #fffdf2 0%, #ffe0a3 52%, #f5bf6a 100%);
  box-shadow: inset 0 0 12px rgba(255, 244, 214, 0.4);
}
/* The moon's rim shading would grey a golden disc, so the sun keeps only the
   soft highlight. */
.ws-body--sun .ws-body__shade {
  background: radial-gradient(circle at 50% 40%, rgba(255, 255, 255, 0.28), transparent 62%);
  box-shadow: none;
}

html.is-transitioning .ws-star,
html.is-transitioning .ws-body,
html.is-transitioning .ws-body__surface {
  animation-play-state: paused;
}

/* The scene is allowed to get genuinely bright at midday, and the cards and
   copy above it are white-on-dark, so the light is bought back where they sit.
   The scrim is heaviest through the middle band, which is exactly where the
   headline and the cards are, and lets the sky stay open at the top corners. */
.ws-scene__scrim {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    130% 96% at 50% 58%,
    rgba(0, 0, 0, var(--ws-scrim-core)) 0%,
    rgba(0, 0, 0, var(--ws-scrim-edge)) 100%
  );
  transition: background 2.4s linear;
}
.ws-scene__grain {
  position: absolute;
  inset: 0;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------------
   Time scrubber — step the scene's clock to inspect any hour
   --------------------------------------------------------------------- */
.ws-timescrub {
  position: absolute;
  left: 50%;
  bottom: clamp(16px, 3vh, 28px);
  z-index: 4;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-radius: var(--chrome-radius);
  background: var(--chrome-glass);
  backdrop-filter: var(--chrome-blur);
  -webkit-backdrop-filter: var(--chrome-blur);
  box-shadow: var(--chrome-shadow), var(--chrome-highlight);
}
.ws-timescrub__step {
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 300ms var(--chrome-ease), color 300ms var(--chrome-ease);
}
.ws-timescrub__step svg {
  width: 15px;
  height: 15px;
}
.ws-timescrub__step--next svg {
  transform: rotate(180deg);
}
.ws-timescrub__step:hover {
  background: var(--chrome-fill-hover);
  color: var(--text-primary);
}
.ws-timescrub__read {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 10px;
  min-width: 116px;
  justify-content: center;
}
.ws-timescrub__clock {
  font-size: 12px;
  font-weight: 300;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--text-primary);
}
.ws-timescrub__phase {
  font-size: var(--chrome-kicker-size);
  font-weight: 300;
  letter-spacing: var(--chrome-kicker-track);
  text-indent: var(--chrome-kicker-track);
  text-transform: uppercase;
  color: var(--text-muted);
}
.ws-timescrub__live {
  margin-left: 2px;
  padding: 0 10px;
  height: 30px;
  border: none;
  border-radius: 8px;
  background: var(--chrome-fill-hover);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: var(--chrome-kicker-size);
  font-weight: 300;
  letter-spacing: var(--chrome-kicker-track);
  text-indent: var(--chrome-kicker-track);
  text-transform: uppercase;
  cursor: pointer;
  transition: color 300ms var(--chrome-ease);
}
.ws-timescrub__live:hover {
  color: var(--text-primary);
}

/* ---------------------------------------------------------------------
   Top chrome — brand, New World
   --------------------------------------------------------------------- */
.ws-topbar {
  position: relative;
  z-index: 3;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: clamp(20px, 3.2vh, 34px) clamp(20px, 4vw, 48px) 0;
}
.ws-brand {
  display: inline-flex;
  align-items: center;
}
.ws-brand__mark {
  height: 18px;
  width: auto;
  object-fit: contain;
  filter: brightness(0) invert(1);
  opacity: 0.92;
}

/* The chrome pill recipe, in the chrome's label voice. Disabled, so it never
   lights on hover. */
.ws-newworld {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 14px;
  border-radius: var(--chrome-radius);
  background: var(--chrome-glass);
  backdrop-filter: var(--chrome-blur);
  -webkit-backdrop-filter: var(--chrome-blur);
  box-shadow: var(--chrome-shadow), var(--chrome-highlight);
  color: var(--text-muted);
  font-size: var(--chrome-kicker-size);
  font-weight: 300;
  letter-spacing: var(--chrome-kicker-track);
  text-indent: var(--chrome-kicker-track);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: default;
  user-select: none;
}
.ws-newworld__icon {
  display: inline-flex;
  width: 15px;
  height: 15px;
}
.ws-newworld__icon svg {
  width: 100%;
  height: 100%;
}
.ws-newworld__note {
  color: rgba(255, 255, 255, 0.24);
}

/* ---------------------------------------------------------------------
   Stage — heading, cards, footnote
   --------------------------------------------------------------------- */
.ws-stage {
  position: relative;
  z-index: 2;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(24px, 4vh, 44px);
  padding: clamp(24px, 4vh, 48px) clamp(20px, 4vw, 48px) clamp(24px, 4vh, 44px);
  text-align: center;
}
.ws-intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.ws-kicker {
  font-size: var(--chrome-kicker-size);
  font-weight: 300;
  letter-spacing: var(--chrome-kicker-track);
  text-indent: var(--chrome-kicker-track);
  text-transform: uppercase;
  color: var(--text-muted);
}
.ws-headline {
  margin: 0;
  font-size: clamp(26px, 2.6vw, 34px);
  font-weight: 200;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--text-primary);
}
.ws-subhead {
  margin: 0;
  font-size: 13px;
  font-weight: 300;
  letter-spacing: -0.01em;
  color: var(--text-secondary);
}
.ws-footnote {
  margin: 0;
  font-size: 11px;
  font-weight: 300;
  color: rgba(255, 255, 255, 0.26);
}

/* ---------------------------------------------------------------------
   Cards — the panel primitive, one per world
   --------------------------------------------------------------------- */
.ws-cards {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: clamp(14px, 1.6vw, 22px);
  width: 100%;
  max-width: 1080px;
}

.ws-card {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  max-width: 340px;
  min-height: clamp(300px, 42vh, 400px);
  padding: 22px 22px 18px;
  overflow: hidden;
  text-align: left;
  cursor: pointer;
  color: var(--text-primary);
  font-family: inherit;
  border: none;
  border-radius: var(--panel-radius);
  background: var(--panel-glass);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  box-shadow: var(--panel-shadow), var(--panel-highlight);
  transition:
    transform var(--tab-anim-duration) var(--tab-anim-ease),
    box-shadow 300ms var(--chrome-ease),
    border-radius 700ms var(--tab-anim-ease),
    opacity 300ms var(--chrome-ease);
}
/* Photography lives inside the panel, pushed back behind the glass, rather
   than being the surface. Same grading register as the space wallpapers. */
.ws-card__art {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: var(--ws-card-art);
  background-size: cover;
  background-position: center;
  /* Black and white is the resting state, so the world you are standing in is
     the only colour on the screen and you can find it without reading. This
     grading is local to the cards — the workspace behind the overlay draws its
     wallpapers at full colour. */
  filter: grayscale(1) brightness(0.5) contrast(1.08);
  opacity: 0.42;
  transition:
    transform 700ms var(--tab-anim-ease),
    filter 600ms var(--chrome-ease),
    opacity 300ms var(--chrome-ease);
}
.ws-card--current .ws-card__art {
  filter: grayscale(0.82) brightness(0.54) contrast(1.05);
  opacity: 0.5;
}
.ws-card__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    165deg,
    rgba(10, 12, 11, 0.42) 0%,
    rgba(10, 12, 11, 0.82) 62%,
    rgba(10, 12, 11, 0.94) 100%
  );
  transition: opacity 300ms var(--chrome-ease);
}

.ws-card__body {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}
.ws-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}

/* The icon tile is the world menu's tile, at the same size and weight. */
.ws-card__icon {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border-soft);
  color: var(--text-secondary);
  transition: color 300ms var(--chrome-ease), border-color 300ms var(--chrome-ease);
}
.ws-card__icon svg {
  width: 19px;
  height: 19px;
  opacity: 0.85;
}

/* One point of light, the way every list in this product marks the row you
   are standing on. Dark until this is the world you came from. */
.ws-card__marker {
  width: 3px;
  height: 3px;
  margin-top: 8px;
  border-radius: 50%;
  background: transparent;
  transition: background 300ms var(--chrome-ease), box-shadow 300ms var(--chrome-ease);
}
.ws-card--current .ws-card__marker {
  background: #fff;
  box-shadow: 0 0 8px 2px rgba(255, 255, 255, 0.7);
}

.ws-card__titles {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 16px;
}
.ws-card__title {
  font-size: 24px;
  font-weight: 200;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--text-primary);
}
.ws-card__subtitle {
  font-size: 12px;
  font-weight: 300;
  letter-spacing: -0.01em;
  color: var(--text-secondary);
}
.ws-card__spacer {
  flex: 1 1 auto;
  min-height: 18px;
}

/* Spaces read as the nav tabs they will become: uppercase, tracked, muted. */
.ws-card__spaces {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
}
.ws-card__space {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 10px;
  font-weight: 300;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-muted);
  transition: color 300ms var(--chrome-ease);
}
.ws-card__space::before {
  content: "";
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.26);
}

.ws-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 20px;
  padding-top: 14px;
  border-top: 1px solid var(--border-softer);
}
.ws-card__cta {
  font-size: var(--chrome-kicker-size);
  font-weight: 300;
  letter-spacing: var(--chrome-kicker-track);
  text-indent: var(--chrome-kicker-track);
  text-transform: uppercase;
  color: var(--text-secondary);
  transition: color 300ms var(--chrome-ease);
}
.ws-card__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  color: var(--text-muted);
  transition: transform 300ms var(--chrome-ease), color 300ms var(--chrome-ease);
}
.ws-card__arrow svg {
  width: 100%;
  height: 100%;
}

/* Hover / focus — the card lifts a little further off the scene and the
   photograph inside it wakes up. That is the whole effect: no coloured bloom
   under the panel, no fill, no stroke. Depth is the shadow, exactly as it is
   for every other panel in the product. */
.ws-card:hover,
.ws-card:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 34px 80px rgba(0, 0, 0, 0.58), var(--panel-highlight);
  outline: none;
  z-index: 3;
}
.ws-card:hover .ws-card__art,
.ws-card:focus-visible .ws-card__art {
  transform: scale(1.05);
  opacity: 0.56;
}
.ws-card:hover .ws-card__icon,
.ws-card:focus-visible .ws-card__icon {
  color: var(--text-primary);
  border-color: rgba(255, 255, 255, 0.16);
}
.ws-card:hover .ws-card__space,
.ws-card:focus-visible .ws-card__space {
  color: var(--text-secondary);
}
.ws-card:hover .ws-card__cta,
.ws-card:focus-visible .ws-card__cta {
  color: var(--text-primary);
}
.ws-card:hover .ws-card__arrow,
.ws-card:focus-visible .ws-card__arrow {
  transform: translateX(3px);
  color: var(--text-primary);
}
.ws-card:focus-visible {
  outline: 1px solid rgba(255, 255, 255, 0.24);
  outline-offset: 3px;
}

/* ---------------------------------------------------------------------
   Enter / return transition
   --------------------------------------------------------------------- */
.ws-root--transitioning .ws-dimmable {
  transition:
    opacity 300ms var(--chrome-ease),
    transform 300ms var(--chrome-ease);
}
.ws-root--expanded .ws-dimmable {
  opacity: 0;
  transform: scale(0.98);
}
.ws-root--transitioning .ws-card {
  will-change: transform, opacity;
  /* Blur + scale on the same node forces a full repaint every frame. Drop the
     glass while transitioning (the card is either zooming to a full-bleed image
     or fading out) so the zoom stays on the compositor. */
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transition:
    transform 720ms cubic-bezier(0.6, 0.02, 0.9, 0.35),
    opacity 400ms ease,
    border-radius 500ms ease;
}
.ws-card--dimmed {
  transform: scale(0.9);
  opacity: 0;
}
.ws-card--selected {
  transform: scale(3.4);
  border-radius: 0;
  z-index: 5;
}
/* The chosen card is on its way to becoming the workspace, and the workspace is
   in colour. Draining the grey out during the zoom means the card dissolves
   into the real wallpaper instead of cutting to it. */
.ws-card--selected .ws-card__art {
  transform: scale(1.2);
  opacity: 1;
  filter: grayscale(0) brightness(0.55) contrast(1.04) saturate(1.02);
  will-change: transform;
}
.ws-card--selected .ws-card__scrim {
  opacity: 0.7;
}

.ws-veil {
  position: absolute;
  inset: 0;
  z-index: 6;
  opacity: 0;
  pointer-events: none;
  /* Compositor-only dark haze. A full-screen backdrop-filter re-blurs the whole
     scene every frame the backdrop changes — and the selected card is scaling
     behind it — which caused the mid-zoom stall. Fading a translucent dark
     gradient via opacity only is pure GPU compositing → smooth start to finish. */
  background: radial-gradient(
    120% 100% at 50% 45%,
    rgba(10, 12, 11, 0.5) 0%,
    rgba(10, 12, 11, 0.9) 100%
  );
  transition: opacity 400ms ease;
  transition-delay: 300ms;
}
.ws-veil--on {
  opacity: 1;
}

/* Return (exit): the card leads back into its slot, the rest follows */
.ws-card--returning {
  z-index: 6;
}
.ws-root--exit .ws-card {
  transition:
    transform 920ms var(--tab-anim-ease),
    opacity 620ms ease,
    border-radius 720ms ease;
}
.ws-root--exit .ws-dimmable {
  transition:
    opacity 560ms var(--chrome-ease),
    transform 560ms var(--chrome-ease);
  transition-delay: 220ms;
}
.ws-root--exit .ws-veil {
  transition: opacity 560ms ease;
}

/* Overlay crossfade (leave = forward enter-world, enter = return) */
.ws-fade-leave-active,
.ws-fade-enter-active {
  transition: opacity 280ms ease;
}
.ws-fade-leave-to,
.ws-fade-enter-from {
  opacity: 0;
}

/* ---------------------------------------------------------------------
   Responsive
   --------------------------------------------------------------------- */
@media (max-width: 899px) {
  /* Small screens can't fit three cards without scrolling; allow it here only. */
  .ws-root {
    overflow-y: auto;
  }
  .ws-stage {
    justify-content: flex-start;
    padding: 32px 16px;
  }
  .ws-cards {
    flex-wrap: wrap;
  }
  .ws-card {
    flex: 1 1 260px;
    max-width: 360px;
    min-height: 300px;
  }
  .ws-footnote {
    max-width: 34ch;
  }
}

/* ---------------------------------------------------------------------
   Reduced motion
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ws-body,
  .ws-body__surface {
    animation: none;
    transition: none;
  }
  .ws-star {
    animation: none;
    opacity: var(--ws-star-opacity, 0.7);
  }
  .ws-card,
  .ws-card__art,
  .ws-card__scrim,
  .ws-card__arrow {
    transition: none;
  }
  .ws-card:hover,
  .ws-card:focus-visible {
    transform: none;
  }
  .ws-card:hover .ws-card__art,
  .ws-card:focus-visible .ws-card__art {
    transform: none;
  }
  .ws-card:hover .ws-card__arrow,
  .ws-card:focus-visible .ws-card__arrow {
    transform: none;
  }
  .ws-card--selected {
    transform: none;
    border-radius: var(--panel-radius);
  }
  .ws-card--selected .ws-card__art {
    transform: none;
  }
  .ws-veil--on {
    transition: opacity 200ms ease;
    background: var(--bg-base);
  }
}
