/* =========================================================================
   PLUMB - Interaction & motion layer
   -------------------------------------------------------------------------
   The brand is named for the plumb line: a weight on a string that swings,
   then settles to true vertical. That single idea drives the motion system.

   Two registers of motion:
     1. WORKING motion - fast, precise, no bounce. Buttons, rows, inputs,
        page transitions. This is 95% of the product. Uses --ease-out.
     2. SETTLE motion - the one place the brand "finds true vertical": the
        mark on load, a value resolving, an analysis completing. A damped
        pendulum that overshoots once and settles. Uses --ease-plumb /
        --ease-settle and the @keyframes below. Reserved, never decorative.

   Import order: this file is pulled in by colors_and_type.css after the
   tokens are defined, so every var below resolves.
   ========================================================================= */

:root {
  /* ---------- MOTION CURVES --------------------------------------- */
  /* Working UI - Tobias Ahlin ease-out-quint. Precise, no overshoot.     */
  --ease-out:    cubic-bezier(0.22, 1, 0.36, 1);   /* @kind other */
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);   /* @kind other */
  /* The plumb settle - a single, controlled overshoot. The signature.    */
  --ease-plumb:  cubic-bezier(0.34, 1.42, 0.5, 1); /* @kind other */
  /* A softer settle for larger travel (panels, drawers).                 */
  --ease-settle: cubic-bezier(0.16, 1.08, 0.3, 1); /* @kind other */
  /* Radar / scan for AI work.                                            */
  --ease-radar:  cubic-bezier(0.4, 0, 0, 1);       /* @kind other */

  /* ---------- DURATIONS (all @kind other) ------------------------- */
  --dur-instant: 80ms;    /* @kind other */  /* page cross-fade            */
  --dur-fast:    120ms;   /* @kind other */  /* hover, press, focus        */
  --dur-base:    180ms;   /* @kind other */  /* default transition         */
  --dur-slow:    320ms;   /* @kind other */  /* drawer / panel travel      */
  --dur-swing:   1150ms;  /* @kind other */  /* full pendulum settle       */
  --dur-radar:   1600ms;  /* @kind other */  /* one analysis sweep         */

  /* ---------- INTERACTION DISPLACEMENTS --------------------------- */
  /* The system moves by TONE first (ink stop), then by tiny travel.      */
  --press-drop:  1px;     /* how far a control sinks on :active           */
  --lift-rise:   2px;     /* how far a card rises on hover                */
  --nudge:       2px;     /* icon / chevron nudge on hover                */

  /* ---------- PLUMB GEOMETRY (shared by mark + accents) ----------- */
  --plumb-swing-max: 13deg;  /* @kind other */  /* starting amplitude of the settle */
}

/* =========================================================================
   KEYFRAMES
   ========================================================================= */

/* The pendulum settle - a damped swing to true vertical (0deg).
   Apply to a group whose transform-origin sits at the suspension point. */
@keyframes plumb-swing {
  0%   { transform: rotate(calc(-1 * var(--plumb-swing-max))); }
  22%  { transform: rotate(calc(0.62 * var(--plumb-swing-max))); }
  44%  { transform: rotate(calc(-0.32 * var(--plumb-swing-max))); }
  64%  { transform: rotate(calc(0.16 * var(--plumb-swing-max))); }
  82%  { transform: rotate(calc(-0.07 * var(--plumb-swing-max))); }
  100% { transform: rotate(0deg); }
}

/* The string drops and the bob falls into place - used on first paint. */
@keyframes plumb-drop {
  0%   { transform: translateY(-8px); opacity: 0; }
  60%  { opacity: 1; }
  100% { transform: translateY(0); opacity: 1; }
}

/* A value "finds level" - slides up a hair and settles. KPI / number reveal.
   Translate-only (no opacity) so the value is never hidden if the animation
   is skipped (print, reduced-motion, paused/offscreen render). */
@keyframes plumb-settle-up {
  0%   { transform: translateY(7px); }
  100% { transform: translateY(0); }
}

/* Radar sweep for AI analysis cards - a thin signal bar crossing a panel. */
@keyframes plumb-radar {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* Live pulse - the "analysis running" dot. */
@keyframes plumb-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklab, var(--signal-500) 55%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in oklab, var(--signal-500) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--signal-500) 0%, transparent); }
}

/* Right-side drawer / inspector slides in and settles. */
@keyframes plumb-drawer-in {
  0%   { transform: translateX(20px); opacity: 0; }
  100% { transform: translateX(0); opacity: 1; }
}

/* Focus ring drawing in from the corners - used on inputs. */
@keyframes plumb-focus-in {
  0%   { box-shadow: 0 0 0 6px color-mix(in oklab, var(--signal-500) 0%, transparent); }
  100% { box-shadow: 0 0 0 3px color-mix(in oklab, var(--signal-500) 22%, transparent); }
}

/* =========================================================================
   INTERACTION UTILITIES
   Opt-in classes. They encode the system's hover/press/focus behaviour so
   any surface can feel responsive without re-deriving the values.
   ========================================================================= */

/* A control that sinks on press by tone + 1px. Never scales. */
.plumb-press {
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.plumb-press:active {
  transform: translateY(var(--press-drop));
}

/* A card / tile that rises a hair and brightens its border on hover. */
.plumb-lift {
  transition: transform var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
  will-change: transform;
}
.plumb-lift:hover {
  transform: translateY(calc(-1 * var(--lift-rise)));
}

/* An icon / chevron that nudges in the read direction on parent hover. */
.plumb-nudge {
  transition: transform var(--dur-base) var(--ease-plumb);
}
:hover > .plumb-nudge,
.plumb-nudge:hover {
  transform: translateX(var(--nudge));
}

/* A link whose underline draws in from the left on hover. */
.plumb-underline {
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--dur-base) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
  text-decoration: none;
}
.plumb-underline:hover { background-size: 100% 1px; }

/* The signature: any element with .plumb-settle plays the swing once when
   it (or an ancestor with [data-settle]) enters. Replays on :hover for the
   mark. transform-origin must be set by the element (its suspension point). */
.plumb-settle {
  animation: plumb-swing var(--dur-swing) var(--ease-settle) both;
}

/* Number / value that finds level on mount. */
.plumb-value {
  animation: plumb-settle-up var(--dur-slow) var(--ease-plumb) both;
}

/* A panel that hosts a moving radar bar while [data-analyzing] is set. */
.plumb-scan { position: relative; overflow: hidden; }
.plumb-scan[data-analyzing]::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in oklab, var(--signal-500) 0%, transparent) 35%,
    color-mix(in oklab, var(--signal-500) 22%, transparent) 50%,
    color-mix(in oklab, var(--signal-500) 0%, transparent) 65%,
    transparent 100%);
  animation: plumb-radar var(--dur-radar) var(--ease-radar) infinite;
  pointer-events: none;
}

/* Respect reduced-motion - collapse all signature motion to its end state. */
@media (prefers-reduced-motion: reduce) {
  .plumb-settle, .plumb-value { animation: none; }
  .plumb-scan[data-analyzing]::after { animation: none; opacity: 0; }
  * { scroll-behavior: auto !important; }
}
