/* ============================================================
   MOTION SYSTEM — universal scroll-reveal + card surface.
   All durations, easings, distances come from design-tokens.css.

   Markup contract (for js/scroll-reveal.js):
     <div class="reveal" data-reveal="up">…</div>
     <div class="reveal" data-reveal="fade">…</div>
     <div class="reveal" data-reveal="scale">…</div>
     <div class="reveal" data-reveal="up" data-reveal-once>…</div>  (no exit)
     <div class="reveal-group" data-stagger>            <!-- children stagger -->
       <div class="reveal" data-reveal="up">…</div>
       <div class="reveal" data-reveal="up">…</div>
     </div>

   States set by JS:
     .reveal              — initial (hidden)
     .reveal.is-in-view   — entered (visible)
     (class is removed when leaving viewport unless data-reveal-once)

   prefers-reduced-motion is respected via global-a11y.css.
   ============================================================ */

/* ---- Initial / hidden state ----
   Opacity uses a longer + softer curve than transform so the fade-in
   keeps building after the element has visually settled. The result
   reads as "content has eased into place" rather than a single snap. */
.reveal {
    opacity: 0;
    transition:
        opacity   var(--reveal-duration-fade, 1100ms) var(--reveal-ease-fade, ease),
        transform var(--reveal-duration, 900ms)       var(--reveal-ease, ease),
        filter    var(--reveal-duration-fade, 1100ms) var(--reveal-ease-fade, ease);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

/* will-change is opt-in via .reveal.is-armed (set by scroll-reveal.js
   only while an element is near the viewport). A permanent will-change
   on every .reveal blew Safari memory on fast-scrolled pages with
   many reveals — each became its own GPU layer. */
.reveal.is-armed {
    will-change: opacity, transform;
}

/* ---- Variants — direction / motion type ---- */
.reveal[data-reveal="up"]      { transform: translate3d(0, var(--reveal-distance, 24px), 0); }
.reveal[data-reveal="down"]    { transform: translate3d(0, calc(var(--reveal-distance, 24px) * -1), 0); }
.reveal[data-reveal="left"]    { transform: translate3d(var(--reveal-distance, 24px), 0, 0); }
.reveal[data-reveal="right"]   { transform: translate3d(calc(var(--reveal-distance, 24px) * -1), 0, 0); }
.reveal[data-reveal="fade"]    { transform: none; }
.reveal[data-reveal="scale"]   { transform: scale(var(--reveal-scale, 0.96)); }
.reveal[data-reveal="zoom-up"] { transform: translate3d(0, var(--reveal-distance, 24px), 0) scale(var(--reveal-scale, 0.96)); }
.reveal[data-reveal="blur"]    { filter: blur(8px); transform: translate3d(0, var(--reveal-distance-sm, 12px), 0); }

/* Larger reveal distances + slower fade for hero / showcase contexts */
.reveal[data-reveal-size="lg"] {
    transition-duration:
        var(--reveal-duration-fade-lg, 1400ms),
        var(--reveal-duration-lg, 1200ms),
        var(--reveal-duration-fade-lg, 1400ms);
}
.reveal[data-reveal-size="lg"][data-reveal="up"]      { transform: translate3d(0, var(--reveal-distance-lg, 32px), 0); }
.reveal[data-reveal-size="lg"][data-reveal="zoom-up"] { transform: translate3d(0, var(--reveal-distance-lg, 32px), 0) scale(var(--reveal-scale, 0.985)); }
.reveal[data-reveal-size="sm"][data-reveal="up"]      { transform: translate3d(0, var(--reveal-distance-sm, 8px), 0); }

/* ---- Active / in-view state — universal target ---- */
.reveal.is-in-view {
    opacity: 1;
    transform: none;
    filter: none;
}

/* ---- Stagger — children animate sequentially ----
   Apply data-stagger to a parent. Children with .reveal get
   incremental transition-delay based on their position. */
.reveal-group[data-stagger] > .reveal:nth-child(1)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 0); }
.reveal-group[data-stagger] > .reveal:nth-child(2)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 1); }
.reveal-group[data-stagger] > .reveal:nth-child(3)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 2); }
.reveal-group[data-stagger] > .reveal:nth-child(4)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 3); }
.reveal-group[data-stagger] > .reveal:nth-child(5)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 4); }
.reveal-group[data-stagger] > .reveal:nth-child(6)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 5); }
.reveal-group[data-stagger] > .reveal:nth-child(7)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 6); }
.reveal-group[data-stagger] > .reveal:nth-child(8)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 7); }
.reveal-group[data-stagger] > .reveal:nth-child(9)  { transition-delay: calc(var(--reveal-stagger, 80ms) * 8); }
.reveal-group[data-stagger] > .reveal:nth-child(10) { transition-delay: calc(var(--reveal-stagger, 80ms) * 9); }
.reveal-group[data-stagger] > .reveal:nth-child(11) { transition-delay: calc(var(--reveal-stagger, 80ms) * 10); }
.reveal-group[data-stagger] > .reveal:nth-child(12) { transition-delay: calc(var(--reveal-stagger, 80ms) * 11); }
.reveal-group[data-stagger] > .reveal:nth-child(n + 13) { transition-delay: calc(var(--reveal-stagger, 80ms) * 12); }

/* Slower stagger variant for hero rows */
.reveal-group[data-stagger="lg"] > .reveal:nth-child(1)  { transition-delay: calc(var(--reveal-stagger-lg, 140ms) * 0); }
.reveal-group[data-stagger="lg"] > .reveal:nth-child(2)  { transition-delay: calc(var(--reveal-stagger-lg, 140ms) * 1); }
.reveal-group[data-stagger="lg"] > .reveal:nth-child(3)  { transition-delay: calc(var(--reveal-stagger-lg, 140ms) * 2); }
.reveal-group[data-stagger="lg"] > .reveal:nth-child(4)  { transition-delay: calc(var(--reveal-stagger-lg, 140ms) * 3); }
.reveal-group[data-stagger="lg"] > .reveal:nth-child(5)  { transition-delay: calc(var(--reveal-stagger-lg, 140ms) * 4); }
.reveal-group[data-stagger="lg"] > .reveal:nth-child(n + 6) { transition-delay: calc(var(--reveal-stagger-lg, 140ms) * 5); }

/* When leaving the viewport, reverse the cascade so items closest to the
   exit edge fade out first — feels more natural than uniform fade-out. */
.reveal-group[data-stagger]:not(.is-in-view) > .reveal { transition-delay: 0ms; }

/* ---- Reduced-motion safety net ----
   global-a11y.css already neutralizes durations, but we also remove
   transforms so content is immediately visible on first paint. */
@media (prefers-reduced-motion: reduce) {
    .reveal,
    .reveal[data-reveal] {
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
        transition: none !important;
    }
}

/* ============================================================
   CARD SURFACE — universal card chrome.
   Apply .card-surface to give any block the same border, radius,
   padding, shadow, and hover behavior as every other "card" in the
   theme. Works alone or in combination with .reveal.
   ============================================================ */

.card-surface {
    background: var(--card-bg, #fff);
    border: var(--card-border, 1px solid #e2e8f0);
    border-radius: var(--card-radius, 16px);
    padding: var(--card-pad, 24px);
    box-shadow: var(--card-shadow);
    transition: var(--card-transition);
    position: relative;
}

.card-surface--sm    { border-radius: var(--card-radius-sm, 12px); padding: var(--card-pad-sm, 16px); }
.card-surface--lg    { padding: var(--card-pad-lg, 32px); }
.card-surface--flush { padding: 0; overflow: hidden; }
.card-surface--ghost { background: transparent; border-color: transparent; box-shadow: none; }

/* Lift on hover — universal motion language */
.card-surface--interactive,
a.card-surface,
button.card-surface {
    cursor: pointer;
    text-decoration: none;
    color: inherit;
}
.card-surface--interactive:hover,
a.card-surface:hover,
button.card-surface:hover {
    transform: translateY(var(--card-hover-lift, -4px));
    box-shadow: var(--card-shadow-hover);
    border-color: color-mix(in srgb, var(--color-border, #e2e8f0) 60%, var(--brand-pri, #3264f5));
}
.card-surface--interactive:focus-visible,
a.card-surface:focus-visible,
button.card-surface:focus-visible {
    outline: none;
    box-shadow: var(--card-shadow-hover), var(--shadow-focus);
}
.card-surface--interactive:active,
a.card-surface:active,
button.card-surface:active {
    transform: translateY(calc(var(--card-hover-lift, -4px) / 2));
    transition-duration: var(--duration-instant, 80ms);
}

/* ---- Card layout helpers ---- */
.card-surface__media {
    margin: calc(var(--card-pad) * -1) calc(var(--card-pad) * -1) var(--card-pad);
    border-radius: var(--card-radius) var(--card-radius) 0 0;
    overflow: hidden;
    aspect-ratio: 16 / 10;
    background: var(--color-bg-muted, #f8fafc);
}
.card-surface--flush .card-surface__media { margin: 0; border-radius: 0; }
.card-surface__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--duration-slow, 420ms) var(--ease-standard, ease);
}
.card-surface--interactive:hover .card-surface__media img,
a.card-surface:hover .card-surface__media img,
button.card-surface:hover .card-surface__media img {
    transform: scale(1.04);
}
.card-surface__title {
    margin: 0 0 var(--space-2, 8px);
    font-size: var(--text-lg, 1.25rem);
    font-weight: var(--weight-semibold, 600);
    color: var(--color-fg, #0f172a);
    line-height: var(--leading-snug, 1.35);
}
.card-surface__body {
    margin: 0;
    color: var(--color-fg-subtle, #64748b);
    font-size: var(--text-sm, .875rem);
    line-height: var(--leading-normal, 1.55);
}
.card-surface__footer {
    margin-top: var(--card-gap, 16px);
    display: flex;
    align-items: center;
    gap: var(--space-2, 8px);
}
