/* ═══════════════════════════════════════════════════════════════════
   DOT LANGUAGE BUTTONS — Click & Interaction States
   Integrates with the existing .al-btn canvas dot-morph system.
   Tokens: --ag, --ag-danger, --ink-*, --warm-bg, --white, --spring, --ease-out
   ═══════════════════════════════════════════════════════════════════ */

/* ─── Dot Language Color Tokens ──────────────────────────────────
   These are specific to the dot-morph button system (#4A8B6A green)
   and distinct from the app's semantic --color-green (#34A853).
   Defined here so the button system is self-contained. ────────── */
.al-btn {
  --ag: #4A8B6A;
  --ag-danger: #B5453C;
}

/* ─── 1. PRIMARY CLICK → FILL → CONFIRMED ─────────────────────── */

/*
 * The fill element uses a radial gradient anchored left-center
 * so it feels like liquid washing across, not a progress bar.
 */
.al-btn .al-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0;
  background: radial-gradient(
    ellipse 200% 160% at -20% 50%,
    rgba(74, 139, 106, 0.14) 0%,
    rgba(74, 139, 106, 0.06) 60%,
    transparent 100%
  );
  transition: none;
  z-index: 0;
  pointer-events: none;
}

.al-btn.filling .al-fill {
  width: 110%; /* overshoot slightly for organic feel */
  transition: width 1500ms cubic-bezier(0.22, 0.68, 0.35, 1.02);
}

.al-btn > span:not(.al-fill),
.al-btn > canvas {
  position: relative;
  z-index: 1;
}

/* Dot pulse on click — the canvas gets a brief scale kick */
.al-btn.clicking canvas.al-dot {
  animation: dot-pulse 350ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

@keyframes dot-pulse {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.3); }
  100% { transform: scale(1); }
}

/* Border glow during fill */
.al-btn.filling {
  box-shadow: 0 0 0 3px rgba(74, 139, 106, 0.10),
              0 0 12px rgba(74, 139, 106, 0.08);
  border-color: rgba(74, 139, 106, 0.4);
  transition: box-shadow 400ms var(--ease-out),
              border-color 300ms var(--ease-out);
}

/* Confirmed state — solid green border, fading glow ring */
.al-btn.confirmed {
  border-color: var(--ag);
  background: rgba(74, 139, 106, 0.04);
  box-shadow: 0 0 0 3px rgba(74, 139, 106, 0.12),
              0 0 16px rgba(74, 139, 106, 0.10);
  transition: box-shadow 600ms var(--ease-out),
              border-color 200ms var(--ease-out),
              background 200ms var(--ease-out);
}

/* Glow ring settles */
.al-btn.confirmed.glow-settle {
  box-shadow: 0 0 0 2px rgba(74, 139, 106, 0.08),
              0 0 4px rgba(74, 139, 106, 0.04);
  transition: box-shadow 1200ms var(--ease-out);
}

/* Text crossfade — the label span */
.al-btn .al-btn-label {
  transition: opacity 180ms var(--ease-out);
}

.al-btn.text-fading .al-btn-label {
  opacity: 0;
}

/* Reverse animation — smooth return to resting */
.al-btn.reversing {
  transition: box-shadow 500ms var(--ease-out),
              border-color 400ms var(--ease-out),
              background 400ms var(--ease-out);
}

.al-btn.reversing .al-fill {
  width: 0;
  opacity: 0;
  transition: width 500ms var(--ease-out),
              opacity 300ms var(--ease-out);
}


/* ─── 2. SECONDARY BUTTON CLICK ───────────────────────────────── */

.al-btn--secondary.clicking {
  animation: secondary-press 380ms var(--spring) forwards;
}

@keyframes secondary-press {
  0%   { transform: scale(1); }
  20%  { transform: scale(0.97); }
  55%  { transform: scale(1.02); }
  100% { transform: scale(1); }
}

.al-btn--secondary.clicking {
  border-color: var(--ink-25);
  transition: border-color 150ms var(--ease-out);
}

/* Ink ripple — pseudo-element radial expansion from click point */
.al-btn--secondary .al-ripple {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(22, 19, 14, 0.06) 0%,
    transparent 70%
  );
  width: 0;
  height: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 0;
  opacity: 1;
}

.al-btn--secondary .al-ripple.expanding {
  animation: ink-ripple 500ms var(--ease-out) forwards;
}

@keyframes ink-ripple {
  0%   { width: 0; height: 0; opacity: 0.8; }
  100% { width: 200px; height: 200px; opacity: 0; }
}


/* ─── 3. DANGER BUTTON → CONFIRMATION ─────────────────────────── */

/* First click — "Are you sure?" state */
.al-btn--danger.al-btn--danger-confirm {
  border-color: rgba(181, 69, 60, 0.5);
  color: var(--ag-danger);
  background: rgba(181, 69, 60, 0.03);
  box-shadow: 0 0 0 2px rgba(181, 69, 60, 0.06);
  transition: all 250ms var(--ease-out);
}

/* Pulsing border while awaiting confirmation */
.al-btn--danger.al-btn--danger-confirm::after {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: 8px;
  border: 1px solid rgba(181, 69, 60, 0.3);
  animation: danger-border-pulse 1.5s ease-in-out infinite;
  pointer-events: none;
}

@keyframes danger-border-pulse {
  0%, 100% { border-color: rgba(181, 69, 60, 0.3); }
  50%      { border-color: rgba(181, 69, 60, 0.55); }
}

/* Second click — red fill sweep */
.al-btn--danger .al-danger-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0;
  background: radial-gradient(
    ellipse 200% 160% at -20% 50%,
    rgba(181, 69, 60, 0.12) 0%,
    rgba(181, 69, 60, 0.05) 60%,
    transparent 100%
  );
  z-index: 0;
  pointer-events: none;
  transition: none;
}

.al-btn--danger.danger-filling .al-danger-fill {
  width: 110%;
  transition: width 500ms cubic-bezier(0.22, 0.68, 0.35, 1.02);
}

.al-btn--danger.danger-confirmed {
  border-color: var(--ag-danger);
  background: rgba(181, 69, 60, 0.05);
  color: var(--ag-danger);
  box-shadow: 0 0 0 2px rgba(181, 69, 60, 0.08);
}

/* Revert animation — smooth fade back */
.al-btn--danger.danger-reverting {
  transition: all 400ms var(--ease-out);
}


/* ─── 4. GHOST BUTTON CLICK ───────────────────────────────────── */

.al-btn--ghost.clicking {
  animation: ghost-press 280ms var(--ease-out) forwards;
}

@keyframes ghost-press {
  0%   { transform: scale(1); background: transparent; }
  30%  { transform: scale(0.98); background: var(--ink-06); }
  60%  { background: var(--ink-06); }
  100% { transform: scale(1); background: transparent; }
}


/* ─── 5. LOADING / PROCESSING STATE ───────────────────────────── */

.al-btn.al-btn--loading {
  pointer-events: none;
  cursor: wait;
}

/* The canvas dot becomes a spinner — handled in JS (draws arc).
   This class tells the draw loop to switch to spinner mode. */

/* Breathing border gradient */
.al-btn.al-btn--loading::before {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: 8px;
  padding: 1px;
  background: linear-gradient(
    90deg,
    var(--ink-12) 0%,
    var(--ag) 25%,
    var(--ink-12) 50%,
    var(--ag) 75%,
    var(--ink-12) 100%
  );
  background-size: 300% 100%;
  animation: border-breathe 2s ease-in-out infinite;
  -webkit-mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
  z-index: 2;
}

@keyframes border-breathe {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* Text crossfade for "Processing..." */
.al-btn.al-btn--loading .al-btn-label {
  opacity: 0.6;
}


/* ─── 6. ERROR STATE ──────────────────────────────────────────── */

.al-btn.al-btn--error {
  animation: error-shake 400ms var(--ease-out);
}

@keyframes error-shake {
  0%   { transform: translateX(0); }
  15%  { transform: translateX(-3px); }
  35%  { transform: translateX(3px); }
  55%  { transform: translateX(-2px); }
  75%  { transform: translateX(2px); }
  100% { transform: translateX(0); }
}

/* Red border flash */
.al-btn.al-btn--error::after {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: 8px;
  border: 1.5px solid var(--ag-danger);
  opacity: 0;
  animation: error-border-flash 400ms var(--ease-out) forwards;
  pointer-events: none;
}

@keyframes error-border-flash {
  0%   { opacity: 0; }
  20%  { opacity: 0.8; }
  100% { opacity: 0; }
}


/* ─── 7. SUCCESS STATE (PERSISTENT) ──────────────────────────── */

.al-btn.al-btn--success {
  border-color: var(--ag);
  box-shadow: 0 0 0 2px rgba(74, 139, 106, 0.08),
              0 0 8px rgba(74, 139, 106, 0.06);
  transition: all 300ms var(--ease-out);
}

/* The dot draws as a green check — handled in JS via icon override.
   This just ensures the text color shifts. */
.al-btn.al-btn--success .al-btn-label {
  color: var(--ink-80);
}


/* ─── SHARED UTILITIES ────────────────────────────────────────── */

/* Prevent layout shift — buttons never change dimensions during states */
.al-btn.filling,
.al-btn.confirmed,
.al-btn.clicking,
.al-btn.al-btn--loading,
.al-btn.al-btn--error,
.al-btn.al-btn--success,
.al-btn.al-btn--danger-confirm {
  height: 36px;
}

/* Stacking context — keeps pseudo-element overlays (::before, ::after)
   inside the button's z-index scope. The base .al-btn class must also
   set position: relative and overflow: hidden for fills to clip. */
.al-btn {
  isolation: isolate;
}


/* ─── REDUCED MOTION ─────────────────────────────────────────────
   Collapse all animations to instant state changes for users who
   prefer reduced motion. Transitions shortened to near-instant. ── */
@media (prefers-reduced-motion: reduce) {
  .al-btn.clicking canvas.al-dot,
  .al-btn--secondary.clicking,
  .al-btn--ghost.clicking,
  .al-btn.al-btn--error {
    animation: none;
  }

  .al-btn.filling .al-fill {
    transition: width 1ms;
  }

  .al-btn--danger.danger-filling .al-danger-fill {
    transition: width 1ms;
  }

  .al-btn.al-btn--loading::before {
    animation: none;
    background: var(--ag);
    background-size: 100% 100%;
  }

  .al-btn--danger.al-btn--danger-confirm::after {
    animation: none;
    border-color: rgba(181, 69, 60, 0.4);
  }

  .al-btn.al-btn--error::after {
    animation: none;
    opacity: 0;
  }

  .al-btn.filling,
  .al-btn.confirmed,
  .al-btn.confirmed.glow-settle,
  .al-btn.reversing,
  .al-btn.reversing .al-fill,
  .al-btn--secondary.clicking,
  .al-btn--danger.danger-reverting,
  .al-btn .al-btn-label,
  .al-btn.al-btn--success {
    transition-duration: 1ms;
  }
}
