/**
 * Side cart (Shoptimizer's slide-out mini cart), the add-to-cart feedback that
 * leads into it, and the closed state of the off-canvas mobile menu.
 * Behaviour lives in assets/js/side-cart.js; see the notes there (TASK-67).
 *
 * Container, buttons, motion and feedback only. The cart lines, the total and
 * whatever renders between them come from WooCommerce's mini-cart fragment and
 * other features hook into it, so nothing here restructures that markup.
 *
 * Layers on the :root tokens in style.css — no new colours, fonts or radii.
 */

:root {
  /* One duration for everything that slides or fades in and out with the
     drawer. Under the 250ms the eye reads as "waiting"; the parent's 0.35s
     slide plus its 0.6s overlay fade felt like lag after an add. */
  --fn-drawer-dur: 0.24s;
}

/* --- Drawer: slide with transform, hidden when closed ------------------- */

/* The parent parks the closed drawer at right: -420px and animates `right`
   (transition: all), which re-lays-out the panel on every frame. Worse, a
   panel that is merely off-screen is still visible to the browser, so its
   close button, line links, View cart and Checkout stayed in the Tab order
   and in the screen-reader tree on every page (TASK-67 AC #2).

   Now it sits at right: 0, is pushed out with a transform, and is
   visibility: hidden while closed. The visibility change waits for the slide
   on the way out (the delay) and is immediate on the way in, so the parent's
   synchronous focus() on open lands on a visible element. */
.shoptimizer-mini-cart-wrap {
  right: 0;
  transform: translate3d(100%, 0, 0);
  visibility: hidden;
  transition:
    transform var(--fn-drawer-dur) var(--sg-lux-ease),
    visibility 0s linear var(--fn-drawer-dur);
}

.drawer-open .shoptimizer-mini-cart-wrap {
  transform: none;
  visibility: visible;
  box-shadow: -8px 0 32px rgba(0, 0, 0, 0.08);
  transition:
    transform var(--fn-drawer-dur) var(--sg-lux-ease),
    visibility 0s;
}

/* The parent's own query: it moves the full-width phone drawer to
   right: -100%, which would otherwise win over the right: 0 above. */
@media (max-width: 480px) {
  .shoptimizer-mini-cart-wrap {
    right: 0;
  }
}

/* The drawer is focused on open so a screen reader announces the dialog; it
   is never a Tab stop (tabindex="-1"). Ringing the whole panel would be the
   same fault as the full-region "Skip to content" ring (AC #3), and every
   control inside keeps the site-wide ring. */
#shoptimizerCartDrawer:focus-visible {
  outline: none !important;
  box-shadow: -8px 0 32px rgba(0, 0, 0, 0.08) !important;
}

/* Desktop scrim: the parent's .drawer-open::before only exists while open,
   so it popped in at full strength. Fade it in with the slide. */
@media (min-width: 993px) {
  .drawer-open::before {
    animation: fn-side-cart-fade-in var(--fn-drawer-dur) ease-out both;
  }
}

/* Tablet/phone scrim (.mobile-overlay, shared with the mobile menu and the
   filters): the parent fades it over 0.6s, well behind the panel. */
@media (max-width: 992px) {
  .mobile-overlay {
    transition:
      opacity var(--fn-drawer-dur) ease-out,
      visibility var(--fn-drawer-dur);
  }
}

@keyframes fn-side-cart-fade-in {
  from {
    opacity: 0;
  }
}

/* --- Bottom bars stay out of the way of the drawer and the menu ---------- */

/* The PDP's sticky "Add to cart" bar, the set builder's and the creator
   page's mobile bars are fixed to the bottom at z-index 900–999, above the
   drawer (102). On a phone the open side cart's Checkout button sat exactly
   under the PDP bar — measured at 390×844: Checkout 780–830px, bar 778–844px
   — so the one button the drawer exists for could not be seen or tapped.
   Slide them away while the drawer or the mobile menu is open. */
.pdp-sticky-mobile-cart,
.fn-sb-mbar,
.fn-cr-mbar {
  transition:
    transform var(--fn-drawer-dur) var(--sg-lux-ease),
    visibility 0s;
}

.drawer-open :is(.pdp-sticky-mobile-cart, .fn-sb-mbar, .fn-cr-mbar),
.mobile-toggled :is(.pdp-sticky-mobile-cart, .fn-sb-mbar, .fn-cr-mbar) {
  transform: translate3d(0, 100%, 0);
  visibility: hidden;
  transition:
    transform var(--fn-drawer-dur) var(--sg-lux-ease),
    visibility 0s linear var(--fn-drawer-dur);
}

/* --- Header and close button ------------------------------------------- */

.cart-drawer-heading {
  font-family: var(--sg-body);
  color: var(--sg-text);
}

/* 26px of hit area for the only way out on a phone. 40px now, the icon
   unchanged and still centred on the same spot. */
.shoptimizer-mini-cart-wrap .close-drawer {
  display: flex;
  align-items: center;
  justify-content: center;
  top: 5.5px;
  right: 9px;
  width: 40px;
  height: 40px;
  color: var(--sg-text);
}

/* --- Busy state while the cart updates --------------------------------- */

/* The parent washes the whole drawer white with a spinner in the middle on
   every fragment refresh and remove, so the cart flashed. The overlay still
   blocks clicks (no double removes); what shows is a thin bar under the
   header and the line being removed fading (below). */
#ajax-loading {
  background-color: transparent;
}

#ajax-loading .shoptimizer-loader {
  display: none;
}

#ajax-loading::before {
  content: '';
  position: absolute;
  top: 49px;
  left: 0;
  width: 30%;
  height: 2px;
  background: var(--sg-accent);
  animation: fn-side-cart-progress 0.9s var(--sg-lux-ease) infinite;
}

@keyframes fn-side-cart-progress {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(340%);
  }
}

/* --- Lines --------------------------------------------------------------- */

/* The trash icon was a 14×14px target (WCAG 2.5.8 asks for 24). Grow the
   link to 32px around the same icon, in the 35px gutter it already owns. */
.shoptimizer-mini-cart-wrap .widget_shopping_cart .product_list_widget li a.remove {
  align-items: center;
  justify-content: center;
  left: -4px;
  width: 32px;
  height: 32px;
  margin-top: -16px;
}

/* A removed line answers the tap at once instead of after the round trip. */
.shoptimizer-mini-cart-wrap li.mini_cart_item.fn-line-removing {
  opacity: 0.35;
  pointer-events: none;
  transition: opacity var(--sg-dur-fast) ease-out;
}

/* The line that was just added (or whose quantity just went up): a saffron
   wash that fades out, and a short settle into place. */
.shoptimizer-mini-cart-wrap li.mini_cart_item.fn-line-new {
  animation: fn-side-cart-line-new 1.6s var(--sg-lux-ease) both;
}

@keyframes fn-side-cart-line-new {
  0% {
    background-color: var(--sg-accent-light-bg);
    box-shadow: inset 2px 0 0 var(--sg-accent);
    transform: translateX(8px);
    opacity: 0.4;
  }
  15% {
    transform: none;
    opacity: 1;
  }
  60% {
    background-color: var(--sg-accent-light-bg);
    box-shadow: inset 2px 0 0 var(--sg-accent);
  }
  100% {
    background-color: transparent;
    box-shadow: inset 2px 0 0 transparent;
  }
}

/* --- Buttons ------------------------------------------------------------- */

/* Square, like every other control on the site (the radius tokens are all
   0); the parent rounds these two to 6px. */
.shoptimizer-mini-cart-wrap .woocommerce-mini-cart__buttons a.button {
  border-radius: var(--sg-radius-md);
}

.shoptimizer-mini-cart-wrap .woocommerce-mini-cart__buttons a.button:not(.checkout) {
  border-color: var(--sg-border);
  color: var(--sg-text);
  transition: background-color var(--sg-dur-fast) ease-out;
}

.shoptimizer-mini-cart-wrap .woocommerce-mini-cart__buttons a.button:not(.checkout):hover {
  background-color: var(--sg-accent-light-bg);
}

/* --- Header cart count --------------------------------------------------- */

/* Played when the drawer closes after an add (the drawer covers the header
   cart while open), so the eye lands on where the basket lives. */
.shoptimizer-cart .count.fn-count-bump {
  animation: fn-side-cart-bump 0.42s var(--sg-lux-ease);
}

@keyframes fn-side-cart-bump {
  40% {
    transform: scale(1.3);
  }
}

/* --- Add-to-cart buttons: busy, then done -------------------------------- */

/* PDP. The parent's spinner and transparent-text rules are written for
   `div.product form.cart`; this PDP's form is not inside a div.product, so
   neither matched and "busy" was just the button at 50% opacity — read as
   disabled. Keep it at full strength and swap the label for a spinner.
   No transition: these buttons ease their colour over 0.5s, which left the
   label half-faded under the spinner for most of a short request. */
form.cart .single_add_to_cart_button.loading {
  opacity: 1;
  color: transparent !important;
  cursor: progress;
  transition: none;
}

form.cart .single_add_to_cart_button.loading::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border: 2px solid color-mix(in srgb, var(--sg-on-dark) 35%, transparent);
  border-left-color: var(--sg-on-dark);
  border-radius: 50%;
  content: '';
  opacity: 1;
  animation: fn-side-cart-spin 0.6s linear infinite;
}

/* Shop cards (CommerceKit quick add). CommerceKit greys the link to 40%
   (its .disabled) and draws a 30px spinner over the middle of the card,
   on top of the size swatches. The spinner moves into the link instead.
   The link's wrapper is the form's sibling, not its child; the
   ul.products li.product prefix outranks woocommerce-shop.css's .disabled. */
.cgkit-swatch-form.cgkit-loading::after {
  display: none;
}

.cgkit-as-single-atc-wrap .button.cgkit-as-single-atc {
  position: relative;
}

ul.products li.product form.cgkit-loading ~ .cgkit-as-single-atc-wrap .button.cgkit-as-single-atc {
  opacity: 1;
  color: transparent !important;
  cursor: progress;
  transition: none;
}

ul.products li.product form.cgkit-loading ~ .cgkit-as-single-atc-wrap .button.cgkit-as-single-atc::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  border: 1.5px solid var(--sg-border);
  border-left-color: var(--sg-text);
  border-radius: 50%;
  content: '';
  animation: fn-side-cart-spin 0.6s linear infinite;
}

@keyframes fn-side-cart-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Done: "✓ Added" laid over the label for a moment (side-cart.js adds the
   span), so the button that was pressed confirms it even once the drawer is
   closed again. The label stays in the DOM for assistive tech; the overlay
   is aria-hidden because the dialog opening is what gets announced. */
.fn-atc-done {
  color: transparent !important;
  /* CommerceKit clears the card's size choice right after an add, which
     greys the link (.disabled, 40%) while it is saying "Added". */
  opacity: 1 !important;
  transition: none !important;
}

.fn-atc-done .fn-atc-feedback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45em;
  color: var(--sg-on-dark);
  animation: fn-side-cart-fade-in var(--sg-dur-fast) ease-out both;
  pointer-events: none;
}

/* The card link is ink text on its underline, left-aligned. */
.cgkit-as-single-atc.fn-atc-done .fn-atc-feedback {
  justify-content: flex-start;
  color: var(--sg-text);
}

.fn-atc-feedback svg {
  width: 1.1em;
  height: 1.1em;
  flex: none;
}

/* The parent's own "added" tick (a ::before mask, product.css, more specific
   than anything here) would sit beside ours; it comes back afterwards. */
form.cart .single_add_to_cart_button.fn-atc-done::before {
  display: none !important;
}

/* --- Mobile menu: hidden when closed (TASK-67 AC #2) --------------------- */

/* Same fault as the drawer: below 993px the parent parks .col-full-nav at
   left: -300px and leaves it visible, so all six menu links were Tab stops
   on every phone page. The parent's own query (max-width: 992px) — the child
   pins this element differently above it, see style.css. Visibility waits
   out the parent's 0.1s delay + 0.35s slide on close. */
@media (max-width: 992px) {
  .col-full-nav {
    visibility: hidden;
    transition:
      all 0.35s 0.1s,
      visibility 0s linear 0.45s;
  }

  .mobile-toggled .col-full-nav {
    visibility: visible;
    transition:
      all 0.35s 0.1s,
      visibility 0s;
  }
}

/* --- Reduced motion ------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .shoptimizer-mini-cart-wrap,
  .drawer-open .shoptimizer-mini-cart-wrap,
  .pdp-sticky-mobile-cart,
  .fn-sb-mbar,
  .fn-cr-mbar,
  .drawer-open :is(.pdp-sticky-mobile-cart, .fn-sb-mbar, .fn-cr-mbar),
  .mobile-toggled :is(.pdp-sticky-mobile-cart, .fn-sb-mbar, .fn-cr-mbar) {
    transition: none;
  }

  .drawer-open::before,
  .shoptimizer-cart .count.fn-count-bump,
  .fn-atc-done .fn-atc-feedback {
    animation: none;
  }

  /* No slide or fade: the new line is simply tinted while the class is on. */
  .shoptimizer-mini-cart-wrap li.mini_cart_item.fn-line-new {
    animation: none;
    background-color: var(--sg-accent-light-bg);
    box-shadow: inset 2px 0 0 var(--sg-accent);
  }

  /* A still bar, not a sweeping one. */
  #ajax-loading::before {
    width: 100%;
    animation: none;
    opacity: 0.6;
  }

  @media (max-width: 992px) {
    .mobile-overlay {
      transition: none;
    }

    .col-full-nav,
    .mobile-toggled .col-full-nav {
      transition: none;
    }
  }
}
