/* =======================================================================
 * MOTION — the interface layer that moves
 *
 * Loaded last so it can layer over every component without out-specifying
 * one. Everything here is built from the existing duration and easing tokens;
 * there is no new timing value in this file, deliberately — motion that does
 * not share the system's rhythm reads as a different site.
 *
 * SCROLL REVEALS ARE NOT HERE. They are run by Motion (motion.dev, MIT),
 * vendored at assets/js/vendor/motion.min.js and driven from initMotion() in
 * ui.js — `inView` + `stagger` + spring easing, applied as inline styles and
 * removed again when the animation settles. Nothing in this file hides content,
 * deliberately: if the script is blocked or fails, the page is fully readable.
 *
 * What stays here is everything that is a *response to input*. Those belong in
 * CSS: a hover or a press has to be instant, and routing it through JS would
 * make the cheapest interaction on the page the most expensive.
 *
 * Three rules this file holds itself to:
 *   1. Motion never gates content. Nothing is hidden by a stylesheet.
 *   2. Motion is a response, not decoration. Things move because a finger,
 *      a pointer or a scroll position asked them to.
 *   3. prefers-reduced-motion turns all of it off. The duration tokens already
 *      collapse to 0ms, and initMotion() returns before doing anything.
 * ===================================================================== */

/* -----------------------------------------------------------------------
 * MICRO-INTERACTIONS
 *
 * Deliberately small. The brand target is a premium boutique, and the tell of
 * a cheap storefront is UI that bounces.
 * --------------------------------------------------------------------- */

/* Cards lift towards the pointer. Touch has no hover, so the press state
   below is what a phone actually gets. */
.nk-product-card,
.nk-category-card,
.nk-benefit-card {
  transition:
    transform var(--nk-transition-base),
    box-shadow var(--nk-transition-base),
    border-color var(--nk-transition-base);
}
@media (hover: hover) {
  .nk-product-card:hover,
  .nk-category-card:hover,
  .nk-benefit-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--nk-shadow-md);
  }
}
.nk-product-card:active,
.nk-category-card:active,
.nk-benefit-card:active { transform: scale(0.99); }

/* A button that does not move under a finger reads as a button that did not
   register the tap. 0.97 is the smallest press that is still legible. */
.nk-btn { transition: transform var(--nk-duration-instant) var(--nk-ease-standard),
  background-color var(--nk-transition-base), color var(--nk-transition-base),
  border-color var(--nk-transition-base), box-shadow var(--nk-transition-base); }
.nk-btn:active:not([disabled]) { transform: scale(0.97); }
.nk-icon-btn:active:not([disabled]) { transform: scale(0.92); }

/* The cart count is the one number on the page that changes without the page
   changing, so it is the one that has to announce itself visually too. */
.nk-cart-badge { animation: nk-pop var(--nk-duration-normal) var(--nk-ease-out); }
@keyframes nk-pop {
  0% { transform: scale(0.4); opacity: 0; }
  60% { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); }
}

/*
 * Back to top lifts towards the pointer, like a card does, and deepens its
 * shadow by one step. Only the *visible* button: the resting one carries a
 * transform of its own (the entrance offset, in layout.css) and hovering an
 * invisible button in the corner must not disturb it.
 *
 * The press comes free from `.nk-icon-btn:active:not([disabled])` above, which
 * outranks this rule (0,3,0 against 0,2,0). That is the intended outcome: a
 * finger down beats a pointer over.
 */
@media (hover: hover) {
  .nk-scrolltop--visible:hover {
    transform: translateY(-2px);
    box-shadow: var(--nk-shadow-lg);
  }
}

/* The contact trigger and its rows answer a press the way every other control
   does. The rows lift towards the pointer; the trigger does not, because it is
   also the anchor the menu expands from and a moving anchor drags the column. */
@media (hover: hover) {
  .nk-contact-fab__action:hover {
    transform: translateY(-2px);
    box-shadow: var(--nk-shadow-lg);
  }
}
.nk-contact-fab__trigger:active { transform: scale(0.94); }
.nk-contact-fab__action:active { transform: scale(0.97); }

/* -----------------------------------------------------------------------
 * THE CONTACT TRIGGER'S BREATHING RING
 *
 * Like the stock dot it is allowed for one reason: it is the only thing on
 * the page claiming to be *available right now*. A support button that never
 * moves reads as a link to a contact page; a slow ring says someone is at the
 * other end. It is the loudest of the theme's three loops — a ring that
 * spreads across 12px — which is why it is also the one that yields.
 *
 * It rides on `box-shadow` and nothing else — no transform, no opacity on the
 * button itself — so it stays off the layout, off the main thread and cannot
 * shift the menu anchored to it. 3.2s is slow enough to be peripheral: this is
 * a breath, not a notification.
 *
 * It stops for three reasons, all of them the same principle — the pulse is
 * asking for attention, so it yields whenever something else on screen has a
 * better claim to it:
 *   1. the menu is open (it has already been answered),
 *   2. the pointer is on it,
 *   3. the product page's sticky add-to-cart is up — coral asking to be bought
 *      outranks coral asking to be called, and two pulsing corals do not share
 *      a viewport.
 * --------------------------------------------------------------------- */

@keyframes nk-fab-breathe {
  0%   { box-shadow: var(--nk-shadow-accent), 0 0 0 0 rgb(242 96 60 / 0.35); }
  70%  { box-shadow: var(--nk-shadow-accent), 0 0 0 12px rgb(242 96 60 / 0); }
  100% { box-shadow: var(--nk-shadow-accent), 0 0 0 0 rgb(242 96 60 / 0); }
}

.nk-contact-fab__trigger {
  animation: nk-fab-breathe 3.2s var(--nk-ease-out) infinite;
}
.nk-contact-fab[data-open="true"] .nk-contact-fab__trigger,
body:has(.nk-sticky-cta--visible) .nk-contact-fab__trigger {
  animation: none;
}
@media (hover: hover) {
  .nk-contact-fab__trigger:hover {
    animation: none;
  }
}

/* Social and contact icons: the ring fills, the glyph does not jump. */
.nk-footer__social { transition: background-color var(--nk-transition-base),
  border-color var(--nk-transition-base), color var(--nk-transition-base),
  transform var(--nk-transition-base); }
@media (hover: hover) {
  .nk-footer__social:hover { transform: translateY(-2px); }
}

/* Nav rows settle their background rather than snapping it. */
.nk-drawer__link,
.nk-drawer__sublink,
.nk-mega__list a,
.nk-footer__list a {
  transition: background-color var(--nk-transition-base), color var(--nk-transition-base);
}

/* -----------------------------------------------------------------------
 * REDUCED MOTION
 *
 * The duration tokens already collapse to 0ms, which covers every transition
 * above. Keyframe animations do not read those tokens, so they are stopped
 * here, and the reveal state is forced open in case the observer ran before
 * the preference changed.
 * --------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .nk-cart-badge { animation: none; }
  .nk-stock__dot { animation: none; }
  .nk-contact-fab__trigger { animation: none; }
  .nk-product-sold__icon { animation: none; transform: none; }
  .nk-contact-fab__action:hover,
  .nk-contact-fab__action:active,
  .nk-contact-fab__trigger:active { transform: none; }
  .nk-product-card:hover,
  .nk-category-card:hover,
  .nk-benefit-card:hover,
  .nk-footer__social:hover,
  .nk-scrolltop--visible:hover { transform: none; }
  .nk-btn:active:not([disabled]),
  .nk-icon-btn:active:not([disabled]),
  .nk-product-card:active,
  .nk-category-card:active,
  .nk-benefit-card:active { transform: none; }
}

/* -----------------------------------------------------------------------
 * LIVE STOCK DOT
 *
 * The dot beside "موجود" is the page's only claim that something is true
 * *right now*, and a static dot reads as decoration. A slow pulse on the
 * ring — not the dot — says "live" without turning the buy box into a
 * notification. It rides on box-shadow and opacity only, so it stays off the
 * layout and off the main thread.
 *
 * Only the in-stock and low-stock states pulse. An out-of-stock dot pulsing
 * would be animating a dead end.
 * --------------------------------------------------------------------- */

@keyframes nk-stock-pulse {
  0%   { box-shadow: 0 0 0 0 currentColor; opacity: 1; }
  100% { box-shadow: 0 0 0 6px transparent; opacity: 1; }
}

.nk-stock--in .nk-stock__dot,
.nk-stock--low .nk-stock__dot {
  animation: nk-stock-pulse 1.1s var(--nk-ease-out) infinite;
}

/* -----------------------------------------------------------------------
 * THE SALES BADGE'S HEARTBEAT
 *
 * The third and last loop in this theme, and the quietest of the three. The
 * meta row's «N فروش» pill is the product page's only social proof, and a
 * static pill is read as a label rather than as a number that moves; a slow
 * beat on the bag glyph says other people are buying this.
 *
 * Only the glyph beats, never the pill: the pill carries text, and animating
 * a text box means animating a reflow candidate on every frame. The glyph is
 * an inline-block SVG with a fixed icon-token size, so `transform: scale()`
 * on it composites and touches nothing around it — the number beside it does
 * not shift by a pixel.
 *
 * 2.6s and a 6% peak, deliberately under the contact FAB's 3.2s ring: two
 * coral loops do share this viewport (the FAB only stands down for the
 * sticky add-to-cart, which is a different element), so this one has to stay
 * small enough to be peripheral. It is a heartbeat, not a notification.
 * --------------------------------------------------------------------- */

@keyframes nk-sold-beat {
  0%, 70%, 100% { transform: scale(1); }
  80%           { transform: scale(1.06); }
}

.nk-product-sold__icon {
  animation: nk-sold-beat 2.6s var(--nk-ease-out) infinite;
  /* Isolate the frames from the inline baseline the SVG would otherwise
     be scaled around, so the beat grows from the glyph's own centre. */
  transform-origin: center;
}
