﻿/* ═══════════════════════════════════════════════════════════════════════════
   Vior Privé — FX Interaction Layer
   Requires style.css (tokens: --ease-out, --ease-spring, --t-* etc.)
   Class contracts owned by interactions.js (window.FX)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── GLOBAL FOCUS-VISIBLE BASELINE ──────────────────────────────────────── */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
  outline: 1px solid var(--ac);
  outline-offset: 3px;
}
:focus:not(:focus-visible) { outline: none; }

/* ─── REDUCED MOTION — motion off, semantics on ───────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
  .fx-pop  { animation: none !important; }
  .fx-shake { animation: none !important; }
  .fx-check--draw { stroke-dashoffset: 0 !important; transition: none !important; }
  .fx-toast { transition: none !important; }
  .fx-skeleton::after { animation: none !important; }
}

/* ─── KEYFRAMES ───────────────────────────────────────────────────────────── */
@keyframes fx-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.18); }
  70%  { transform: scale(0.96); }
  100% { transform: scale(1); }
}
@keyframes fx-shake {
  0%,100% { transform: translateX(0); }
  20%     { transform: translateX(-6px); }
  40%     { transform: translateX(6px); }
  60%     { transform: translateX(-4px); }
  80%     { transform: translateX(4px); }
}
@keyframes fx-skeleton {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
@keyframes fx-toast-in {
  from { transform: translateY(-14px); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}
@keyframes fx-slide-up {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0);   opacity: 1; }
}

/* ─── TOAST REGION — Mobile-First: full-width strip ──────────────────────── */
.fx-toast-region {
  position: fixed;
  top: 16px;
  left: 16px;
  right: 16px;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
@media (min-width: 768px) {
  .fx-toast-region { top: 24px; left: auto; right: 24px; }
}

.fx-toast {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--sf);
  border: 1px solid var(--bd);
  color: var(--tx);
  font-family: var(--ff-m);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 14px 20px;
  opacity: 0;
  pointer-events: auto;
  will-change: transform, opacity;
}
.fx-toast--in {
  animation: fx-toast-in var(--t-toast) var(--ease-out) forwards;
}
.fx-toast--out {
  transition: opacity var(--t-ui-out) var(--ease-in),
              transform var(--t-ui-out) var(--ease-in);
  opacity: 0;
  transform: translateY(6px);
}
.fx-toast[data-type="error"] {
  border-color: var(--err);
  color: var(--err);
}
.fx-toast[data-type="success"] {
  border-color: var(--ok);
}

/* ─── BUTTON MORPH (Add-to-Cart peak) ────────────────────────────────────── */
.fx-btn-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: opacity var(--t-ui-out) var(--ease-out);
}
.fx-check {
  display: inline-block;
  flex-shrink: 0;
  opacity: 0;
  transform: scale(0);
  transition: opacity var(--t-ui-in) var(--ease-out),
              transform var(--t-ui-in) var(--ease-spring);
}
.fx-check--draw {
  opacity: 1;
  transform: scale(1);
}
.fx-check--draw polyline,
.fx-check--draw path {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset var(--t-success) var(--ease-out);
}
.fx-check polyline,
.fx-check path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 22;
  stroke-dashoffset: 22;
}

/* ─── CART COUNT POP ─────────────────────────────────────────────────────── */
.fx-pop {
  animation: fx-pop 420ms var(--ease-spring) forwards;
  will-change: transform;
}

/* ─── SHAKE (form validation error) ─────────────────────────────────────── */
.fx-shake {
  animation: fx-shake 380ms var(--ease-out) forwards;
  will-change: transform;
}

/* ─── FORM VALIDATION STATES ─────────────────────────────────────────────── */
.fx-field-check {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--ok);
  font-family: var(--ff-m);
  font-size: 8px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin-top: 6px;
  transform: scale(0);
  transform-origin: left center;
  transition: transform var(--t-ui-in) var(--ease-spring);
}
.fx-field-check.visible { transform: scale(1); }
.fx-field-err {
  color: var(--err);
  font-family: var(--ff-m);
  font-size: 8px;
  letter-spacing: 0.12em;
  margin-top: 6px;
  opacity: 0;
  transition: opacity var(--t-ui-in) var(--ease-out);
}
.fx-field-err.visible { opacity: 1; }

/* ─── GRID FILTER TRANSITION ─────────────────────────────────────────────── */
.is-leaving {
  opacity: 0;
  transition: opacity var(--t-ui-out) var(--ease-in);
  pointer-events: none;
}

/* ─── SKELETON SHIMMER ───────────────────────────────────────────────────── */
.fx-skeleton {
  background: var(--sf);
  position: relative;
  overflow: hidden;
}
.fx-skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(51,61,71,0.06) 40%,
    rgba(51,61,71,0.12) 50%,
    rgba(51,61,71,0.06) 60%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: fx-skeleton 1.6s ease-in-out infinite;
}

/* ─── LINK UNDERLINE REVEAL ──────────────────────────────────────────────── */
.link-underline {
  position: relative;
  text-decoration: none;
}
.link-underline::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-hover) var(--ease-out);
}
.link-underline:hover::after,
.link-underline:focus-visible::after { transform: scaleX(1); }

/* ─── DROPDOWN (Sort, future) ────────────────────────────────────────────── */
.fx-dropdown {
  position: absolute;
  z-index: 100;
  background: var(--sf);
  border: 1px solid var(--bd);
  min-width: 160px;
  opacity: 0;
  transform: scale(.97) translateY(-4px);
  transform-origin: top left;
  pointer-events: none;
  transition: opacity var(--t-ui-in) var(--ease-out),
              transform var(--t-ui-in) var(--ease-out);
}
.fx-dropdown.open {
  opacity: 1;
  transform: scale(1) translateY(0);
  pointer-events: auto;
}
