/* Site-wide motion: page entrances, scroll reveals and hover/press feedback.
   Only opacity and transform move, and all of it stops for visitors who ask their
   device for reduced motion. motion.js adds the scroll reveals. */
:root {
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-spring: cubic-bezier(.34, 1.45, .64, 1);
}

/* A soft cross-fade between pages (Chrome, Edge, Safari 18+). The header and sidebar
   stay still while the page under them changes. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vt-fade-out .12s ease both; }
::view-transition-new(root) { animation: vt-fade-in .22s ease both; }
.topbar { view-transition-name: topbar; }
.overlay-nav .topbar { view-transition-name: none; }
.mobilebar { view-transition-name: mobilebar; }
@media (min-width: 821px) { .sidebar { view-transition-name: sidebar; } }
@keyframes vt-fade-out { to { opacity: 0; } }
@keyframes vt-fade-in { from { opacity: 0; } }

/* Page entrance: the first blocks of every page rise in, one after another. */
.page > *, .panel-main > *, .auth > * { animation: rise .4s var(--ease-out) backwards; }
.page > :nth-child(2), .panel-main > :nth-child(2), .auth > :nth-child(2) { animation-delay: .04s; }
.page > :nth-child(3), .panel-main > :nth-child(3), .auth > :nth-child(3) { animation-delay: .08s; }
.page > :nth-child(n + 4), .panel-main > :nth-child(n + 4) { animation-delay: .12s; }
.hero h1, .hero .lead, .hero-pill, .hero-cta { animation: rise .5s var(--ease-out) backwards; }
.hero-pill { animation-delay: .03s; }
.hero h1 { animation-delay: .08s; }
.hero .lead { animation-delay: .14s; }
.hero-cta { animation-delay: .2s; }
.hero-stage .screen { animation: pop-in .6s var(--ease-out) .16s backwards; }
.herotabs a { animation: rise .45s var(--ease-out) .24s backwards; }
.herotabs a:nth-child(2) { animation-delay: .28s; }
.herotabs a:nth-child(n + 3) { animation-delay: .32s; }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes pop-in { from { opacity: 0; transform: translateY(18px) scale(.97); } }

/* Scroll reveals, set up by motion.js only for blocks below the fold. The doubled
   attribute outranks each card's own hover transition while the reveal plays. */
[data-motion][data-motion] { opacity: 0; transform: translateY(22px); transition: opacity .42s ease, transform .55s var(--ease-out); transition-delay: var(--reveal-delay, 0s); }
[data-motion][data-motion].revealed { opacity: 1; transform: none; }
@media print { [data-motion][data-motion] { opacity: 1; transform: none; } }

/* Buttons press in and lift a little. */
.btn, .iconbtn, .navicon, .linkbtn { transition: transform .18s var(--ease-spring), opacity .16s, background-color .16s, color .16s, border-color .16s; }
.btn:active, .iconbtn:active, .navicon:active { transform: scale(.95); transition-duration: .07s; }
input, textarea, select { transition: border-color .16s, box-shadow .16s, background-color .16s; }
.sidebar a.nav, .tabs a, .herotabs a, .marquee-item, .screen-row { transition: background-color .16s, color .16s, border-color .16s, transform .2s var(--ease-out); }
.faq details { transition: border-color .16s, transform .22s var(--ease-out); }
.faq details[open] > :not(summary) { animation: rise .3s var(--ease-out) backwards; }
.faq details[open] summary svg { transition: transform .22s var(--ease-spring); }

/* Cards lift on hover; only on devices with a real pointer, so taps don't stick. */
.tool, .railcard, .flip, .rack-item .pass, a.stat, .compare-card, .steps-row li { transition: transform .26s var(--ease-out), box-shadow .26s var(--ease-out); }
.tool .toolart, .railcard .railart { transition: transform .42s var(--ease-out); }
@media (hover: hover) {
  .btn:hover { transform: translateY(-1px); }
  .iconbtn:hover, .navicon:hover { transform: scale(1.08); }
  .tool:hover, .railcard:hover, a.stat:hover, .steps-row li:hover { transform: translateY(-4px); box-shadow: 0 18px 40px rgba(0, 0, 0, .18); }
  .tool:hover .toolart, .railcard:hover .railart { transform: scale(1.04); }
  /* Login cards lift as a whole: a transform on a face would undo its 3D flip. */
  .flip:hover, .rack-item .pass:hover { transform: translateY(-4px); }
  .screen-row:hover, .sidebar a.nav:hover { transform: translateX(3px); }
  .marquee-item:hover { transform: translateY(-2px); }
  .faq details:hover { transform: translateY(-1px); }
}

/* Messages slide in. */
.flash { animation: flash-in .34s var(--ease-spring) backwards; }
@keyframes flash-in { from { opacity: 0; transform: translateY(-10px) scale(.98); } }

/* Switching day/night fades the colours instead of snapping. */
.theme-fade, .theme-fade *, .theme-fade *::before, .theme-fade *::after {
  transition: background-color .3s ease, color .3s ease, border-color .3s ease, fill .3s ease, stroke .3s ease !important;
}

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
  [data-motion][data-motion] { opacity: 1; transform: none; }
}
