/* ============================================================
   scroll.css — scroll-reveal About + Gallery beneath the hero.
   Loaded AFTER the other stylesheets so these rules win on
   source-order (equal specificity). Nothing above is restyled;
   this only (a) lets the page scroll, (b) pins #app to 100vh,
   (c) fades hero chrome once you scroll past it, and (d) styles
   the two new sections.
   ============================================================ */

/* ── Enable scrolling (overrides body/html overflow:hidden in styles.css) ── */
html, body {
  overflow-x: hidden;
  overflow-y: auto;
  height: auto;
  min-height: 100%;
  scroll-behavior: smooth;
}

/* ── Scene-matched dark scrollbar ──
   The TRACK is painted the page's own background colour per scene so the
   channel vanishes into the page (no default light-gray backdrop, no seam
   from the thumb's transparent border). Only the thumb reads: a dark
   teal-slate for the sea, dark lavender-slate for christmas. Cross-fades
   on scene toggle. The thumb's transparent border matches the track via
   border-color so its rounded edges don't reveal a lighter strip. */
html {
  scrollbar-width: thin;                              /* Firefox */
  scrollbar-color: #35505e #0f1a24;
}
html::-webkit-scrollbar { width: 11px; background: #0f1a24; }
html::-webkit-scrollbar-track,
html::-webkit-scrollbar-corner {
  background: #0f1a24;                                /* = sea page bottom tone */
}
html::-webkit-scrollbar-thumb {
  background: #2f4653;                                /* dark sea teal-slate */
  border-radius: 6px;
  border: 2px solid #0f1a24;                          /* blend edges into track */
  background-clip: content-box;
  transition: background-color 1.1s ease, border-color 1.1s ease;
}
html::-webkit-scrollbar-thumb:hover {
  background: #416072;
  background-clip: content-box;
}

/* Christmas: dark lavender-slate thumb on the night-scene base tone */
html.xmas-on { scrollbar-color: #3a3f5c #1A2740; }
html.xmas-on::-webkit-scrollbar,
html.xmas-on::-webkit-scrollbar-track,
html.xmas-on::-webkit-scrollbar-corner {
  background: #1A2740;                                /* = christmas scene base */
}
html.xmas-on::-webkit-scrollbar-thumb {
  background: #343954;                                /* dark snow lavender-slate */
  border-color: #1A2740;
  background-clip: content-box;
}
html.xmas-on::-webkit-scrollbar-thumb:hover {
  background: #4a5178;
  background-clip: content-box;
}

/* Base behind everything so the fixed koi canvas reads well below
   the hero. This must tonally MATCH the bottom of #app's sea gradient
   (hsl(215,44%,12%)) — otherwise a visible band appears at the 100vh
   fold where #app ends and the body backdrop takes over. A fixed
   gradient keeps the sea tone continuous down the whole page. */
body {
  background: linear-gradient(
    to bottom,
    hsl(215, 40%, 11%) 0%,
    hsl(213, 38%, 8%) 60%,
    #04090f 100%
  ) no-repeat;
  background-attachment: fixed;
}

/* Pin the hero to exactly one viewport. The koi canvas inside
   is position:fixed, so the whole sea scene stays painted behind
   every lower section as you scroll (it never scrolls away).
   The Christmas scene and Discord panel are overridden to absolute
   below, so they scroll away with the hero leaving a clean gallery. */
#app {
  height: 100vh;
  min-height: 100vh;
}

/* KILL THE SEAM AT 100vh.
   #app's decorative layers (base gradient + the warm ambient ::before
   glow) only cover the hero's 100vh box, so below the fold the water
   looks tonally different → a hard band at 100vh. Promote the ambient
   glow to a fixed, full-viewport layer so it tints the whole page
   uniformly at every scroll position, and drop #app's own opaque
   gradient (the fixed koi canvas already IS the water everywhere). */
#app { background: transparent; animation: none; }
#app::before {
  position: fixed;
  inset: 0;
  z-index: 2;           /* above the fixed koi canvas, below the UI/sections */
}


/* ── Hero → header transition ──
   Driven by --scroll-progress (0 at top → 1 once past the hero),
   set on :root by scroll-page.js. The koi scene stays fixed; only
   the "cian" wordmark travels. It slides up, shrinks, and fades to
   a subtle small-caps header at the top. The Christmas scene and
   panel scroll away with the hero (position: absolute, see below). */
:root { --scroll-progress: 0; }

.wordmark-container {
  /* Interpolate vertical position (50% → ~8% of viewport) and scale
     (1 → 0.46) across the scroll progress. Docks lower so the whole
     wordmark clears the top edge, stays large enough to read, and keeps
     most of its opacity so it reads as a proper header. */
  top: calc(50% - (50% - 8%) * var(--scroll-progress));
  opacity: calc(1 - var(--scroll-progress) * 0.15);
  transform:
    translate(-50%, -50%)
    scale(calc(1 - 0.54 * var(--scroll-progress)));
  /* Fixed positioning keeps it pinned; z-index above the sections. */
  z-index: 60;
  transition: none; /* progress updates every frame — no lag desired */
}

/* Docked header: a drop shadow so the wordmark stands out cleanly against
   the busy photos / snow behind it. */
body.past-hero .wordmark {
  text-shadow:
    0 2px 12px rgba(0, 0, 0, 0.55),
    0 1px 3px  rgba(0, 0, 0, 0.45);
}

/* Once docked at the top, keep it clickable but out of the way. */
body.past-hero .wordmark-container {
  pointer-events: auto;
}

/* ── Christmas scene scrolls away with the hero ──
   #xmas-scene is position:fixed in christmas.css (fills the viewport
   as a backdrop). Override to absolute so it stays inside #app and
   scrolls away when you enter the gallery — the photos underneath
   are then visible with the koi pond as their background. */
#xmas-scene {
  position: absolute !important;
  overflow: visible !important;  /* don't clip the fixed snow layers */
}

/* But keep the snow GROUND pinned — the 3 flat snow bars from the
   Christmas scene recreated as standalone fixed layers so they persist
   behind the gallery. JS injects the container (#snow-ground) with 3
   children matching the original colors + clip-paths. z-index 1 keeps
   it below gallery sections (z-index 2) so photos scroll over it. */
/* Full-viewport snow backdrop (not just a bottom strip): the darkest band
   colour fills the WHOLE screen so the snowfield extends infinitely behind
   the gallery — no dark gap, no stripes crossing the photos. The two lighter
   bands stack at the bottom as the receding horizon, same palette + slanted
   clip-paths as the hero scene, so it reads as one continuous snow world. */
#snow-ground {
  position: fixed;
  inset: 0;                /* fill the whole viewport, top to bottom */
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
  /* Just the hero's 3rd (front) snow bar, extended infinitely: one flat
     palest tone filling the whole screen behind the gallery. No sub-bands —
     a fixed banded horizon here would sit at a constant screen height and
     read as a seam crossing the photos while you scroll. The hero scene
     keeps its own 3-band horizon; its front bar is this exact colour, so the
     fold between hero and gallery is seamless. */
  background: #B4C2DF;     /* = hero front bar colour, extended over everything */
  /* Only present in Christmas mode. Hidden (and cheap) in sea mode; fades
     in/out in step with #xmas-scene when #app.xmas-on toggles. */
  opacity: 0;
  visibility: hidden;
  transition: opacity 2.2s ease, visibility 0s linear 2.2s;
}
#app.xmas-on ~ #snow-ground {
  opacity: 1;
  visibility: visible;
  transition: opacity 1.1s ease, visibility 0s linear 0s;
}
/* 3 bands anchored to the bottom — same colours + heights (24/18/12vh) and
   darkest → palest order as the hero ground, each fading to transparent at
   its TOP edge (soft gradient, no hard steps) so they melt together and into
   the palest base above. Same layered horizon as the hero set. */
#snow-ground .sg-back {
  position: absolute;
  bottom: 0; left: 0;
  width: 100%;
  height: 24vh;
  background: linear-gradient(to top, #8C9CC2 45%, rgba(140,156,194,0) 100%);
}
#snow-ground .sg-mid {
  position: absolute;
  bottom: 0; left: 0;
  width: 100%;
  height: 18vh;
  background: linear-gradient(to top, #A0AFCF 45%, rgba(160,175,207,0) 100%);
}
#snow-ground .sg-front {
  position: absolute;
  bottom: 0; left: 0;
  width: 100%;
  height: 12vh;
  background: linear-gradient(to top, #B4C2DF 45%, rgba(180,194,223,0) 100%);
}
/* Keep the snow clean: drop the warm sea-sunset ambient glow while in
   Christmas mode so it doesn't tint the lavender snowfield orange. */
#app.xmas-on::before { opacity: 0; }

/* Root cause of the "snow colour doesn't match when scrolling" seam:
   .scroll-section::before is a dark legibility scrim over the busy koi sea.
   The hero above the fold has no scrim, so in snow mode the scrim dims the
   gallery's snow and a tone step appears at the fold. The snow is a calm,
   light backdrop (photos carry their own borders/shadows), so drop the scrim
   while xmas-on — snow now reads identically above and below the fold. */
#app.xmas-on ~ .scroll-section::before { opacity: 0; }

#xmas-snow-1 {
  position: fixed !important;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 999;
  pointer-events: none;
}

/* Once past the hero, both the social nav AND the presence panel have
   scrolled away with the hero scene (panel is absolutely positioned to
   #app, see below). The gallery below is a plain masonry — nothing to
   wrap around. */
#social-nav {
  transition:
    opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

body.past-hero #social-nav {
  opacity: 0;
  transform: translateX(-50%) translateY(-12px);
  pointer-events: none;
}

/* The presence panel is part of the HERO scene: absolutely anchored
   to #app (the hero container) so it scrolls away naturally with the
   koi/wordmark, instead of staying fixed over the gallery. Once you're
   in the gallery there's nothing for photos to wrap around — the
   masonry below just flows normally. */
#bottom-panel {
  position: absolute !important;
  bottom: 20px;
  left: 20px;
  z-index: 55;
  /* Match what layout.css gives desktop; the !important overrides the
     fixed rule there. Mobile media queries in layout.css still apply. */
}
/* On mobile the panel is centred; keep that behaviour but absolute. */
@media (max-width: 768px) {
  #bottom-panel {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }
}



/* ============================================================
   Shared section scaffolding
   ============================================================ */
.scroll-section {
  position: relative;
  width: 100%;
  padding: clamp(80px, 14vh, 180px) clamp(20px, 6vw, 80px);
  box-sizing: border-box;
}

/* Sections are transparent so the live koi scene shows through.
   A soft vertical scrim eases content out of the sea — it FADES IN
   from fully transparent at the very top so there's no hard seam
   against the hero, then settles to a gentle darkening for legibility. */
.scroll-section::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(4, 9, 15, 0.20) 18%,
    rgba(4, 9, 15, 0.42) 50%,
    rgba(4, 9, 15, 0.42) 100%
  );
  pointer-events: none;
  z-index: 1;
}

/* Section heading — uppercase eyebrow, matches .activity-title vibe */
.section-eyebrow {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: rgba(143, 188, 187, 0.65);
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.section-eyebrow::before {
  content: '';
  width: 22px;
  height: 1px;
  background: rgba(143, 188, 187, 0.4);
}


/* ============================================================
   About section
   ============================================================ */
#about {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 100vh;
}

.about-card {
  position: relative;
  z-index: 2;
  width: min(620px, 100%);
  padding: clamp(36px, 6vw, 64px) clamp(28px, 5vw, 52px);
  background: linear-gradient(145deg, rgba(8, 14, 26, 0.90), rgba(4, 8, 18, 0.82));
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 24px;
  box-shadow:
    0 12px 44px rgba(0, 0, 0, 0.55),
    0 2px 8px rgba(0, 0, 0, 0.25),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  text-align: left;
}

.about-card .section-eyebrow {
  margin-bottom: 28px;
}

/* The empty typing area — a bordered box holding the live caret
   and the faux-typed text. */
.typing-area {
  min-height: 2.6em;
  padding: 18px 20px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  display: flex;
  align-items: center;
  font-size: clamp(1rem, 2.2vw, 1.25rem);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.85);
  line-height: 1.4;
  word-break: break-word;
}

.typing-text {
  white-space: pre-wrap;
}

.typing-caret {
  display: inline-block;
  width: 2px;
  height: 1.1em;
  margin-left: 3px;
  background: #8fbcbb;
  border-radius: 1px;
  animation: caret-blink 1.05s step-end infinite;
  transform: translateY(2px);
  flex-shrink: 0;
}

@keyframes caret-blink {
  0%, 50%      { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

/* Discord-style "is typing…" three-dot indicator under the box */
.typing-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.42);
  font-weight: 500;
}

.typing-dots {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.typing-dots span {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #8fbcbb;
  opacity: 0.5;
  animation: typing-bounce 1.3s infinite ease-in-out;
}
.typing-dots span:nth-child(2) { animation-delay: 0.18s; }
.typing-dots span:nth-child(3) { animation-delay: 0.36s; }

@keyframes typing-bounce {
  0%, 60%, 100% { transform: translateY(0);   opacity: 0.35; }
  30%           { transform: translateY(-4px); opacity: 1;    }
}


/* ============================================================
   Gallery section — scattered collage floating over the live
   koi scene. Tiles overlap slightly and each carries a small
   random tilt (--tilt) + vertical lift (--lift) set inline by
   scroll-page.js, giving a scrapbook pile feel. On hover a tile
   lifts flat and rises above its neighbours.
   ============================================================ */
#gallery {
  /* Small top room so the first row starts close under the hero fold. */
  padding-top: clamp(24px, 4vh, 48px);
  padding-bottom: clamp(80px, 12vh, 160px);
  position: relative;
  z-index: 2;
  min-height: 100vh;
}

/* ── Masonry via CSS multi-column ──
   Pure CSS, no JS positioning: photos flow into columns top-to-bottom
   and wrap into the next column when full. break-inside:avoid keeps
   each tile intact (never split across columns → no overlaps ever).
   The number of columns adapts to viewport width. The Discord widget
   lives in the hero above and scrolls away before this section, so the
   masonry never has to wrap around anything. */
#gallery-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
  column-count: 5;
  column-gap: 14px;
}
@media (max-width: 1200px) { #gallery-grid { column-count: 4; } }
@media (max-width: 900px)  { #gallery-grid { column-count: 3; } }
@media (max-width: 620px)  { #gallery-grid { column-count: 2; } }
@media (max-width: 400px)  { #gallery-grid { column-count: 1; } }

.collage-item {
  /* break-inside keeps each tile whole inside its column. */
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  display: block;
  margin-bottom: 14px;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
  /* Static scrapbook lean. TranslateZ promotes to its own GPU layer so
     the compositor handles it without main-thread reflow. */
  transform: rotate(var(--tilt, 0deg)) translateZ(0);
  will-change: transform;
  /* Only animate the hover lift — animating transform would re-composite
     every paint and is a big source of scroll jank with many tiles. */
  transition: box-shadow 0.25s ease, transform 0.25s ease;
}

.collage-item:hover,
.collage-item:focus-within {
  transform: rotate(0deg) scale(1.04) translateZ(0);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.5);
}


.collage-item img,
.collage-item video {
  width: 100%;
  height: auto;          /* natural aspect ratio drives tile height */
  display: block;
  vertical-align: bottom;
}

/* Little play glyph so videos read as videos in the pile. */
.collage-item.is-video::after {
  content: '\f04b'; /* fa-play */
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  position: absolute;
  right: 10px;
  bottom: 8px;
  font-size: 0.7rem;
  color: rgba(255, 255, 255, 0.85);
  background: rgba(0, 0, 0, 0.45);
  padding: 5px 7px;
  border-radius: 50%;
  pointer-events: none;
  backdrop-filter: blur(3px);
}

/* The empty-state placeholder card shown when no photos are set */
#gallery-empty {
  width: 100%;
  padding: 48px 28px;
  border-radius: 16px;
  border: 1px dashed rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.02);
  text-align: center;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: rgba(255, 255, 255, 0.5);
  font-size: 0.95rem;
  line-height: 1.6;
}
#gallery-empty strong { color: rgba(143, 188, 187, 0.85); font-weight: 600; }
#gallery-empty code {
  background: rgba(255, 255, 255, 0.06);
  padding: 2px 7px;
  border-radius: 5px;
  font-size: 0.85em;
  color: rgba(255, 255, 255, 0.7);
}



/* ============================================================
   Reduced motion — match the pattern in styles.css
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html, body { scroll-behavior: auto; }
  .typing-caret,
  .typing-dots span { animation: none; }
  #bottom-panel,
  #social-nav { transition: opacity 0.01ms; }
  .collage-item { transition: box-shadow 0.2s ease; }
  .collage-item:hover,
  .collage-item:focus-within { transform: none; }
}
