/* ============================================================
   ALLEZ — Animations Stylesheet
   animations.css

   Premium / institutional motion system.
   Principles:
     · Easing  — cubic-bezier(0.16, 1, 0.3, 1), a refined ease-out
     · Entrance duration — 500–800ms (slow reads as expensive)
     · Travel  — small: ≤24px on fade-ins, never more
     · Only transform + opacity are animated on scroll
     · No bounce, spring, rotation, scale-pop or colour flashing
   The restraint is the point. Nothing should draw attention to
   itself; the site should simply feel calm and considered.
   ============================================================ */

:root {
  --ease-premium: cubic-bezier(0.16, 1, 0.3, 1);
}

/* Smooth anchor / breadcrumb scrolling.
   (Also declared in style.css:36 — kept here so this file is
   self-contained; identical value, harmless duplicate.) */
html { scroll-behavior: smooth; }

/* ============================================================
   PREMIUM CARD HOVER  (.card-hover, .news-card)
   Declared BEFORE .fi so that, for cards that are both .card-hover
   and .fi, the .fi entrance transition wins during reveal (equal
   specificity → later rule wins). After the entrance settles, JS
   adds .fi-done — declared after .fi, so it wins by source order
   and hands control back to this snappier hover transition.
   See animations.js.

   Subtle lift + soft shadow deepen + faint accent border.
   box-shadow blur/opacity transitions are acceptable on hover.
   ============================================================ */
.card-hover,
.news-card {
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
  transition: transform 0.3s var(--ease-premium),
              box-shadow 0.3s var(--ease-premium),
              border-color 0.3s var(--ease-premium);
}
.card-hover:hover,
.news-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.10);
  /* coral at low opacity — only visible where a border exists,
     never a full-saturation flash */
  border-color: rgba(232, 68, 42, 0.35);
}

/* ============================================================
   SCROLL FADE-INS  (.fi / .fi-left / .fi-right)
   Revealed once via IntersectionObserver (animations.js):
   ~15% visible, unobserved after firing. Re-animating on every
   scroll looks nervous, so it fires a single time.
   ============================================================ */
.fi {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s var(--ease-premium),
              transform 0.7s var(--ease-premium);
}
.fi.visible {
  opacity: 1;
  transform: translateY(0);
}

.fi-left {
  opacity: 0;
  transform: translateX(-24px);
  transition: opacity 0.7s var(--ease-premium),
              transform 0.7s var(--ease-premium);
}
.fi-left.visible {
  opacity: 1;
  transform: translateX(0);
}

.fi-right {
  opacity: 0;
  transform: translateX(24px);
  transition: opacity 0.7s var(--ease-premium),
              transform 0.7s var(--ease-premium);
}
.fi-right.visible {
  opacity: 1;
  transform: translateX(0);
}

/* On narrow screens the page has no overflow-x clip and the gutter
   shrinks to 16px, so a horizontal slide could push past the
   viewport edge. Fall back to a vertical rise — no horizontal
   shift, same calm feel. */
@media (max-width: 640px) {
  .fi-left,
  .fi-right {
    transform: translateY(20px);
  }
  .fi-left.visible,
  .fi-right.visible {
    transform: translateY(0);
  }
}

/* Stagger for card grids is applied as an inline transition-delay
   per child (~90ms, capped at 450ms) by animations.js. There is no
   global .fi:nth-child stagger any more — it wrongly cascaded every
   .fi on the page, including lone headings. */

/* Once the entrance transition finishes, animations.js adds
   .fi-done and clears the inline delay / will-change. This hands
   the element over to the snappier hover transition (and keeps a
   smooth, quick fade if a tab/filter re-reveals it). Declared
   after .fi, so it wins by source order once JS adds it. */
.fi-done {
  transition: opacity 0.3s var(--ease-premium),
              transform 0.3s var(--ease-premium),
              box-shadow 0.3s var(--ease-premium),
              border-color 0.3s var(--ease-premium),
              background-color 0.25s var(--ease-premium);
  transition-delay: 0s;
  will-change: auto;
}

/* ============================================================
   HERO ENTRANCE SEQUENCE  (homepage, load-triggered)
   main.js adds .loaded to .hero-content on window load (not on
   scroll — the hero is above the fold). The children arrive in a
   calm cascade (the headline reveal lives in style.css):
     eyebrow 0 → headline 120 → sub 240ms
   Each: opacity 0→1, translateY(16px→0), 600ms, refined easing.
   will-change is left on this small, fixed set (used sparingly).
   ============================================================ */
.hero-content > .hero-eyebrow,
.hero-content > .hero-sub {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s var(--ease-premium),
              transform 0.6s var(--ease-premium);
  will-change: transform, opacity;
}
.hero-content.loaded > .hero-eyebrow       { opacity: 1; transform: none; transition-delay: 0s;    }
.hero-content.loaded > .hero-sub           { opacity: 1; transform: none; transition-delay: 0.24s; }

/* ============================================================
   LINE-REVEAL  (coral underline that grows on card hover)
   A clean left-to-right wipe — refined easing, slim 2px line.
   ============================================================ */
.line-reveal {
  position: relative;
  overflow: hidden;
}
.line-reveal::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--coral);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease-premium);
}
.line-reveal:hover::after { transform: scaleX(1); }

/* ============================================================
   PULSE  (live / active badges) — subtle opacity breathing
   ============================================================ */
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.6; }
}
.pulse { animation: pulse 2.5s ease-in-out infinite; }

/* ============================================================
   SHIMMER  (placeholder / i18n blank-flash)
   Rewritten to an OPACITY pulse — no background-position animation
   (which Lighthouse flags and which cannot be GPU-composited).
   Note: this @keyframes shares the name "shimmer" with the rule in
   style.css used by [data-i18n]:empty; this file loads last, so the
   i18n placeholder also resolves to this opacity pulse. The i18n
   rule itself is untouched.
   ============================================================ */
@keyframes shimmer {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 0.75; }
}
.shimmer {
  background: rgba(255, 255, 255, 0.04);
  border-radius: 3px;
  animation: shimmer 1.6s ease-in-out infinite;
}

/* ============================================================
   FADE-SCALE  (modal / overlay entry)
   Softened from scale(0.95) to a barely-there scale(0.98).
   ============================================================ */
@keyframes fadeScale {
  from { opacity: 0; transform: scale(0.98); }
  to   { opacity: 1; transform: scale(1); }
}
.fade-scale { animation: fadeScale 0.4s var(--ease-premium) forwards; }

/* ============================================================
   LINK & BUTTON MICRO-INTERACTIONS
   ============================================================ */

/* Gold underline link */
.gold-link {
  color: var(--gold);
  text-decoration: none;
  border-bottom: 1px solid rgba(245, 168, 0, 0.35);
  transition: border-color 0.25s var(--ease-premium);
}
.gold-link:hover { border-color: var(--gold); }

/* Coral text link — keep the existing arrow-gap slide, add a smooth
   colour transition so any hover shift eases rather than jumps. */
.coral-link {
  transition: gap 0.25s var(--ease-premium),
              color 0.2s ease;
}
.coral-link:hover { color: #9e2109; }

/* Nav links — refined colour transition, 250ms ease-out. */
.nav-link { transition: color 0.25s ease-out; }

/* Buttons — unify to 250ms refined easing; primary gets a 2px lift
   and a soft shadow on hover (no scale-pop). */
.btn {
  transition: background-color 0.25s var(--ease-premium),
              transform 0.25s var(--ease-premium),
              box-shadow 0.25s var(--ease-premium);
}
.btn-primary:hover {
  background: var(--deep-navy2);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(15, 25, 35, 0.25);
}

/* ============================================================
   PAGE TRANSITION  (router-less fade) — opacity only
   ============================================================ */
@keyframes pageFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
main { animation: pageFadeIn 0.5s var(--ease-premium); }

/* ============================================================
   REDUCED MOTION
   Users who request reduced motion see content instantly, with no
   movement. (style.css carries a guard too; this keeps animations
   self-contained.)
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .fi, .fi-left, .fi-right {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero-content > * {
    opacity: 1 !important;
    transform: none !important;
  }
}
