/* ─────────────────────────────────────────────────────────────
   Starboard · Delight layer
   User-flow micro-rewards grounded in Laws of UX, expressed
   strictly inside the frozen motion rails: --duration-1…8,
   --ease-out (enter) / --ease-in (exit), the shared keyframe
   library, no bounces, exits faster than enters, and the global
   prefers-reduced-motion collapse (colors_and_type.css).

   ONE sanctioned keyframe addition: ad-flash-ring (the one-time
   "fresh result" marker). Everything else rides existing
   keyframes (ad-draw, ad-fade-in, ad-fade-up) and tokens.
   Pairs with delight.js (adCountUp, adFlashOnce, adButtonSuccess).
   ───────────────────────────────────────────────────────────── */
@import url('../../colors_and_type.css');

/* ═══ Fresh-result flash — Von Restorff ═════════════════════
   One-time focus-ring pulse: the ring appears at full strength
   and fades out over 1.2s ease-out. Marks the ONE new thing on
   screen (fresh query result, just-arrived row). Runs once —
   never loops. JS (adFlashOnce) removes the class on
   animationend so it can re-arm. */
@keyframes ad-flash-ring {
  from { box-shadow: var(--shadow-focus-ring); }
  to   { box-shadow: 0 0 0 3px rgba(51, 96, 255, 0); }
}
.ad-flash { animation: ad-flash-ring 1.2s var(--ease-out) 1 both; }

/* ═══ Check-draw — peak-end micro-reward ════════════════════
   Checkbox ticks draw themselves on check via the EXISTING
   ad-draw keyframe over --duration-8 (220ms). The 24-unit dash
   covers the 12px check path "m5 12 5 5 9-11" (length ≈ 21.3).
   Opt in per surface with .ad-delight, or use .ad-check-draw on
   any inline check SVG (toasts, confirmation rows). */
.ad-delight .ad-ck__box.is-checked svg path,
.ad-check-draw path {
  stroke-dasharray: 24;
  --ad-draw-length: 24;
  animation: ad-draw var(--duration-8) var(--ease-out) both;
}

/* ═══ Button success morph — peak-end ═══════════════════════
   JS (adButtonSuccess) adds .is-success + injects .ad-btn__check;
   fill swaps to success-500 over --motion-status-change (180ms),
   the label fades, and a centered check draws in via ad-draw.
   Width is preserved — the label keeps its layout at opacity 0,
   the check overlays. JS removes the class to revert. */
.ad-btn .ad-btn__label,
.ad-btn .ad-btn__icon {
  /* Same value the loading state already uses — makes the
     label fade (and revert) ride one beat. Additive only. */
  transition: opacity var(--duration-4) var(--ease-out);
}
.ad-btn.is-success,
.ad-btn.is-success:hover:not(:disabled) {
  color: var(--fg-on-dark);
  background: var(--success-500);
  border-color: var(--success-500);
  box-shadow: none;
  transition:
    background-color var(--motion-status-change),
    border-color var(--motion-status-change),
    box-shadow var(--motion-status-change),
    transform var(--duration-2) var(--ease-out);
}
.ad-btn.is-success .ad-btn__label,
.ad-btn.is-success .ad-btn__icon { opacity: 0; }

.ad-btn__check {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  color: var(--fg-on-dark);
  pointer-events: none;
  opacity: 0;
  /* Exit (revert) fades faster than the draw-in, on --ease-in */
  transition: opacity var(--duration-3) var(--ease-in);
}
.ad-btn__check svg { display: block; }
.ad-btn.is-success .ad-btn__check { opacity: 1; transition: none; }
.ad-btn.is-success .ad-btn__check path {
  stroke-dasharray: 24;
  --ad-draw-length: 24;
  animation: ad-draw var(--duration-8) var(--ease-out) both;
}

/* ═══ Input validation wash — micro-interactions spec ═══════
   One-time background tint: holds for --duration-3 (100ms,
   the validation-bg beat), then fades out over --duration-6.
   Rides the EXISTING ad-fade-in keyframe played in reverse —
   reversing --ease-out yields the ease-in exit feel, and exits
   stay faster than enters. The rgba tints mirror success-100 /
   error-100 composited on white so text stays legible under
   the wash. No shake, ever. JS removes the class on
   animationend to re-arm. */
.ad-input.is-flash-ok::after,
.ad-input.is-flash-err::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  animation: ad-fade-in var(--duration-6) var(--ease-out) var(--duration-3) 1 reverse both;
}
.ad-input.is-flash-ok::after  { background: rgba(18, 183, 106, 0.18); } /* = success-100 wash */
.ad-input.is-flash-err::after { background: rgba(240, 68, 56, 0.14); }  /* = error-100 wash */

/* ═══ Selection pop — pill toggles ══════════════════════════
   Press scale already exists in the system (.ad-btn:active
   0.98, danger 0.97). Pill toggles get the firmer 0.97 on
   press; release pops back to 1 over --duration-2 (80ms).
   Selection fill itself is unchanged (buttons.css). */
.ad-tglgrp--pill .ad-toggle {
  transition:
    background-color var(--duration-4) var(--ease-out),
    color var(--duration-4) var(--ease-out),
    border-color var(--duration-4) var(--ease-out),
    box-shadow var(--motion-focus-primary),
    transform var(--duration-2) var(--ease-out);
}
.ad-tglgrp--pill .ad-toggle:active:not(:disabled) { transform: scale(0.97); }

/* ═══ Hover row glow — list / menu items ════════════════════
   Matches the table row-select pattern: neutral-50 wash plus a
   2px inline-start accent bar scaling in over --motion-row-change
   (120ms). Logical properties keep it RTL-correct. */
.ad-delight-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--fg-default);
  cursor: pointer;
  transition:
    background-color var(--motion-row-change),
    color var(--motion-row-change);
}
.ad-delight-row::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 6px; bottom: 6px;
  width: 2px;
  border-radius: var(--radius-pill);
  background: var(--primary-500);
  transform: scaleY(0);
  transition: transform var(--motion-row-change);
}
.ad-delight-row:hover,
.ad-delight-row:focus-visible {
  background: var(--neutral-50);
  color: var(--fg-strong);
  outline: none;
}
.ad-delight-row:hover::before,
.ad-delight-row:focus-visible::before { transform: scaleY(1); }

/* ═══ Progress goal-gradient — goal-gradient effect ═════════
   Mirrors feedback-v2.css class names (.ad-progress,
   .ad-progress__fill, .ad-progress__value). When the fill
   reaches ≥80%, JS adds .is-nearly-done and the fill brightens
   to a primary-500 → primary-600 gradient. The gradient lives
   on an ::after overlay so the brighten cross-fades on
   --motion-status-change (gradients can't interpolate). */
.ad-progress--goal .ad-progress__fill {
  position: relative;
  overflow: hidden;
}
.ad-progress--goal .ad-progress__fill::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--primary-500), var(--primary-600));
  opacity: 0;
  transition: opacity var(--motion-status-change);
}
.ad-progress--goal.is-nearly-done .ad-progress__fill::after,
.ad-progress--goal .ad-progress__fill.is-nearly-done::after { opacity: 1; }
.ad-progress--goal.is-nearly-done .ad-progress__value { color: var(--primary-700); }

/* Reduced motion: no extra handling needed — the global
   prefers-reduced-motion collapse in colors_and_type.css snaps
   every animation/transition above to 1ms. Nothing here loops
   (ad-shimmer remains the only sanctioned loop, unchanged). */
