/* =====================================================================
   HilfBuddy — motion layer
   ---------------------------------------------------------------------
   Deliberately a separate file. Everything in here is additive: delete
   motion.css + motion.js and remove the two tags from the HTML head and
   the site is exactly as it was.

   Every rule below is gated behind `html.motion-ready`, a class that
   motion.js adds *before first paint* and never adds when the visitor
   has "reduce motion" on. So if the script fails, is blocked, or the OS
   asks for calm, nothing is hidden and nothing moves — the page just
   renders.
   ===================================================================== */

:root {
  /* Fall back to local copies in case styles.css ever loads after this. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
}

/* ---------------------------------------------------------------------
   1. Hero entrance
   Seen once per page load, so it can afford to be the most expressive
   moment on the site. Rises 10px and fades — never from scale(0), never
   from nothing. Stagger is 55ms: enough to read as a cascade, short
   enough that the whole hero has settled in under half a second.
   --------------------------------------------------------------------- */
@keyframes hbRiseIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

.motion-ready .hero .kicker,
.motion-ready .hero h1,
.motion-ready .hero .subtitle,
.motion-ready .hero .cta-row,
.motion-ready .price-hero .kicker,
.motion-ready .price-hero h1,
.motion-ready .price-hero .subtitle,
.motion-ready .price-hero .cta-row {
  animation: hbRiseIn 460ms var(--ease-out) both;
}

.motion-ready .hero .kicker,
.motion-ready .price-hero .kicker   { animation-delay: 40ms; }
.motion-ready .hero h1,
.motion-ready .price-hero h1        { animation-delay: 95ms; }
.motion-ready .hero .subtitle,
.motion-ready .price-hero .subtitle { animation-delay: 150ms; }
.motion-ready .hero .cta-row,
.motion-ready .price-hero .cta-row  { animation-delay: 205ms; }

/* ---------------------------------------------------------------------
   2. THE BLOCKS — boomerang in, gravity out
   Only the resting and out states live here. The motion itself is driven
   by the Web Animations API in motion.js, because this is a two-phase
   move — wind up, then release — and a CSS transition can only interpolate
   between two states. WAAPI keeps the hardware acceleration of CSS while
   letting the second phase start from wherever the first one got to.

   ORIGIN AT THE TOP. Everything here stretches or falls downward, and a
   top origin means scaleY grows toward the floor instead of splitting the
   difference around the middle. It is what makes the wind-up read as the
   block sagging under load rather than simply getting bigger.

   No transition on this element: WAAPI owns transform and opacity outright,
   and a CSS transition sitting underneath would fight it every frame.
   --------------------------------------------------------------------- */
.motion-ready [data-block] {
  opacity: 0;
  transform: translateY(16px);
  transform-origin: 50% 0%;
  /* Blocks are backdrop-blurred cards; without this the browser re-rasterises
     that blur on every frame of the pop. */
  backface-visibility: hidden;
}

.motion-ready [data-block].is-in {
  opacity: 1;
  transform: translateY(0);
}

/* ---------------------------------------------------------------------
   3. Cards gain depth on hover, not just size
   scale() alone reads as a zoom. A 2px lift with a deeper shadow reads
   as the card coming toward you, which is what the shadow already
   implies. Fine pointers only — on touch, :hover latches.
   --------------------------------------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  .card,
  .panel {
    transition: transform 220ms var(--ease-out), box-shadow 220ms var(--ease-out),
      border-color 220ms var(--ease-out);
  }

  .card:hover,
  .panel:hover {
    transform: translateY(-2px) scale(1.012);
  }

  .card:active,
  .panel:active {
    transform: translateY(-1px) scale(0.998);
    transition-duration: 90ms;
  }
}

/* ---------------------------------------------------------------------
   4. The primary CTA catches the light
   One sheen sweep across the gold gradient on hover. Slow going out
   (620ms — it is decoration, it should feel liquid), instant coming
   back: slow where the user is deciding, fast where the system is
   responding. Only on the primary button, once per hover, so it stays
   an accent rather than a tic.
   --------------------------------------------------------------------- */
.motion-ready .btn.primary {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.motion-ready .btn.primary::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    rgba(255, 255, 255, 0) 25%,
    rgba(255, 255, 255, 0.42) 50%,
    rgba(255, 255, 255, 0) 75%
  );
  transform: translateX(-130%);
  transition: transform 0ms;
}

@media (hover: hover) and (pointer: fine) {
  .motion-ready .btn.primary:hover::after {
    transform: translateX(130%);
    transition: transform 620ms var(--ease-out);
  }
}

/* ---------------------------------------------------------------------
   5. Mobile menu opens instead of appearing
   display:none -> display:flex is a hard cut, which reads as a glitch on
   a panel that large. The iOS drawer curve suits a surface sliding down
   from under the nav bar. Closing stays instant: the user has already
   decided, and a dismissal that lingers feels like lag.
   --------------------------------------------------------------------- */
@keyframes hbMenuDrop {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes hbMenuRow {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.motion-ready .site-nav.nav-open .nav-actions {
  animation: hbMenuDrop 240ms var(--ease-drawer) both;
}

.motion-ready .site-nav.nav-open .nav-actions > * {
  animation: hbMenuRow 220ms var(--ease-out) both;
}
.motion-ready .site-nav.nav-open .nav-actions > *:nth-child(1) { animation-delay: 40ms; }
.motion-ready .site-nav.nav-open .nav-actions > *:nth-child(2) { animation-delay: 80ms; }
.motion-ready .site-nav.nav-open .nav-actions > *:nth-child(3) { animation-delay: 120ms; }
.motion-ready .site-nav.nav-open .nav-actions > *:nth-child(4) { animation-delay: 160ms; }

/* The burger's three bars morph into an X. Give them the movement curve
   rather than the entrance one — they are travelling, not arriving. */
.motion-ready .nav-burger span {
  transition: transform 260ms var(--ease-in-out), opacity 160ms var(--ease-out);
}

/* ---------------------------------------------------------------------
   6. Configurator chips confirm the toggle
   A module switching on is a state change the price depends on, so it
   earns a beat of feedback. 1.05 and 200ms — noticeable, not bouncy.
   --------------------------------------------------------------------- */
@keyframes hbChipPop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}

.motion-ready .cfg-chip.is-on {
  animation: hbChipPop 200ms var(--ease-out);
}

.motion-ready .cfg-chip:active {
  transform: scale(0.96);
}

/* ---------------------------------------------------------------------
   7. Tara answers a hover
   She already breathes on her own. On hover the idle bob hands over to
   a small lean-in, and the ring around her opens up.
   --------------------------------------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  .motion-ready .tara-fab:hover .tara-photo {
    animation-play-state: paused;
    transform: translateY(-4px) scale(1.06) rotate(-2deg);
  }
}

/* ---------------------------------------------------------------------
   8. Focus rings arrive rather than snap
   Keyboard users see this on every single tab press, so it has to be
   fast — 120ms, and only the offset moves.
   --------------------------------------------------------------------- */
.motion-ready :focus-visible {
  transition: outline-offset 120ms var(--ease-out);
}

/* ---------------------------------------------------------------------
   9. Reduce motion
   Belt and braces: motion.js already withholds `.motion-ready` when the
   OS asks for reduced motion, but if the setting is changed after load
   this catches it without a reload.
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .motion-ready [data-block],
  .motion-ready [data-block].is-in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }

  .motion-ready .hero .kicker,
  .motion-ready .hero h1,
  .motion-ready .hero .subtitle,
  .motion-ready .hero .cta-row,
  .motion-ready .price-hero .kicker,
  .motion-ready .price-hero h1,
  .motion-ready .price-hero .subtitle,
  .motion-ready .price-hero .cta-row,
  .motion-ready .site-nav.nav-open .nav-actions,
  .motion-ready .site-nav.nav-open .nav-actions > *,
  .motion-ready .cfg-chip.is-on {
    animation: none !important;
  }

  .motion-ready .btn.primary::after {
    display: none;
  }

  .motion-ready .card:hover,
  .motion-ready .panel:hover,
  .motion-ready .tara-fab:hover .tara-photo {
    transform: none !important;
  }
}

/* ---------------------------------------------------------------------
   10. The mobile drawer
   This is the menu people actually get on a phone — mobile-menu.js
   injects it and hides the burger nav above. Its stylesheet is appended
   to <head> at runtime, so it sits after this file; the id + class
   selectors below out-specify it rather than reaching for !important.

   Opening is a decision, closing is a dismissal: 280ms out on the iOS
   drawer curve, 180ms back. The rows cascade in behind the panel so the
   menu reads as arriving rather than being already there.
   --------------------------------------------------------------------- */
html.motion-ready #hb-mmenu-panel {
  transition: transform 180ms var(--ease-out);
}

html.motion-ready #hb-mmenu-backdrop.open #hb-mmenu-panel {
  transition: transform 280ms var(--ease-drawer);
}

@keyframes hbDrawerRow {
  from { opacity: 0; transform: translateX(12px); }
  to   { opacity: 1; transform: translateX(0); }
}

html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a,
html.motion-ready #hb-mmenu-backdrop.open .hb-seg {
  animation: hbDrawerRow 260ms var(--ease-out) both;
}

html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a:nth-child(1) { animation-delay: 110ms; }
html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a:nth-child(2) { animation-delay: 145ms; }
html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a:nth-child(3) { animation-delay: 180ms; }
html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a:nth-child(4) { animation-delay: 215ms; }
html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a:nth-child(5) { animation-delay: 250ms; }
html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a:nth-child(6) { animation-delay: 285ms; }
html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a:nth-child(7) { animation-delay: 320ms; }
html.motion-ready #hb-mmenu-backdrop.open .hb-seg { animation-delay: 300ms; }

/* Touch targets in the drawer press like everything else on the site. */
html.motion-ready #hb-mmenu-panel a:active,
html.motion-ready #hb-mmenu-panel button:active {
  transform: scale(0.97);
}

@media (prefers-reduced-motion: reduce) {
  html.motion-ready #hb-mmenu-backdrop.open .hb-mmenu-links a,
  html.motion-ready #hb-mmenu-backdrop.open .hb-seg {
    animation: none !important;
  }
}
