/* LiNK motion, "Comet" R3 (spec docs/superpowers/specs/2026-10-06-r3-comet-panel-and-motion-design.md
   section 4; Comet spec section 2 as amended). The seven motions live in this one file so
   tests/test_motion_css.py can read every animation at once.
   - The un-animated state IS the finished state: keyframes run only inside the no-preference block
     and use fill-mode backwards, so reduced motion, a stale sheet or no CSS animation all show the
     final layout.
   - Only transform and opacity move (comet-progress also slides its background inside the track).
   - Nothing moves over or inside a table, a form field, money or a danger page. No hover motion.
   - Menus and drawers animate when they open and close instantly (focus returns at once).
   - Nothing loops: comet-progress makes three passes and stops.
   readout-settle counts in nav.js; only its layout rules are here. */

/* ---- 1 comet-streak: the tail under the current nav item. A static ornament: the solid underline
   (chrome.css), the bold label and aria-current carry the meaning. .lk-streak is the hook for any
   other nav (the panel side nav adds it). ---- */
.lk-head .lk-nav-link[aria-current="page"],
.lk-streak[aria-current="page"] { position: relative; }
.lk-head .lk-nav-link[aria-current="page"]::after,
.lk-streak[aria-current="page"]::after {
  content: ""; position: absolute; inset-inline: 10px; bottom: 5px; height: 2px;
  background: linear-gradient(90deg, transparent, var(--lk-peach), var(--lk-orchid), var(--lk-cyan));
  transform-origin: left center; pointer-events: none;
}

/* ---- 3 readout-settle (nav.js): reserve the width; the real number is only visually hidden while
   its aria-hidden copy counts, so screen readers always read the real value ---- */
[data-lk-settle] { display: inline-block; font-variant-numeric: tabular-nums; }
.lk-settle--run .lk-settle__real {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

@media (prefers-reduced-motion: no-preference) {
  /* 1 comet-streak: once per page load, after first paint */
  .lk-head .lk-nav-link[aria-current="page"]::after,
  .lk-streak[aria-current="page"]::after {
    animation: lk-comet-streak var(--lk-dur-4) var(--lk-ease-out) 120ms backwards;
  }
  @keyframes lk-comet-streak { from { opacity: 0; transform: scaleX(0); } }

  /* 2 hero-reveal: the page's one orchestrated moment (home, game page, gate-page art).
     The H1 never moves: it is the LCP element. Text starts at 40 % opacity, never invisible. */
  .lk-hero__lead {
    animation: lk-hero-reveal var(--lk-dur-3) var(--lk-ease-out) backwards;
  }
  .lk-hero__actions, .lk-game-hero__actions {
    animation: lk-hero-reveal var(--lk-dur-3) var(--lk-ease-out) 60ms backwards;
  }
  /* .lk-gate__art and .lk-hero .lk-comet match nothing until Plan Pb adds that markup */
  .lk-hero .lk-comet, .lk-game-hero .lk-comet, .lk-gate__art {
    animation: lk-hero-reveal var(--lk-dur-3) var(--lk-ease-out) 120ms backwards;
  }
  @keyframes lk-hero-reveal { from { opacity: 0.4; transform: translateY(4px); } }
  /* 2b hero comet (Plan Pb): the still fades out while the canvas takes over, and back in if the
     canvas gives up. The only transition in this file. */
  .lk-comet__still { transition: opacity var(--lk-dur-3) var(--lk-ease-out); }

  /* 2c skin-nova gate art (skin-nova.css) is the gate page's hero moment: same reveal */
  html[data-skin="nova"] .lk-skin-art {
    animation: lk-hero-reveal var(--lk-dur-3) var(--lk-ease-out) backwards;
  }
  /* 2d owner decision 2026-10-12: the depth-skin gate figure hovers gently, forever (the only loop
     in the site, depth skin only, 8 px of travel, nothing near the form). It starts after the reveal. */
  html[data-skin="nova"] .lk-skin-art__svg {
    animation: lk-skin-float 7s ease-in-out 400ms infinite;
  }
  @keyframes lk-skin-float { 50% { transform: translateY(-8px); } }

  /* 4 menu-open: the account menu grows from its corner. No closing rule: closing is instant. */
  .lk-js .lk-profile__menu[data-open="true"],
  .lk-profile[open] > .lk-profile__menu {
    transform-origin: top right;
    animation: lk-menu-open var(--lk-dur-2) var(--lk-ease-out) backwards;
  }
  @keyframes lk-menu-open { from { opacity: 0; transform: translateY(-4px) scale(0.98); } }

  /* 5 drawer: the phone menu slides in from the inline-start edge. Closing is instant. */
  .lk-js .lk-head .site-menu[data-open="true"],
  .lk-drawer[data-open="true"] {
    animation: lk-drawer var(--lk-dur-3) var(--lk-ease-out) backwards;
  }
  @keyframes lk-drawer { from { transform: translateX(-100%); } }

  /* 6 comet-progress: a real pending task, its text always beside the bar. Three passes (2.7 s),
     then the still striped track (components.css). */
  .lk-progress__bar:indeterminate {
    animation: lk-comet-progress 900ms linear 3 backwards;
  }
  @keyframes lk-comet-progress {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
  }

  /* 7 sparkle-new: one twinkle when the unread count grows (nav.js adds the class, never on load) */
  .noti-badge.lk-sparkle-new .lk-icon {
    animation: lk-sparkle-new 600ms var(--lk-ease-out);
  }
  @keyframes lk-sparkle-new {
    0% { transform: scale(0.6) rotate(0deg); }
    60% { transform: scale(1.1) rotate(20deg); }
    100% { transform: scale(1) rotate(0deg); }
  }
}
