/* ==========================================================================
   Shopfront Studios — Opening study
   --------------------------------------------------------------------------
   A full-screen, tap-to-open introduction. The laptop rises out of the dark,
   opens on command, then docks into the hero stage while the page is revealed
   behind it. The CSS artwork underneath the WebGL canvas is both the loading
   placeholder and the permanent no-WebGL fallback.
   ========================================================================== */

html.intro-mode,
html.intro-mode body {
  overflow: hidden;
}

html.intro-failed,
html.intro-failed body {
  overflow: auto;
}

html.intro-failed .intro {
  display: none !important;
}

html.intro-mode {
  /* Reserve the scrollbar so the page does not shift when it unlocks. */
  scrollbar-gutter: stable;
}

html.intro-mode .skip-link {
  display: none;
}

html.intro-mode #app {
  /* The page is present and painted, but held at the threshold. */
  pointer-events: none;
}

html.intro-reveal #app {
  pointer-events: auto;
}

/* Hold the hero entrance until the visitor has opened the study. */
html.intro-mode .hero-eyebrow,
html.intro-mode .hero-title__line > span,
html.intro-mode .hero-lede,
html.intro-mode .hero-ctas,
html.intro-mode .hero-meta,
html.intro-mode .hero-foot {
  animation-play-state: paused;
}

html.intro-mode.intro-reveal .hero-eyebrow,
html.intro-mode.intro-reveal .hero-title__line > span,
html.intro-mode.intro-reveal .hero-lede,
html.intro-mode.intro-reveal .hero-ctas,
html.intro-mode.intro-reveal .hero-meta,
html.intro-mode.intro-reveal .hero-foot {
  animation-play-state: running;
}

/* --------------------------------------------------------------------------
   Shell
   -------------------------------------------------------------------------- */

.intro {
  position: fixed;
  z-index: 1000;
  inset: 0;
  overflow: hidden;
  color: var(--color-text);
  background: #08040f;
  isolation: isolate;
}

.intro__bg {
  position: absolute;
  z-index: 0;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 72% 64% at 50% 44%, #0b1b45 0%, #081124 38%, #050a18 74%, #03050c 100%);
  opacity: 1;
  transition: opacity 1s var(--ease-out);
}

.intro.is-docking .intro__bg {
  opacity: 0;
}

.intro__glow {
  position: absolute;
  top: 45%;
  left: 50%;
  width: min(84vw, 62rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 48%, rgba(124, 92, 255, 0.24), transparent 46%),
    radial-gradient(circle at 34% 58%, rgba(76, 201, 255, 0.1), transparent 38%),
    radial-gradient(circle at 66% 40%, rgba(79, 216, 255, 0.05), transparent 34%);
  filter: blur(18px);
  transform: translate(-50%, -50%);
  opacity: 0.9;
}

.intro__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(90deg, rgba(207, 196, 230, 0.055) 1px, transparent 1px),
    linear-gradient(rgba(207, 196, 230, 0.04) 1px, transparent 1px);
  background-size: 4.5rem 4.5rem;
  -webkit-mask-image: radial-gradient(ellipse 66% 62% at 50% 44%, #000 0%, transparent 78%);
  mask-image: radial-gradient(ellipse 66% 62% at 50% 44%, #000 0%, transparent 78%);
  opacity: 0.62;
}

.intro__grain {
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140' viewBox='0 0 140 140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.92' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
  mix-blend-mode: soft-light;
  opacity: 0.15;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Chrome
   -------------------------------------------------------------------------- */

.intro__top {
  position: absolute;
  z-index: 6;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 1.5rem;
  padding: clamp(1.15rem, 2.8vw, 1.9rem) var(--gutter);
  transition: opacity 0.45s var(--ease-out);
}

.intro__brand,
.intro__meta,
.intro__coords,
.intro__status,
.intro__skip {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.5rem;
  letter-spacing: 0.17em;
  line-height: 1.5;
  text-transform: uppercase;
}

.intro__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--color-text-muted);
}

.intro__mark {
  width: 0.34rem;
  height: 0.34rem;
  flex: none;
  border-radius: 50%;
  background: var(--color-accent);
  box-shadow: 0 0 12px rgba(79, 216, 255, 0.65);
}

.intro__meta {
  color: var(--color-text-faint);
}

.intro__meta span {
  padding-inline: 0.35rem;
  color: var(--color-line-strong);
}

.intro__heading {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   The object
   -------------------------------------------------------------------------- */

.intro__stage {
  position: absolute;
  z-index: 2;
  inset: 0;
  pointer-events: none;
  animation: intro-stage-in 1.15s 0.12s var(--ease-out) both;
}

.intro__halo {
  position: absolute;
  z-index: 0;
  top: 46%;
  left: 50%;
  width: min(70vw, 42rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(124, 92, 255, 0.2), rgba(76, 201, 255, 0.05) 46%, transparent 70%);
  filter: blur(26px);
  transform: translate(-50%, -50%);
}

.intro__fallback {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: 1;
  transition: opacity 0.6s var(--ease-out), visibility 0s 0s;
}

.intro.is-live .intro__fallback {
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.6s var(--ease-out), visibility 0s 0.6s;
}

.intro.is-fallback .intro__fallback {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.3s var(--ease-out), visibility 0s 0s;
}

.laptop-graphic {
  display: block;
  width: min(80vw, 50rem, 88vh);
  height: auto;
  filter: drop-shadow(0 34px 64px rgba(0, 0, 0, 0.55));
}

.intro__fallback-open {
  display: none;
}

.intro.is-fallback .intro__fallback-open {
  display: block;
}

.intro.is-fallback .intro__fallback-closed {
  display: none;
}

.intro__stage .laptop-graphic {
  animation: intro-laptop-float 7s 1.3s var(--ease-in-out) infinite alternate;
}

.intro.is-live .laptop-graphic,
.intro.is-docking .laptop-graphic {
  animation: none;
}

.intro__canvas {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: block;
  opacity: 0;
  transition: opacity 0.9s var(--ease-out);
}

.intro__canvas canvas {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.intro.is-live .intro__canvas {
  opacity: 1;
}

.intro.is-fallback .intro__canvas {
  visibility: hidden;
  opacity: 0;
}

/* --------------------------------------------------------------------------
   Tap target and prompt
   -------------------------------------------------------------------------- */

.intro__tapzone {
  position: absolute;
  z-index: 5;
  inset: 0;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 0.5s var(--ease-out),
    visibility 0s linear 0.5s;
}

.intro.is-ready .intro__tapzone {
  visibility: visible;
  opacity: 1;
  transition:
    opacity 0.5s var(--ease-out),
    visibility 0s linear 0s;
}

.intro__trigger {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(92vw, 64rem);
  height: min(78vh, 45rem);
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  transform: translate(-50%, -50%);
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}

.intro__trigger:focus {
  outline: none;
}

.intro__prompt {
  position: absolute;
  bottom: clamp(0.4rem, 7vh, 4.5rem);
  left: 50%;
  display: inline-flex;
  align-items: center;
  gap: 0.72rem;
  padding: 0.68rem 1.15rem 0.68rem 0.85rem;
  border: 1px solid rgba(207, 196, 230, 0.26);
  border-radius: 999px;
  background: rgba(11, 5, 22, 0.58);
  text-align: left;
  white-space: nowrap;
  transform: translateX(-50%);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  transition:
    border-color var(--duration-base) var(--ease-out),
    background var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out);
}

.intro__trigger:hover .intro__prompt,
.intro__trigger:focus-visible .intro__prompt {
  border-color: rgba(79, 216, 255, 0.55);
  background: rgba(18, 10, 36, 0.82);
  transform: translateX(-50%) translateY(-2px);
}

.intro__trigger:focus-visible .intro__prompt {
  outline: 2px solid var(--color-accent);
  outline-offset: 4px;
}

.intro__prompt-dot {
  width: 0.42rem;
  height: 0.42rem;
  flex: none;
  border-radius: 50%;
  background: var(--color-accent);
  box-shadow: 0 0 0 0 rgba(79, 216, 255, 0.5);
  animation: intro-signal 2.4s var(--ease-out) infinite;
}

.intro__prompt-copy {
  display: grid;
  gap: 0.12rem;
}

.intro__prompt-copy b {
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: 0.55rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  line-height: 1.2;
  text-transform: uppercase;
}

.intro__prompt-copy i {
  color: var(--color-text-faint);
  font-family: var(--font-mono);
  font-size: 0.46rem;
  font-style: normal;
  letter-spacing: 0.13em;
  line-height: 1.2;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Footer chrome
   -------------------------------------------------------------------------- */

.intro__status {
  position: absolute;
  z-index: 6;
  bottom: clamp(1.15rem, 3vh, 1.8rem);
  left: var(--gutter);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--color-text-faint);
  transition: opacity 0.45s var(--ease-out);
}

.intro__status-dot {
  width: 0.3rem;
  height: 0.3rem;
  flex: none;
  border-radius: 50%;
  background: var(--color-accent);
  animation: intro-signal 2.6s var(--ease-out) infinite;
}

.intro.is-fallback .intro__status-dot {
  background: #ffb15c;
  animation: none;
}

.intro__foot {
  position: absolute;
  z-index: 6;
  right: var(--gutter);
  bottom: clamp(1.15rem, 3vh, 1.8rem);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.2rem);
  transition: opacity 0.45s var(--ease-out);
}

.intro__coords {
  color: var(--color-text-faint);
  letter-spacing: 0.14em;
}

.intro__skip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0;
  border: 0;
  border-bottom: 1px solid rgba(207, 196, 230, 0.24);
  background: none;
  color: var(--color-text-muted);
  letter-spacing: 0.16em;
  cursor: pointer;
  transition: color var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out);
}

.intro__skip:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.intro__skip:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 4px;
}

/* --------------------------------------------------------------------------
   State changes
   -------------------------------------------------------------------------- */

.intro.is-opening .intro__tapzone,
.intro.is-docking .intro__tapzone {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 0.3s var(--ease-out),
    visibility 0s linear 0.3s;
}

.intro.is-opening .intro__skip,
.intro.is-docking .intro__skip {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

.intro.is-docking .intro__top,
.intro.is-docking .intro__status,
.intro.is-docking .intro__foot {
  opacity: 0;
}

.intro.is-docking .intro__halo {
  opacity: 0;
  transition: opacity 0.9s var(--ease-out);
}

.intro.is-docking .intro__grid,
.intro.is-docking .intro__grain {
  opacity: 0;
  transition: opacity 0.9s var(--ease-out);
}

/* The reference frame gives way as the object becomes part of the page. */
.intro__top::after,
.intro__status::before {
  content: none;
}

/* --------------------------------------------------------------------------
   Motion
   -------------------------------------------------------------------------- */

@keyframes intro-stage-in {
  from {
    opacity: 0;
    transform: translateY(26px) scale(0.985);
    filter: blur(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}

@keyframes intro-laptop-float {
  0% {
    transform: translateY(7px) rotate(-0.25deg);
  }
  100% {
    transform: translateY(-9px) rotate(0.25deg);
  }
}

@keyframes intro-signal {
  0% {
    box-shadow: 0 0 0 0 rgba(79, 216, 255, 0.45);
  }
  60% {
    box-shadow: 0 0 0 6px rgba(79, 216, 255, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(79, 216, 255, 0);
  }
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 48rem) {
  .intro__meta,
  .intro__coords {
    display: none;
  }

  .intro__stage .laptop-graphic {
    width: min(94vw, 40rem, 78vh);
  }

  .intro__trigger {
    width: 100vw;
    height: min(74vh, 38rem);
  }

  .intro__prompt {
    bottom: clamp(0.5rem, 10vh, 4rem);
    padding: 0.62rem 1rem 0.62rem 0.78rem;
  }

  .intro__prompt-copy b {
    font-size: 0.52rem;
  }

  .intro__prompt-copy i {
    font-size: 0.43rem;
  }

  .intro__status {
    letter-spacing: 0.12em;
  }
}

@media (max-height: 34rem) and (orientation: landscape) {
  .intro__prompt {
    bottom: 0.2rem;
  }

  .intro__stage .laptop-graphic {
    width: min(46vw, 34rem, 66vh);
  }

  .intro__top {
    padding-block: 0.8rem;
  }
}

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .intro__stage,
  .intro__stage .laptop-graphic,
  .intro__prompt-dot,
  .intro__status-dot {
    animation: none !important;
  }

  .intro__bg,
  .intro__canvas,
  .intro__fallback,
  .intro__top,
  .intro__status,
  .intro__foot,
  .intro__tapzone,
  .intro__halo,
  .intro__grid,
  .intro__grain {
    transition-duration: 0.01s !important;
  }
}
