/* ==========================================================================
   digitalmarketingtools.ai — motion layer
   --------------------------------------------------------------------------
   Loaded after aurora.css. Everything here is additive: remove this file and
   the site still works, it just sits still.

   Rule followed throughout: the page must be READABLE at rest. Nothing is
   parked at opacity:0 waiting on an observer that might not fire — the load
   sequence animates *from* a visible state, and the reveal system has a
   failsafe that shows everything after 1.2s regardless.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. PAGE-LOAD SEQUENCE — the hero assembles itself once, on arrival
   -------------------------------------------------------------------------- */

/* Headline lines rise in sequence. Each line is clipped by its own mask so
   the type appears to lift off the baseline rather than just fading. */
.hero__title span,
.hero__title em {
  display: inline-block;
  will-change: transform, opacity;
}

html.js .hero__title > span,
html.js .hero__title > em {
  animation: lineUp .95s cubic-bezier(.16,1,.3,1) backwards;
}
html.js .hero__title > span:nth-of-type(1) { animation-delay: .06s; }
html.js .hero__title > span:nth-of-type(2) { animation-delay: .17s; }
html.js .hero__title > em                  { animation-delay: .28s; }

@keyframes lineUp {
  from { opacity: 0; transform: translate3d(0, 42px, 0) rotate(1.2deg); filter: blur(7px); }
  60%  { filter: blur(0); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

/* The badge, sub-line, search bar and chips follow the headline in. */
html.js .hero .badge      { animation: fadeUp .8s cubic-bezier(.16,1,.3,1) backwards .02s; }
html.js .hero__sub        { animation: fadeUp .8s cubic-bezier(.16,1,.3,1) backwards .40s; }
html.js .hero .searchbar  { animation: fadeUp .9s cubic-bezier(.16,1,.3,1) backwards .50s; }
html.js .hero .chips      { animation: fadeUp .8s cubic-bezier(.16,1,.3,1) backwards .60s; }
html.js .hero__stats      { animation: fadeUp .8s cubic-bezier(.16,1,.3,1) backwards .68s; }

@keyframes fadeUp {
  from { opacity: 0; transform: translate3d(0, 20px, 0); }
  to   { opacity: 1; transform: none; }
}

/* The aurora field itself blooms in rather than being there from frame one. */
html.js .hero .aurora-field { animation: bloom 1.6s cubic-bezier(.16,1,.3,1) backwards; }
@keyframes bloom {
  from { opacity: 0; transform: scale(1.14); }
  to   { opacity: 1; transform: none; }
}

/* The search bar's aurora ring sweeps once on arrival, then settles. */
html.js .searchbar__glow { animation: auroraShift 8s var(--ease) infinite alternate, ringIn 1.4s cubic-bezier(.16,1,.3,1) backwards .55s; }
@keyframes ringIn {
  from { opacity: 0; transform: scaleX(.82); }
  to   { opacity: .35; transform: none; }
}

/* --------------------------------------------------------------------------
   2. SCROLL-LINKED AURORA — parallax without a scroll listener
   -------------------------------------------------------------------------- */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero .aurora-blob--1,
    .hero .aurora-blob--3 {
      animation-timeline: scroll(root);
      animation-range: 0 90vh;
    }
    .hero .aurora-blob--1 { animation-name: drift1, parallaxSlow; }
    .hero .aurora-blob--3 { animation-name: drift3, parallaxFast; }
    .hero .grid-veil {
      animation: parallaxVeil linear both;
      animation-timeline: scroll(root);
      animation-range: 0 100vh;
    }
  }
}
@keyframes parallaxSlow { to { transform: translate3d(0, 12vh, 0); } }
@keyframes parallaxFast { to { transform: translate3d(0, 22vh, 0); } }
@keyframes parallaxVeil { to { transform: translate3d(0, 8vh, 0); opacity: .3; } }

/* --------------------------------------------------------------------------
   3. SECTION ENTRANCES — each block header draws its own rule
   -------------------------------------------------------------------------- */
.block__head { position: relative; }
.block__head::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, var(--accent), transparent 62%);
  transform: scaleX(0); transform-origin: left;
  transition: transform 1.1s cubic-bezier(.16,1,.3,1);
}
.block.is-in .block__head::after { transform: scaleX(1); }

/* The square marker beside a block title pops as the section arrives. */
.block__title::before { transition: transform .5s cubic-bezier(.34,1.56,.64,1), box-shadow .5s var(--ease); }
.block.is-in .block__title::before { animation: markerPop .7s cubic-bezier(.34,1.56,.64,1) both .1s; }
@keyframes markerPop {
  0%   { transform: scale(0) rotate(-45deg); }
  100% { transform: scale(1) rotate(0); }
}

/* --------------------------------------------------------------------------
   4. CARD INTERACTION — pointer-tracked light, subtle tilt
   -------------------------------------------------------------------------- */
.card {
  position: relative;
  transform-style: preserve-3d;
  will-change: transform;
}

/* A soft highlight that follows the cursor across the card. --mx/--my are
   set from JS in percentages; the card is perfectly fine without them. */
.card::after {
  content: "";
  position: absolute; inset: 0; z-index: 3;
  border-radius: inherit; pointer-events: none;
  opacity: 0; transition: opacity .35s var(--ease);
  background: radial-gradient(
    340px circle at var(--mx, 50%) var(--my, 50%),
    color-mix(in srgb, var(--accent) 13%, transparent),
    transparent 62%);
}
.card:hover::after { opacity: 1; }

/* The category tag slides out of the cover edge on hover. */
.card__tag { transition: transform .4s cubic-bezier(.16,1,.3,1), box-shadow .3s var(--ease); }
.card:hover .card__tag { transform: translateY(-2px); box-shadow: var(--shadow-1); }

/* Read the excerpt: a hairline grows under the title as you hover. */
.card__title { position: relative; display: inline-block; }
.card__title::after {
  content: "";
  position: absolute; left: 0; right: 100%; bottom: -2px; height: 1.5px;
  background: var(--accent); border-radius: 2px;
  transition: right .45s cubic-bezier(.16,1,.3,1);
}
.card:hover .card__title::after { right: 0; }

/* Feature card gets a slightly deeper lift so the hierarchy holds on hover. */
.card--feature:hover { transform: translateY(-6px); }

/* --------------------------------------------------------------------------
   5. TOOL CARDS
   -------------------------------------------------------------------------- */
.tool__logo { transition: transform .5s cubic-bezier(.34,1.56,.64,1); }
.tool:hover .tool__logo { transform: rotate(-6deg) scale(1.06); }

.tool { position: relative; overflow: hidden; }
.tool::after {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(300px circle at var(--mx, 50%) var(--my, 50%),
    color-mix(in srgb, var(--accent) 9%, transparent), transparent 60%);
  opacity: 0; transition: opacity .35s var(--ease);
}
.tool:hover::after { opacity: 1; }

/* --------------------------------------------------------------------------
   6. PILLS + CHIPS — springy, not linear
   -------------------------------------------------------------------------- */
.pill  { transition: border-color .2s var(--ease), color .2s var(--ease),
                     background-color .2s var(--ease),
                     transform .35s cubic-bezier(.34,1.56,.64,1); }
.pill:hover  { transform: translateY(-2px) scale(1.03); }
.pill:active { transform: translateY(0) scale(.98); }

.chip { transition: all .3s cubic-bezier(.34,1.56,.64,1); }
.chip:hover { transform: translateY(-2px) scale(1.04); box-shadow: var(--shadow-1); }

/* The active homepage pill gets a travelling underline via scroll-spy. */
.pill.is-active { transform: translateY(-1px); }

/* --------------------------------------------------------------------------
   7. BUTTONS — the aurora button gets a sheen sweep
   -------------------------------------------------------------------------- */
.btn--aurora { position: relative; overflow: hidden; }
.btn--aurora::after {
  content: "";
  position: absolute; top: 0; bottom: 0; left: -140%; width: 55%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.42), transparent);
  transform: skewX(-18deg);
  transition: left .75s cubic-bezier(.16,1,.3,1);
}
.btn--aurora:hover::after { left: 150%; }

.btn--primary { position: relative; overflow: hidden; }
.btn--primary::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(120px circle at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,.16), transparent 70%);
  opacity: 0; transition: opacity .3s var(--ease);
}
.btn--primary:hover::after { opacity: 1; }

/* --------------------------------------------------------------------------
   8. STAT COUNTERS
   -------------------------------------------------------------------------- */
.stat__n { font-variant-numeric: tabular-nums; }
.stat { transition: transform .4s cubic-bezier(.16,1,.3,1); }
.stat:hover { transform: translateY(-3px); }

/* --------------------------------------------------------------------------
   9. TICKER — edges fade, and it reverses direction on the second row
   -------------------------------------------------------------------------- */
.ticker { position: relative; }
.ticker__item { transition: color .25s var(--ease); }
.ticker__item:hover { color: var(--ink); }
.ticker__tag { transition: transform .3s cubic-bezier(.34,1.56,.64,1); }
.ticker__item:hover .ticker__tag { transform: scale(1.06); }

/* --------------------------------------------------------------------------
   10. NEWSLETTER BAND — aurora responds to the cursor
   -------------------------------------------------------------------------- */
.band { transition: box-shadow .5s var(--ease); }
.band__inner > * { position: relative; z-index: 3; }
.band::after {
  content: "";
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,.10), transparent 60%);
  opacity: 0; transition: opacity .5s var(--ease);
}
.band:hover::after { opacity: 1; }

.subscribe { transition: border-color .3s var(--ease), background-color .3s var(--ease); }
.subscribe:focus-within { border-color: rgba(255,255,255,.4); background: rgba(255,255,255,.14); }

/* --------------------------------------------------------------------------
   11. HANDOFF CTA — the block that earns the leads should feel alive
   -------------------------------------------------------------------------- */
.handoff { transition: transform .5s cubic-bezier(.16,1,.3,1), box-shadow .5s var(--ease); }
.handoff:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); }
.handoff__list span { transition: transform .3s cubic-bezier(.34,1.56,.64,1), background-color .3s var(--ease); }
.handoff:hover .handoff__list span { background: color-mix(in srgb, var(--violet) 10%, var(--paper-3)); }
.handoff__list span:hover { transform: translateY(-2px); }

/* --------------------------------------------------------------------------
   12. NAV — the logo mark keeps a slow idle rotation on the homepage hero
   -------------------------------------------------------------------------- */
.nav { transition: border-color .3s var(--ease), background-color .3s var(--ease),
                   box-shadow .3s var(--ease), height .3s var(--ease); }
.logo__mark { transition: transform .6s cubic-bezier(.34,1.56,.64,1), box-shadow .3s var(--ease); }
.logo:hover .logo__mark { transform: rotate(135deg) scale(1.06); box-shadow: 0 5px 18px color-mix(in srgb, var(--violet) 40%, transparent); }

/* --------------------------------------------------------------------------
   13. ARTICLE — tags, drop-cap, and a smoother progress bar
   -------------------------------------------------------------------------- */
.a-tags { display: flex; flex-wrap: wrap; gap: var(--s-2); max-width: var(--measure); margin: var(--s-7) auto 0; }
.tag {
  font-family: var(--font-mono); font-size: var(--t-xs);
  padding: 5px 11px; border-radius: var(--r-pill);
  background: var(--paper-3); color: var(--ink-2);
  transition: all .25s cubic-bezier(.34,1.56,.64,1);
}
.tag:hover { background: var(--ink); color: var(--paper); transform: translateY(-2px); }

.prose > p:first-of-type::first-letter {
  float: left; font-family: var(--font-display); font-weight: 600;
  font-size: 3.3em; line-height: .84; margin: .06em .09em 0 0; color: var(--accent);
}

.progress { transition: transform .1s linear; }

/* Prose images and callouts arrive as you reach them. */
.prose .callout { transition: transform .5s cubic-bezier(.16,1,.3,1), box-shadow .4s var(--ease); }
.prose .callout:hover { transform: translateY(-2px); box-shadow: var(--shadow-1); }

/* --------------------------------------------------------------------------
   14. REVEAL — richer variants, still failsafe
   -------------------------------------------------------------------------- */
[data-reveal="scale"] { transform: translateY(16px) scale(.97); }
[data-reveal="left"]  { transform: translateX(-24px); }
[data-reveal="right"] { transform: translateX(24px); }
[data-reveal].is-in   { transform: none !important; }

/* --------------------------------------------------------------------------
   15. ADMIN LINK PILL
   -------------------------------------------------------------------------- */
.proto__link {
  color: var(--paper); text-decoration: underline; text-underline-offset: 2px;
  text-decoration-color: rgba(255,255,255,.4);
  transition: text-decoration-color .2s var(--ease);
}
.proto__link:hover { text-decoration-color: var(--paper); }

/* --------------------------------------------------------------------------
   16. REDUCED MOTION — everything above collapses to a still, readable page
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html.js .hero__title > span,
  html.js .hero__title > em,
  html.js .hero .badge,
  html.js .hero__sub,
  html.js .hero .searchbar,
  html.js .hero .chips,
  html.js .hero__stats,
  html.js .hero .aurora-field,
  html.js .searchbar__glow {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
  .block__head::after { transform: scaleX(1); transition: none; }
  .block.is-in .block__title::before { animation: none; }
  .card::after, .tool::after, .band::after, .btn--primary::after { display: none; }
  .btn--aurora::after { display: none; }
  .card__title::after { display: none; }
  .prose > p:first-of-type::first-letter { float: none; font-size: inherit; margin: 0; color: inherit; }
}

/* ==========================================================================
   17. CSS-ONLY REVEAL FAILSAFE  ← load-bearing, do not remove
   --------------------------------------------------------------------------
   [data-reveal] starts at opacity:0 and waits for JS to add .is-in. That is
   fine until JS does not run — and on this host LiteSpeed rewrites scripts to
   type="litespeed/javascript" and holds them until the visitor interacts, so
   the whole page rendered blank.

   The governing rule for this build is that the page must be READABLE AT
   REST. So the reveal no longer depends on JavaScript at all: this animation
   runs in pure CSS and makes every element visible shortly after paint,
   whatever happens to the script. When JS is working it adds .is-in first,
   this selector stops matching, and the normal transition takes over.

   Belt and braces on purpose: a page that is readable beats a page that
   animates correctly.
   ========================================================================== */
@keyframes dmtRevealFailsafe {
  to { opacity: 1; transform: none; filter: none; }
}
[data-reveal]:not(.is-in) {
  animation: dmtRevealFailsafe .45s cubic-bezier(.16, 1, .3, 1) 1.4s forwards;
}

/* Same protection for the hero load sequence, which is CSS-driven but gated
   on html.js — and that class is set by an inline script a cache plugin can
   also defer. Without the gate the elements simply start visible. */
html:not(.js) [data-reveal] {
  animation: none;
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal]:not(.is-in) { animation: none; opacity: 1; transform: none; }
}
