/* ==========================================================================
   Alkando — home, scroll-driven sky
   The stage is a tall scroll track; inside it a sticky viewport holds the
   canvas, so scrolling the track scrubs the animation while the picture
   stays pinned to the screen.
   ========================================================================== */

.home {
  width: 100%;
}

/* --- the scroll track --- */

.sky {
  position: relative;
  /* How far you scroll to play the whole sequence. Longer = slower, more
     deliberate scrub; shorter = the day/night arc flies past. */
  height: 360vh;
  background: var(--bg-0);
}

.sky__viewport {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

.sky__canvas {
  display: block;
  width: 100%;
  height: 100%;
  /* Until the first frame is painted this is a flat block of page
     background rather than a white flash. */
  background: var(--bg-0);
  opacity: 0;
  transition: opacity 0.6s ease;
}

.sky.is-painted .sky__canvas {
  opacity: 1;
}

/* --- overlaid content --- */

.sky__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: clamp(24px, 5vh, 56px) 20px;
  pointer-events: none;
  text-align: center;
}

/* --brand-ink and --brand-halo are written by home.js, which samples the
   sky directly behind this element: near-black while the sun is up, pale
   once the moon is, and tinted with the hue of the sky either way. The
   values below are the noon case, used before the first sample lands and
   if scripting never runs at all. The transition is linear because the
   colour is tracking something moving at a constant rate — an eased curve
   would read as the word reacting rather than following. */
.sky__brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.1rem, 2.4vw, 1.5rem);
  letter-spacing: 0.01em;
  color: var(--brand-ink, hsl(250 32% 10%));
  text-shadow: 0 1px 20px var(--brand-halo, hsl(250 30% 97% / 0.45));
  transition: color 300ms linear, text-shadow 300ms linear;
}

.sky__hint {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.sky__hint svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: rgba(255, 255, 255, 0.8);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: skyHint 2.2s ease-in-out infinite;
}

@keyframes skyHint {
  0%, 100% { transform: translateY(0); opacity: 0.55; }
  50% { transform: translateY(5px); opacity: 1; }
}

/* --- progress --- */

.sky__progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: rgba(255, 255, 255, 0.12);
}

.sky__progress-bar {
  height: 100%;
  background: linear-gradient(90deg, var(--coral) 0%, var(--periwinkle) 60%, var(--purple-mid) 100%);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

/* --- loader --- */

.sky__loader {
  position: absolute;
  left: 50%;
  bottom: clamp(24px, 5vh, 56px);
  transform: translateX(-50%);
  width: 120px;
  height: 2px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.16);
  overflow: hidden;
  transition: opacity 0.4s ease;
}

.sky__loader::after {
  content: "";
  display: block;
  height: 100%;
  width: 100%;
  background: #fff;
  transform: scaleX(var(--loaded, 0));
  transform-origin: 0 50%;
  transition: transform 0.2s linear;
}

.sky.is-ready .sky__loader {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .sky__hint svg {
    animation: none;
  }
  .sky__canvas {
    transition: none;
  }
  .sky__brand {
    transition: none;
  }
}

/* ---------------------------------------------------------------------- */
/* Coming-soon overlay on the sky (index)                                   */
/* ---------------------------------------------------------------------- */

/* Three rows rather than space-between: the middle row absorbs the slack,
   so the headline and meter can be parked low in the frame instead of dead
   centre, where they were sitting across the bird's head. */
.sky__overlay--launch {
  display: grid;
  /* The column has to be declared. Without it the implicit column is sized
     to the widest item, and justify-items then centres everything inside
     that narrow column rather than across the frame. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  justify-items: center;
  align-items: start;
}

.sky__overlay--launch .launch {
  align-self: end;
  padding-bottom: clamp(28px, 7vh, 78px);
}

/* Sits high and centred. Colour is inherited from .sky__brand, which is
   sampled off the sky — the word is a blue-black at noon and a pale
   moonlit lavender at night, so it never fights the picture behind it. */
.sky__overlay--launch {
  padding-top: clamp(12px, 2.4vh, 28px);
}

.sky__overlay--launch .sky__brand {
  justify-self: center;
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.005em;
}

.launch {
  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(20px, 3.5vh, 34px);
}

.launch__headline {
  margin: 0;
  font-family: var(--font-display);
  /* 600 rather than 700, opened up with tracking: at display size the
     heavier cut reads as shouty over soft artwork, while the lighter one
     with air between the letters reads as composed. */
  font-weight: 600;
  font-size: clamp(2.1rem, 5.8vw, 3.6rem);
  line-height: 1.1;
  letter-spacing: 0.005em;
  color: #fff;
  /* Two layers doing different jobs: a tight dark one for edge contrast
     against pale noon sky, and a wide soft one that reads as a halo rather
     than a drop shadow. A single large shadow does neither well. */
  text-shadow:
    0 1px 3px rgba(10, 6, 24, 0.4),
    0 10px 44px rgba(10, 6, 24, 0.5);
  animation: launchTitleIn 700ms var(--ease-out-strong) both;
}

@keyframes launchTitleIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* A glass capsule rather than a bare rail. The sky behind runs from bright
   noon to deep night, and a translucent dark pill keeps the meter and its
   number legible against both without changing colour. */
.launch__meter {
  animation: launchTitleIn 700ms var(--ease-out-strong) 90ms both;
  display: flex;
  align-items: center;
  gap: 14px;
  width: min(84vw, 380px);
  padding: 11px 16px;
  border-radius: 999px;
  background: rgba(12, 8, 24, 0.34);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(16px) saturate(1.2);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  box-shadow:
    0 10px 34px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

.launch__track {
  position: relative;
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  overflow: hidden;
}

.launch__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: calc(var(--progress-num) * 1%);
  border-radius: inherit;
  background: linear-gradient(90deg, var(--coral) 0%, var(--periwinkle) 62%, var(--purple-mid) 100%);
  box-shadow: 0 0 12px rgba(255, 140, 156, 0.55);
  transform-origin: 0 50%;
  /* Fills once on arrival. Strong ease-out so the movement is visible from
     the first frame; the page is seen once, so this is the rare case with
     room for a longer, more deliberate reveal. */
  animation: launchFill 1400ms var(--ease-out-strong);
}

/* A brighter cap at the leading edge — gives the fill a head instead of a
   flat cut, and is what makes it read as charged rather than drawn. */
.launch__fill::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  transform: translate(50%, -50%);
  background: #fff;
  box-shadow: 0 0 10px 2px rgba(255, 255, 255, 0.75);
}

/* Slow highlight sweeping the filled portion. Constant motion, so linear —
   anything eased would read as a pulse instead of a travelling sheen. */
.launch__track::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 40%;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  transform: translateX(-100%);
  animation: launchSheen 3.2s linear 1.4s infinite;
}

@keyframes launchFill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes launchSheen {
  from { transform: translateX(-100%); }
  /* Long tail so the sheen rests off-screen between passes rather than
     scrubbing back and forth continuously. */
  55%, to { transform: translateX(320%); }
}

.launch__value {
  margin: 0;
  min-width: 3.2ch;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.92rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: #fff;
  text-align: right;
}

/* Printed from the same variable that drives the fill, so the label and the
   bar can never disagree. */
.launch__value::after {
  counter-reset: pct var(--progress-num);
  content: counter(pct) "%";
}

@media (prefers-reduced-motion: reduce) {
  .launch__fill,
  .launch__track::after {
    animation: none;
  }
  .launch__track::after {
    display: none;
  }
  /* Keep the fade, drop the movement. */
  .launch__headline,
  .launch__meter {
    animation-name: launchFadeIn;
  }
}

@keyframes launchFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
