/* ============================================================
   FURNILAND LTD — Splash / Preloader
   Background = the hero's own scrolling project-photo mosaic,
   washed pale under white. Full-colour logo. On exit, each of the
   6 real columns simply continues in the direction it's already
   scrolling — the ones moving up keep going up and off-screen,
   the ones moving down keep going down — so nothing is cut through
   an arbitrary line; every strip just carries on its own real,
   already-established motion until it's clear.
   ============================================================ */

html.splash-active,
html.splash-active body {
  overflow: hidden;
  height: 100%;
}

.splash {
  position: fixed;
  inset: 0;
  z-index: 9999;
}

/* ── Scene: the mosaic, fully opaque from the very start — it sits
   hidden behind the opaque intro screen (which paints at a higher
   z-index) the whole time that's up. The reveal is purely the
   intro fading away, never a second layer fading in underneath
   it — so there's no window where both are partially transparent
   and the real page could show through. ── */
.splash__scene {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--off-white);
}
/* The instant the exit starts, drop the scene's own backing so the
   strips sliding away reveal the real page underneath — not this
   off-white fill sitting behind them. */
.splash.is-done .splash__scene { background: transparent; }

/* The shared mosaic component puts a 3px gap between columns for
   its grout-line look on the real hero — but each strip's wash
   only covers its own box, so that gap was never covered by
   anything. Once the scene background goes transparent for the
   exit, that gap becomes a bare seam of the real page showing
   through for the whole slide. Closing it here (scoped to the
   splash only — the real hero keeps its grout lines) removes the
   seam outright instead of trying to cover it after the fact. */
.splash__scene .mosaic__inner { gap: 0; }

.splash__scene .mosaic {
  position: absolute;
  inset: -2%;
  transform: scale(1.09);
  transition: transform 0.85s var(--ease) 0.05s;
}
.splash.is-revealed .splash__scene .mosaic { transform: scale(1); }

/* ── Each column is its own strip so it can exit independently.
   Columns already scrolling up keep going up; columns already
   scrolling down keep going down — a real, staggered, multi-
   directional exit driven by each column's own established
   motion, not a single arbitrary cut line. ── */
.splash__strip {
  position: relative;
  min-width: 0;
  height: 100%;
  overflow: hidden;
  transition: transform 1.05s var(--ease);
}
.splash.is-done .splash__strip:nth-child(1) { transform: translateY(-140%); transition-delay: 0ms; }
.splash.is-done .splash__strip:nth-child(2) { transform: translateY(140%);  transition-delay: 60ms; }
.splash.is-done .splash__strip:nth-child(3) { transform: translateY(-140%); transition-delay: 120ms; }
.splash.is-done .splash__strip:nth-child(4) { transform: translateY(140%);  transition-delay: 180ms; }
.splash.is-done .splash__strip:nth-child(5) { transform: translateY(-140%); transition-delay: 240ms; }
.splash.is-done .splash__strip:nth-child(6) { transform: translateY(140%);  transition-delay: 300ms; }

/* Grout line between columns: painted as an overlay on top of each
   strip's own image (travels with it during the exit) rather than a
   real layout gap, which is exactly what caused the bleed-through
   bug above — a solid line can never expose what's behind it. */
/* A plain white line has no guaranteed contrast — it nearly
   vanishes against the pale, washed-out parts of the mosaic and
   only reads clearly over darker photo content. Framing it with a
   thin dark edge on both sides means there's always a hard contrast
   boundary somewhere in the line, regardless of what's behind it. */
.splash__strip-divider {
  position: absolute;
  inset: 0 auto 0 0;
  width: 5px;
  background: var(--white);
  border-left: 1px solid rgba(14, 13, 12, 0.18);
  border-right: 1px solid rgba(14, 13, 12, 0.18);
  pointer-events: none;
}

/* ── White wash: fades the photography into the background while
   the logo sits over it. Lives inside each strip (not as one
   layer over the whole scene) so it exits together with its own
   strip — nothing is left behind sitting over the revealed page. ── */
.splash__wash {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.8);
  pointer-events: none;
}

/* ── Intro: coloured icon on plain white, shown while the mosaic
   loads invisibly behind it. Once ready, this fades out as the
   mosaic + full logo fade in — so the photography only ever
   appears fully loaded, no ragged pop-in. ── */
.splash__intro {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(circle at 50% 44%, rgba(37, 88, 224, 0.07), transparent 58%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%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"),
    var(--off-white);
  background-blend-mode: normal, overlay, normal;
  background-repeat: no-repeat, repeat, no-repeat;
  transition: opacity 0.4s var(--ease) 0.05s, transform 0.45s cubic-bezier(0.6, 0, 1, 1) 0.05s, filter 0.4s var(--ease) 0.05s;
}
.splash.is-revealed .splash__intro {
  opacity: 0;
  transform: scale(1.8);
  filter: blur(10px);
  pointer-events: none;
}

/* ── A brief flash right at the crossfade instant — gives the
   handoff an actual "moment" instead of a flat dissolve. ── */
.splash__flash {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: radial-gradient(circle at 50% 45%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0) 62%);
  opacity: 0;
  pointer-events: none;
}
.splash.is-revealed .splash__flash {
  animation: splashFlash 0.5s ease-out;
}
@keyframes splashFlash {
  0%   { opacity: 0; }
  20%  { opacity: 1; }
  100% { opacity: 0; }
}

/* ── Badge: blue disc behind the icon, with a single orange arc
   orbiting just outside its rim — reads as "actively loading"
   rather than a decorative burst. ── */
.splash__intro-badge {
  position: relative;
  width: clamp(108px, 14vw, 166px);
  height: clamp(108px, 14vw, 166px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.splash__intro-circle {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, var(--charcoal) 0%, var(--black) 65%, var(--black) 100%);
  box-shadow: 0 30px 60px -16px rgba(0, 0, 0, 0.55), 0 8px 20px rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.35s var(--ease), transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.splash.is-ready .splash__intro-circle { opacity: 1; transform: scale(1); }

.splash__intro-icon {
  position: relative;
  z-index: 1;
  width: 68%;
  height: auto;
  opacity: 0;
  transform: scale(0.4) rotate(-170deg);
  transition: opacity 0.35s var(--ease) 0.05s, transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) 0.05s;
}
.splash.is-ready .splash__intro-icon { opacity: 1; transform: scale(1) rotate(0deg); }

/* The rotation lives on this plain <div> wrapper, not on any SVG-
   internal geometry. Two earlier attempts (rotating the root <svg>,
   then rotating the <circle> via transform-box:fill-box) both
   turned out to depend on how a given browser computes a transform
   origin for SVG content, and that's inconsistent — fill-box on a
   fill:none (stroke-only) shape is ambiguous enough that even
   Chrome got it wrong, not just Safari. A plain HTML div's
   transform-origin (default 50% 50% of its own border-box) has no
   such ambiguity anywhere, so the spin is rotated here instead. */
.splash__intro-arc-spin {
  position: absolute;
  inset: -22%;
  opacity: 0;
  transition: opacity 0.4s var(--ease) 0.15s;
}
.splash.is-ready .splash__intro-arc-spin {
  opacity: 1;
  animation: introArcSpin 2.6s linear infinite;
}
.splash__intro-arc {
  display: block;
  width: 100%;
  height: 100%;
}
.splash__intro-arc-track {
  fill: none;
  stroke: var(--orange);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 92 500;
}
@keyframes introArcSpin {
  from { transform: rotate(-90deg); }
  to   { transform: rotate(270deg); }
}

/* ── Content ── */
.splash__content {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.splash.is-loaded .splash__content {
  opacity: 0;
  transform: translateY(-14px) scale(0.98);
}

/* ── Corner frame ── */
.splash__corner {
  position: absolute;
  width: 22px;
  height: 22px;
  border: 1px solid rgba(35, 33, 32, 0.25);
  opacity: 0;
  transform: scale(0.55);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
  transition-delay: 0.05s;
}
.splash.is-ready .splash__corner { opacity: 1; transform: scale(1); }

.splash__corner--tl { top: clamp(20px, 4vw, 44px); left: clamp(20px, 4vw, 44px); border-right: none; border-bottom: none; }
.splash__corner--tr { top: clamp(20px, 4vw, 44px); right: clamp(20px, 4vw, 44px); border-left: none; border-bottom: none; }
.splash__corner--bl { bottom: clamp(20px, 4vw, 44px); left: clamp(20px, 4vw, 44px); border-right: none; border-top: none; }
.splash__corner--br { bottom: clamp(20px, 4vw, 44px); right: clamp(20px, 4vw, 44px); border-left: none; border-top: none; }

/* ── Logo, phrases and progress form one deliberate column: each
   step narrower than the last, all sharing the same rhythm and
   center line, rather than three independently-sized pieces. ── */
.splash__logo {
  width: clamp(180px, 20vw, 300px);
  height: auto;
  display: block;
  opacity: 0;
  transform: translateY(18px) scale(0.94);
  filter: drop-shadow(0 18px 34px rgba(14, 13, 12, 0.16));
  transition: opacity 0.8s var(--ease), transform 0.9s var(--ease);
  transition-delay: 0.15s;
}
.splash.is-revealed .splash__logo { opacity: 1; transform: translateY(0) scale(1); }

/* ── Rotating brand phrases: each centers on its own width rather
   than stretching to a shared container, so a long phrase never
   wraps — it just sizes and centers itself correctly. ── */
.splash__phrases {
  position: relative;
  margin-top: 24px;
  min-height: 28px;
  max-width: 92vw;
}
.splash__phrase {
  position: absolute;
  left: 50%;
  top: 0;
  max-width: 92vw;
  white-space: nowrap;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.4;
  color: rgba(35, 33, 32, 0.5);
  opacity: 0;
  transform: translate(-50%, 8px);
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}
.splash__phrase.is-active { opacity: 1; transform: translate(-50%, 0); }

@media (max-width: 480px) {
  /* .splash__phrases (the parent) has no explicit width, and its
     only child is position:absolute — removed from normal flow —
     so with nothing in-flow to size against, the parent shrink-
     wraps to near-zero width and sits centered as a single point.
     That's harmless for the desktop rule (left:50% + translateX
     only needs a point to center from), but our left+right anchors
     below need a real width to measure from, not a point — without
     this, they were being measured from that near-zero box, which
     is what pushed the whole line off to one side. */
  .splash__phrases { width: 100%; }
  .splash__phrase {
    left: 16px;
    right: 16px;
    max-width: none;
    transform: translateY(8px);
    font-size: 0.5625rem;
    letter-spacing: 0.05em;
    white-space: normal;
    text-align: center;
  }
  .splash__phrase.is-active { transform: translateY(0); }
}

/* ── Progress line: a "getting ready" fill under the mosaic view,
   timed by JS to run 0→100% across the reveal-hold window so it
   finishes right as the curtain splits. ── */
.splash__progress {
  margin-top: 24px;
  width: min(40vw, 180px);
  height: 2px;
  background: rgba(35, 33, 32, 0.1);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
  transition-delay: 0.15s;
}
.splash.is-revealed .splash__progress { opacity: 1; }
.splash__progress-fill {
  height: 100%;
  width: 0%;
  background: var(--blue);
}

/* ── Accessibility utility ── */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Replicate the real hero's mobile column reduction. The shared rule
   (.mosaic__col:nth-child(n+5)) targets columns as direct siblings,
   which is true on the real hero but not here — each splash column
   is wrapped in its own .splash__strip, making every .mosaic__col an
   only-child, so that rule silently never matches. Without this, all
   6 columns stayed on screen and got crushed painfully thin on
   mobile. Hide the strip itself instead, at the same breakpoints. */
@media (max-width: 768px) {
  .splash__strip:nth-child(n+5) { display: none; }
}
@media (max-width: 480px) {
  .splash__strip:nth-child(n+4) { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .splash { display: none !important; }
  html.splash-active, html.splash-active body { overflow: visible; height: auto; }
}
