/* ==========================================================================
   motion.css — the "premium + dynamic" layer (v2 elevated direction)

   FLAGGED BRAND-RULE BENDS (each marked ⚠ inline):
     ⚠ B1  scroll-reveals            (§10 allows reveals — flagged for visibility)
     ⚠ B2  scale-on-hover + lift     (bends §10 "color shift only, no scale")
     ⚠ B3  drop-shadows / elevation  (bends §7.2 "no drop-shadows, flat fills")
     ⚠ B4  animated counters         (new; in spirit of "no wow on scroll")
     ⚠ B5  animated hero scatter      (bends §13 "no animated elements")

   Everything respects prefers-reduced-motion (reveals resolve to visible,
   counters jump to final value via JS, scatter settles instantly).
   ========================================================================== */

/* --------------------------------------------------------------------------
   No elevation tokens — shadows dropped per design decision (#2/#3).
   Cards are flat; hover affordance is color-shift only.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   ⚠ B1 — Scroll-reveal primitives.
   Elements tagged [data-reveal] start hidden+offset, resolve on .is-in.
   JS (IntersectionObserver) adds .is-in. Staggering via --reveal-i.
   -------------------------------------------------------------------------- */
[data-reveal] {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity 620ms var(--ease-out),
                transform 620ms var(--ease-out);
    transition-delay: calc(var(--reveal-i, 0) * 90ms);
    will-change: opacity, transform;
}
[data-reveal].is-in {
    opacity: 1;
    transform: none;
}
/* Variant: reveal from the side (used for split intros) */
[data-reveal="left"]  { transform: translateX(-26px); }
[data-reveal="right"] { transform: translateX(26px); }
[data-reveal="left"].is-in,
[data-reveal="right"].is-in { transform: none; }

/* Variant: scale-in for the three-dot mark + numerals (subtle) */
[data-reveal="pop"] { transform: translateY(10px) scale(0.96); }
[data-reveal="pop"].is-in { transform: none; }

/* The three-dot mark draws in square-by-square when revealed */
[data-reveal] .title-mark span,
.title-mark[data-reveal] span {
    opacity: 0;
    transform: scale(0.4);
    transition: opacity 360ms var(--ease-out), transform 360ms var(--ease-out);
}
.is-in .title-mark span,
.title-mark.is-in span { opacity: 1; transform: none; }
.is-in .title-mark span:nth-child(1),
.title-mark.is-in span:nth-child(1) { transition-delay: 60ms; }
.is-in .title-mark span:nth-child(2),
.title-mark.is-in span:nth-child(2) { transition-delay: 150ms; }
.is-in .title-mark span:nth-child(3),
.title-mark.is-in span:nth-child(3) { transition-delay: 240ms; }

/* --------------------------------------------------------------------------
   Card hover — FLAT (bends #2/#3 removed). No shadow, no scale, no lift.
   Hover affordance is color-shift only (§10): the pillar seam wipes in and
   the border shifts to cerulean. Numbered/usecase cards keep their flat fill.
   -------------------------------------------------------------------------- */
.num-card,
.pillar,
.usecase {
    transition: border-color var(--dur-mid) var(--ease-inout);
}
.usecase:hover { border-color: var(--cerulean); }
.pillar:hover  { border-color: var(--cerulean); }
/* num-cards have no border to shift; their hover affordance is the seam only
   on pillar cards. Ice/cerulean/midnight fills stay constant — flat by design. */

/* A thin cerulean top-accent that wipes in on hover — the "premium seam" */
.pillar { position: relative; overflow: hidden; }
.pillar::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: var(--cerulean);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 320ms var(--ease-out);
}
[dir="rtl"] .pillar::before { transform-origin: right center; }
.pillar:hover::before { transform: scaleX(1); }

/* --------------------------------------------------------------------------
   Buttons — flat. Press feedback is a 1px nudge only (no shadow).
   -------------------------------------------------------------------------- */
.btn--primary:active { transform: translateY(1px); }

/* --------------------------------------------------------------------------
   ⚠ B5 — Animated hero scatter.
   Tiles drift up + fade into place on load, staggered. After settling they
   hold a near-imperceptible float (8s ease-in-out) — disabled for reduced
   motion. This is the single "wow" moment, spent in the hero only.
   -------------------------------------------------------------------------- */
.scatter .stile {
    opacity: 0;
    animation: tile-settle 900ms var(--ease-out) forwards;
    animation-delay: calc(var(--tile-i, 0) * 80ms + 120ms);
}
@keyframes tile-settle {
    from { opacity: 0; transform: translateY(16px) scale(0.92); }
    to   { opacity: var(--tile-op, 1); transform: none; }
}
/* Perpetual motion once settled — "more alive" choreography.
   Tiles get VARIED drift (vertical / horizontal / diagonal), a few rotate
   slowly, and the diagonal accent's stripe shimmers. Motion is slow
   (8–15s loops) and compositor-only (transform/opacity) so it stays calm and
   cheap. Opacity is pinned to --tile-op so tiles never fall back to 0.
   Positioning is via top/right/bottom/left, so animating transform is safe.

   Per-tile assignment uses :nth-of-type so each tile reads a different
   animation — no two adjacent tiles move identically. */
.hero.is-loaded .scatter .stile {
    opacity: var(--tile-op, 1);
    will-change: transform;
}

/* Drift A — slow vertical bob */
.hero.is-loaded .scatter .stile:nth-of-type(1),
.hero.is-loaded .scatter .stile:nth-of-type(6) {
    animation: drift-bob 11s var(--ease-inout) infinite;
}
/* Drift B — horizontal sway */
.hero.is-loaded .scatter .stile:nth-of-type(2),
.hero.is-loaded .scatter .stile:nth-of-type(7) {
    animation: drift-sway 13s var(--ease-inout) infinite;
}
/* Drift C — diagonal glide */
.hero.is-loaded .scatter .stile:nth-of-type(3),
.hero.is-loaded .scatter .stile:nth-of-type(9) {
    animation: drift-glide 14s var(--ease-inout) infinite;
}
/* Drift D — bob + slow rotation (the small accent + indigo tiles) */
.hero.is-loaded .scatter .stile:nth-of-type(4) {
    animation: drift-rotate 16s var(--ease-inout) infinite;
}
.hero.is-loaded .scatter .stile:nth-of-type(5) {
    animation: drift-rotate-rev 18s var(--ease-inout) infinite;
}
/* Drift E — the SVG dot-grid / architectural tiles: gentle scale-breathe */
.hero.is-loaded .scatter .stile:nth-of-type(8) {
    animation: drift-breathe 12s var(--ease-inout) infinite;
}
/* Stagger the starts so they don't pulse in unison */
.hero.is-loaded .scatter .stile:nth-of-type(2) { animation-delay: -2s; }
.hero.is-loaded .scatter .stile:nth-of-type(3) { animation-delay: -5s; }
.hero.is-loaded .scatter .stile:nth-of-type(4) { animation-delay: -1s; }
.hero.is-loaded .scatter .stile:nth-of-type(5) { animation-delay: -7s; }
.hero.is-loaded .scatter .stile:nth-of-type(6) { animation-delay: -3s; }
.hero.is-loaded .scatter .stile:nth-of-type(7) { animation-delay: -9s; }
.hero.is-loaded .scatter .stile:nth-of-type(8) { animation-delay: -4s; }
.hero.is-loaded .scatter .stile:nth-of-type(9) { animation-delay: -6s; }

@keyframes drift-bob {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-12px); }
}
@keyframes drift-sway {
    0%, 100% { transform: translateX(0); }
    50%      { transform: translateX(10px); }
}
@keyframes drift-glide {
    0%, 100% { transform: translate(0, 0); }
    50%      { transform: translate(-8px, -10px); }
}
@keyframes drift-rotate {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50%      { transform: translateY(-8px) rotate(6deg); }
}
@keyframes drift-rotate-rev {
    0%, 100% { transform: translate(0,0) rotate(0deg); }
    50%      { transform: translate(6px,-6px) rotate(-8deg); }
}
@keyframes drift-breathe {
    0%, 100% { transform: scale(1) translateY(0); }
    50%      { transform: scale(1.06) translateY(-6px); }
}

/* Diagonal accent stripe shimmer — the white band sweeps across the tile.
   Animates background-position of an enlarged gradient so the highlight
   travels. Independent of the tile's own drift. */
.hero.is-loaded .scatter .st-accent::after {
    background: linear-gradient(135deg,
        transparent 40%,
        rgba(255,255,255,0.25) 47%,
        rgba(255,255,255,0.65) 50%,
        rgba(255,255,255,0.25) 53%,
        transparent 60%);
    background-size: 280% 280%;
    background-position: 100% 100%;
    animation: stripe-shimmer 6.5s var(--ease-inout) infinite;
}
@keyframes stripe-shimmer {
    0%   { background-position: 130% 130%; }
    50%  { background-position: -30% -30%; }
    100% { background-position: 130% 130%; }
}

/* --------------------------------------------------------------------------
   Hero text entrance — staggered rise on load (no observer; immediate)
   -------------------------------------------------------------------------- */
.hero__eyebrow,
.hero__title,
.hero__rule,
.hero__lead,
.hero__actions {
    opacity: 0;
    transform: translateY(18px);
    animation: hero-rise 720ms var(--ease-out) forwards;
}
.hero__eyebrow { animation-delay: 80ms; }
.hero__title   { animation-delay: 180ms; }
.hero__rule    { animation-delay: 320ms; transform-origin: left center; }
.hero__lead    { animation-delay: 420ms; }
.hero__actions { animation-delay: 520ms; }
@keyframes hero-rise {
    to { opacity: 1; transform: none; }
}
[dir="rtl"] .hero__rule { transform-origin: right center; }

/* --------------------------------------------------------------------------
   Counter styling hook ⚠ B4 — the number element JS animates.
   No visual change here beyond tabular alignment so digits don't jitter.
   -------------------------------------------------------------------------- */
.count { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   Shift band: the arrow draws its line + the "to" term illuminates on reveal
   -------------------------------------------------------------------------- */
.shift__arrow svg line { stroke-dasharray: 70; stroke-dashoffset: 70; transition: stroke-dashoffset 700ms var(--ease-out) 200ms; }
.shift__arrow svg polyline { opacity: 0; transition: opacity 240ms var(--ease-out) 760ms; }
.shift.is-in .shift__arrow svg line { stroke-dashoffset: 0; }
.shift.is-in .shift__arrow svg polyline { opacity: 1; }

/* --------------------------------------------------------------------------
   Reduced-motion: resolve everything to final state, no animation.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    [data-reveal],
    [data-reveal="left"],
    [data-reveal="right"],
    [data-reveal="pop"] { opacity: 1 !important; transform: none !important; }
    .title-mark span { opacity: 1 !important; transform: none !important; }

    .hero__eyebrow, .hero__title, .hero__rule, .hero__lead, .hero__actions {
        opacity: 1 !important; transform: none !important; animation: none !important;
    }
    .scatter .stile {
        opacity: var(--tile-op, 1) !important;
        animation: none !important;
        transform: none !important;
    }
    .hero.is-loaded .scatter .stile { animation: none !important; transform: none !important; }
    .hero.is-loaded .scatter .st-accent::after { animation: none !important; }
    .shift__arrow svg line { stroke-dashoffset: 0; }
    .shift__arrow svg polyline { opacity: 1; }
}
