/* ==========================================================================
   LocalDubaiBusiness — motion system
   Rules this file obeys:
   1. Only transform, opacity, clip-path and stroke-dashoffset are animated.
      Nothing animates width, height, top, left or margin, so no layout is
      recalculated mid-animation and nothing contributes to CLS.
   2. Every element has a legible resting state. Reveal classes are applied by
      JS only after it confirms it can also remove them, so a JS failure leaves
      the page fully readable rather than blank.
   3. prefers-reduced-motion disables all of it in one place, at the bottom.
   ========================================================================== */

/* ---- 1. REVEAL PRIMITIVES ----------------------------------------------- */
/* .js-motion is set on <html> by the inline module boot, so these rules only
   apply when JavaScript is actually running. */
.js-motion [data-reveal]{opacity:0;will-change:transform,opacity}
.js-motion [data-reveal="up"]    {transform:translate3d(0,18px,0)}
.js-motion [data-reveal="down"]  {transform:translate3d(0,-14px,0)}
.js-motion [data-reveal="left"]  {transform:translate3d(-18px,0,0)}
.js-motion [data-reveal="right"] {transform:translate3d(18px,0,0)}
.js-motion [data-reveal="scale"] {transform:scale(.965)}
.js-motion [data-reveal="blur"]  {transform:translate3d(0,10px,0);filter:blur(6px)}

.js-motion [data-reveal].is-in{
  opacity:1;transform:none;filter:none;
  transition:opacity 620ms var(--ease),transform 760ms var(--ease),filter 520ms var(--ease);
  transition-delay:var(--d,0ms);
  will-change:auto;
}

/* ---- 2. HEADLINE REVEAL -------------------------------------------------
   The headline is split into word spans by JS. Each word rises out of its own
   clipping mask, so the line assembles rather than fading. The <h1> keeps its
   real text for screen readers and for the no-JS case. */
.headline .w{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.08em;margin-bottom:-.08em}
.headline .w > i{display:inline-block;font-style:inherit;transform:translateY(110%);
  transition:transform 900ms var(--ease);transition-delay:var(--d,0ms)}
.headline.is-in .w > i{transform:none}
.js-motion .headline.is-pending{opacity:1}

/* ---- 3. HERO CHOREOGRAPHY -----------------------------------------------
   One orchestrated entrance, ~700ms end to end. The input is interactive from
   the first frame: it is never disabled and never covered. */
.js-motion .hero-in > *{opacity:0;transform:translate3d(0,14px,0)}
.hero-in.is-in > *{opacity:1;transform:none;
  transition:opacity 540ms var(--ease),transform 680ms var(--ease);transition-delay:var(--d,0ms)}
.js-motion .hero .ask{transform:translate3d(0,22px,0) scale(.985)}
.hero-in.is-in .ask{transform:none;transition:opacity 560ms var(--ease),transform 820ms var(--ease);
  transition-delay:var(--d,0ms)}

/* ---- 4. STAGGERED LISTS -------------------------------------------------- */
.js-motion [data-stagger] > *{opacity:0;transform:translate3d(0,14px,0)}
[data-stagger].is-in > *{opacity:1;transform:none;
  transition:opacity 480ms var(--ease),transform 620ms var(--ease)}
[data-stagger].is-in > *:nth-child(1){transition-delay:0ms}
[data-stagger].is-in > *:nth-child(2){transition-delay:55ms}
[data-stagger].is-in > *:nth-child(3){transition-delay:110ms}
[data-stagger].is-in > *:nth-child(4){transition-delay:165ms}
[data-stagger].is-in > *:nth-child(5){transition-delay:220ms}
[data-stagger].is-in > *:nth-child(6){transition-delay:275ms}
[data-stagger].is-in > *:nth-child(7){transition-delay:320ms}
[data-stagger].is-in > *:nth-child(8){transition-delay:360ms}
[data-stagger].is-in > *:nth-child(n+9){transition-delay:400ms}

/* ---- 5. FLIP REORDER ----------------------------------------------------
   Used when organic results are filtered or re-sorted. JS measures before and
   after, then plays the difference as a transform. The DOM is already in its
   final position throughout, so nothing jumps if the animation is interrupted. */
.flip-move{transition:transform 520ms var(--ease)}
.flip-enter{animation:flipEnter 460ms var(--ease) both}
.flip-exit{animation:flipExit 240ms var(--ease) both;pointer-events:none}
@keyframes flipEnter{from{opacity:0;transform:translate3d(0,16px,0) scale(.985)}
  to{opacity:1;transform:none}}
@keyframes flipExit{to{opacity:0;transform:translate3d(0,-8px,0) scale(.99)}}

/* Results container fades to a working state rather than flashing white. */
.results-wrap{position:relative;transition:opacity var(--dur-2) var(--ease)}
.results-wrap.is-loading{opacity:.55;pointer-events:none}

/* ---- 6. ASK → MATCH → CHOOSE STORY ---------------------------------------
   The brand sequence. Three stages advance on scroll; each stage is legible on
   its own, so a viewer who never scrolls still sees the whole idea. */
.story{position:relative;display:grid;gap:18px;min-width:0}
@media(min-width:880px){.story{grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}}
.story-stage{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:22px;position:relative;overflow:hidden;
  transition:border-color 420ms var(--ease),box-shadow 520ms var(--ease),transform 520ms var(--ease)}
.story-stage.is-live{border-color:var(--accent);box-shadow:var(--sh-2);transform:translateY(-3px)}
.story-stage .n{font-family:var(--f-mono);font-size:.68rem;letter-spacing:.16em;color:var(--accent);
  text-transform:uppercase}
.story-stage h3{margin:8px 0 6px}
.story-stage p{font-size:.875rem;color:var(--ink-2)}
.story-vis{margin-top:14px;min-height:92px;display:flex;flex-wrap:wrap;gap:7px;align-items:flex-start;
  align-content:flex-start}
.story-vis .chip{animation:none;opacity:0;transform:translateY(8px)}
.story-stage.is-live .story-vis .chip,.story-stage.is-seen .story-vis .chip{
  opacity:1;transform:none;transition:opacity 420ms var(--ease),transform 520ms var(--ease)}
.story-stage .story-vis .chip:nth-child(2){transition-delay:120ms}
.story-stage .story-vis .chip:nth-child(3){transition-delay:240ms}
.story-line{position:absolute;left:0;top:0;height:2px;background:var(--accent);width:0;
  transition:width 700ms var(--ease);border-radius:2px}
.story-stage.is-live .story-line,.story-stage.is-seen .story-line{width:100%}
.story-card{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-md);
  padding:10px 12px;font-size:.8125rem;width:100%;display:flex;justify-content:space-between;gap:10px;
  align-items:center;opacity:0;transform:translateY(10px)}
.story-stage.is-live .story-card,.story-stage.is-seen .story-card{opacity:1;transform:none;
  transition:opacity 420ms var(--ease),transform 520ms var(--ease)}
.story-stage .story-card:nth-of-type(2){transition-delay:110ms}
.story-stage .story-card:nth-of-type(3){transition-delay:220ms}
.story-card .m{font-family:var(--f-mono);font-size:.72rem;color:var(--accent)}

/* ---- 7. COUNTERS --------------------------------------------------------
   Counted from a real database value rendered in the HTML. JS reads the final
   number from the element, so the correct figure is present with JS disabled. */
.count{font-variant-numeric:tabular-nums}

/* ---- 8. TAP FEEDBACK ----------------------------------------------------- */
@media (hover:none){
  .cat:active,.area:active,.ccard:active,.fcard:active{transform:scale(.98)}
}

/* ---- 9. PAGE TRANSITION --------------------------------------------------
   A short outgoing fade only. No content is hidden on arrival, so a slow
   navigation never leaves a blank screen. */
.js-motion body{animation:pageIn 320ms var(--ease) both}
@keyframes pageIn{from{opacity:0}to{opacity:1}}
body.is-leaving{opacity:.35;transition:opacity 180ms var(--ease)}

/* ---- 10. REDUCED MOTION --------------------------------------------------
   One switch. Everything above collapses to its resting state instantly, and
   no information is lost, because nothing is conveyed by motion alone. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
  html{scroll-behavior:auto}
  .js-motion [data-reveal],
  .js-motion [data-stagger] > *,
  .js-motion .hero-in > *,
  .js-motion .hero .ask{opacity:1!important;transform:none!important;filter:none!important}
  .headline .w > i{transform:none!important}
  .carousel-track{scroll-behavior:auto}
  .story-stage .story-vis .chip,.story-card{opacity:1!important;transform:none!important}
  .ring .bar{transition:none}
  .sbar i{transition:none}
}
