/* ===========================================================================
   Forever Sandy VB — the motion layer.
   Loaded on top of styles.css for the /motion preview only, so the plain site
   is untouched. Bahama Bucks' trick is depth: decorative objects drift behind
   the content at different rates, and everything arrives rather than just
   being there. Neumorphism is quiet, so the movement stays slow and small —
   the point is that the page feels alive, not that it performs.
   =========================================================================== */

/* The hero's white wash sits above the drift layer and turns the balls gray.
   On the motion page the wash pulls back so they keep their color. */
.hero .dune { opacity: .55; }

/* ---- the drifting background -------------------------------------------- */
.drift { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.drift .obj { position: absolute; will-change: transform; }
.drift .ball { filter: drop-shadow(6px 10px 16px rgba(15, 42, 64, .16)); }
.drift .foam {
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, rgba(255,255,255,.95), rgba(14,144,198,.13) 70%, transparent 72%);
}

/* Each object gets its own slow loop; the parallax offset is layered on top of
   this by script, via a CSS variable, so the two never fight. */
.drift .obj { transform: translate3d(0, var(--py, 0px), 0); }
.drift .obj > * { display: block; animation: sway var(--dur, 14s) ease-in-out infinite; animation-delay: var(--delay, 0s); }
@keyframes sway {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
  50%      { transform: translate3d(14px, -26px, 0) rotate(9deg); }
}

/* ---- things arrive ------------------------------------------------------- */
[data-rise] {
  opacity: 0; transform: translate3d(0, 26px, 0);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  transition-delay: var(--rise-delay, 0s);
}
[data-rise].seen { opacity: 1; transform: none; }

/* Lists are replaced wholesale on every data change, which restarts the
   animation for free — no observer needed for these. */
.tour-card, .album, #gearList > .card, .chat-card, .day-panel > *, #dayPanel .sess {
  animation: rise .55s var(--ease) both;
}
.tour-card:nth-child(2), .album:nth-child(2), #gearList > .card:nth-child(2), .chat-card:nth-child(2) { animation-delay: .07s; }
.tour-card:nth-child(3), .album:nth-child(3), #gearList > .card:nth-child(3) { animation-delay: .14s; }
.album:nth-child(4) { animation-delay: .21s; }
.album:nth-child(5) { animation-delay: .28s; }
@keyframes rise { from { opacity: 0; transform: translate3d(0, 22px, 0); } to { opacity: 1; transform: none; } }

.cal-cell.has { animation: pop .4s var(--ease) both; animation-delay: calc(var(--i, 0) * 9ms); }
@keyframes pop { from { opacity: 0; transform: scale(.86); } to { opacity: 1; transform: none; } }

/* ---- the hero ------------------------------------------------------------ */
.hero-shot { will-change: transform; }
.hero-shot img { transform: scale(1.06); transition: transform 1.4s var(--ease); }
.hero.ready .hero-shot img { transform: scale(1); }
.hero-badge { animation: bob 7s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(-9px) rotate(-3deg); } }

.scroll-cue {
  display: inline-flex; align-items: center; gap: 9px; margin: 26px 0 0;
  font-size: 12px; letter-spacing: .18em; text-transform: uppercase; font-weight: 700; color: var(--ink-45);
}
.scroll-cue i { display: block; animation: nudge 1.8s ease-in-out infinite; }
@keyframes nudge { 50% { transform: translateY(6px); } }

/* ---- the wave breaks actually move --------------------------------------- */
.tide { overflow: hidden; }
.tide svg { width: 200%; animation: roll 22s linear infinite; }
.tide.flip svg { animation-duration: 30s; animation-direction: reverse; }
@keyframes roll { to { transform: translateX(-50%); } }
.tide.flip svg { transform-origin: center; }

/* ---- touchable things answer back ---------------------------------------- */
.card, .tour-card, .album-cover, .chat-card { transition: box-shadow .3s var(--ease), transform .3s var(--ease); }
.tour-card:hover { transform: translateY(-4px) scale(1.006); }
.chat-card:hover { transform: translateY(-3px); box-shadow: var(--lift-lg); }
.album:hover .album-cover { transform: translateY(-5px) scale(1.012); }
.btn:hover, .nub:hover { transform: translateY(-2px); }
.btn:active, .nub:active { transform: translateY(1px) scale(.98); }
.size:hover, .chip:hover { transform: translateY(-2px); }
.cal-cell.has:hover { transform: translateY(-2px) scale(1.04); }

/* ---- the bar tightens once you've moved ---------------------------------- */
.bar { transition: padding .3s var(--ease), box-shadow .3s var(--ease); }
.bar.tight { padding-top: 5px; padding-bottom: 5px; box-shadow: 0 10px 26px -18px var(--shade); }
.bar.tight .bar-logo { width: 32px; height: 32px; transition: width .3s var(--ease), height .3s var(--ease); }
.bar-logo { transition: width .3s var(--ease), height .3s var(--ease); }

/* ---- section headings get a moving underline ----------------------------- */
.sec .h2 { position: relative; display: inline-block; }
.sec .h2::after {
  content: ""; position: absolute; left: 0; bottom: -6px; height: 4px; width: 100%;
  border-radius: 3px; background: linear-gradient(90deg, var(--sea), var(--optx));
  transform: scaleX(0); transform-origin: left; transition: transform .8s var(--ease) .15s;
}
.sec .h2.seen::after { transform: scaleX(1); }

/* Motion is a preference, not a given. */
@media (prefers-reduced-motion: reduce) {
  .drift, .scroll-cue i { display: none; }
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; }
  [data-rise] { opacity: 1 !important; transform: none !important; }
  .hero-shot img { transform: none; }
  .sec .h2::after { transform: scaleX(1); }
}

/* ===========================================================================
   Dark / light flips and the horizontal rail.
   The palette is three ground variables and everything else derives from them,
   so a section goes dark by redeclaring those three — every card, button and
   inset shadow inside it reshades itself.
   =========================================================================== */
.sec-dark, .panel-dark {
  --ground: #123A56; --paper: #1B5075; --shade: #0A2639;
  --ink: #EAF3F9;
  --ink-70: rgba(234,243,249,.78); --ink-45: rgba(234,243,249,.56); --ink-25: rgba(234,243,249,.28);
  --sea-ink: #8FD3F4; --optx-ink: #F2CE1E; --navy: #EAF3F9;
  /* These have to be redeclared wherever the ground changes. A custom property
     whose value contains var() is substituted where it is DECLARED, so the
     copies inherited from :root still carry the light palette's white
     highlight — which is why dark cards were getting a white halo. */
  --lift:     7px 7px 15px var(--shade), -7px -7px 15px var(--paper);
  --lift-sm:  4px 4px 9px var(--shade), -4px -4px 9px var(--paper);
  --lift-lg:  14px 14px 30px var(--shade), -12px -12px 26px var(--paper);
  --sink:     inset 5px 5px 11px var(--shade), inset -5px -5px 11px var(--paper);
  --sink-sm:  inset 3px 3px 7px var(--shade), inset -3px -3px 7px var(--paper);
  background: var(--ground); color: var(--ink);
}
.sec-dark .eyebrow, .panel-dark .eyebrow { color: var(--sea-ink); }
.sec-dark .ink-sea, .panel-dark .ink-sea { color: var(--sea-ink); }
/* The underline gradient needs to read on navy too. */
.sec-dark .h2::after, .panel-dark .h2::after { background: linear-gradient(90deg, var(--sea-ink), var(--optx)); }

/* ---- the rail ------------------------------------------------------------ */
/* Tall enough to give the pinned panel room to travel: one screen of scroll
   per panel after the first. */
.rail { position: relative; height: 400vh; }
.rail-pin { position: sticky; top: 0; height: 100vh; overflow: hidden; }
.rail-track { display: flex; height: 100%; will-change: transform; }

.panel {
  flex: 0 0 100vw; height: 100vh; display: grid; align-items: center;
  padding: clamp(70px, 9vh, 110px) 0 clamp(40px, 6vh, 70px);
  background: var(--ground); color: var(--ink);
}
.panel-in {
  width: 100%; max-width: var(--wrap); margin: 0 auto;
  padding: 0 var(--pad); max-height: 100%; overflow: hidden;
}
.panel .h2 { margin-bottom: 10px; }
.panel .lede { margin-bottom: 20px; }
/* A panel is one screen; long content scrolls inside itself rather than
   spilling out of the pinned frame. */
.panel #albumView { max-height: 46vh; overflow-y: auto; }
.panel .gear-row { max-height: 52vh; overflow-y: auto; }
.panel .pay-wrap { display: grid; grid-template-columns: 1fr auto; gap: 30px; align-items: center; }
@media (max-width: 820px) { .panel .pay-wrap { grid-template-columns: 1fr; } .panel .pay-art { display: none; } }

/* how far through the rail you are */
.rail-progress {
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: rgba(127,160,185,.22); z-index: 3;
}
.rail-progress i { display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--sea), var(--optx)); transition: width .12s linear; }

/* ---- phones don't get pinned ---------------------------------------------
   Scroll-jacking a thumb is miserable. The same four panels become a swipeable
   carousel with snap points, which is what the gesture already expects. */
@media (max-width: 900px), (prefers-reduced-motion: reduce) {
  .rail { height: auto; }
  .rail-pin { position: static; height: auto; overflow: visible; }
  .rail-track {
    /* Without this every panel stretches to the tallest one (Gear, which stacks
       three cards here) and the short ones end in a slab of empty colour. */
    align-items: flex-start;
    height: auto; overflow-x: auto; scroll-snap-type: x mandatory;
    gap: 14px; padding: 0 16px 18px; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .rail-track::-webkit-scrollbar { display: none; }
  .panel {
    flex: 0 0 88vw; height: auto; min-height: 60vh; scroll-snap-align: center;
    border-radius: var(--r); padding: clamp(24px, 5vw, 34px) 0;
  }
  .panel-in { padding: 0 clamp(18px, 5vw, 26px); max-height: none; overflow: visible; }
  .panel #albumView, .panel .gear-row { max-height: none; overflow: visible; }
  /* Snapping fights a scroll we're driving; released the moment you touch it. */
  .rail-track.free { scroll-snap-type: none; }
  /* Keep the progress bar on phones — it's the cue that there's more sideways. */
  .rail-progress { position: sticky; bottom: 0; margin: 4px 16px 0; border-radius: 3px; }
}
