/* ============================================================
   IMMERSIVE STUDIO — LOADING SCREEN
   The screen an experience opens on when it hasn't got one of its
   own, from the moment its HTML parses until the page says it is
   ready. One look for all of them: what you see between a card on
   the grid and the thing the card promised is the studio, not
   eight different waits. (Perfume is excluded — it has its own,
   and one wait gets one screen.)

   Paired with /common/js/loading-screen.js, which builds the
   markup and owns the dismissal. See common/docs/021.

   Fully self-contained, for the same reason .studio-home is
   (design-system.css): this runs on the copycat brand pages —
   fashion, jewelry, agentic-ai — which adopt a real site's look
   and don't use the rest of the design system. Every colour here
   is a literal with the studio token as an optional override, so
   the screen looks the same whatever the host page has done to
   its own palette.
   ============================================================ */

.loading-screen {
  position: fixed;
  inset: 0;
  /* Over everything, including the configurator's own per-product
     overlay (.loading, z-index 900) and the studio bar (2000..3000).
     Nothing on any page is meant to show through this. */
  z-index: 9000;

  display: grid;
  place-items: center;

  box-sizing: border-box;
  padding: 2rem;

  background:
    radial-gradient(60% 45% at 50% 38%, rgba(123, 47, 255, 0.18), transparent 70%),
    radial-gradient(45% 35% at 50% 100%, rgba(46, 110, 255, 0.12), transparent 70%),
    #000000;

  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  color: #ffffff;
  text-align: center;

  /* Opacity only — no transform, so nothing under it is asked to
     re-layout on the way out. */
  opacity: 1;
  transition: opacity 420ms ease;
}

/* The one state: on the way out. The element is removed from the
   DOM when the transition ends, so there is no lingering fixed
   layer swallowing pointer events on a page that has arrived. */
.loading-screen.is-out {
  opacity: 0;
  pointer-events: none;
}

.loading-screen__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: min(420px, 82vw);
}

/* The section the experience belongs to on the grid (Product
   Configuration, Experiences, Technologies) — so the wait names
   where you are, not just what you clicked. */
.loading-screen__section {
  margin: 0 0 0.85rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
}

/* The experience's name, as its card on the grid says it. */
.loading-screen__title {
  margin: 0 0 1.5rem;
  font-size: clamp(1.5rem, 4vw, 2rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: #ffffff;
}

.loading-screen__track {
  position: relative;
  width: 100%;
  height: 2px;
  overflow: hidden;
  border-radius: 100px;
  background: rgba(255, 255, 255, 0.12);
}

.loading-screen__bar {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: inherit;
  background: linear-gradient(90deg, #7B2FFF, #D44EFF);
  /* Determinate mode: the page reports a fraction and the bar is
     its width. Starts at zero. */
  width: 0%;
  transition: width 240ms ease;
}

/* Indeterminate mode, and the default: booting an experience means
   downloading modules, a catalog and an HDRI, and no page can put an
   honest number on that before the first of them answers. A segment
   that sweeps says "working" without claiming to know how much is
   left. The first call to progress() swaps this for the bar above. */
.loading-screen[data-mode="indeterminate"] .loading-screen__bar {
  width: 38%;
  transition: none;
  animation: loading-screen-sweep 1.5s ease-in-out infinite;
}

@keyframes loading-screen-sweep {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(290%); }
}

/* What is happening, in words — the page's own labels land here
   (progress()'s second argument), and until one does it carries the
   note the page's script tag set. */
.loading-screen__note {
  margin: 0.95rem 0 0;
  min-height: 1.1em;
  font-size: 0.74rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.42);
}

/* Said out loud only when a boot has failed: the screen stops
   pretending to load and the note becomes the reason. */
.loading-screen[data-state="failed"] .loading-screen__track { display: none; }
.loading-screen[data-state="failed"] .loading-screen__note { color: rgba(255, 138, 138, 0.9); }

/* The studio's mark under the wait, dim. The experience's name is
   the headline here, so this is a signature rather than a title —
   and it is the only brand on screen while the host page's own
   chrome is still covered. */
.loading-screen__brand {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1.6rem;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.22);
}

/* Reduced motion: the sweep is decoration and goes. The screen still
   appears and still leaves — a wait with no sign of life would be
   worse than one that doesn't animate — but it cuts rather than
   fades, and the track holds still. */
@media (prefers-reduced-motion: reduce) {
  .loading-screen { transition: none; }
  .loading-screen[data-mode="indeterminate"] .loading-screen__bar {
    width: 100%;
    animation: none;
    opacity: 0.4;
  }
  .loading-screen__bar { transition: none; }
}
