/**
 * AUTOLINE Motion & Interaction-State layer — PROPOSAL v0.2 (2026-07-27)
 * Sits alongside al-design-tokens.css; same naming style, same rules:
 * tokens or nothing, animate transform/opacity/colour only, no layout thrash.
 * Ships as CSS over the existing WoodMart/Woo markup — no template rewrite.
 * v0.2: card press composes with the hover lift instead of replacing it;
 * hover lift restated through --al-lift-hover; inner-control presses no longer
 * scale the whole card; non-.al-btn controls (.al-box-add, .al-vselect, the
 * usual-items chip controls) covered; specimen-only selectors removed.
 */
:root{
  /* ===== Motion — Duration (extends fast/base/slow) =====
     instant  press acknowledgement — must feel wired to the finger
     enter    things arriving (drawers/large surfaces run the pair at slow)
     exit     things leaving — always shorter than enter
     confirm  how long a success state holds before reverting
     skel     one skeleton sheen loop */
  --al-dur-instant:70ms;
  --al-dur-enter:200ms;
  --al-dur-exit:140ms;
  --al-dur-confirm:1600ms;
  --al-dur-skel:1.4s;

  /* ===== Motion — Easing (pairs alongside --al-ease) =====
     enter  decelerate: arrives fast, settles — for things appearing
     exit   accelerate: leaves without ceremony — for things disappearing
     pop    slight overshoot — ONLY for success ticks and quantity bumps */
  --al-ease-enter:cubic-bezier(0,0,.2,1);
  --al-ease-exit:cubic-bezier(.55,0,1,1);
  --al-ease-pop:cubic-bezier(.2,0,.25,1.2);

  /* ===== Interaction states ===== */
  --al-lift-hover:-3px;          /* the card hover lift, now a token */
  --al-press-scale:.97;          /* buttons and inline controls */
  --al-press-scale-card:.99;     /* whole-card tap acknowledgement */
  --al-disabled-opacity:.45;
  --al-success-ring:0 0 0 2px var(--al-success-500);
  --al-danger-ring:0 0 0 2px var(--al-danger-500);
}

/* ============ Buttons — complete state set (al-btn + al-btn2) ============ */
/* transform joins the transition list at instant speed: press feedback must
   land inside one frame budget, not ease in over 180ms.
   SELECTOR DOUBLED ON PURPOSE — .al-btn.al-btn is (0,2,0) and beats al-home.css's
   own .al-btn{transition:background,border-color} at (0,1,0). Load order cannot be
   used here: al-home.css lands ~490KB LATER in the LiteSpeed combined bundle than
   this file (measured on staging: 178711 vs 671560) regardless of enqueue priority
   or a declared dependency, so an equal-specificity rule silently loses its
   transform transition and the press feedback snaps instead of easing. Same idiom
   al-controls.css already uses (.btn.btn:not(.btn-style-link)) for the same reason. */
.al-btn.al-btn,.al-btn2.al-btn2{transition:background var(--al-dur-base) var(--al-ease),border-color var(--al-dur-base) var(--al-ease),color var(--al-dur-base) var(--al-ease),transform var(--al-dur-instant) var(--al-ease)}
/* active / pressed — the state that was "essentially unstyled site-wide" */
.al-btn:not([disabled]):not(.al-loading):active,
.al-btn2:not([disabled]):active{transform:scale(var(--al-press-scale))}
/* disabled — replaces per-specimen invented opacity */
.al-btn[disabled],.al-btn2[disabled]{opacity:var(--al-disabled-opacity);cursor:not-allowed}
/* success — existing .al-ok colour swap, now announced with a pop */
.al-btn.al-ok{animation:al-pop var(--al-dur-enter) var(--al-ease-pop)}
/* error — existing .al-err colour swap + a short, small shake */
.al-btn.al-err{animation:al-shake 240ms var(--al-ease)}
@keyframes al-pop{0%{transform:scale(.9)}55%{transform:scale(1.04)}100%{transform:scale(1)}}
@keyframes al-shake{20%{transform:translateX(-3px)}40%{transform:translateX(3px)}60%{transform:translateX(-2px)}80%{transform:translateX(2px)}}

/* ==== Commerce controls that are NOT .al-btn get the same vocabulary ====
   .al-box-add (case shortcut), select.al-vselect, and the usual-items chip
   controls (.al-uadd-line, .al-uvar-add, .al-ubox, .al-uqd, .al-uqi) */
.al-box-add,.al-uadd-line,.al-uvar-add,.al-ubox,.al-uqd,.al-uqi{transition:background var(--al-dur-base) var(--al-ease),color var(--al-dur-base) var(--al-ease),border-color var(--al-dur-base) var(--al-ease),transform var(--al-dur-instant) var(--al-ease)}
/* al-home.css sets .al-card .al-box-add{transition:background} at (0,2,0), which
   outranks the (0,1,0) rule above wherever the case button sits inside a card —
   i.e. everywhere it actually renders. Re-state at (0,3,0). The chip controls need
   no such guard: al-home has no descendant-scoped transition rule for them. */
.al-card .al-box-add.al-box-add{transition:background var(--al-dur-base) var(--al-ease),color var(--al-dur-base) var(--al-ease),border-color var(--al-dur-base) var(--al-ease),transform var(--al-dur-instant) var(--al-ease)}
.al-box-add:not([disabled]):active,.al-uadd-line:not([disabled]):not(.al-loading):active,
.al-uvar-add:active,.al-ubox:active,.al-uqd:active,.al-uqi:active{transform:scale(var(--al-press-scale))}
.al-box-add[disabled],.al-uadd-line[disabled],.al-vselect[disabled]{opacity:var(--al-disabled-opacity);cursor:not-allowed}
.al-box-add:focus-visible,.al-uadd-line:focus-visible,.al-uvar-add:focus-visible,
.al-ubox:focus-visible,.al-uqd:focus-visible,.al-uqi:focus-visible{outline:0;box-shadow:var(--al-focus-ring)}
.al-uadd-line.al-ok{animation:al-pop var(--al-dur-enter) var(--al-ease-pop)}
.al-uadd-line.al-err{animation:al-shake 240ms var(--al-ease)}

/* ============ Product card ============ */
.al-card{transition:box-shadow var(--al-dur-base) var(--al-ease),border-color var(--al-dur-base),transform var(--al-dur-base) var(--al-ease)}
/* hover lift restated through the token (same -3px production has always had) */
.al-card:hover{transform:translateY(var(--al-lift-hover))}
/* tap acknowledgement on the whole card (touch has no hover). COMPOSED with
   the lift, never replacing it — and a press on an inner control (buy row,
   variation select) must not scale the card it sits in */
.al-card:active:not(:has(.al-add :active,.al-vselect:active)){transform:scale(var(--al-press-scale-card));transition:box-shadow var(--al-dur-base) var(--al-ease),border-color var(--al-dur-base),transform var(--al-dur-instant) var(--al-ease)}
.al-card:hover:active:not(:has(.al-add :active,.al-vselect:active)){transform:translateY(var(--al-lift-hover)) scale(var(--al-press-scale-card))}
/* add-to-cart confirmed ON the card — success ring, so a dealer adding 40
   lines never has to look away to the drawer */
.al-card.al-added{border-color:var(--al-success-500);box-shadow:var(--al-success-ring),var(--al-shadow-2)}
/* persistent "in cart" line under the buy row — enters, stays for the session */
.al-incart{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:6px;padding:5px 8px;border-radius:var(--al-radius-sm);background:var(--al-success-100);color:var(--al-success-600);font-size:var(--al-fs-xs);font-weight:var(--al-fw-semibold);animation:al-in var(--al-dur-enter) var(--al-ease-enter)}
/* "N in cart", as an OVERLAY rather than a row. Owner 2026-07-27 rejected the
   .al-incart line above for cards: it adds a row under the buy area, grid rows
   stretch, so one card gaining it grows the entire row — which would undo the
   mobile card-height work (381px → 347px). Absolutely positioned inside
   .al-thumb (already position:relative) it costs ZERO layout height.
   .al-incart itself is kept: it is still the right pattern in a list/drawer
   context where a row is free. */
.al-incart-pill{position:absolute;left:8px;bottom:8px;z-index:2;display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:var(--al-radius-pill);background:var(--al-success-500);color:#fff;font-size:var(--al-fs-2xs);font-weight:var(--al-fw-semibold);line-height:1.4;box-shadow:var(--al-shadow-2);pointer-events:none;white-space:nowrap;max-width:calc(100% - 16px);overflow:hidden;text-overflow:ellipsis}

/* quantity change acknowledgement — generic utility, works on .al-qty, the
   chip stepper value, and the header cart count alike */
.al-bump{animation:al-bump 300ms var(--al-ease-pop)}
@keyframes al-bump{40%{transform:scale(1.16)}}
.al-qty:focus-visible{outline:0;box-shadow:var(--al-focus-ring);border-color:var(--al-blue-500)}

/* ============ Enter / exit utilities (confirm lines, filters, drawers) ==== */
/* drawers and large surfaces: same keyframes/eases at --al-dur-slow */
.al-enter{animation:al-in var(--al-dur-enter) var(--al-ease-enter) both}
.al-exit{animation:al-out var(--al-dur-exit) var(--al-ease-exit) forwards}
@keyframes al-in{from{opacity:0;transform:translateY(4px)}}
@keyframes al-out{to{opacity:0;transform:translateY(4px)}}

/* ============ Skeleton (cards + lists) ============ */
/* transform-based sheen (not background-position): compositor-only, and one
   shared pattern replaces the two ad-hoc shimmers in production */
.al-skel{position:relative;overflow:hidden;background:var(--al-bg-100);border-radius:var(--al-radius-sm)}
.al-skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,var(--al-line-200),transparent);animation:al-sheen var(--al-dur-skel) linear infinite}
@keyframes al-sheen{to{transform:translateX(100%)}}

/* ============ Empty state ============ */
.al-empty{display:flex;flex-direction:column;align-items:center;gap:var(--al-sp-2);padding:var(--al-sp-8) var(--al-sp-4);color:var(--al-ink-500);text-align:center;font-size:var(--al-fs-sm);line-height:var(--al-lh-base)}
.al-empty b{color:var(--al-ink-700);font-size:var(--al-fs-md)}

/* ============ Reduced motion ============
   Colour/opacity feedback stays (it carries meaning); movement goes.
   The loading spinner is kept: progress indication is essential motion. */
@media(prefers-reduced-motion:reduce){
  :root{--al-dur-instant:0ms;--al-dur-enter:0ms;--al-dur-exit:0ms}
  .al-btn.al-ok,.al-btn.al-err,.al-uadd-line.al-ok,.al-uadd-line.al-err,
  .al-bump,.al-enter,.al-exit,.al-incart{animation-duration:1ms}
  .al-btn:active,.al-btn2:active,.al-box-add:active,.al-uadd-line:active,
  .al-uvar-add:active,.al-ubox:active,.al-uqd:active,.al-uqi:active,.al-card:active{transform:none}
  .al-card:hover,.al-tile:hover{transform:none}
  .al-skel::after{animation:none}
}
